|
|
1.1 ! root 1: /* @(#)uucp.c 1.6 ! 2: */ ! 3: #include "uucp.h" ! 4: VERSION(@(#)uucp.c 1.6); ! 5: ! 6: /* ! 7: * uucp ! 8: * user id ! 9: * make a copy in spool directory ! 10: */ ! 11: int Copy = 0; ! 12: static int _Transfer = 0; ! 13: char Nuser[32]; ! 14: char *Ropt = " "; ! 15: char Optns[10]; ! 16: char Uopts[BUFSIZ]; ! 17: char Grade = 'N'; ! 18: ! 19: char Sfile[MAXFULLNAME]; ! 20: #ifndef V7 ! 21: long ulimit(); ! 22: #endif ! 23: ! 24: main(argc, argv, envp) ! 25: char *argv[]; ! 26: char **envp; ! 27: { ! 28: int ret; ! 29: int errors = 0; ! 30: char *fopt; ! 31: char sys1[MAXFULLNAME], sys2[MAXFULLNAME]; ! 32: char fwd1[MAXFULLNAME], fwd2[MAXFULLNAME]; ! 33: char file1[MAXFULLNAME], file2[MAXFULLNAME]; ! 34: short jflag = 0; /* -j flag Jobid printout */ ! 35: ! 36: void split(); ! 37: #ifndef V7 ! 38: long limit, dummy; ! 39: char msg[100]; ! 40: #endif V7 ! 41: ! 42: ! 43: /* this fails in some versions, but it doesn't hurt */ ! 44: Uid = getuid(); ! 45: Euid = geteuid(); ! 46: if (Uid == 0) ! 47: (void) setuid(UUCPUID); ! 48: ! 49: /* choose LOGFILE */ ! 50: (void) strcpy(Logfile, LOGUUCP); ! 51: ! 52: Env = envp; ! 53: fopt = NULL; ! 54: (void) strcpy(Progname, "uucp"); ! 55: Pchar = 'U'; ! 56: *Uopts = NULLCHAR; ! 57: ! 58: /* ! 59: * find name of local system ! 60: */ ! 61: uucpname(Myname); ! 62: Optns[0] = '-'; ! 63: Optns[1] = 'd'; ! 64: Optns[2] = 'c'; ! 65: Optns[3] = Nuser[0] = Sfile[0] = NULLCHAR; ! 66: ! 67: /* ! 68: * find id of user who spawned command to ! 69: * determine ! 70: */ ! 71: (void) guinfo(Uid, User); ! 72: ! 73: while ((ret = getopt(argc, argv, "Ccdfg:jmn:rx:")) != EOF) { ! 74: switch (ret) { ! 75: ! 76: /* ! 77: * make a copy of the file in the spool ! 78: * directory. ! 79: */ ! 80: case 'C': ! 81: Copy = 1; ! 82: Optns[2] = 'C'; ! 83: break; ! 84: ! 85: /* ! 86: * not used (default) ! 87: */ ! 88: case 'c': ! 89: break; ! 90: ! 91: /* ! 92: * not used (default) ! 93: */ ! 94: case 'd': ! 95: break; ! 96: case 'f': ! 97: Optns[1] = 'f'; ! 98: break; ! 99: ! 100: /* ! 101: * set service grade ! 102: */ ! 103: case 'g': ! 104: Grade = *optarg; ! 105: break; ! 106: ! 107: case 'j': /* job id */ ! 108: jflag = 1; ! 109: break; ! 110: ! 111: /* ! 112: * send notification to local user ! 113: */ ! 114: case 'm': ! 115: (void) strcat(Optns, "m"); ! 116: break; ! 117: ! 118: /* ! 119: * send notification to user on remote ! 120: * if no user specified do not send notification ! 121: */ ! 122: case 'n': ! 123: (void) strcat(Optns, "n"); ! 124: (void) sprintf(Nuser, "%.8s", optarg); ! 125: (void) sprintf(Uopts+strlen(Uopts), "-n%s ", Nuser); ! 126: break; ! 127: ! 128: /* ! 129: * create JCL files but do not start uucico ! 130: */ ! 131: case 'r': ! 132: Ropt = "-r"; ! 133: break; ! 134: ! 135: /* ! 136: * return status file ! 137: */ ! 138: ! 139: /* ! 140: * turn on debugging ! 141: */ ! 142: case 'x': ! 143: Debug = atoi(optarg); ! 144: if (Debug <= 0) ! 145: Debug = 1; ! 146: break; ! 147: ! 148: default: ! 149: /* getopt has already (stupidly) babbled */ ! 150: break; ! 151: } ! 152: } ! 153: DEBUG(4, "\n\n** %s **\n", "START"); ! 154: gwd(Wrkdir); ! 155: if (fopt) { ! 156: if (*fopt != '/') ! 157: (void) sprintf(Sfile, "%s/%s", Wrkdir, fopt); ! 158: else ! 159: (void) sprintf(Sfile, "%s", fopt); ! 160: ! 161: } ! 162: /* ! 163: * work in WORKSPACE directory ! 164: */ ! 165: ret = chdir(WORKSPACE); ! 166: if (ret != 0) { ! 167: (void) fprintf(stderr, "No work directory - %s - get help\n", ! 168: WORKSPACE); ! 169: cleanup(-12); ! 170: } ! 171: ! 172: if (Nuser[0] == NULLCHAR) ! 173: (void) strcpy(Nuser, User); ! 174: (void) strcpy(Loginuser, User); ! 175: DEBUG(4, "UID %d, ", Uid); ! 176: DEBUG(4, "User %s\n", User); ! 177: if (argc - optind < 2) { ! 178: (void) fprintf(stderr, "usage uucp from ... to\n"); ! 179: cleanup(-2); ! 180: } ! 181: ! 182: /* ! 183: * set up "to" system and file names ! 184: */ ! 185: ! 186: split(argv[argc - 1], sys2, fwd2, file2); ! 187: if (*sys2 != NULLCHAR) { ! 188: if (versys(sys2, 0) != 0) { ! 189: (void) fprintf(stderr, "bad system: %s\n", sys2); ! 190: cleanup(-11); ! 191: } ! 192: } ! 193: else ! 194: (void) strcpy(sys2, Myname); ! 195: ! 196: (void) strncpy(Rmtname, sys2, MAXBASENAME); ! 197: Rmtname[MAXBASENAME] = NULLCHAR; ! 198: ! 199: DEBUG(9, "sys2: %s, ", sys2); ! 200: DEBUG(9, "fwd2: %s, ", fwd2); ! 201: DEBUG(9, "file2: %s\n", file2); ! 202: ! 203: /* ! 204: * if there are more than 2 argsc, file2 is a directory ! 205: */ ! 206: if (argc - optind > 2) ! 207: (void) strcat(file2, "/"); ! 208: ! 209: /* ! 210: * do each from argument ! 211: */ ! 212: ! 213: for ( ; optind < argc - 1; optind++) { ! 214: split(argv[optind], sys1, fwd1, file1); ! 215: if (*sys1 != NULLCHAR) { ! 216: if (versys(sys1, 0) != 0) { ! 217: (void) fprintf(stderr, "bad system: %s\n", sys1); ! 218: cleanup(-11); ! 219: } ! 220: } ! 221: ! 222: /* source files can have at most one ! */ ! 223: if (*fwd1 != NULLCHAR) { ! 224: /* syntax error */ ! 225: (void) fprintf(stderr, "illegal syntax %s\n", argv[optind]); ! 226: exit(2); ! 227: } ! 228: ! 229: /* ! 230: * check for required remote expansion of file names -- generate ! 231: * and execute a uux command ! 232: * e.g. ! 233: * uucp owl!~/dan/* ~/dan/ ! 234: * ! 235: * NOTE: The source file part must be full path name. ! 236: * If ~ it will be expanded locally - it assumes the remote ! 237: * names are the same. ! 238: */ ! 239: ! 240: if (*sys1 != NULLCHAR) ! 241: if ((strchr(file1, '*') != NULL ! 242: || strchr(file1, '?') != NULL ! 243: || strchr(file1, '[') != NULL)) { ! 244: /* do a uux command */ ! 245: if (ckexpf(file1) == FAIL) ! 246: exit(6); ! 247: ruux(sys1, sys1, file1, sys2, fwd2, file2); ! 248: continue; ! 249: } ! 250: ! 251: /* ! 252: * check for forwarding -- generate and execute a uux command ! 253: * e.g. ! 254: * uucp uucp.c raven!owl!~/dan/ ! 255: */ ! 256: ! 257: if (*fwd2 != NULLCHAR) { ! 258: ruux(sys2, sys1, file1, "", fwd2, file2); ! 259: continue; ! 260: } ! 261: ! 262: /* ! 263: * check for both source and destination on other systems -- ! 264: * generate and execute a uux command ! 265: */ ! 266: ! 267: if (*sys1 != NULLCHAR ) ! 268: if ( (!EQUALS(Myname, sys1)) ! 269: && *sys2 != NULLCHAR ! 270: && (!EQUALS(sys2, Myname)) ) { ! 271: ruux(sys2, sys1, file1, "", fwd2, file2); ! 272: continue; ! 273: } ! 274: ! 275: ! 276: if (*sys1 == NULLCHAR) ! 277: (void) strcpy(sys1, Myname); ! 278: else { ! 279: (void) strncpy(Rmtname, sys1, MAXBASENAME); ! 280: Rmtname[MAXBASENAME] = NULLCHAR; ! 281: } ! 282: ! 283: DEBUG(4, "sys1 - %s, ", sys1); ! 284: DEBUG(4, "file1 - %s, ", file1); ! 285: DEBUG(4, "Rmtname - %s\n", Rmtname); ! 286: if (copy(sys1, file1, sys2, file2)) ! 287: errors++; ! 288: } ! 289: ! 290: /* move the work files to their proper places */ ! 291: commitall(); ! 292: ! 293: /* ! 294: * do not spawn daemon if -r option specified ! 295: */ ! 296: #ifndef V7 ! 297: limit = ulimit(1, dummy); ! 298: #endif V7 ! 299: if (*Ropt != '-') ! 300: #ifndef V7 ! 301: if (limit < MINULIMIT) { ! 302: (void) sprintf(msg, ! 303: "ULIMIT (%ld) < MINULIMIT (%ld)", limit, MINULIMIT); ! 304: logent(msg, "Low-ULIMIT"); ! 305: } ! 306: else ! 307: #endif ! 308: xuucico(Rmtname); ! 309: if (jflag) ! 310: printf("%s\n", Jobid); ! 311: cleanup(errors); ! 312: } ! 313: ! 314: /* ! 315: * cleanup lock files before exiting ! 316: */ ! 317: cleanup(code) ! 318: register int code; ! 319: { ! 320: rmlock(CNULL); ! 321: if (code != 0) ! 322: wfabort(); /* this may be extreme -- abort all work */ ! 323: if (code < 0) { ! 324: (void) fprintf(stderr, "uucp failed completely (%d)\n", (-code)); ! 325: exit(-code); ! 326: } ! 327: else if (code > 0) { ! 328: (void) fprintf(stderr, ! 329: "uucp failed partially: %d file(s) sent; %d error(s)\n", ! 330: _Transfer, code); ! 331: exit(code); ! 332: } ! 333: exit(code); ! 334: } ! 335: ! 336: /* ! 337: * generate copy files for s1!f1 -> s2!f2 ! 338: * Note: only one remote machine, other situations ! 339: * have been taken care of in main. ! 340: * return: ! 341: * 0 -> success ! 342: * Non-zero -> failure ! 343: */ ! 344: ! 345: copy(s1, f1, s2, f2) ! 346: char *s1, *f1, *s2, *f2; ! 347: { ! 348: FILE *cfp, *syscfile(); ! 349: struct stat stbuf, stbuf1; ! 350: int type, statret; ! 351: char dfile[NAMESIZE]; ! 352: char cfile[NAMESIZE]; ! 353: char file1[MAXFULLNAME], file2[MAXFULLNAME]; ! 354: char msg[BUFSIZ]; ! 355: ! 356: type = 0; ! 357: (void) strcpy(file1, f1); ! 358: (void) strcpy(file2, f2); ! 359: if (!EQUALS(s1, Myname)) ! 360: type = 1; ! 361: if (!EQUALS(s2, Myname)) ! 362: type = 2; ! 363: ! 364: switch (type) { ! 365: case 0: ! 366: ! 367: /* ! 368: * all work here ! 369: */ ! 370: DEBUG(4, "all work here %d\n", type); ! 371: ! 372: /* ! 373: * check access control permissions ! 374: */ ! 375: if (ckexpf(file1)) ! 376: return(-6); ! 377: if (ckexpf(file2)) ! 378: return(-7); ! 379: if (uidstat(file1, &stbuf) != 0) { ! 380: (void) fprintf(stderr, ! 381: "can't get file status %s\n copy failed\n", file1); ! 382: return(8); ! 383: } ! 384: statret = uidstat(file2, &stbuf1); ! 385: if (statret == 0 ! 386: && stbuf.st_ino == stbuf1.st_ino ! 387: && stbuf.st_dev == stbuf1.st_dev) { ! 388: (void) fprintf(stderr, ! 389: "%s %s - same file; can't copy\n", file1, file2); ! 390: return(5); ! 391: } ! 392: if (chkperm(file1, file2, strchr(Optns, 'd')) ) { ! 393: (void) fprintf(stderr, "permission denied\n"); ! 394: cleanup(1); ! 395: } ! 396: if ((stbuf.st_mode & S_IFMT) == S_IFDIR) { ! 397: (void) fprintf(stderr, "directory name illegal - %s\n", ! 398: file1); ! 399: return(9); ! 400: } ! 401: /* see if I can read this file as read uid, gid */ ! 402: if ( !(stbuf.st_mode & ANYREAD) ! 403: && !(stbuf.st_uid == Uid && stbuf.st_mode & 0400) ! 404: && !(stbuf.st_gid == getgid() && stbuf.st_mode & 0040) ! 405: ) { ! 406: (void) fprintf(stderr, ! 407: "uucp can't read (%s) mode (%o)\n", ! 408: file1, stbuf.st_mode); ! 409: (void) fprintf(stderr, "use cp command\n"); ! 410: return(3); ! 411: } ! 412: if (statret == 0 && (stbuf1.st_mode & ANYWRITE) == 0) { ! 413: (void) fprintf(stderr, ! 414: "can't write file (%s) mode (%o)\n", ! 415: file2, stbuf1.st_mode); ! 416: return(4); ! 417: } ! 418: ! 419: /* ! 420: * copy file locally ! 421: */ ! 422: DEBUG(2, "local copy: uidxcp(%s, ", file1); ! 423: DEBUG(2, "%s\n", file2); ! 424: ! 425: /* do copy as Uid, but the file will be owned by uucp */ ! 426: if (uidxcp(file1, file2) == FAIL) { ! 427: (void) fprintf(stderr, ! 428: "can't copy file (%s) errno %d\n", file2, errno); ! 429: return(5); ! 430: } ! 431: (void) chmod(file2, (int) (stbuf.st_mode | 0666) & 0777); ! 432: return(0); ! 433: case 1: ! 434: ! 435: /* ! 436: * receive file ! 437: */ ! 438: DEBUG(4, "receive file - %d\n", type); ! 439: ! 440: /* ! 441: * expand source and destination file names ! 442: * and check access permissions ! 443: */ ! 444: if (file1[0] != '~') ! 445: if (ckexpf(file1)) ! 446: return(6); ! 447: if (ckexpf(file2)) ! 448: return(7); ! 449: ! 450: /* ! 451: * insert JCL card in file ! 452: */ ! 453: cfp = syscfile(cfile, s1); ! 454: (void) fprintf(cfp, ! 455: "R %s %s %s %s %s %o %s\n", file1, file2, ! 456: User, Optns, ! 457: *Sfile ? Sfile : "dummy", ! 458: 0777, Nuser); ! 459: (void) fclose(cfp); ! 460: (void) sprintf(msg, "%s!%s --> %s!%s", Rmtname, file1, ! 461: Myname, file2); ! 462: logent(msg, "QUEUED"); ! 463: break; ! 464: case 2: ! 465: ! 466: /* ! 467: * send file ! 468: */ ! 469: if (ckexpf(file1)) ! 470: return(6); ! 471: /* XQTDIR hook enables 3rd party uux requests (cough) */ ! 472: if (file2[0] != '~' && !EQUALS(Wrkdir, XQTDIR)) ! 473: if (ckexpf(file2)) ! 474: return(7); ! 475: DEBUG(4, "send file - %d\n", type); ! 476: ! 477: if (uidstat(file1, &stbuf) != 0) { ! 478: (void) fprintf(stderr, ! 479: "can't get status for file %s\n", file1); ! 480: return(8); ! 481: } ! 482: if ((stbuf.st_mode & S_IFMT) == S_IFDIR) { ! 483: (void) fprintf(stderr, ! 484: "directory name illegal - %s\n", file1); ! 485: return(9); ! 486: } ! 487: ! 488: /* ! 489: * make a copy of file in spool directory ! 490: */ ! 491: if (Copy || !READANY(file1) ) { ! 492: gename(DATAPRE, s2, Grade, dfile); ! 493: ! 494: if (uidxcp(file1, dfile)) ! 495: return(5); ! 496: ! 497: (void) chmod(dfile, DFILEMODE); ! 498: wfcommit(dfile, dfile, s2); ! 499: } else { ! 500: ! 501: /* ! 502: * make a dummy D. name ! 503: * cntrl.c knows names < 6 chars are dummy D. files ! 504: */ ! 505: (void) strcpy(dfile, "D.0"); ! 506: } ! 507: ! 508: /* ! 509: * insert JCL card in file ! 510: */ ! 511: cfp = syscfile(cfile, s2); ! 512: (void) fprintf(cfp, "S %s %s %s %s %s %o %s %s\n", ! 513: file1, file2, User, Optns, dfile, ! 514: stbuf.st_mode & 0777, Nuser, Sfile); ! 515: (void) fclose(cfp); ! 516: (void) sprintf(msg, "%s!%s --> %s!%s", Myname, file1, ! 517: Rmtname, file2); ! 518: logent(msg, "QUEUED"); ! 519: break; ! 520: } ! 521: _Transfer++; ! 522: return(0); ! 523: } ! 524: ! 525: ! 526: /* ! 527: * syscfile(file, sys) ! 528: * char *file, *sys; ! 529: * ! 530: * get the cfile for system sys (creat if need be) ! 531: * return stream pointer ! 532: * ! 533: * returns ! 534: * stream pointer to open cfile ! 535: * ! 536: */ ! 537: ! 538: static FILE * ! 539: syscfile(file, sys) ! 540: char *file, *sys; ! 541: { ! 542: FILE *cfp; ! 543: ! 544: if (gtcfile(file, sys) == FAIL) { ! 545: gename(CMDPRE, sys, Grade, file); ! 546: ASSERT(access(file, 0) != 0, Fl_EXISTS, file, errno); ! 547: cfp = fdopen(creat(file, CFILEMODE), "w"); ! 548: svcfile(file, sys); ! 549: } else ! 550: cfp = fopen(file, "a"); ! 551: /* set Jobid -- C.jobid */ ! 552: (void) strncpy(Jobid, BASENAME(file, '.'), NAMESIZE); ! 553: Jobid[NAMESIZE-1] = '\0'; ! 554: ASSERT(cfp != NULL, Ct_OPEN, file, errno); ! 555: return(cfp); ! 556: } ! 557: ! 558: ! 559: /* ! 560: * split - split the name into parts: ! 561: * sys - system name ! 562: * fwd - intermediate destinations ! 563: * file - file part ! 564: */ ! 565: ! 566: static ! 567: void ! 568: split(arg, sys, fwd, file) ! 569: char *arg, *sys, *fwd, *file; ! 570: { ! 571: register char *cl, *cr, *n; ! 572: *sys = *fwd = *file = NULLCHAR; ! 573: ! 574: for (n=arg ;; n=cl+1) { ! 575: cl = strchr(n, '!'); ! 576: if ( cl == NULL) { ! 577: /* no ! in n */ ! 578: (void) strcpy(file, n); ! 579: return; ! 580: } ! 581: ! 582: if (PREFIX(Myname, n)) ! 583: continue; ! 584: ! 585: cr = strrchr(n, '!'); ! 586: (void) strcpy(file, cr+1); ! 587: (void) strncpy(sys, n, cl-n); ! 588: sys[cl-n] = NULLCHAR; ! 589: ! 590: if (cr != cl) { ! 591: /* more than one ! */ ! 592: (void) strncpy(fwd, cl+1, cr-cl-1); ! 593: fwd[cr-cl-1] = NULLCHAR; ! 594: } ! 595: return; ! 596: } ! 597: /*NOTREACHED*/ ! 598: } ! 599: ! 600: ! 601: /* ! 602: * generate and execute a uux command ! 603: */ ! 604: ! 605: ruux(rmt, sys1, file1, sys2, fwd2, file2) ! 606: char *rmt, *sys1, *file1, *sys2, *fwd2, *file2; ! 607: { ! 608: char cmd[BUFSIZ]; ! 609: ! 610: if (*Uopts != NULLCHAR) ! 611: (void) sprintf(cmd, "uux -C %s %s!uucp -C \\(%s\\) ", Ropt, rmt, Uopts); ! 612: else ! 613: (void) sprintf(cmd, "uux -C %s %s!uucp -C ", Ropt, rmt); ! 614: ! 615: if (*sys1 == NULLCHAR || EQUALS(sys1, Myname)) { ! 616: if (ckexpf(file1)) ! 617: exit(6); ! 618: (void) sprintf(cmd+strlen(cmd), " %s!%s ", sys1, file1); ! 619: } ! 620: else ! 621: if (!EQUALS(rmt, sys1)) ! 622: (void) sprintf(cmd+strlen(cmd), " \\(%s!%s\\) ", sys1, file1); ! 623: else ! 624: (void) sprintf(cmd+strlen(cmd), " \\(%s\\) ", file1); ! 625: ! 626: if (*fwd2 != NULLCHAR) { ! 627: if (*sys2 != NULLCHAR) ! 628: (void) sprintf(cmd+strlen(cmd), ! 629: " \\(%s!%s!%s\\) ", sys2, fwd2, file2); ! 630: else ! 631: (void) sprintf(cmd+strlen(cmd), " \\(%s!%s\\) ", fwd2, file2); ! 632: } ! 633: else { ! 634: if (*sys2 == NULLCHAR || EQUALS(sys2, Myname)) ! 635: if (ckexpf(file2)) ! 636: exit(7); ! 637: (void) sprintf(cmd+strlen(cmd), " \\(%s!%s\\) ", sys2, file2); ! 638: } ! 639: ! 640: DEBUG(2, "cmd: %s\n", cmd); ! 641: logent(cmd, "QUEUED"); ! 642: system(cmd); ! 643: return; ! 644: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.