|
|
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, User, _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, User, *_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: gwd(Wrkdir); ! 204: if(fopt){ ! 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: setbuf(fpc, CNULL); ! 289: ! 290: /* set Jobid -- C.jobid */ ! 291: (void) strncpy(Jobid, BASENAME(cfile, '.'), NAMESIZE); ! 292: Jobid[NAMESIZE-1] = '\0'; ! 293: ! 294: /* ! 295: * rxfile is the X. file for the job, fprx is its stream ptr. ! 296: * if the command is to be executed locally, rxfile becomes ! 297: * a local X. file, otherwise we send it as a D. file to the ! 298: * remote site. ! 299: */ ! 300: ! 301: gename(DATAPRE, xsys, 'X', rxfile); ! 302: DEBUG(9, "rxfile = %s\n", rxfile); ! 303: ASSERT(access(rxfile, 0) != 0, Fl_EXISTS, rxfile, errno); ! 304: fprx = fdopen(ret = creat(rxfile, DFILEMODE), "w"); ! 305: ASSERT(ret >= 0 && fprx != NULL, Ct_WRITE, rxfile, errno); ! 306: setbuf(fprx, CNULL); ! 307: clearerr(fprx); ! 308: ! 309: (void) fprintf(fprx,"%c %s %s\n", X_USER, User, Myname); ! 310: if (zflag) { ! 311: (void) fprintf(fprx, "%c return status on success\n", ! 312: X_COMMENT); ! 313: (void) fprintf(fprx,"%c\n", X_SENDZERO); ! 314: } ! 315: ! 316: if (nflag) { ! 317: (void) fprintf(fprx, "%c don't return status on failure\n", ! 318: X_COMMENT); ! 319: (void) fprintf(fprx,"%c\n", X_SENDNOTHING); ! 320: } else { ! 321: (void) fprintf(fprx, "%c return status on failure\n", ! 322: X_COMMENT); ! 323: fprintf(fprx,"%c\n", X_NONZERO); ! 324: } ! 325: ! 326: if (bringback) { ! 327: (void) fprintf(fprx, "%c return input on abnormal exit\n", ! 328: X_COMMENT); ! 329: (void) fprintf(fprx,"%c\n", X_BRINGBACK); ! 330: } ! 331: if (_Statop) ! 332: (void) fprintf(fprx,"%c %s\n", X_MAILF, _Sfile); ! 333: ! 334: if (retaddr != NULL) { ! 335: (void) fprintf(fprx, "%c return address for status or input return\n", ! 336: X_COMMENT); ! 337: (void) fprintf(fprx,"%c %s\n", X_RETADDR, retaddr); ! 338: } ! 339: ! 340: /* ! 341: * create a JCL file to spool pipe input into ! 342: */ ! 343: if (pipein) { ! 344: /* ! 345: * fpd is the D. file into which we now read ! 346: * input from stdin ! 347: */ ! 348: ! 349: gename(DATAPRE, Myname, 'B', dfile); ! 350: ! 351: ASSERT(access(dfile, 0) != 0, Fl_EXISTS, dfile, errno); ! 352: fpd = fdopen(ret = creat(dfile, DFILEMODE), "w"); ! 353: ASSERT(ret >= 0 && fpd != NULL, Ct_OPEN, dfile, errno); ! 354: ! 355: /* ! 356: * read pipe to EOF ! 357: */ ! 358: while (!feof(stdin)) { ! 359: ret = fread(buf, 1, BUFSIZ, stdin); ! 360: ASSERT(fwrite(buf, 1, ret, fpd) == ret, Ct_WRITE, ! 361: dfile, errno); ! 362: } ! 363: ASSERT(ferror(fpd) == 0, Ct_WRITE, dfile, errno); ! 364: (void) fclose(fpd); ! 365: ! 366: /* ! 367: * if command is to be executed on remote ! 368: * create extra JCL ! 369: */ ! 370: if (!EQUALSN(Myname, xsys, SYSNSIZE)) { ! 371: GENSEND(fpc, dfile, dfile, dfile); ! 372: } ! 373: ! 374: /* ! 375: * create file for X_ commands ! 376: */ ! 377: (void) fprintf(fprx, "%c %s\n", X_RQDFILE, dfile); ! 378: (void) fprintf(fprx, "%c %s\n", X_STDIN, dfile); ! 379: ! 380: wfcommit(dfile, dfile, xsys); ! 381: ! 382: } ! 383: /* ! 384: * parse command ! 385: */ ! 386: ap = inargs; ! 387: while ((ap = getprm(ap, prm)) != NULL) { ! 388: DEBUG(4, "prm - %s\n", prm); ! 389: ! 390: /* ! 391: * redirection of I/O ! 392: */ ! 393: if (prm[0] == '>' || prm[0] == '<') { ! 394: redir = prm[0]; ! 395: continue; ! 396: } ! 397: ! 398: /* ! 399: * some terminator ! 400: */ ! 401: if ( prm[0] == '|' || prm[0] == '^' ! 402: || prm[0] == '&' || prm[0] == ';') { ! 403: if (*cmd != '\0') /* not 1st thing on line */ ! 404: APPCMD(prm); ! 405: command = TRUE; ! 406: continue; ! 407: } ! 408: ! 409: /* ! 410: * process command or file or option ! 411: * break out system and file name and ! 412: * use default if necessary ! 413: */ ! 414: ret = split(prm, syspart, rest); ! 415: DEBUG(4, "syspart -> %s, ", syspart); ! 416: DEBUG(4, "rest -> %s, ", rest); ! 417: DEBUG(4, "ret -> %d\n", ret); ! 418: ! 419: if (command && redir == '\0') { ! 420: /* ! 421: * command ! 422: */ ! 423: APPCMD(rest); ! 424: command = FALSE; ! 425: continue; ! 426: } ! 427: ! 428: if (syspart[0] == '\0') { ! 429: (void) strcpy(syspart, Myname); ! 430: DEBUG(6, "syspart -> %s\n", syspart); ! 431: } else if (versys(syspart, 0) != 0) { ! 432: /* ! 433: * bad system name ! 434: */ ! 435: fprintf(stderr, "bad system name: %s\n", syspart); ! 436: if (fprx != NULL) ! 437: (void) fclose(fprx); ! 438: if (fpc != NULL) ! 439: (void) fclose(fpc); ! 440: cleanup(11); ! 441: } ! 442: ! 443: /* ! 444: * process file or option ! 445: */ ! 446: ! 447: /* ! 448: * process file argument ! 449: * expand filename and create JCL card for ! 450: * redirected output ! 451: * e.g., X file sys ! 452: */ ! 453: if (redir == '>') { ! 454: if (rest[0] != '~') ! 455: if (ckexpf(rest)) ! 456: cleanup(6); ! 457: ASSERT(fprintf(fprx, "%c %s %s\n", X_STDOUT, rest, ! 458: syspart) >= 0, Ct_WRITE, rxfile, errno); ! 459: redir = '\0'; ! 460: continue; ! 461: } ! 462: ! 463: /* ! 464: * if no system specified, then being ! 465: * processed locally ! 466: */ ! 467: if (ret == NOSYSPART && redir == '\0') { ! 468: ! 469: /* ! 470: * option ! 471: */ ! 472: APPCMD(rest); ! 473: continue; ! 474: } ! 475: ! 476: ! 477: /* local xeqn + local file (!x !f) */ ! 478: if ((EQUALSN(xsys, Myname, SYSNSIZE)) ! 479: && (EQUALSN(xsys, syspart, SYSNSIZE))) { ! 480: /* ! 481: * create JCL card ! 482: */ ! 483: if (ckexpf(rest)) ! 484: cleanup(7); ! 485: /* ! 486: * JCL card for local input ! 487: * e.g., I file ! 488: */ ! 489: if (redir == '<') { ! 490: (void) fprintf(fprx, "%c %s\n", X_STDIN, rest); ! 491: } else ! 492: APPCMD(rest); ! 493: ASSERT(fprx != NULL, Ct_WRITE, rxfile, errno); ! 494: redir = '\0'; ! 495: continue; ! 496: } ! 497: ! 498: /* remote xeqn + local file (sys!x !f) */ ! 499: if (EQUALSN(syspart, Myname, SYSNSIZE)) { ! 500: /* ! 501: * check access to local file ! 502: * if cflag is set, copy to spool directory ! 503: * otherwise, just mention it in the X. file ! 504: */ ! 505: if (ckexpf(rest)) ! 506: cleanup(6); ! 507: DEBUG(4, "rest %s\n", rest); ! 508: ! 509: /* see if I can read this file as read uid, gid */ ! 510: if (uidstat(rest, &stbuf) != 0) { ! 511: (void) fprintf(stderr, ! 512: "can't get file status %s\n", rest); ! 513: cleanup(8); ! 514: } ! 515: if ( !(stbuf.st_mode & ANYREAD) ! 516: && !(stbuf.st_uid == Uid && stbuf.st_mode & 0400) ! 517: && !(stbuf.st_gid ==getgid() && stbuf.st_mode & 0040) ! 518: ) { ! 519: fprintf(stderr,"permission denied %s\n", rest); ! 520: cleanup(1); ! 521: } ! 522: ! 523: /* D. file for sending local file */ ! 524: gename(DATAPRE, xsys, 'A', dfile); ! 525: ! 526: if (cflag || !(stbuf.st_mode & ANYREAD)) { ! 527: /* make local copy */ ! 528: if (uidxcp(rest, dfile) != 0) { ! 529: fprintf(stderr,"can't copy %s\n", rest); ! 530: cleanup(5); ! 531: } ! 532: (void) chmod(dfile, DFILEMODE); ! 533: /* generate 'send' entry in command file */ ! 534: GENSEND(fpc, rest, dfile, dfile); ! 535: wfcommit(dfile, dfile, xsys); /* commit input */ ! 536: } else /* don't make local copy */ ! 537: GENSEND(fpc, rest, dfile, "D.0"); ! 538: ! 539: /* ! 540: * JCL cards for redirected input in X. file, ! 541: * e.g. ! 542: * I D.xxx ! 543: * F D.xxx ! 544: */ ! 545: if (redir == '<') { ! 546: /* ! 547: * don't bother making a X_RQDFILE line that ! 548: * renames stdin on the remote side, since the ! 549: * remote command can't know its name anyway ! 550: */ ! 551: (void) fprintf(fprx, "%c %s\n", X_STDIN, dfile); ! 552: (void) fprintf(fprx, "%c %s\n", X_RQDFILE, dfile); ! 553: } else { ! 554: APPCMD(BASENAME(rest, '/'));; ! 555: /* ! 556: * generate X. JCL card that specifies ! 557: * F file ! 558: */ ! 559: (void) fprintf(fprx, "%c %s %s\n", X_RQDFILE, ! 560: dfile, BASENAME(rest, '/')); ! 561: } ! 562: redir = '\0'; ! 563: ! 564: continue; ! 565: } ! 566: ! 567: /* local xeqn + remote file (!x sys!f ) */ ! 568: if (EQUALS(Myname, xsys)) { ! 569: /* ! 570: * expand receive file name ! 571: */ ! 572: if (ckexpf(rest)) ! 573: cleanup(6); ! 574: /* ! 575: * tfile is command file for receive from remote. ! 576: * we defer commiting until later so ! 577: * that only one C. file is created per site. ! 578: * ! 579: * dfile is name of data file to receive into; ! 580: * we don't use it, just name it. ! 581: * ! 582: * the name of the remote is appended to the ! 583: * X_RQDFILE line to help uuxqt in finding the ! 584: * D. file when it arrives. ! 585: */ ! 586: if (gtcfile(tfile, syspart) != SUCCESS) { ! 587: gename(CMDPRE, syspart, 'R', tfile); ! 588: ! 589: ASSERT(access(tfile, 0) != 0, ! 590: Fl_EXISTS, tfile, errno); ! 591: svcfile(tfile, syspart); ! 592: (void) close(creat(tfile, CFILEMODE)); ! 593: } ! 594: fp = fopen(tfile, "a"); ! 595: ASSERT(fp != NULL, Ct_OPEN, tfile, errno); ! 596: setbuf(fp, CNULL); ! 597: gename(DATAPRE, syspart, 'R', dfile); ! 598: ! 599: /* prepare JCL card to receive file */ ! 600: GENRCV(fp, rest, dfile); ! 601: ASSERT(ferror(fp) == 0, Ct_WRITE, dfile, errno); ! 602: (void) fclose(fp); ! 603: rflag++; ! 604: if (rest[0] != '~') ! 605: if (ckexpf(rest)) ! 606: cleanup(7); ! 607: ! 608: /* ! 609: * generate receive entries ! 610: */ ! 611: if (redir == '<') { ! 612: (void) fprintf(fprx, ! 613: "%c %s/%s/%s\n", X_RQDFILE, Spool, ! 614: syspart, dfile); ! 615: (void) fprintf(fprx, "%c %s\n", X_STDIN, dfile); ! 616: } else { ! 617: (void) fprintf(fprx, "%c %s/%s/%s %s\n", ! 618: X_RQDFILE, Spool, syspart, dfile, ! 619: BASENAME(rest, '/')); ! 620: APPCMD(BASENAME(rest, '/')); ! 621: } ! 622: ! 623: redir = '\0'; ! 624: continue; ! 625: } ! 626: ! 627: /* remote xeqn/file, different remotes (xsys!cmd syspart!rest) */ ! 628: if (!EQUALS(syspart, xsys)) { ! 629: /* ! 630: * strategy: ! 631: * request rest from syspart. ! 632: * ! 633: * set up a local X. file that will send rest to xsys, ! 634: * once it arrives from syspart. ! 635: * ! 636: * arrange so that the xsys D. file (fated to become ! 637: * an X. file on xsys), rest is required and named. ! 638: * ! 639: * pictorially: ! 640: * ! 641: * ===== syspart/C.syspartR.... ===== (tfile) ! 642: * R rest D.syspart... (dfile) ! 643: * ! 644: * ! 645: * ===== local/X.local... ===== (t2file) ! 646: * F Spool/syspart/D.syspart... rest (dfile) ! 647: * C uucp -C rest D.syspart... (dfile) ! 648: * ! 649: * ===== xsys/D.xsysG.... (fprx) ! 650: * F D.syspart... rest (dfile) ! 651: * or, in the case of redir == '<' ! 652: * F D.syspart... (dfile) ! 653: * I D.syspart... (dfile) ! 654: * ! 655: * while we do push rest around a bunch, ! 656: * we use the protection scheme to good effect. ! 657: * ! 658: * we must rely on uucp's treatment of requests ! 659: * form XQTDIR to get the data file to the right ! 660: * place ultimately. ! 661: */ ! 662: ! 663: /* build (or append to) C.syspartR... */ ! 664: if (gtcfile(tfile, syspart) != SUCCESS) { ! 665: gename(CMDPRE, syspart, 'R', tfile); ! 666: ! 667: ASSERT(access(tfile, 0) != 0, ! 668: Fl_EXISTS, tfile, errno); ! 669: svcfile(tfile, syspart); ! 670: (void) close(creat(tfile, CFILEMODE)); ! 671: } ! 672: fp = fopen(tfile, "a"); ! 673: ASSERT(fp != NULL, Ct_OPEN, tfile, errno); ! 674: setbuf(fp, CNULL); ! 675: gename(DATAPRE, syspart, 'R', dfile); ! 676: GENRCV(fp, rest, dfile); ! 677: ASSERT(ferror(fp) == 0, Ct_WRITE, dfile, errno); ! 678: (void) fclose(fp); ! 679: ! 680: /* build local/X.localG... */ ! 681: gename(XQTPRE, Myname, _Grade, t2file); ! 682: ASSERT(access(t2file, 0)!=0, Fl_EXISTS, t2file, errno); ! 683: (void) close(creat(t2file, CFILEMODE)); ! 684: fp = fopen(t2file, "w"); ! 685: ASSERT(fp != NULL, Ct_OPEN, t2file, errno); ! 686: setbuf(fp, CNULL); ! 687: (void) fprintf(fp, "%c %s/%s/%s %s\n", X_RQDFILE, ! 688: Spool, syspart, dfile, BASENAME(rest, '/')); ! 689: (void) fprintf(fp, "%c uucp -C %s %s!%s\n", ! 690: X_CMD, BASENAME(rest, '/'), xsys, dfile); ! 691: ASSERT(ferror(fp) == 0, Ct_WRITE, t2file, errno); ! 692: (void) fclose(fp); ! 693: ! 694: /* put t2file where uuxqt can get at it */ ! 695: wfcommit(t2file, t2file, Myname); ! 696: ! 697: /* generate xsys/X.sysG... cards */ ! 698: if (redir == '<') { ! 699: (void) fprintf(fprx, "%c %s\n", ! 700: X_RQDFILE, dfile); ! 701: (void) fprintf(fprx, "%c %s\n", X_STDIN, dfile); ! 702: } else { ! 703: (void) fprintf(fprx, "%c %s %s\n", X_RQDFILE, ! 704: dfile, BASENAME(rest, '/')); ! 705: APPCMD(BASENAME(rest, '/')); ! 706: } ! 707: redir = '\0'; ! 708: continue; ! 709: } ! 710: ! 711: /* remote xeqn + remote file, same remote (sys!x sys!f) */ ! 712: if (rest[0] != '~') /* expand '~' on remote */ ! 713: if (ckexpf(rest)) ! 714: cleanup(7); ! 715: if (redir == '<') { ! 716: (void) fprintf(fprx, "%c %s\n", X_STDIN, rest); ! 717: } ! 718: else ! 719: APPCMD(rest); ! 720: redir = '\0'; ! 721: continue; ! 722: ! 723: } ! 724: ! 725: /* ! 726: * place command to be executed in JCL file ! 727: */ ! 728: (void) fprintf(fprx, "%c %s\n", X_CMD, cmd); ! 729: ASSERT(ferror(fprx) == 0, Ct_WRITE, rxfile, errno); ! 730: (void) fclose(fprx); /* rxfile is ready for commit */ ! 731: logent(cmd, "QUEUED"); ! 732: ! 733: /* the X. name must have the X.Jobid so status reporting is by jobid */ ! 734: (void) sprintf(tfile, "X.%s", Jobid); ! 735: if (EQUALS(xsys, Myname)) { ! 736: /* local xeqn -- use X_ file here */ ! 737: wfcommit(rxfile, tfile, xsys); ! 738: ! 739: /* ! 740: * see if -r option requested JCL to be queued only ! 741: */ ! 742: if (startjob) ! 743: xuuxqt(Myname); ! 744: } else { ! 745: /* remote xeqn -- send rxfile to remote */ ! 746: /* put it in a place where cico can get at it */ ! 747: wfcommit(rxfile, rxfile, xsys); ! 748: ! 749: GENSEND(fpc, rxfile, tfile, rxfile); ! 750: } ! 751: ! 752: cfileUsed = (ftell(fpc) != 0L); /* was cfile used? */ ! 753: ASSERT(ferror(fpc) == 0, Ct_WRITE, cfile, errno); ! 754: (void) fclose(fpc); ! 755: ! 756: /* ! 757: * has any command been placed in command JCL file ! 758: */ ! 759: if (cfileUsed) { ! 760: wfcommit(cfile, cfile, xsys); ! 761: /* ! 762: * see if -r option requested JCL to be queued only ! 763: */ ! 764: if (startjob) ! 765: xuucico(xsys); ! 766: } else ! 767: unlink(cfile); ! 768: ! 769: /* commit any leftover C. files for remote receive */ ! 770: commitall(); ! 771: if (jflag) /* print Jobid */ ! 772: printf("%s\n", Jobid); ! 773: ! 774: cleanup(0); ! 775: } ! 776: ! 777: ! 778: /* ! 779: * cleanup and unlink if error ! 780: * code -> exit code ! 781: * return: ! 782: * none ! 783: */ ! 784: cleanup(code) ! 785: register int code; ! 786: { ! 787: rmlock(CNULL); ! 788: if (code) { ! 789: wfabort(); ! 790: fprintf(stderr, "uux failed ( %d )\n", code); ! 791: fflush(stderr); ! 792: if (code < 0) { ! 793: setuid(getuid()); ! 794: signal(SIGIOT, SIG_DFL); ! 795: abort(); ! 796: } ! 797: } ! 798: DEBUG(1, "exit code %d\n", code); ! 799: if (code < 0) ! 800: exit(-code); ! 801: else ! 802: exit(code); ! 803: } ! 804: ! 805: /* ! 806: * catch signal then cleanup and exit ! 807: */ ! 808: onintr(inter) ! 809: register int inter; ! 810: { ! 811: char str[30]; ! 812: (void) signal(inter, SIG_IGN); ! 813: (void) sprintf(str, "XSIGNAL %d", inter); ! 814: logent(str, "XCAUGHT"); ! 815: cleanup(-inter); ! 816: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.