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