|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)uux.c 5.14 (Berkeley) 10/27/88"; ! 3: #endif ! 4: ! 5: #include "uucp.h" ! 6: #include <sys/stat.h> ! 7: #include <sysexits.h> ! 8: ! 9: #define NOSYSPART 0 ! 10: #define HASSYSPART 1 ! 11: ! 12: #define LQUOTE '(' ! 13: #define RQUOTE ')' ! 14: ! 15: #define APPCMD(d) {\ ! 16: register char *p; for (p = d; *p != '\0';)\ ! 17: {*cmdp++ = *p++;\ ! 18: if(cmdp>(sizeof(cmd)+&cmd[0])){\ ! 19: fprintf(stderr,"argument list too long\n");\ ! 20: cleanup(EX_SOFTWARE);\ ! 21: }\ ! 22: }\ ! 23: *cmdp++ = ' '; *cmdp = '\0';} ! 24: ! 25: #define GENSEND(f, a, b, c, d, e) {\ ! 26: fprintf(f, "S %s %s %s -%s %s 0666\n", a, b, c, d, e); } ! 27: #define GENRCV(f, a, b, c) {fprintf(f, "R %s %s %s - \n", a, b, c);} ! 28: ! 29: struct timeb Now; ! 30: ! 31: main(argc, argv) ! 32: int argc; ! 33: char **argv; ! 34: { ! 35: char cfile[NAMESIZE]; /* send commands for files from here */ ! 36: char dfile[NAMESIZE]; /* used for all data files from here */ ! 37: char rxfile[NAMESIZE]; /* to be sent to xqt file (X. ...) */ ! 38: char tfile[NAMESIZE]; /* temporary file name */ ! 39: char tcfile[NAMESIZE]; /* temporary file name */ ! 40: char t2file[NAMESIZE]; /* temporary file name */ ! 41: int cflag = 0; /* commands in C. file flag */ ! 42: int rflag = 0; /* C. files for receiving flag */ ! 43: #ifdef DONTCOPY ! 44: int Copy = 0; /* Don't Copy spool files */ ! 45: #else !DONTCOPY ! 46: int Copy = 1; /* Copy spool files */ ! 47: #endif !DONTCOPY ! 48: int Linkit = 0; /* Try link before copy */ ! 49: char buf[2*BUFSIZ]; ! 50: char inargs[2*BUFSIZ]; ! 51: int pipein = 0; ! 52: int startjob = 1; ! 53: char Grade = 'A'; ! 54: long Gradedelta = 100000000L; /* "huge number" */ ! 55: long size = 0L; ! 56: char path[MAXFULLNAME]; ! 57: char cmd[2*BUFSIZ]; ! 58: char *ap, *cmdp; ! 59: char prm[2*BUFSIZ]; ! 60: char syspart[MAXBASENAME+1], rest[MAXFULLNAME]; ! 61: char Xsys[MAXBASENAME+1], local[MAXBASENAME+1]; ! 62: char *xsys = Xsys; ! 63: FILE *fprx, *fpc, *fpd, *fp; ! 64: extern char *getprm(), *lastpart(); ! 65: extern FILE *ufopen(); ! 66: int uid, ret, c; ! 67: char redir = '\0'; ! 68: int nonoti = 0; ! 69: int nonzero = 0; ! 70: int link_failed; ! 71: char *ReturnTo = NULL; ! 72: extern int LocalOnly; ! 73: extern char *optarg; ! 74: extern int optind; ! 75: ! 76: strcpy(Progname, "uux"); ! 77: uucpname(Myname); ! 78: umask(WFMASK); ! 79: Ofn = 1; ! 80: Ifn = 0; ! 81: #ifdef VMS ! 82: arg_fix(argc, argv); ! 83: #endif ! 84: while (((c = getopt(argc, argv, "-prclCg:x:nzLa:")) != EOF) || ! 85: (optind < argc && (c = *argv[optind]) == '-' && ++optind)) ! 86: switch (c) { ! 87: case '-': ! 88: /* FALLTHROUGH */ ! 89: case 'p': ! 90: pipein = 1; ! 91: break; ! 92: case 'r': ! 93: startjob = 0; ! 94: break; ! 95: case 'c': ! 96: Copy = 0; ! 97: Linkit = 0; ! 98: break; ! 99: case 'l': ! 100: Copy = 0; ! 101: Linkit = 1; ! 102: break; ! 103: case 'C': ! 104: Copy = 1; ! 105: Linkit = 0; ! 106: break; ! 107: case 'g': ! 108: Grade = *optarg; ! 109: Gradedelta = atol(optarg+1); ! 110: break; ! 111: case 'x': ! 112: chkdebug(); ! 113: Debug = atoi(optarg); ! 114: if (Debug <= 0) ! 115: Debug = 1; ! 116: break; ! 117: case 'n': ! 118: nonoti = 1; ! 119: break; ! 120: case 'z': ! 121: nonzero = 1; ! 122: break; ! 123: case 'L': ! 124: LocalOnly++; ! 125: break; ! 126: case 'a': ! 127: ReturnTo = optarg; ! 128: if (prefix(Myname, ReturnTo) && ReturnTo[strlen(Myname)] == '!') ! 129: ReturnTo = index(ReturnTo, '!') + 1; ! 130: break; ! 131: case '?': ! 132: default: ! 133: break; ! 134: } ! 135: ! 136: ap = getwd(Wrkdir); ! 137: if (ap == 0) { ! 138: fprintf(stderr, "can't get working directory; will try to continue\n"); ! 139: strcpy(Wrkdir, "/UNKNOWN"); ! 140: } ! 141: ! 142: DEBUG(4, "\n\n** %s **\n", "START"); ! 143: ! 144: inargs[0] = '\0'; ! 145: while (optind < argc) { ! 146: DEBUG(4, "arg - %s:", argv[optind]); ! 147: strcat(inargs, " "); ! 148: strcat(inargs, argv[optind++]); ! 149: } ! 150: DEBUG(4, "arg - %s\n", inargs); ! 151: if (subchdir(Spool) < 0) { ! 152: syslog(LOG_WARNING, "chdir(%s) failed: %m", Spool); ! 153: cleanup(1); ! 154: } ! 155: uid = getuid(); ! 156: if (guinfo(uid, User, path) != SUCCESS) { ! 157: syslog(LOG_WARNING, "Can't find username for uid %d", uid); ! 158: DEBUG(1, "Using username", "uucp"); ! 159: strcpy(User, "uucp"); ! 160: } ! 161: ! 162: strncpy(local, Myname, MAXBASENAME); ! 163: cmdp = cmd; ! 164: *cmdp = '\0'; ! 165: gename(DATAPRE, local, 'X', rxfile); ! 166: fprx = ufopen(rxfile, "w"); ! 167: if (fprx == NULL) { ! 168: syslog(LOG_WARNING, "fopen(%s) failed: %m", rxfile); ! 169: cleanup(1); ! 170: } ! 171: gename(DATAPRE, local, 'T', tcfile); ! 172: fpc = ufopen(tcfile, "w"); ! 173: if (fpc == NULL) { ! 174: syslog(LOG_WARNING, "fopen(%s) failed: %m", tcfile); ! 175: cleanup(1); ! 176: } ! 177: fprintf(fprx, "%c %s %s\n", X_USER, User, local); ! 178: if (nonoti) ! 179: fprintf(fprx, "%c\n", X_NONOTI); ! 180: if (nonzero) ! 181: fprintf(fprx, "%c\n", X_NONZERO); ! 182: if (ReturnTo == NULL || *ReturnTo == '\0') ! 183: ReturnTo = User; ! 184: fprintf(fprx, "%c %s\n", X_RETURNTO, ReturnTo); ! 185: ! 186: /* find remote system name */ ! 187: ap = inargs; ! 188: xsys[0] = '\0'; ! 189: while ((ap = getprm(ap, prm)) != NULL) { ! 190: if (prm[0] == '>' || prm[0] == '<') { ! 191: ap = getprm(ap, prm); ! 192: continue; ! 193: } ! 194: ! 195: split(prm, xsys, rest); ! 196: break; ! 197: } ! 198: if (xsys[0] == '\0') ! 199: strcpy(xsys, local); ! 200: if (versys(&xsys) != 0) { ! 201: /* bad system name */ ! 202: fprintf(stderr, "bad system name: %s\n", xsys); ! 203: fclose(fprx); ! 204: fclose(fpc); ! 205: cleanup(EX_NOHOST); ! 206: } ! 207: ! 208: strncpy(Rmtname, xsys, MAXBASENAME); ! 209: DEBUG(4, "xsys %s\n", xsys); ! 210: ! 211: if (pipein) { ! 212: gename(DATAPRE, local, 'B', dfile); ! 213: fpd = ufopen(dfile, "w"); ! 214: if (fpd == NULL) { ! 215: syslog(LOG_WARNING, "fopen(%s) failed: %m", dfile); ! 216: cleanup(1); ! 217: } ! 218: while (!feof(stdin)) { ! 219: ret = fread(buf, 1, BUFSIZ, stdin); ! 220: fwrite(buf, 1, ret, fpd); ! 221: if (ferror(stdin)) { ! 222: perror("stdin"); ! 223: cleanup(EX_IOERR); ! 224: } ! 225: if (ferror(fpd)) { ! 226: perror(dfile); ! 227: cleanup(EX_IOERR); ! 228: } ! 229: size += ret; ! 230: } ! 231: fclose(fpd); ! 232: strcpy(tfile, dfile); ! 233: if (strcmp(local, xsys) != SAME) { ! 234: register int Len = strlen(local); ! 235: if (Len > SYSNSIZE) ! 236: Len = SYSNSIZE; ! 237: tfile[Len + 2] = 'S'; ! 238: GENSEND(fpc, dfile, tfile, User, "", dfile); ! 239: cflag++; ! 240: } ! 241: fprintf(fprx, "%c %s\n", X_RQDFILE, tfile); ! 242: fprintf(fprx, "%c %s\n", X_STDIN, tfile); ! 243: } ! 244: /* parse command */ ! 245: ap = inargs; ! 246: while ((ap = getprm(ap, prm)) != NULL) { ! 247: DEBUG(4, "prm - %s\n", prm); ! 248: if (prm[0] == '>' || prm[0] == '<') { ! 249: redir = prm[0]; ! 250: continue; ! 251: } ! 252: ! 253: if (prm[0] == ';') { ! 254: APPCMD(prm); ! 255: continue; ! 256: } ! 257: ! 258: if (prm[0] == '|' || prm[0] == '^') { ! 259: if (cmdp != cmd) ! 260: APPCMD(prm); ! 261: continue; ! 262: } ! 263: ! 264: /* process command or file or option */ ! 265: ret = split(prm, syspart, rest); ! 266: DEBUG(4, "s - %s, ", syspart); ! 267: DEBUG(4, "r - %s, ", rest); ! 268: DEBUG(4, "ret - %d\n", ret); ! 269: if (syspart[0] == '\0') ! 270: strcpy(syspart, local); ! 271: ! 272: if (cmdp == cmd && redir == '\0') { ! 273: /* command */ ! 274: APPCMD(rest); ! 275: continue; ! 276: } ! 277: ! 278: /* process file or option */ ! 279: DEBUG(4, "file s- %s, ", syspart); ! 280: DEBUG(4, "local - %s\n", local); ! 281: /* process file */ ! 282: if (redir == '>') { ! 283: if (rest[0] != '~') ! 284: if (ckexpf(rest)) ! 285: cleanup(EX_CANTCREAT); ! 286: fprintf(fprx, "%c %s %s\n", X_STDOUT, rest, ! 287: syspart); ! 288: redir = '\0'; ! 289: continue; ! 290: } ! 291: ! 292: if (ret == NOSYSPART && redir == '\0') { ! 293: /* option */ ! 294: APPCMD(rest); ! 295: continue; ! 296: } ! 297: ! 298: if (rest[0] != '\0') { ! 299: struct stat stbuf; ! 300: if (stat(rest, &stbuf) < 0) ! 301: DEBUG(4, "Can't stat %s\n", rest); ! 302: else ! 303: size += stbuf.st_size; ! 304: DEBUG(4, "size = %ld\n", size); ! 305: } ! 306: ! 307: if (strcmp(xsys, local) == SAME ! 308: && strcmp(xsys, syspart) == SAME) { ! 309: if (ckexpf(rest)) ! 310: cleanup(EX_CANTCREAT); ! 311: if (redir == '<') ! 312: fprintf(fprx, "%c %s\n", X_STDIN, rest); ! 313: else ! 314: APPCMD(rest); ! 315: redir = '\0'; ! 316: continue; ! 317: } ! 318: ! 319: if (strcmp(syspart, local) == SAME) { ! 320: /* generate send file */ ! 321: if (ckexpf(rest)) ! 322: cleanup(EX_CANTCREAT); ! 323: gename(DATAPRE, local, 'A', dfile); ! 324: DEBUG(4, "rest %s\n", rest); ! 325: if ((chkpth(User, "", rest) || anyread(rest)) != 0) { ! 326: fprintf(stderr, "permission denied %s\n", rest); ! 327: cleanup(EX_NOINPUT); ! 328: } ! 329: link_failed = 0; ! 330: if (Linkit) { ! 331: if (link(subfile(rest), subfile(dfile)) != 0) ! 332: link_failed++; ! 333: else ! 334: GENSEND(fpc, rest, dfile, User, "", dfile); ! 335: } ! 336: if (Copy || link_failed) { ! 337: if (xcp(rest, dfile) != 0) { ! 338: fprintf(stderr, "can't copy %s to %s\n", rest, dfile); ! 339: cleanup(EX_NOINPUT); ! 340: } ! 341: GENSEND(fpc, rest, dfile, User, "", dfile); ! 342: } ! 343: if (!Copy && !Linkit) { ! 344: GENSEND(fpc, rest, dfile, User, "c", "D.0"); ! 345: } ! 346: cflag++; ! 347: if (redir == '<') { ! 348: fprintf(fprx, "%c %s\n", X_STDIN, dfile); ! 349: fprintf(fprx, "%c %s\n", X_RQDFILE, dfile); ! 350: } else { ! 351: APPCMD(lastpart(rest)); ! 352: fprintf(fprx, "%c %s %s\n", X_RQDFILE, ! 353: dfile, lastpart(rest)); ! 354: } ! 355: redir = '\0'; ! 356: continue; ! 357: } ! 358: ! 359: if (strcmp(local, xsys) == SAME) { ! 360: /* generate local receive */ ! 361: gename(CMDPRE, syspart, 'R', tfile); ! 362: strcpy(dfile, tfile); ! 363: dfile[0] = DATAPRE; ! 364: fp = ufopen(tfile, "w"); ! 365: if (fp == NULL) { ! 366: syslog(LOG_WARNING, "fopen(%s) failed: %m", ! 367: tfile); ! 368: cleanup(1); ! 369: } ! 370: if (ckexpf(rest)) ! 371: cleanup(EX_CANTCREAT); ! 372: GENRCV(fp, rest, dfile, User); ! 373: fclose(fp); ! 374: rflag++; ! 375: if (rest[0] != '~') ! 376: if (ckexpf(rest)) ! 377: cleanup(EX_CANTCREAT); ! 378: if (redir == '<') { ! 379: fprintf(fprx, "%c %s\n", X_RQDFILE, dfile); ! 380: fprintf(fprx, "%c %s\n", X_STDIN, dfile); ! 381: } else { ! 382: fprintf(fprx, "%c %s %s\n", X_RQDFILE, dfile, ! 383: lastpart(rest)); ! 384: APPCMD(lastpart(rest)); ! 385: } ! 386: ! 387: redir = '\0'; ! 388: continue; ! 389: } ! 390: ! 391: if (strcmp(syspart, xsys) != SAME) { ! 392: /* generate remote receives */ ! 393: gename(DATAPRE, syspart, 'R', dfile); ! 394: strcpy(tfile, dfile); ! 395: tfile[0] = CMDPRE; ! 396: fpd = ufopen(dfile, "w"); ! 397: if (fpd == NULL) { ! 398: syslog(LOG_WARNING, "fopen(%s) failed: %m", ! 399: dfile); ! 400: cleanup(1); ! 401: } ! 402: gename(DATAPRE, local, 'T', t2file); ! 403: GENRCV(fpd, rest, t2file, User); ! 404: fclose(fpd); ! 405: GENSEND(fpc, dfile, tfile, User, "", dfile); ! 406: cflag++; ! 407: if (redir == '<') { ! 408: fprintf(fprx, "%c %s\n", X_RQDFILE, t2file); ! 409: fprintf(fprx, "%c %s\n", X_STDIN, t2file); ! 410: } else { ! 411: fprintf(fprx, "%c %s %s\n", X_RQDFILE, t2file, ! 412: lastpart(rest)); ! 413: APPCMD(lastpart(rest)); ! 414: } ! 415: redir = '\0'; ! 416: continue; ! 417: } ! 418: ! 419: /* file on remote system */ ! 420: if (rest[0] != '~') ! 421: if (ckexpf(rest)) ! 422: cleanup(EX_CANTCREAT); ! 423: if (redir == '<') ! 424: fprintf(fprx, "%c %s\n", X_STDIN, rest); ! 425: else ! 426: APPCMD(rest); ! 427: redir = '\0'; ! 428: continue; ! 429: ! 430: } ! 431: /* ! 432: * clean up trailing ' ' in command. ! 433: */ ! 434: if (cmdp > cmd && cmdp[0] == '\0' && cmdp[-1] == ' ') ! 435: *--cmdp = '\0'; ! 436: /* block multi-hop uux, which doesn't work */ ! 437: for (ap = cmd; *ap && *ap != ' '; ap++) ! 438: if (*ap == '!') { ! 439: fprintf(stderr, "uux handles only adjacent sites.\n"); ! 440: fprintf(stderr, "Try uusend for multi-hop delivery.\n"); ! 441: cleanup(EX_USAGE); ! 442: } ! 443: ! 444: fprintf(fprx, "%c %s\n", X_CMD, cmd); ! 445: if (ferror(fprx)) { ! 446: logent(cmd, "COULD NOT QUEUE XQT"); ! 447: cleanup(EX_IOERR); ! 448: } else ! 449: logent(cmd, "XQT QUE'D"); ! 450: fclose(fprx); ! 451: ! 452: if (size > 0 && Gradedelta > 0) { ! 453: DEBUG (4, "Grade changed from %c ", Grade); ! 454: Grade += size/Gradedelta; ! 455: if (Grade > 'z') ! 456: Grade = 'z'; ! 457: DEBUG(4, "to %c\n", Grade); ! 458: } ! 459: gename(XQTPRE, local, Grade, tfile); ! 460: if (strcmp(xsys, local) == SAME) { ! 461: /* rti!trt: xmv() works across filesystems, link(II) doesnt */ ! 462: xmv(rxfile, tfile); ! 463: if (startjob) ! 464: if (rflag) ! 465: xuucico(xsys); ! 466: else ! 467: xuuxqt(); ! 468: } ! 469: else { ! 470: GENSEND(fpc, rxfile, tfile, User, "", rxfile); ! 471: cflag++; ! 472: } ! 473: ! 474: if (ferror(fpc)) ! 475: cleanup(EX_IOERR); ! 476: fclose(fpc); ! 477: if (cflag) { ! 478: gename(CMDPRE, xsys, Grade, cfile); ! 479: /* rti!trt: use xmv() rather than link(II) */ ! 480: xmv(tcfile, cfile); ! 481: if (startjob) ! 482: xuucico(xsys); ! 483: cleanup(0); ! 484: } ! 485: else ! 486: unlink(subfile(tcfile)); ! 487: exit(0); ! 488: } ! 489: ! 490: #define FTABSIZE 30 ! 491: char Fname[FTABSIZE][NAMESIZE]; ! 492: int Fnamect = 0; ! 493: ! 494: /* ! 495: * cleanup and unlink if error ! 496: * ! 497: * return - none - do exit() ! 498: */ ! 499: ! 500: cleanup(code) ! 501: int code; ! 502: { ! 503: int i; ! 504: ! 505: logcls(); ! 506: rmlock(CNULL); ! 507: if (code) { ! 508: for (i = 0; i < Fnamect; i++) ! 509: unlink(subfile(Fname[i])); ! 510: fprintf(stderr, "uux failed. code %d\n", code); ! 511: } ! 512: DEBUG(1, "exit code %d\n", code); ! 513: exit(code); ! 514: } ! 515: ! 516: /* ! 517: * open file and record name ! 518: * ! 519: * return file pointer. ! 520: */ ! 521: ! 522: FILE *ufopen(file, mode) ! 523: char *file, *mode; ! 524: { ! 525: if (Fnamect < FTABSIZE) ! 526: strcpy(Fname[Fnamect++], file); ! 527: else ! 528: logent("Fname", "TABLE OVERFLOW"); ! 529: return fopen(subfile(file), mode); ! 530: } ! 531: #ifdef VMS ! 532: /* ! 533: * EUNICE bug: ! 534: * quotes are not stripped from DCL. Do it here. ! 535: * Note if we are running under Unix shell we don't ! 536: * do the right thing. ! 537: */ ! 538: arg_fix(argc, argv) ! 539: char **argv; ! 540: { ! 541: register char *cp, *tp; ! 542: ! 543: for (; argc > 0; --argc, argv++) { ! 544: cp = *argv; ! 545: if (cp == (char *)0 || *cp++ != '"') ! 546: continue; ! 547: tp = cp; ! 548: while (*tp++) ; ! 549: tp -= 2; ! 550: if (*tp == '"') { ! 551: *tp = '\0'; ! 552: *argv = cp; ! 553: } ! 554: } ! 555: } ! 556: #endif VMS ! 557: ! 558: /* ! 559: * split into system and file part ! 560: * ! 561: * return codes: ! 562: * NOSYSPART ! 563: * HASSYSPART ! 564: */ ! 565: ! 566: split(name, sys, rest) ! 567: register char *name, *rest; ! 568: char *sys; ! 569: { ! 570: register char *c; ! 571: ! 572: if (*name == LQUOTE) { ! 573: if ((c = index(name + 1, RQUOTE)) != NULL) { ! 574: /* strip off quotes */ ! 575: name++; ! 576: while (c != name) ! 577: *rest++ = *name++; ! 578: *rest = '\0'; ! 579: *sys = '\0'; ! 580: return NOSYSPART; ! 581: } ! 582: } ! 583: ! 584: if ((c = index(name, '!')) == NULL) { ! 585: strcpy(rest, name); ! 586: *sys = '\0'; ! 587: return NOSYSPART; ! 588: } ! 589: ! 590: *c++ = '\0'; ! 591: strncpy(sys, name, MAXBASENAME); ! 592: sys[MAXBASENAME] = '\0'; ! 593: ! 594: strcpy(rest, c); ! 595: return HASSYSPART; ! 596: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.