1 #include <errno.h>
2 #include <fcntl.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <unistd.h>
9 #include "installer.h"
10 
11 static int sourcedir;
12 
13 static char buffer[4096];
14 
diesys(const char * msg)15 static void diesys(const char* msg)
16 {
17   fprintf(stderr, "installer error: %s:\n  %s\n", msg,
18 	  strerror(errno));
19   exit(1);
20 }
21 
diefsys(const char * msg,const char * filename)22 static void diefsys(const char* msg, const char* filename)
23 {
24   fprintf(stderr, "installer error: %s '%s':\n  %s\n", msg, filename,
25 	  strerror(errno));
26   exit(1);
27 }
28 
setmodes(const char * filename,unsigned uid,unsigned gid,unsigned mode)29 static void setmodes(const char* filename,
30 		     unsigned uid, unsigned gid, unsigned mode)
31 {
32   if (chown(filename, uid, gid) == -1)
33     diefsys("Could not set owner or group for", filename);
34   if (chmod(filename, mode) == -1)
35     diefsys("Could not set mode for", filename);
36 }
37 
c(int dir,const char * filename,unsigned uid,unsigned gid,unsigned mode)38 void c(int dir, const char* filename,
39        unsigned uid, unsigned gid, unsigned mode)
40 {
41   int fdin;
42   int fdout;
43   size_t rd;
44   size_t wr;
45   size_t offset;
46 
47   if (fchdir(sourcedir) == -1)
48     diesys("Could not change base directory");
49   if ((fdin = open(filename, O_RDONLY)) == -1)
50     diefsys("Could not open input file", filename);
51 
52   if (fchdir(dir) == -1)
53     diesys("Could not change base directory");
54   if ((fdout = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) == -1)
55     diefsys("Could not create output file", filename);
56 
57   while ((rd = read(fdin, buffer, sizeof buffer)) != 0) {
58     if (rd == (unsigned)-1) diefsys("Error reading from input file", filename);
59     for (offset = 0; offset < rd; offset += wr) {
60       if ((wr = write(fdout, buffer+offset, rd-offset)) == (unsigned)-1)
61 	diefsys("Error writing to output file", filename);
62     }
63   }
64   if (close(fdout) == -1) diefsys("Error closing output file", filename);
65   close(fdin);
66   setmodes(filename, uid, gid, mode);
67 }
68 
d(int dir,const char * subdir,unsigned uid,unsigned gid,unsigned mode)69 int d(int dir, const char* subdir,
70       unsigned uid, unsigned gid, unsigned mode)
71 {
72   if (fchdir(dir) == -1)
73     diesys("Could not change base directory");
74   if (mkdir(subdir, 0700) == -1 && errno != EEXIST)
75     diefsys("Could not create directory", subdir);
76   if ((dir = open(subdir, O_RDONLY)) == -1)
77     diefsys("Could not open created directory", subdir);
78   setmodes(subdir, uid, gid, mode);
79   return dir;
80 }
81 
opendir(const char * dir)82 int opendir(const char* dir)
83 {
84   int fd;
85   if (chdir(dir) == -1)
86     diefsys("Could not change directory to", dir);
87   if ((fd = open(".", O_RDONLY)) == -1)
88     diefsys("Could not open directory", dir);
89   return fd;
90 }
91 
opensubdir(int dir,const char * subdir)92 int opensubdir(int dir, const char* subdir)
93 {
94   if (fchdir(dir) == -1)
95     diesys("Could not change base directory in opensubdir");
96   return opendir(subdir);
97 }
98 
main(void)99 int main(void)
100 {
101   sourcedir = opendir(".");
102   umask(077);
103   insthier();
104   return 0;
105 }
106