Import ezmlm 0.53
[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 }