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