|
|
1.1 ! root 1: /* /sccs/src/cmd/uucp/s.uux.c ! 2: uux.c 1.12 8/30/84 17:38:15 ! 3: */ ! 4: #include "uucp.h" ! 5: VERSION(@(#)uux.c 1.12); ! 6: ! 7: #define NOSYSPART 0 ! 8: #define HASSYSPART 1 ! 9: ! 10: #define GENSEND(f, a, b, c) {\ ! 11: ASSERT(fprintf(f, "S %s %s %s -%s %s 0666 %s %s\n", a, b, retaddr, _Statop?"o":"", c, User, _Sfile) >= 0, Ct_WRITE, "", errno);\ ! 12: } ! 13: #define GENRCV(f, a, b) {\ ! 14: ASSERT(fprintf(f, "R %s %s %s - %s 0666 %s\n", a, b, retaddr, *_Sfile ? _Sfile : "dummy", User) >= 0, \ ! 15: Ct_WRITE, "", errno);\ ! 16: } ! 17: ! 18: #define USAGE "[-aNAME] [-b] [-c] [-C] [-j] [-gGRADE] [-n] [-p] [-r] [-sFILE] [-xNUM] [-z] command-string" ! 19: #define APPCMD(p) {(void) strcat(cmd, p); (void) strcat(cmd, " ");} ! 20: ! 21: static char _Sfile[MAXFULLNAME]; ! 22: static int _Statop; ! 23: ! 24: char _Grade = 'N'; ! 25: /* ! 26: * uux ! 27: */ ! 28: main(argc, argv) ! 29: char *argv[]; ! 30: { ! 31: FILE *fprx = NULL, *fpc = NULL, *fpd = NULL, *fp = NULL; ! 32: extern onintr(); ! 33: int cfileUsed = 0; /* >0 if commands put in C. file flag */ ! 34: int rflag = 0; /* C. files for receiving flag */ ! 35: int cflag = 0; /* if > 0 make local copy of files to be sent */ ! 36: int nflag = 0; /* if != 0, do not request error notification */ ! 37: int zflag = 0; /* if != 0, request success notification */ ! 38: int pipein = 0; ! 39: int startjob = 1; ! 40: short jflag = 0; /* -j flag output Jobid */ ! 41: int bringback = 0; /* return stdin to invoker on error */ ! 42: int ret, i; ! 43: char *getprm(); ! 44: char redir = '\0'; ! 45: char command = TRUE; ! 46: char cfile[NAMESIZE]; /* send commands for files from here */ ! 47: char dfile[NAMESIZE]; /* used for all data files from here */ ! 48: char rxfile[NAMESIZE]; /* file for X_ commands */ ! 49: char tfile[NAMESIZE]; /* temporary file name */ ! 50: char t2file[NAMESIZE]; /* temporary file name */ ! 51: char buf[BUFSIZ]; ! 52: char inargs[BUFSIZ]; ! 53: char cmd[BUFSIZ]; ! 54: char *ap; ! 55: char prm[BUFSIZ]; ! 56: char syspart[NAMEBUF], rest[BUFSIZ]; ! 57: char xsys[NAMEBUF]; ! 58: char *fopt = NULL; ! 59: char *retaddr = NULL; ! 60: ! 61: struct stat stbuf; ! 62: ! 63: /* we want this to run as uucp, even if the kernel doesn't */ ! 64: Uid = getuid(); ! 65: Euid = geteuid(); /* this should be UUCPUID */ ! 66: if (Uid == 0) ! 67: setuid(UUCPUID); ! 68: ! 69: /* choose LOGFILE */ ! 70: (void) strcpy(Logfile, LOGUUX); ! 71: ! 72: /* ! 73: * determine local system name ! 74: */ ! 75: (void) strcpy(Progname, "uux"); ! 76: Pchar = 'X'; ! 77: (void) signal(SIGILL, onintr); ! 78: (void) signal(SIGTRAP, onintr); ! 79: (void) signal(SIGIOT, onintr); ! 80: (void) signal(SIGEMT, onintr); ! 81: (void) signal(SIGFPE, onintr); ! 82: (void) signal(SIGBUS, onintr); ! 83: (void) signal(SIGSEGV, onintr); ! 84: (void) signal(SIGSYS, onintr); ! 85: (void) signal(SIGTERM, SIG_IGN); ! 86: uucpname(Myname); ! 87: Ofn = 1; ! 88: Ifn = 0; ! 89: *_Sfile = '\0'; ! 90: /* ! 91: * since getopt() can't handle the pipe input option '-' ! 92: * I'll change it to "-p" ! 93: */ ! 94: for (i=0; i<argc; i++) ! 95: if (EQUALS(argv[i], "-")) ! 96: argv[i] = "-p"; ! 97: ! 98: while ((i = getopt(argc, argv, "a:bcCjg:nprs:x:z")) != EOF) { ! 99: switch(i){ ! 100: ! 101: /* ! 102: * use this name in the U line ! 103: */ ! 104: case 'a': ! 105: retaddr = optarg; ! 106: break; ! 107: ! 108: /* ! 109: * if return code non-zero, return command's input ! 110: */ ! 111: case 'b': ! 112: bringback = 1; ! 113: break; ! 114: ! 115: /* do not make local copies of files to be sent (default) */ ! 116: case 'c': ! 117: cflag = 0; ! 118: break; ! 119: ! 120: /* make local copies of files to be sent */ ! 121: case 'C': ! 122: cflag = 1; ! 123: break; ! 124: /* ! 125: * set priority of request ! 126: */ ! 127: case 'g': ! 128: _Grade = *optarg; ! 129: break; ! 130: ! 131: ! 132: case 'j': /* job id */ ! 133: jflag = 1; ! 134: break; ! 135: ! 136: ! 137: /* ! 138: * do not send failure notification to user ! 139: */ ! 140: case 'n': ! 141: nflag++; ! 142: break; ! 143: ! 144: /* ! 145: * send success notification to user ! 146: */ ! 147: case 'z': ! 148: zflag++; ! 149: break; ! 150: ! 151: /* ! 152: * -p or - option specifies input from pipe ! 153: */ ! 154: case 'p': ! 155: pipein = 1; ! 156: break; ! 157: ! 158: /* ! 159: * do not start transfer ! 160: */ ! 161: case 'r': ! 162: startjob = 0; ! 163: break; ! 164: ! 165: case 's': ! 166: fopt = optarg; ! 167: _Statop++; ! 168: break; ! 169: ! 170: /* ! 171: * debugging level ! 172: */ ! 173: case 'x': ! 174: Debug = atoi(optarg); ! 175: if (Debug <= 0) ! 176: Debug = 1; ! 177: break; ! 178: ! 179: default: ! 180: (void) fprintf(stderr, "\tusage: %s %s\n", Progname, USAGE); ! 181: exit(2); ! 182: } ! 183: } ! 184: ! 185: DEBUG(4, "\n\n** %s **\n", "START"); ! 186: ! 187: /* ! 188: * copy arguments into a buffer for later ! 189: * processing ! 190: */ ! 191: inargs[0] = '\0'; ! 192: for (; optind < argc; optind++) { ! 193: DEBUG(4, "arg - %s:", argv[optind]); ! 194: (void) strcat(inargs, " "); ! 195: (void) strcat(inargs, argv[optind]); ! 196: } ! 197: ! 198: /* ! 199: * get working directory and change ! 200: * to spool directory ! 201: */ ! 202: DEBUG(4, "arg - %s\n", inargs); ! 203: if(fopt){ ! 204: gwd(Wrkdir); ! 205: if(*fopt != '/') ! 206: (void) sprintf(_Sfile, "%s/%s", Wrkdir, fopt); ! 207: else ! 208: (void) sprintf(_Sfile, "%s", fopt); ! 209: ! 210: } ! 211: if (chdir(WORKSPACE) != 0) { ! 212: (void) fprintf(stderr, "No spool directory - %s - get help\n", WORKSPACE); ! 213: cleanup(12); ! 214: } ! 215: /* ! 216: * find remote system name ! 217: * remote name is first to know that ! 218: * is not > or < ! 219: */ ! 220: ap = inargs; ! 221: xsys[0] = '\0'; ! 222: while ((ap = getprm(ap, prm)) != NULL) { ! 223: if (prm[0] == '>' || prm[0] == '<') { ! 224: ap = getprm(ap, prm); ! 225: continue; ! 226: } ! 227: ! 228: /* ! 229: * split name into system name ! 230: * and command name ! 231: */ ! 232: split(prm, xsys, rest); ! 233: break; ! 234: } ! 235: if (xsys[0] == '\0') ! 236: (void) strcpy(xsys, Myname); ! 237: strncpy(Rmtname, xsys, MAXBASENAME); ! 238: Rmtname[MAXBASENAME] = '\0'; ! 239: DEBUG(4, "xsys %s\n", xsys); ! 240: ! 241: /* ! 242: * check to see if system name is valid ! 243: */ ! 244: if (versys(xsys, 0) != 0) { ! 245: /* ! 246: * bad system name ! 247: */ ! 248: fprintf(stderr, "bad system name: %s\n", xsys); ! 249: if (fprx != NULL) ! 250: (void) fclose(fprx); ! 251: if (fpc != NULL) ! 252: (void) fclose(fpc); ! 253: cleanup(11); ! 254: } ! 255: ! 256: /* ! 257: * determine id of user starting remote ! 258: * execution ! 259: */ ! 260: guinfo(Uid, User); ! 261: (void) strcpy(Loginuser,User); ! 262: ! 263: DEBUG(6, "User %s\n", User); ! 264: if (retaddr == NULL) ! 265: retaddr = User; ! 266: ! 267: /* ! 268: * initialize command buffer ! 269: */ ! 270: *cmd = '\0'; ! 271: ! 272: /* ! 273: * generate JCL files to work from ! 274: */ ! 275: ! 276: /* ! 277: * fpc is the C. file for the local site. ! 278: * collect commands into cfile. ! 279: * commit if not empty (at end). ! 280: * ! 281: * the appropriate C. file. ! 282: */ ! 283: gename(CMDPRE, xsys, _Grade, cfile); ! 284: DEBUG(9, "cfile = %s\n", cfile); ! 285: ASSERT(access(cfile, 0) != 0, Fl_EXISTS, cfile, errno); ! 286: fpc = fdopen(ret = creat(cfile, CFILEMODE), "w"); ! 287: ASSERT(ret >= 0 && fpc != NULL, Ct_OPEN, cfile, errno); ! 288: ! 289: /* set Jobid -- C.jobid */ ! 290: (void) strncpy(Jobid, BASENAME(cfile, '.'), NAMESIZE); ! 291: Jobid[NAMESIZE-1] = '\0'; ! 292: ! 293: /* ! 294: * rxfile is the X. file for the job, fprx is its stream ptr. ! 295: * if the command is to be executed locally, rxfile becomes ! 296: * a local X. file, otherwise we send it as a D. file to the ! 297: * remote site. ! 298: */ ! 299: ! 300: gename(DATAPRE, xsys, 'X', rxfile); ! 301: DEBUG(9, "rxfile = %s\n", rxfile); ! 302: ASSERT(access(rxfile, 0) != 0, Fl_EXISTS, rxfile, errno); ! 303: fprx = fdopen(ret = creat(rxfile, DFILEMODE), "w"); ! 304: ASSERT(ret >= 0 && fprx != NULL, Ct_WRITE, rxfile, errno); ! 305: clearerr(fprx); ! 306: ! 307: (void) fprintf(fprx,"%c %s %s\n", X_USER, User, Myname); ! 308: if (zflag) { ! 309: (void) fprintf(fprx, "%c return status on success\n", ! 310: X_COMMENT); ! 311: (void) fprintf(fprx,"%c\n", X_SENDZERO); ! 312: } ! 313: ! 314: if (nflag) { ! 315: (void) fprintf(fprx, "%c don't return status on failure\n", ! 316: X_COMMENT); ! 317: (void) fprintf(fprx,"%c\n", X_SENDNOTHING); ! 318: } else { ! 319: (void) fprintf(fprx, "%c return status on failure\n", ! 320: X_COMMENT); ! 321: fprintf(fprx,"%c\n", X_NONZERO); ! 322: } ! 323: ! 324: if (bringback) { ! 325: (void) fprintf(fprx, "%c return input on abnormal exit\n", ! 326: X_COMMENT); ! 327: (void) fprintf(fprx,"%c\n", X_BRINGBACK); ! 328: } ! 329: if (_Statop) ! 330: (void) fprintf(fprx,"%c %s\n", X_MAILF, _Sfile); ! 331: ! 332: if (retaddr != NULL) { ! 333: (void) fprintf(fprx, "%c return address for status or input return\n", ! 334: X_COMMENT); ! 335: (void) fprintf(fprx,"%c %s\n", X_RETADDR, retaddr); ! 336: } ! 337: ! 338: /* ! 339: * create a JCL file to spool pipe input into ! 340: */ ! 341: if (pipein) { ! 342: /* ! 343: * fpd is the D. file into which we now read ! 344: * input from stdin ! 345: */ ! 346: ! 347: gename(DATAPRE, Myname, 'B', dfile); ! 348: ! 349: ASSERT(access(dfile, 0) != 0, Fl_EXISTS, dfile, errno); ! 350: i = creat(dfile, DFILEMODE); ! 351: ASSERT(i >= 0, Ct_OPEN, dfile, errno); ! 352: while ((ret = read(0, buf, BUFSIZ)) > 0) ! 353: ASSERT(write(i, buf, ret) == ret, Ct_WRITE, dfile, errno); ! 354: (void) close(i); ! 355: /* ! 356: * if command is to be executed on remote ! 357: * create extra JCL ! 358: */ ! 359: if (!EQUALSN(Myname, xsys, SYSNSIZE)) { ! 360: GENSEND(fpc, dfile, dfile, dfile); ! 361: } ! 362: ! 363: /* ! 364: * create file for X_ commands ! 365: */ ! 366: (void) fprintf(fprx, "%c %s\n", X_RQDFILE, dfile); ! 367: (void) fprintf(fprx, "%c %s\n", X_STDIN, dfile); ! 368: ! 369: wfcommit(dfile, dfile, xsys); ! 370: ! 371: } ! 372: /* ! 373: * parse command ! 374: */ ! 375: ap = inargs; ! 376: while ((ap = getprm(ap, prm)) != NULL) { ! 377: DEBUG(4, "prm - %s\n", prm); ! 378: ! 379: /* ! 380: * redirection of I/O ! 381: */ ! 382: if (prm[0] == '>' || prm[0] == '<') { ! 383: redir = prm[0]; ! 384: continue; ! 385: } ! 386: ! 387: /* ! 388: * some terminator ! 389: */ ! 390: if ( prm[0] == '|' || prm[0] == '^' ! 391: || prm[0] == '&' || prm[0] == ';') { ! 392: if (*cmd != '\0') /* not 1st thing on line */ ! 393: APPCMD(prm); ! 394: command = TRUE; ! 395: continue; ! 396: } ! 397: ! 398: /* ! 399: * process command or file or option ! 400: * break out system and file name and ! 401: * use default if necessary ! 402: */ ! 403: ret = split(prm, syspart, rest); ! 404: DEBUG(4, "syspart -> %s, ", syspart); ! 405: DEBUG(4, "rest -> %s, ", rest); ! 406: DEBUG(4, "ret -> %d\n", ret); ! 407: ! 408: if (command && redir == '\0') { ! 409: /* ! 410: * command ! 411: */ ! 412: APPCMD(rest); ! 413: command = FALSE; ! 414: continue; ! 415: } ! 416: ! 417: if (syspart[0] == '\0') { ! 418: (void) strcpy(syspart, Myname); ! 419: DEBUG(6, "syspart -> %s\n", syspart); ! 420: } else if (versys(syspart, 0) != 0) { ! 421: /* ! 422: * bad system name ! 423: */ ! 424: fprintf(stderr, "bad system name: %s\n", syspart); ! 425: if (fprx != NULL) ! 426: (void) fclose(fprx); ! 427: if (fpc != NULL) ! 428: (void) fclose(fpc); ! 429: cleanup(11); ! 430: } ! 431: ! 432: /* ! 433: * process file or option ! 434: */ ! 435: ! 436: /* ! 437: * process file argument ! 438: * expand filename and create JCL card for ! 439: * redirected output ! 440: * e.g., X file sys ! 441: */ ! 442: if (redir == '>') { ! 443: if (rest[0] != '~') ! 444: if (ckexpf(rest)) ! 445: cleanup(6); ! 446: ASSERT(fprintf(fprx, "%c %s %s\n", X_STDOUT, rest, ! 447: syspart) >= 0, Ct_WRITE, rxfile, errno); ! 448: redir = '\0'; ! 449: continue; ! 450: } ! 451: ! 452: /* ! 453: * if no system specified, then being ! 454: * processed locally ! 455: */ ! 456: if (ret == NOSYSPART && redir == '\0') { ! 457: ! 458: /* ! 459: * option ! 460: */ ! 461: APPCMD(rest); ! 462: continue; ! 463: } ! 464: ! 465: ! 466: /* local xeqn + local file (!x !f) */ ! 467: if ((EQUALSN(xsys, Myname, SYSNSIZE)) ! 468: && (EQUALSN(xsys, syspart, SYSNSIZE))) { ! 469: /* ! 470: * create JCL card ! 471: */ ! 472: if (ckexpf(rest)) ! 473: cleanup(7); ! 474: /* ! 475: * JCL card for local input ! 476: * e.g., I file ! 477: */ ! 478: if (redir == '<') { ! 479: (void) fprintf(fprx, "%c %s\n", X_STDIN, rest); ! 480: } else ! 481: APPCMD(rest); ! 482: ASSERT(fprx != NULL, Ct_WRITE, rxfile, errno); ! 483: redir = '\0'; ! 484: continue; ! 485: } ! 486: ! 487: /* remote xeqn + local file (sys!x !f) */ ! 488: if (EQUALSN(syspart, Myname, SYSNSIZE)) { ! 489: /* ! 490: * check access to local file ! 491: * if cflag is set, copy to spool directory ! 492: * otherwise, just mention it in the X. file ! 493: */ ! 494: if (ckexpf(rest)) ! 495: cleanup(6); ! 496: DEBUG(4, "rest %s\n", rest); ! 497: ! 498: /* see if I can read this file as read uid, gid */ ! 499: if (uidstat(rest, &stbuf) != 0) { ! 500: (void) fprintf(stderr, ! 501: "can't get file status %s\n", rest); ! 502: cleanup(8); ! 503: } ! 504: if ( !(stbuf.st_mode & ANYREAD) ! 505: && !(stbuf.st_uid == Uid && stbuf.st_mode & 0400) ! 506: && !(stbuf.st_gid ==getgid() && stbuf.st_mode & 0040) ! 507: ) { ! 508: fprintf(stderr,"permission denied %s\n", rest); ! 509: cleanup(1); ! 510: } ! 511: ! 512: /* D. file for sending local file */ ! 513: gename(DATAPRE, xsys, 'A', dfile); ! 514: ! 515: if (cflag || !(stbuf.st_mode & ANYREAD)) { ! 516: /* make local copy */ ! 517: if (uidxcp(rest, dfile) != 0) { ! 518: fprintf(stderr,"can't copy %s\n", rest); ! 519: cleanup(5); ! 520: } ! 521: (void) chmod(dfile, DFILEMODE); ! 522: /* generate 'send' entry in command file */ ! 523: GENSEND(fpc, rest, dfile, dfile); ! 524: wfcommit(dfile, dfile, xsys); /* commit input */ ! 525: } else /* don't make local copy */ ! 526: GENSEND(fpc, rest, dfile, "D.0"); ! 527: ! 528: /* ! 529: * JCL cards for redirected input in X. file, ! 530: * e.g. ! 531: * I D.xxx ! 532: * F D.xxx ! 533: */ ! 534: if (redir == '<') { ! 535: /* ! 536: * don't bother making a X_RQDFILE line that ! 537: * renames stdin on the remote side, since the ! 538: * remote command can't know its name anyway ! 539: */ ! 540: (void) fprintf(fprx, "%c %s\n", X_STDIN, dfile); ! 541: (void) fprintf(fprx, "%c %s\n", X_RQDFILE, dfile); ! 542: } else { ! 543: APPCMD(BASENAME(rest, '/'));; ! 544: /* ! 545: * generate X. JCL card that specifies ! 546: * F file ! 547: */ ! 548: (void) fprintf(fprx, "%c %s %s\n", X_RQDFILE, ! 549: dfile, BASENAME(rest, '/')); ! 550: } ! 551: redir = '\0'; ! 552: ! 553: continue; ! 554: } ! 555: ! 556: /* local xeqn + remote file (!x sys!f ) */ ! 557: if (EQUALS(Myname, xsys)) { ! 558: /* ! 559: * expand receive file name ! 560: */ ! 561: if (ckexpf(rest)) ! 562: cleanup(6); ! 563: /* ! 564: * tfile is command file for receive from remote. ! 565: * we defer commiting until later so ! 566: * that only one C. file is created per site. ! 567: * ! 568: * dfile is name of data file to receive into; ! 569: * we don't use it, just name it. ! 570: * ! 571: * the name of the remote is appended to the ! 572: * X_RQDFILE line to help uuxqt in finding the ! 573: * D. file when it arrives. ! 574: */ ! 575: if (gtcfile(tfile, syspart) != SUCCESS) { ! 576: gename(CMDPRE, syspart, 'R', tfile); ! 577: ! 578: ASSERT(access(tfile, 0) != 0, ! 579: Fl_EXISTS, tfile, errno); ! 580: svcfile(tfile, syspart); ! 581: (void) close(creat(tfile, CFILEMODE)); ! 582: } ! 583: fp = fopen(tfile, "a"); ! 584: ASSERT(fp != NULL, Ct_OPEN, tfile, errno); ! 585: setbuf(fp, CNULL); ! 586: gename(DATAPRE, syspart, 'R', dfile); ! 587: ! 588: /* prepare JCL card to receive file */ ! 589: GENRCV(fp, rest, dfile); ! 590: ASSERT(ferror(fp) == 0, Ct_WRITE, dfile, errno); ! 591: (void) fclose(fp); ! 592: rflag++; ! 593: if (rest[0] != '~') ! 594: if (ckexpf(rest)) ! 595: cleanup(7); ! 596: ! 597: /* ! 598: * generate receive entries ! 599: */ ! 600: if (redir == '<') { ! 601: (void) fprintf(fprx, ! 602: "%c %s/%s/%s\n", X_RQDFILE, Spool, ! 603: syspart, dfile); ! 604: (void) fprintf(fprx, "%c %s\n", X_STDIN, dfile); ! 605: } else { ! 606: (void) fprintf(fprx, "%c %s/%s/%s %s\n", ! 607: X_RQDFILE, Spool, syspart, dfile, ! 608: BASENAME(rest, '/')); ! 609: APPCMD(BASENAME(rest, '/')); ! 610: } ! 611: ! 612: redir = '\0'; ! 613: continue; ! 614: } ! 615: ! 616: /* remote xeqn/file, different remotes (xsys!cmd syspart!rest) */ ! 617: if (!EQUALS(syspart, xsys)) { ! 618: /* ! 619: * strategy: ! 620: * request rest from syspart. ! 621: * ! 622: * set up a local X. file that will send rest to xsys, ! 623: * once it arrives from syspart. ! 624: * ! 625: * arrange so that the xsys D. file (fated to become ! 626: * an X. file on xsys), rest is required and named. ! 627: * ! 628: * pictorially: ! 629: * ! 630: * ===== syspart/C.syspartR.... ===== (tfile) ! 631: * R rest D.syspart... (dfile) ! 632: * ! 633: * ! 634: * ===== local/X.local... ===== (t2file) ! 635: * F Spool/syspart/D.syspart... rest (dfile) ! 636: * C uucp -C rest D.syspart... (dfile) ! 637: * ! 638: * ===== xsys/D.xsysG.... (fprx) ! 639: * F D.syspart... rest (dfile) ! 640: * or, in the case of redir == '<' ! 641: * F D.syspart... (dfile) ! 642: * I D.syspart... (dfile) ! 643: * ! 644: * while we do push rest around a bunch, ! 645: * we use the protection scheme to good effect. ! 646: * ! 647: * we must rely on uucp's treatment of requests ! 648: * form XQTDIR to get the data file to the right ! 649: * place ultimately. ! 650: */ ! 651: ! 652: /* build (or append to) C.syspartR... */ ! 653: if (gtcfile(tfile, syspart) != SUCCESS) { ! 654: gename(CMDPRE, syspart, 'R', tfile); ! 655: ! 656: ASSERT(access(tfile, 0) != 0, ! 657: Fl_EXISTS, tfile, errno); ! 658: svcfile(tfile, syspart); ! 659: (void) close(creat(tfile, CFILEMODE)); ! 660: } ! 661: fp = fopen(tfile, "a"); ! 662: ASSERT(fp != NULL, Ct_OPEN, tfile, errno); ! 663: setbuf(fp, CNULL); ! 664: gename(DATAPRE, syspart, 'R', dfile); ! 665: GENRCV(fp, rest, dfile); ! 666: ASSERT(ferror(fp) == 0, Ct_WRITE, dfile, errno); ! 667: (void) fclose(fp); ! 668: ! 669: /* build local/X.localG... */ ! 670: gename(XQTPRE, Myname, _Grade, t2file); ! 671: ASSERT(access(t2file, 0)!=0, Fl_EXISTS, t2file, errno); ! 672: (void) close(creat(t2file, CFILEMODE)); ! 673: fp = fopen(t2file, "w"); ! 674: ASSERT(fp != NULL, Ct_OPEN, t2file, errno); ! 675: setbuf(fp, CNULL); ! 676: (void) fprintf(fp, "%c %s/%s/%s %s\n", X_RQDFILE, ! 677: Spool, syspart, dfile, BASENAME(rest, '/')); ! 678: (void) fprintf(fp, "%c uucp -C %s %s!%s\n", ! 679: X_CMD, BASENAME(rest, '/'), xsys, dfile); ! 680: ASSERT(ferror(fp) == 0, Ct_WRITE, t2file, errno); ! 681: (void) fclose(fp); ! 682: ! 683: /* put t2file where uuxqt can get at it */ ! 684: wfcommit(t2file, t2file, Myname); ! 685: ! 686: /* generate xsys/X.sysG... cards */ ! 687: if (redir == '<') { ! 688: (void) fprintf(fprx, "%c %s\n", ! 689: X_RQDFILE, dfile); ! 690: (void) fprintf(fprx, "%c %s\n", X_STDIN, dfile); ! 691: } else { ! 692: (void) fprintf(fprx, "%c %s %s\n", X_RQDFILE, ! 693: dfile, BASENAME(rest, '/')); ! 694: APPCMD(BASENAME(rest, '/')); ! 695: } ! 696: redir = '\0'; ! 697: continue; ! 698: } ! 699: ! 700: /* remote xeqn + remote file, same remote (sys!x sys!f) */ ! 701: if (rest[0] != '~') /* expand '~' on remote */ ! 702: if (ckexpf(rest)) ! 703: cleanup(7); ! 704: if (redir == '<') { ! 705: (void) fprintf(fprx, "%c %s\n", X_STDIN, rest); ! 706: } ! 707: else ! 708: APPCMD(rest); ! 709: redir = '\0'; ! 710: continue; ! 711: ! 712: } ! 713: ! 714: /* ! 715: * place command to be executed in JCL file ! 716: */ ! 717: (void) fprintf(fprx, "%c %s\n", X_CMD, cmd); ! 718: ASSERT(ferror(fprx) == 0, Ct_WRITE, rxfile, errno); ! 719: (void) fclose(fprx); /* rxfile is ready for commit */ ! 720: logent(cmd, "QUEUED"); ! 721: ! 722: /* the X. name must have the X.Jobid so status reporting is by jobid */ ! 723: (void) sprintf(tfile, "X.%s", Jobid); ! 724: if (EQUALS(xsys, Myname)) { ! 725: /* local xeqn -- use X_ file here */ ! 726: wfcommit(rxfile, tfile, xsys); ! 727: ! 728: /* ! 729: * see if -r option requested JCL to be queued only ! 730: */ ! 731: if (startjob) ! 732: xuuxqt(Myname); ! 733: } else { ! 734: /* remote xeqn -- send rxfile to remote */ ! 735: /* put it in a place where cico can get at it */ ! 736: wfcommit(rxfile, rxfile, xsys); ! 737: ! 738: GENSEND(fpc, rxfile, tfile, rxfile); ! 739: } ! 740: ! 741: cfileUsed = (ftell(fpc) != 0L); /* was cfile used? */ ! 742: ASSERT(ferror(fpc) == 0, Ct_WRITE, cfile, errno); ! 743: (void) fclose(fpc); ! 744: ! 745: /* ! 746: * has any command been placed in command JCL file ! 747: */ ! 748: if (cfileUsed) { ! 749: wfcommit(cfile, cfile, xsys); ! 750: /* ! 751: * see if -r option requested JCL to be queued only ! 752: */ ! 753: if (startjob) ! 754: xuucico(xsys); ! 755: } else ! 756: unlink(cfile); ! 757: ! 758: /* commit any leftover C. files for remote receive */ ! 759: commitall(); ! 760: if (jflag) /* print Jobid */ ! 761: printf("%s\n", Jobid); ! 762: ! 763: cleanup(0); ! 764: } ! 765: ! 766: ! 767: /* ! 768: * cleanup and unlink if error ! 769: * code -> exit code ! 770: * return: ! 771: * none ! 772: */ ! 773: cleanup(code) ! 774: register int code; ! 775: { ! 776: rmlock(CNULL); ! 777: if (code) { ! 778: wfabort(); ! 779: fprintf(stderr, "uux failed ( %d )\n", code); ! 780: fflush(stderr); ! 781: if (code < 0) { ! 782: setuid(getuid()); ! 783: signal(SIGIOT, SIG_DFL); ! 784: abort(); ! 785: } ! 786: } ! 787: DEBUG(1, "exit code %d\n", code); ! 788: if (code < 0) ! 789: exit(-code); ! 790: else ! 791: exit(code); ! 792: } ! 793: ! 794: /* ! 795: * catch signal then cleanup and exit ! 796: */ ! 797: onintr(inter) ! 798: register int inter; ! 799: { ! 800: char str[30]; ! 801: (void) signal(inter, SIG_IGN); ! 802: (void) sprintf(str, "XSIGNAL %d", inter); ! 803: logent(str, "XCAUGHT"); ! 804: cleanup(-inter); ! 805: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.