|
|
1.1 root 1:
2: static char SCCSID[] = "@(#)pull.c 2.1 DKHOST 85/01/15";
3:
4: #include <errno.h>
5: #include "string.h"
6: #include <varargs.h>
7: #include "pupu.h"
8: #include "ndir.h"
9:
10: Efn takefile, fetchrequest, setdirectory, terminate;
11: Efn takelink, confirmed, remoteerror, alldone;
12:
13: Sexp pulltable[] = {
14: 'F', takefile,
15: 'L', takelink,
16: 'S', fetchrequest,
17: 'D', setdirectory,
18: 'X', terminate,
19: 0, 0
20: };
21:
22: Sexp fetchtable[] = {
23: 'F', takefile,
24: 'L', takelink,
25: 'c', confirmed,
26: 'e', remoteerror,
27: 'X', alldone,
28: 0, 0
29: };
30:
31: Eexp justquit[];
32:
33: Sint dochown;
34:
35: EcharP below();
36: EpwP getpwnam();
37:
38: pull(fd, names, directory, errfcn, options)
39: PfnP errfcn;
40: PcharP *names, directory, options;
41: {
42: begin(fd, errfcn, "local", ".");
43:
44: dochown = (geteuid() == 0);
45:
46: if(setjmp(giveup))
47: return(lasterror);
48:
49: sendinit(options);
50:
51: setbase(directory);
52:
53: while(*names)
54: fetchfile(*names++);
55:
56: msginit('X');
57: msgsend();
58: msgwait(justquit);
59:
60: signal(SIGALRM, alarmwas);
61: return(lasterror);
62: }
63:
64: fetchfile(name)
65: PcharP name;
66: {
67: msginit('S');
68:
69: msgfmt("%s", name);
70:
71: msgconf(fetchtable);
72: }
73:
74: fetchrequest()
75: {
76: Achar name[NAMELEN];
77:
78: msgtake("%s", name);
79:
80: sendfile(name);
81:
82: reply('c');
83:
84: return(0);
85: }
86:
87: ppremote(fd)
88: {
89: begin(fd, (TfnP) 0, "remote", ".");
90:
91: dochown = (geteuid() == 0);
92:
93: if(setjmp(giveup))
94: return(lasterror);
95:
96: msgwait(inittable);
97:
98: msgwait(pulltable);
99:
100: signal(SIGALRM, alarmwas);
101: return(lasterror);
102: }
103:
104: setdirectory()
105: {
106: setbase(&buf[H_DATA]);
107:
108: reply('c');
109:
110: return(0);
111: }
112:
113: setbase(p)
114: RcharP p;
115: {
116: RcharP q;
117: RpwP pw;
118:
119: if(*p == '/')
120: strcpy(basedir, p);
121: else if(*p == '~'){
122: if(q = strchr(++p, '/'))
123: *q++ = '\0';
124:
125: if(*p){
126: if(pw = getpwnam(p))
127: strcpy(basedir, pw->pw_dir);
128: else
129: err("No passwd entry for", p, -EX_NOUSER);
130: }else{
131: curdir(basedir);
132: strcpy(wdir, basedir);
133: }
134:
135: if(q){
136: strcat(basedir, "/");
137: strcat(basedir, q);
138: }
139: }else{
140: curdir(basedir);
141: strcpy(wdir, basedir);
142:
143: if(strcmp(p, ".") != 0){
144: strcat(basedir, "/");
145: strcat(basedir, p);
146: }
147: }
148:
149: db(stderr, "setdirectory %s\n", basedir);
150: changedir(basedir);
151:
152: return(0);
153: }
154:
155: changedir(newdir)
156: PcharP newdir;
157: {
158: RcharP p;
159:
160: if(!(p = below(wdir, newdir)))
161: p = newdir;
162:
163: if(*p){
164: if(chdir(p) < 0 && (makedirectory(p), chdir(p) < 0))
165: err("Can't chdir to", p, EX_NOINPUT);
166:
167: strcpy(wdir, newdir);
168: }
169: db(stderr, "changedir newdir %s p %s wdir %s\n", newdir, p, wdir);
170: }
171:
172: PcharP
173: below(ref, check)
174: RcharP ref, check;
175: {
176: Rint len;
177:
178: len = strlen(ref);
179:
180: if(strncmp(ref, check, len) != 0)
181: return(NIL);
182:
183: check += len;
184:
185: if(*check == '/')
186: return(check+1);
187: if(*check)
188: return(NIL);
189: return(check);
190: }
191:
192: takefile()
193: {
194: RcharP p;
195: Rint haderr;
196: Achar type;
197: Achar name[NAMELEN];
198: Aint mode, uid, gid;
199: Along mtime;
200: time_t timea[2];
201:
202: msgtake("%c", &type);
203: msgtake("%s", name);
204: msgtake("%o", &mode);
205: msgtake("%d", &uid);
206: msgtake("%d", &gid);
207: msgtake("%ld", &mtime);
208:
209: sprintf(wholename, "%s/%s", basedir, name);
210:
211: p = strrchr(wholename, '/');
212: *p = '\0';
213:
214: changedir(wholename);
215:
216: *p++ = '/';
217:
218: switch(type){
219: case 'r':
220: haderr = pluckregular(p);
221: break;
222:
223: case 'd':
224: makedirectory(p);
225: haderr = 0;
226: break;
227:
228: case 'c':
229: haderr = pluckspecial(p, S_IFCHR);
230: break;
231:
232: case 'b':
233: haderr = pluckspecial(p, S_IFBLK);
234: break;
235:
236: case 'p':
237: haderr = pluckspecial(p, S_IFIFO);
238: }
239:
240: reply('c');
241:
242: if(haderr)
243: return(0);
244:
245: chmod(p, mode);
246:
247: timea[0] = time((TlongP) 0);
248: timea[1] = mtime;
249:
250: if(timea[1] >= timea[0])
251: timea[1] = timea[0] - 1;
252:
253: utime(p, timea);
254:
255: if(dochown)
256: chown(p, uid, gid);
257:
258: return(0);
259: }
260:
261: pluckregular(p)
262: PcharP p;
263: {
264: Rint ffd, len;
265:
266: if((ffd = creatn(p, 0200)) < 0
267: && (chmod(p, 0200), (ffd = creatn(p, 0200)) < 0)){
268:
269: warn("Can't create", wholename, EX_CANTCREAT);
270:
271: while(read(cfd, buf, sizeof(buf)) > 0);
272:
273: return(BAD);
274: }
275:
276: currentfile = wholename;
277: timeoutmsg = "File reception timed out";
278:
279: alarm(RTIMEOUT);
280:
281: while((len = read(cfd, buf, sizeof(buf))) > 0){
282: db(stderr, "len %d\n", len);
283: if(write(ffd, buf, len) != len){
284: warn("Write failed on", wholename, EX_IOERR);
285: while((len = read(cfd, buf, sizeof(buf))) > 0);
286: }
287: alarm(RTIMEOUT);
288: }
289:
290: alarm(0);
291:
292: if(len < 0)
293: stopnow(EX_IOERR);
294:
295: closen(ffd);
296:
297: return(GOOD);
298: }
299:
300: pluckspecial(name, mode)
301: PcharP name;
302: {
303: Rint dev;
304: Aint maj, min;
305:
306: unlink(name);
307:
308: if(mode == S_IFIFO)
309: dev = 0;
310: else{
311: msgtake("%d", &maj);
312: msgtake("%d", &min);
313:
314: dev = makedev(maj, min);
315: }
316:
317: if(mknod(name, mode, dev) < 0){
318: warn("Can't mknod", wholename, EX_CANTCREAT);
319: return(BAD);
320: }
321:
322: return(GOOD);
323: }
324:
325: takelink()
326: {
327: RcharP p;
328: Achar name[NAMELEN], prev[NAMELEN];
329:
330: msgtake("%s", name);
331: msgtake("%s", prev);
332:
333: sprintf(wholename, "%s/%s", basedir, name);
334:
335: p = strrchr(wholename, '/');
336: *p = '\0';
337: changedir(wholename);
338: *p++ = '/';
339:
340: sprintf(buf, "%s/%s", basedir, prev);
341:
342: if((link(buf, p) < 0) && (unlink(p), (link(buf, p) < 0)))
343: warn("Can't link to", wholename, EX_CANTCREAT);
344:
345: reply('c');
346:
347: return(0);
348: }
349:
350: makedirectory(p)
351: PcharP p;
352: {
353: RcharP q;
354: Aint pid, n, result;
355: Achar temp[NAMELEN];
356:
357: db(stderr, "makedirectory %s\n", p);
358: sprintf(temp, "%s/", p);
359:
360: q = temp;
361: if(*q == '/')
362: q++;
363:
364: while(q = strchr(q, '/')){
365: *q = '\0';
366:
367: if(access(temp, 1) < 0){
368: db(stderr, "mkdir %s\n", temp);
369: if((pid = fork()) == 0){
370: freopen("/dev/null", "w", stderr);
371: execl("/bin/mkdir", "mkdir", temp, 0);
372: err("No mkdir", NIL, EX_UNAVAILABLE);
373: /* NOTREACHED */
374: }
375: while((n = wait(&result)) > 0 && n != pid);
376:
377: if(result != 0)
378: warn("Can't make directory", temp, -EX_CANTCREAT);
379: }
380:
381: *q++ = '/';
382: }
383: }
384:
385: terminate()
386: {
387: msginit('x');
388: msgfmt("%d", lasterror);
389: msgsend();
390:
391: return(1);
392: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.