nightmaremail

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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;