|
|
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.