instfiles.c (5676B)
1 #include <sys/types.h> 2 #include <sys/stat.h> 3 #include <string.h> 4 #include <stdlib.h> 5 #include <unistd.h> 6 #include "substdio.h" 7 #include "strerr.h" 8 #include "env.h" 9 #include "error.h" 10 #include "fifo.h" 11 #include "open.h" 12 #include "str.h" 13 #include "stralloc.h" 14 15 #define FATAL "instfiles: fatal: " 16 17 int fdsourcedir = -1; 18 19 static void die_nomem() 20 { 21 strerr_die2sys(111,FATAL,"out of memory"); 22 } 23 24 static void ddhome(stralloc *dd, char *home) 25 { 26 const char *denv = env_get("DESTDIR"); 27 if (denv) 28 if (!stralloc_copys(dd,denv)) die_nomem(); 29 30 if (!stralloc_catb(dd,home,str_len(home))) die_nomem(); 31 if (!stralloc_0(dd)) die_nomem(); 32 } 33 34 static int mkdir_p(char *home, int mode) 35 { 36 stralloc parent = { 0 }; 37 unsigned int sl; 38 int r = mkdir(home,mode); 39 if (!r || errno != error_noent) 40 return r; 41 42 /* try parent first */ 43 sl = str_rchr(home, '/'); 44 if (!stralloc_copyb(&parent,home,sl)) die_nomem(); 45 if (!stralloc_0(&parent)) die_nomem(); 46 r = mkdir_p(parent.s,mode); 47 free(parent.s); 48 if (r && errno != error_exist) 49 return r; 50 51 return mkdir(home,mode); 52 } 53 54 void h(char *home, uid_t uid, gid_t gid, int mode) 55 { 56 stralloc dh = { 0 }; 57 ddhome(&dh, home); 58 home=dh.s; 59 if (mkdir_p(home,mode) == -1) 60 if (errno != error_exist) 61 strerr_die4sys(111,FATAL,"unable to mkdir ",home,": "); 62 if (chmod(home,mode) == -1) 63 strerr_die4sys(111,FATAL,"unable to chmod ",home,": "); 64 free(dh.s); 65 } 66 67 void d(char *home, char *subdir, uid_t uid, gid_t gid, int mode) 68 { 69 stralloc dh = { 0 }; 70 ddhome(&dh, home); 71 home=dh.s; 72 if (chdir(home) == -1) 73 strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); 74 if (mkdir(subdir,0700) == -1) 75 if (errno != error_exist) 76 strerr_die6sys(111,FATAL,"unable to mkdir ",home,"/",subdir,": "); 77 if (chmod(subdir,mode) == -1) 78 strerr_die6sys(111,FATAL,"unable to chmod ",home,"/",subdir,": "); 79 free(dh.s); 80 } 81 82 void p(char *home, char *fifo, uid_t uid, gid_t gid, int mode) 83 { 84 stralloc dh = { 0 }; 85 ddhome(&dh, home); 86 home=dh.s; 87 if (chdir(home) == -1) 88 strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); 89 if (fifo_make(fifo,0700) == -1) 90 if (errno != error_exist) 91 strerr_die6sys(111,FATAL,"unable to mkfifo ",home,"/",fifo,": "); 92 if (chmod(fifo,mode) == -1) 93 strerr_die6sys(111,FATAL,"unable to chmod ",home,"/",fifo,": "); 94 free(dh.s); 95 } 96 97 char inbuf[SUBSTDIO_INSIZE]; 98 char outbuf[SUBSTDIO_OUTSIZE]; 99 substdio ssin; 100 substdio ssout; 101 102 void c(char *home, char *subdir, char *fromdir, char *file, uid_t uid, gid_t gid, int mode) 103 { 104 int fdin; 105 int fdout; 106 stralloc dh = { 0 }; 107 108 if (fchdir(fdsourcedir) == -1) 109 strerr_die2sys(111,FATAL,"unable to switch back to top directory: "); 110 111 if (chdir(fromdir) == -1) 112 strerr_die4sys(111,FATAL,"unable to switch back to from directory ",fromdir,": "); 113 114 fdin = open_read(file); 115 if (fdin == -1) { 116 /* silently ignore missing catman pages */ 117 if (errno == error_noent && strncmp(subdir, "man/cat", 7) == 0) 118 return; 119 strerr_die4sys(111,FATAL,"unable to read ",file,": "); 120 } 121 122 /* if the user decided to build only dummy catman pages then don't install */ 123 if (strncmp(subdir, "man/cat", 7) == 0) { 124 struct stat st; 125 if (fstat(fdin, &st) != 0) 126 strerr_die4sys(111,FATAL,"unable to stat ",file,": "); 127 if (st.st_size == 0) { 128 close(fdin); 129 return; 130 } 131 } 132 133 ddhome(&dh, home); 134 home=dh.s; 135 136 substdio_fdbuf(&ssin,read,fdin,inbuf,sizeof(inbuf)); 137 138 if (chdir(home) == -1) 139 strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); 140 if (chdir(subdir) == -1) 141 strerr_die6sys(111,FATAL,"unable to switch to ",home,"/",subdir,": "); 142 143 fdout = open_trunc(file); 144 if (fdout == -1) 145 strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); 146 substdio_fdbuf(&ssout,write,fdout,outbuf,sizeof(outbuf)); 147 148 switch(substdio_copy(&ssout,&ssin)) { 149 case -2: 150 strerr_die4sys(111,FATAL,"unable to read ",file,": "); 151 case -3: 152 strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); 153 } 154 155 close(fdin); 156 if (substdio_flush(&ssout) == -1) 157 strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); 158 if (fsync(fdout) == -1) 159 strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); 160 if (close(fdout) == -1) /* NFS silliness */ 161 strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); 162 163 if (chmod(file,mode) == -1) 164 strerr_die6sys(111,FATAL,"unable to chmod .../",subdir,"/",file,": "); 165 free(dh.s); 166 } 167 168 void z(char *home, char *file, int len, uid_t uid, gid_t gid, int mode) 169 { 170 int fdout; 171 stralloc dh = { 0 }; 172 173 ddhome(&dh, home); 174 home=dh.s; 175 if (chdir(home) == -1) 176 strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); 177 178 fdout = open_trunc(file); 179 if (fdout == -1) 180 strerr_die6sys(111,FATAL,"unable to write ",home,"/",file,": "); 181 substdio_fdbuf(&ssout,write,fdout,outbuf,sizeof(outbuf)); 182 183 while (len-- > 0) 184 if (substdio_put(&ssout,"",1) == -1) 185 strerr_die6sys(111,FATAL,"unable to write ",home,"/",file,": "); 186 187 if (substdio_flush(&ssout) == -1) 188 strerr_die6sys(111,FATAL,"unable to write ",home,"/",file,": "); 189 if (fsync(fdout) == -1) 190 strerr_die6sys(111,FATAL,"unable to write ",home,"/",file,": "); 191 if (close(fdout) == -1) /* NFS silliness */ 192 strerr_die6sys(111,FATAL,"unable to write ",home,"/",file,": "); 193 194 if (chmod(file,mode) == -1) 195 strerr_die6sys(111,FATAL,"unable to chmod ",home,"/",file,": "); 196 free(dh.s); 197 } 198 199 /* these are ignored, but hier() passes them to h() and friends */ 200 uid_t auto_uida = -1; 201 uid_t auto_uido = -1; 202 uid_t auto_uidq = -1; 203 uid_t auto_uidr = -1; 204 uid_t auto_uids = -1; 205 206 gid_t auto_gidq = -1;