Annotation of researchv8dc/cmd/uucp/uux.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.