X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/qmail/blobdiff_plain/2117e02ec495fdfd6e96b39778b701a5bcff8aa5..212b6f5da7c68d4577de2855da3c57ecf476dc96:/install.c?ds=sidebyside diff --git a/install.c b/install.c index ffc09a6..95034f2 100644 --- a/install.c +++ b/install.c @@ -1,167 +1,164 @@ #include "substdio.h" -#include "stralloc.h" -#include "getln.h" +#include "strerr.h" +#include "error.h" +#include "open.h" #include "readwrite.h" #include "exit.h" -#include "open.h" -#include "error.h" -#include "strerr.h" -#include "byte.h" -#include "fifo.h" -stralloc target = {0}; -char *to; +extern void hier(); #define FATAL "install: fatal: " -void nomem() { strerr_die2x(111,FATAL,"out of memory"); } + +int fdsourcedir = -1; + +void h(home,uid,gid,mode) +char *home; +int uid; +int gid; +int mode; +{ + if (mkdir(home,0700) == -1) + if (errno != error_exist) + strerr_die4sys(111,FATAL,"unable to mkdir ",home,": "); + if (chown(home,uid,gid) == -1) + strerr_die4sys(111,FATAL,"unable to chown ",home,": "); + if (chmod(home,mode) == -1) + strerr_die4sys(111,FATAL,"unable to chmod ",home,": "); +} + +void d(home,subdir,uid,gid,mode) +char *home; +char *subdir; +int uid; +int gid; +int mode; +{ + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + if (mkdir(subdir,0700) == -1) + if (errno != error_exist) + strerr_die6sys(111,FATAL,"unable to mkdir ",home,"/",subdir,": "); + if (chown(subdir,uid,gid) == -1) + strerr_die6sys(111,FATAL,"unable to chown ",home,"/",subdir,": "); + if (chmod(subdir,mode) == -1) + strerr_die6sys(111,FATAL,"unable to chmod ",home,"/",subdir,": "); +} + +void p(home,fifo,uid,gid,mode) +char *home; +char *fifo; +int uid; +int gid; +int mode; +{ + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + if (fifo_make(fifo,0700) == -1) + if (errno != error_exist) + strerr_die6sys(111,FATAL,"unable to mkfifo ",home,"/",fifo,": "); + if (chown(fifo,uid,gid) == -1) + strerr_die6sys(111,FATAL,"unable to chown ",home,"/",fifo,": "); + if (chmod(fifo,mode) == -1) + strerr_die6sys(111,FATAL,"unable to chmod ",home,"/",fifo,": "); +} char inbuf[SUBSTDIO_INSIZE]; char outbuf[SUBSTDIO_OUTSIZE]; substdio ssin; substdio ssout; -void doit(line) -stralloc *line; +void c(home,subdir,file,uid,gid,mode) +char *home; +char *subdir; +char *file; +int uid; +int gid; +int mode; { - char *x; - unsigned int xlen; - unsigned int i; - char *type; - char *uidstr; - char *gidstr; - char *modestr; - char *mid; - char *name; - unsigned long uid; - unsigned long gid; - unsigned long mode; int fdin; int fdout; - unsigned long zlen; - - x = line->s; xlen = line->len; - - type = x; - i = byte_chr(x,xlen,':'); if (i == xlen) return; - x[i++] = 0; x += i; xlen -= i; - - uidstr = x; - i = byte_chr(x,xlen,':'); if (i == xlen) return; - x[i++] = 0; x += i; xlen -= i; - - gidstr = x; - i = byte_chr(x,xlen,':'); if (i == xlen) return; - x[i++] = 0; x += i; xlen -= i; - - modestr = x; - i = byte_chr(x,xlen,':'); if (i == xlen) return; - x[i++] = 0; x += i; xlen -= i; - - mid = x; - i = byte_chr(x,xlen,':'); if (i == xlen) return; - x[i++] = 0; x += i; xlen -= i; - - name = x; - i = byte_chr(x,xlen,':'); if (i == xlen) return; - x[i++] = 0; x += i; xlen -= i; - - if (!stralloc_copys(&target,to)) nomem(); - if (!stralloc_cats(&target,mid)) nomem(); - if (!stralloc_cats(&target,name)) nomem(); - if (!stralloc_0(&target)) nomem(); - - uid = -1; if (*uidstr) scan_ulong(uidstr,&uid); - gid = -1; if (*gidstr) scan_ulong(gidstr,&gid); - scan_8long(modestr,&mode); - - switch(*type) { - case 'z': - scan_ulong(type + 1,&zlen); - - fdout = open_trunc(target.s); - if (fdout == -1) - strerr_die4sys(111,FATAL,"unable to write ",target.s,": "); - substdio_fdbuf(&ssout,write,fdout,outbuf,sizeof(outbuf)); - - while (zlen--) - if (substdio_put(&ssout,"",1) == -1) - strerr_die4sys(111,FATAL,"unable to write ",target.s,": "); - - if (substdio_flush(&ssout) == -1) - strerr_die4sys(111,FATAL,"unable to write ",target.s,": "); - if (fsync(fdout) == -1) - strerr_die4sys(111,FATAL,"unable to write ",target.s,": "); - close(fdout); - break; - - case 'p': - if (fifo_make(target.s,0700) == -1) - if (errno != error_exist) - strerr_die4sys(111,FATAL,"unable to mkfifo ",target.s,": "); - break; - - case 'd': - if (mkdir(target.s,0700) == -1) - if (errno != error_exist) - strerr_die4sys(111,FATAL,"unable to mkdir ",target.s,": "); - break; - - case 'c': - fdin = open_read(name); - if (fdin == -1) - strerr_die4sys(111,FATAL,"unable to read ",name,": "); - substdio_fdbuf(&ssin,read,fdin,inbuf,sizeof(inbuf)); - - fdout = open_trunc(target.s); - if (fdout == -1) - strerr_die4sys(111,FATAL,"unable to write ",target.s,": "); - substdio_fdbuf(&ssout,write,fdout,outbuf,sizeof(outbuf)); - - switch(substdio_copy(&ssout,&ssin)) { - case -2: - strerr_die4sys(111,FATAL,"unable to read ",name,": "); - case -3: - strerr_die4sys(111,FATAL,"unable to write ",target.s,": "); - } - - close(fdin); - if (substdio_flush(&ssout) == -1) - strerr_die4sys(111,FATAL,"unable to write ",target.s,": "); - if (fsync(fdout) == -1) - strerr_die4sys(111,FATAL,"unable to write ",target.s,": "); - close(fdout); - break; - - default: - return; + + if (fchdir(fdsourcedir) == -1) + strerr_die2sys(111,FATAL,"unable to switch back to source directory: "); + + fdin = open_read(file); + if (fdin == -1) + strerr_die4sys(111,FATAL,"unable to read ",file,": "); + substdio_fdbuf(&ssin,read,fdin,inbuf,sizeof inbuf); + + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + if (chdir(subdir) == -1) + strerr_die6sys(111,FATAL,"unable to switch to ",home,"/",subdir,": "); + + fdout = open_trunc(file); + if (fdout == -1) + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); + substdio_fdbuf(&ssout,write,fdout,outbuf,sizeof outbuf); + + switch(substdio_copy(&ssout,&ssin)) { + case -2: + strerr_die4sys(111,FATAL,"unable to read ",file,": "); + case -3: + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); } - if (chown(target.s,uid,gid) == -1) - strerr_die4sys(111,FATAL,"unable to chown ",target.s,": "); - if (chmod(target.s,mode) == -1) - strerr_die4sys(111,FATAL,"unable to chmod ",target.s,": "); + close(fdin); + if (substdio_flush(&ssout) == -1) + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); + if (fsync(fdout) == -1) + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); + if (close(fdout) == -1) /* NFS silliness */ + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); + + if (chown(file,uid,gid) == -1) + strerr_die6sys(111,FATAL,"unable to chown .../",subdir,"/",file,": "); + if (chmod(file,mode) == -1) + strerr_die6sys(111,FATAL,"unable to chmod .../",subdir,"/",file,": "); } -char buf[256]; -substdio in = SUBSTDIO_FDBUF(read,0,buf,sizeof(buf)); -stralloc line = {0}; - -void main(argc,argv) -int argc; -char **argv; +void z(home,file,len,uid,gid,mode) +char *home; +char *file; +int len; +int uid; +int gid; +int mode; { - int match; + int fdout; - umask(077); + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + + fdout = open_trunc(file); + if (fdout == -1) + strerr_die6sys(111,FATAL,"unable to write ",home,"/",file,": "); + substdio_fdbuf(&ssout,write,fdout,outbuf,sizeof outbuf); + + while (len-- > 0) + if (substdio_put(&ssout,"",1) == -1) + strerr_die6sys(111,FATAL,"unable to write ",home,"/",file,": "); + + if (substdio_flush(&ssout) == -1) + strerr_die6sys(111,FATAL,"unable to write ",home,"/",file,": "); + if (fsync(fdout) == -1) + strerr_die6sys(111,FATAL,"unable to write ",home,"/",file,": "); + if (close(fdout) == -1) /* NFS silliness */ + strerr_die6sys(111,FATAL,"unable to write ",home,"/",file,": "); + + if (chown(file,uid,gid) == -1) + strerr_die6sys(111,FATAL,"unable to chown ",home,"/",file,": "); + if (chmod(file,mode) == -1) + strerr_die6sys(111,FATAL,"unable to chmod ",home,"/",file,": "); +} - to = argv[1]; - if (!to) strerr_die2x(100,FATAL,"install: usage: install dir"); +void main() +{ + fdsourcedir = open_read("."); + if (fdsourcedir == -1) + strerr_die2sys(111,FATAL,"unable to open current directory: "); - for (;;) { - if (getln(&in,&line,&match,'\n') == -1) - strerr_die2sys(111,FATAL,"unable to read input: "); - doit(&line); - if (!match) - _exit(0); - } + umask(077); + hier(); + _exit(0); }