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