chiark / gitweb /
Debianization and various other fixes.
[ezmlm] / install.c
1 #include "substdio.h"
2 #include "stralloc.h"
3 #include "getln.h"
4 #include "readwrite.h"
5 #include "exit.h"
6 #include "open.h"
7 #include "error.h"
8 #include "strerr.h"
9 #include "byte.h"
10
11 stralloc target = {0};
12 char *to;
13
14 #define FATAL "install: fatal: "
15 void nomem() { strerr_die2x(111,FATAL,"out of memory"); }
16
17 char inbuf[SUBSTDIO_INSIZE];
18 char outbuf[SUBSTDIO_OUTSIZE];
19 substdio ssin;
20 substdio ssout;
21
22 void doit(line)
23 stralloc *line;
24 {
25   char *x;
26   unsigned int xlen;
27   unsigned int i;
28   char *type;
29   char *uidstr;
30   char *gidstr;
31   char *modestr;
32   char *mid;
33   char *name;
34   unsigned long uid;
35   unsigned long gid;
36   unsigned long mode;
37   int fdin;
38   int fdout;
39
40   x = line->s; xlen = line->len;
41
42   type = x;
43   i = byte_chr(x,xlen,':'); if (i == xlen) return;
44   x[i++] = 0; x += i; xlen -= i;
45
46   uidstr = x;
47   i = byte_chr(x,xlen,':'); if (i == xlen) return;
48   x[i++] = 0; x += i; xlen -= i;
49
50   gidstr = x;
51   i = byte_chr(x,xlen,':'); if (i == xlen) return;
52   x[i++] = 0; x += i; xlen -= i;
53
54   modestr = x;
55   i = byte_chr(x,xlen,':'); if (i == xlen) return;
56   x[i++] = 0; x += i; xlen -= i;
57
58   mid = x;
59   i = byte_chr(x,xlen,':'); if (i == xlen) return;
60   x[i++] = 0; x += i; xlen -= i;
61
62   name = x;
63   i = byte_chr(x,xlen,':'); if (i == xlen) return;
64   x[i++] = 0; x += i; xlen -= i;
65
66   if (!stralloc_copys(&target,to)) nomem();
67   if (!stralloc_cats(&target,mid)) nomem();
68   if (!stralloc_cats(&target,name)) nomem();
69   if (!stralloc_0(&target)) nomem();
70
71   uid = -1; if (*uidstr) scan_ulong(uidstr,&uid);
72   gid = -1; if (*gidstr) scan_ulong(gidstr,&gid);
73   scan_8long(modestr,&mode);
74
75   switch(*type) {
76     case 'd':
77       if (mkdir(target.s,0700) == -1)
78         if (errno != error_exist)
79           strerr_die4sys(111,FATAL,"unable to mkdir ",target.s,": ");
80       break;
81
82     case 'c':
83       fdin = open_read(name);
84       if (fdin == -1)
85         strerr_die4sys(111,FATAL,"unable to read ",name,": ");
86       substdio_fdbuf(&ssin,read,fdin,inbuf,sizeof(inbuf));
87
88       fdout = open_trunc(target.s);
89       if (fdout == -1)
90         strerr_die4sys(111,FATAL,"unable to write ",target.s,": ");
91       substdio_fdbuf(&ssout,write,fdout,outbuf,sizeof(outbuf));
92
93       switch(substdio_copy(&ssout,&ssin)) {
94         case -2:
95           strerr_die4sys(111,FATAL,"unable to read ",name,": ");
96         case -3:
97           strerr_die4sys(111,FATAL,"unable to write ",target.s,": ");
98       }
99
100       close(fdin);
101       if (substdio_flush(&ssout) == -1)
102         strerr_die4sys(111,FATAL,"unable to write ",target.s,": ");
103       if (fsync(fdout) == -1)
104         strerr_die4sys(111,FATAL,"unable to write ",target.s,": ");
105       close(fdout);
106       break;
107
108     default:
109       return;
110   }
111
112   if (chown(target.s,uid,gid) == -1)
113     strerr_die4sys(111,FATAL,"unable to chown ",target.s,": ");
114   if (chmod(target.s,mode) == -1)
115     strerr_die4sys(111,FATAL,"unable to chmod ",target.s,": ");
116 }
117
118 char buf[256];
119 substdio in = SUBSTDIO_FDBUF(read,0,buf,sizeof(buf));
120 stralloc line = {0};
121
122 void main(argc,argv)
123 int argc;
124 char **argv;
125 {
126   int match;
127
128   umask(077);
129
130   to = argv[1];
131   if (!to) strerr_die2x(100,FATAL,"install: usage: install dir");
132
133   for (;;) {
134     if (getln(&in,&line,&match,'\n') == -1)
135       strerr_die2sys(111,FATAL,"unable to read input: ");
136     doit(&line);
137     if (!match)
138       _exit(0);
139   }
140 }