Annotation of researchv10no/cmd/uucp/uucp.c, revision 1.1.1.1

1.1       root        1: /*     @(#)uucp.c      1.6
                      2: */
                      3: #include "uucp.h"
                      4: VERSION(@(#)uucp.c     1.6);
                      5: 
                      6: /*
                      7:  * uucp
                      8:  * user id 
                      9:  * make a copy in spool directory
                     10:  */
                     11: int Copy = 0;
                     12: static int _Transfer = 0;
                     13: char Nuser[32];
                     14: char *Ropt = " ";
                     15: char Optns[10];
                     16: char Uopts[BUFSIZ];
                     17: char Grade = 'N';
                     18: 
                     19: char   Sfile[MAXFULLNAME];
                     20: #ifndef        V7
                     21: long ulimit();
                     22: #endif
                     23: 
                     24: main(argc, argv, envp)
                     25: char   *argv[];
                     26: char   **envp;
                     27: {
                     28:        int     ret;
                     29:        int     errors = 0;
                     30:        char    *fopt;
                     31:        char    sys1[MAXFULLNAME], sys2[MAXFULLNAME];
                     32:        char    fwd1[MAXFULLNAME], fwd2[MAXFULLNAME];
                     33:        char    file1[MAXFULLNAME], file2[MAXFULLNAME];
                     34:        short   jflag = 0;      /* -j flag  Jobid printout */
                     35: 
                     36:        void    split();
                     37: #ifndef V7
                     38:        long    limit, dummy;
                     39:        char    msg[100];
                     40: #endif V7
                     41: 
                     42: 
                     43:        /* this fails in some versions, but it doesn't hurt */
                     44:        Uid = getuid();
                     45:        Euid = geteuid();
                     46:        if (Uid == 0)
                     47:                (void) setuid(UUCPUID);
                     48: 
                     49:        /* choose LOGFILE */
                     50:        (void) strcpy(Logfile, LOGUUCP);
                     51: 
                     52:        Env = envp;
                     53:        fopt = NULL;
                     54:        (void) strcpy(Progname, "uucp");
                     55:        Pchar = 'U';
                     56:        *Uopts =  NULLCHAR;
                     57: 
                     58:        /*
                     59:         * find name of local system
                     60:         */
                     61:        uucpname(Myname);
                     62:        Optns[0] = '-';
                     63:        Optns[1] = 'd';
                     64:        Optns[2] = 'c';
                     65:        Optns[3] = Nuser[0] = Sfile[0] = NULLCHAR;
                     66: 
                     67:        /*
                     68:         * find id of user who spawned command to 
                     69:         * determine
                     70:         */
                     71:        (void) guinfo(Uid, User);
                     72: 
                     73:        while ((ret = getopt(argc, argv, "Ccdfg:jmn:rx:")) != EOF) {
                     74:                switch (ret) {
                     75: 
                     76:                /*
                     77:                 * make a copy of the file in the spool
                     78:                 * directory.
                     79:                 */
                     80:                case 'C':
                     81:                        Copy = 1;
                     82:                        Optns[2] = 'C';
                     83:                        break;
                     84: 
                     85:                /*
                     86:                 * not used (default)
                     87:                 */
                     88:                case 'c':
                     89:                        break;
                     90: 
                     91:                /*
                     92:                 * not used (default)
                     93:                 */
                     94:                case 'd':
                     95:                        break;
                     96:                case 'f':
                     97:                        Optns[1] = 'f';
                     98:                        break;
                     99: 
                    100:                /*
                    101:                 * set service grade
                    102:                 */
                    103:                case 'g':
                    104:                        Grade = *optarg;
                    105:                        break;
                    106: 
                    107:                case 'j':       /* job id */
                    108:                        jflag = 1;
                    109:                        break;
                    110: 
                    111:                /*
                    112:                 * send notification to local user
                    113:                 */
                    114:                case 'm':
                    115:                        (void) strcat(Optns, "m");
                    116:                        break;
                    117: 
                    118:                /*
                    119:                 * send notification to user on remote
                    120:                 * if no user specified do not send notification
                    121:                 */
                    122:                case 'n':
                    123:                        (void) strcat(Optns, "n");
                    124:                        (void) sprintf(Nuser, "%.8s", optarg);
                    125:                        (void) sprintf(Uopts+strlen(Uopts), "-n%s ", Nuser);
                    126:                        break;
                    127: 
                    128:                /*
                    129:                 * create JCL files but do not start uucico
                    130:                 */
                    131:                case 'r':
                    132:                        Ropt = "-r";
                    133:                        break;
                    134: 
                    135:                /*
                    136:                 * return status file
                    137:                 */
                    138: 
                    139:                /*
                    140:                 * turn on debugging
                    141:                 */
                    142:                case 'x':
                    143:                        Debug = atoi(optarg);
                    144:                        if (Debug <= 0)
                    145:                                Debug = 1;
                    146:                        break;
                    147: 
                    148:                default:
                    149:                        /* getopt has already (stupidly) babbled */
                    150:                        break;
                    151:                }
                    152:        }
                    153:        DEBUG(4, "\n\n** %s **\n", "START");
                    154:        gwd(Wrkdir);
                    155:        if (fopt) {
                    156:                if (*fopt != '/')
                    157:                        (void) sprintf(Sfile, "%s/%s", Wrkdir, fopt);
                    158:                else
                    159:                        (void) sprintf(Sfile, "%s", fopt);
                    160: 
                    161:        }
                    162:        /*
                    163:         * work in WORKSPACE directory
                    164:         */
                    165:        ret = chdir(WORKSPACE);
                    166:        if (ret != 0) {
                    167:                (void) fprintf(stderr, "No work directory - %s - get help\n",
                    168:                    WORKSPACE);
                    169:                cleanup(-12);
                    170:        }
                    171: 
                    172:        if (Nuser[0] == NULLCHAR)
                    173:                (void) strcpy(Nuser, User);
                    174:        (void) strcpy(Loginuser, User);
                    175:        DEBUG(4, "UID %d, ", Uid);
                    176:        DEBUG(4, "User %s\n", User);
                    177:        if (argc - optind < 2) {
                    178:                (void) fprintf(stderr, "usage uucp from ... to\n");
                    179:                cleanup(-2);
                    180:        }
                    181: 
                    182:        /*
                    183:         * set up "to" system and file names
                    184:         */
                    185: 
                    186:        split(argv[argc - 1], sys2, fwd2, file2);
                    187:        if (*sys2 != NULLCHAR) {
                    188:                if (versys(sys2, 0) != 0) {
                    189:                        (void) fprintf(stderr, "bad system: %s\n", sys2);
                    190:                        cleanup(-11);
                    191:                }
                    192:        }
                    193:        else
                    194:                (void) strcpy(sys2, Myname);
                    195: 
                    196:        (void) strncpy(Rmtname, sys2, MAXBASENAME);
                    197:        Rmtname[MAXBASENAME] = NULLCHAR;
                    198: 
                    199:        DEBUG(9, "sys2: %s, ", sys2);
                    200:        DEBUG(9, "fwd2: %s, ", fwd2);
                    201:        DEBUG(9, "file2: %s\n", file2);
                    202: 
                    203:        /*
                    204:         * if there are more than 2 argsc, file2 is a directory
                    205:         */
                    206:        if (argc - optind > 2)
                    207:                (void) strcat(file2, "/");
                    208: 
                    209:        /*
                    210:         * do each from argument
                    211:         */
                    212: 
                    213:        for ( ; optind < argc - 1; optind++) {
                    214:            split(argv[optind], sys1, fwd1, file1);
                    215:            if (*sys1 != NULLCHAR) {
                    216:                if (versys(sys1, 0) != 0) {
                    217:                        (void) fprintf(stderr, "bad system: %s\n", sys1);
                    218:                        cleanup(-11);
                    219:                }
                    220:            }
                    221: 
                    222:            /*  source files can have at most one ! */
                    223:            if (*fwd1 != NULLCHAR) {
                    224:                /* syntax error */
                    225:                (void) fprintf(stderr, "illegal  syntax %s\n", argv[optind]);
                    226:                exit(2);
                    227:            }
                    228: 
                    229:            /*
                    230:             * check for required remote expansion of file names -- generate
                    231:             *  and execute a uux command
                    232:             * e.g.
                    233:             *          uucp   owl!~/dan/*   ~/dan/
                    234:             *
                    235:             * NOTE: The source file part must be full path name.
                    236:             *  If ~ it will be expanded locally - it assumes the remote
                    237:             *  names are the same.
                    238:             */
                    239: 
                    240:            if (*sys1 != NULLCHAR)
                    241:                if ((strchr(file1, '*') != NULL
                    242:                      || strchr(file1, '?') != NULL
                    243:                      || strchr(file1, '[') != NULL)) {
                    244:                        /* do a uux command */
                    245:                        if (ckexpf(file1) == FAIL)
                    246:                            exit(6);
                    247:                        ruux(sys1, sys1, file1, sys2, fwd2, file2);
                    248:                        continue;
                    249:                }
                    250: 
                    251:            /*
                    252:             * check for forwarding -- generate and execute a uux command
                    253:             * e.g.
                    254:             *          uucp uucp.c raven!owl!~/dan/
                    255:             */
                    256: 
                    257:            if (*fwd2 != NULLCHAR) {
                    258:                ruux(sys2, sys1, file1, "", fwd2, file2);
                    259:                continue;
                    260:            }
                    261: 
                    262:            /*
                    263:             * check for both source and destination on other systems --
                    264:             *  generate and execute a uux command
                    265:             */
                    266: 
                    267:            if (*sys1 != NULLCHAR )
                    268:                if ( (!EQUALS(Myname, sys1))
                    269:                  && *sys2 != NULLCHAR
                    270:                  && (!EQUALS(sys2, Myname)) ) {
                    271:                    ruux(sys2, sys1, file1, "", fwd2, file2);
                    272:                    continue;
                    273:                }
                    274: 
                    275: 
                    276:            if (*sys1 == NULLCHAR)
                    277:                (void) strcpy(sys1, Myname);
                    278:            else {
                    279:                (void) strncpy(Rmtname, sys1, MAXBASENAME);
                    280:                Rmtname[MAXBASENAME] = NULLCHAR;
                    281:            }
                    282: 
                    283:            DEBUG(4, "sys1 - %s, ", sys1);
                    284:            DEBUG(4, "file1 - %s, ", file1);
                    285:            DEBUG(4, "Rmtname - %s\n", Rmtname);
                    286:            if (copy(sys1, file1, sys2, file2))
                    287:                errors++;
                    288:        }
                    289: 
                    290:        /* move the work files to their proper places */
                    291:        commitall();
                    292: 
                    293:        /*
                    294:         * do not spawn daemon if -r option specified
                    295:         */
                    296: #ifndef        V7
                    297:        limit = ulimit(1, dummy);
                    298: #endif V7
                    299:        if (*Ropt != '-')
                    300: #ifndef        V7
                    301:                if (limit < MINULIMIT)  {
                    302:                        (void) sprintf(msg,
                    303:                            "ULIMIT (%ld) < MINULIMIT (%ld)", limit, MINULIMIT);
                    304:                        logent(msg, "Low-ULIMIT");
                    305:                }
                    306:                else
                    307: #endif
                    308:                        xuucico(Rmtname);
                    309:        if (jflag)
                    310:            printf("%s\n", Jobid);
                    311:        cleanup(errors);
                    312: }
                    313: 
                    314: /*
                    315:  * cleanup lock files before exiting
                    316:  */
                    317: cleanup(code)
                    318: register int   code;
                    319: {
                    320:        rmlock(CNULL);
                    321:        if (code != 0)
                    322:                wfabort();      /* this may be extreme -- abort all work */
                    323:        if (code < 0) {
                    324:               (void) fprintf(stderr, "uucp failed completely (%d)\n", (-code));
                    325:                exit(-code);
                    326:        }
                    327:        else if (code > 0) {
                    328:                (void) fprintf(stderr, 
                    329:                "uucp failed partially: %d file(s) sent; %d error(s)\n",
                    330:                 _Transfer, code);
                    331:                exit(code);
                    332:        }
                    333:        exit(code);
                    334: }
                    335: 
                    336: /*
                    337:  * generate copy files for s1!f1 -> s2!f2
                    338:  *     Note: only one remote machine, other situations
                    339:  *     have been taken care of in main.
                    340:  * return:
                    341:  *     0       -> success
                    342:  * Non-zero     -> failure
                    343:  */
                    344: 
                    345: copy(s1, f1, s2, f2)
                    346: char *s1, *f1, *s2, *f2;
                    347: {
                    348:        FILE *cfp, *syscfile();
                    349:        struct stat stbuf, stbuf1;
                    350:        int type, statret;
                    351:        char dfile[NAMESIZE];
                    352:        char cfile[NAMESIZE];
                    353:        char file1[MAXFULLNAME], file2[MAXFULLNAME];
                    354:        char msg[BUFSIZ];
                    355: 
                    356:        type = 0;
                    357:        (void) strcpy(file1, f1);
                    358:        (void) strcpy(file2, f2);
                    359:        if (!EQUALS(s1, Myname))
                    360:                type = 1;
                    361:        if (!EQUALS(s2, Myname))
                    362:                type = 2;
                    363: 
                    364:        switch (type) {
                    365:        case 0:
                    366: 
                    367:                /*
                    368:                 * all work here
                    369:                 */
                    370:                DEBUG(4, "all work here %d\n", type);
                    371: 
                    372:                /*
                    373:                 * check access control permissions
                    374:                 */
                    375:                if (ckexpf(file1))
                    376:                         return(-6);
                    377:                if (ckexpf(file2))
                    378:                         return(-7);
                    379:                if (uidstat(file1, &stbuf) != 0) {
                    380:                        (void) fprintf(stderr,
                    381:                            "can't get file status %s\n copy failed\n", file1);
                    382:                        return(8);
                    383:                }
                    384:                statret = uidstat(file2, &stbuf1);
                    385:                if (statret == 0
                    386:                  && stbuf.st_ino == stbuf1.st_ino
                    387:                  && stbuf.st_dev == stbuf1.st_dev) {
                    388:                        (void) fprintf(stderr,
                    389:                            "%s %s - same file; can't copy\n", file1, file2);
                    390:                        return(5);
                    391:                }
                    392:                if (chkperm(file1, file2, strchr(Optns, 'd')) ) {
                    393:                        (void) fprintf(stderr, "permission denied\n");
                    394:                        cleanup(1);
                    395:                }
                    396:                if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {
                    397:                        (void) fprintf(stderr, "directory name illegal - %s\n",
                    398:                          file1);
                    399:                        return(9);
                    400:                }
                    401:                /* see if I can read this file as read uid, gid */
                    402:                if ( !(stbuf.st_mode & ANYREAD)
                    403:                  && !(stbuf.st_uid == Uid && stbuf.st_mode & 0400)
                    404:                  && !(stbuf.st_gid == getgid() && stbuf.st_mode & 0040)
                    405:                  ) {
                    406:                        (void) fprintf(stderr,
                    407:                            "uucp can't read (%s) mode (%o)\n",
                    408:                            file1, stbuf.st_mode);
                    409:                        (void) fprintf(stderr, "use cp command\n");
                    410:                        return(3);
                    411:                }
                    412:                if (statret == 0 && (stbuf1.st_mode & ANYWRITE) == 0) {
                    413:                        (void) fprintf(stderr,
                    414:                            "can't write file (%s) mode (%o)\n",
                    415:                            file2, stbuf1.st_mode);
                    416:                        return(4);
                    417:                }
                    418: 
                    419:                /*
                    420:                 * copy file locally
                    421:                 */
                    422:                DEBUG(2, "local copy:  uidxcp(%s, ", file1);
                    423:                DEBUG(2, "%s\n", file2);
                    424: 
                    425:                /* do copy as Uid, but the file will be owned by uucp */
                    426:                if (uidxcp(file1, file2) == FAIL) {
                    427:                        (void) fprintf(stderr,
                    428:                            "can't copy file (%s) errno %d\n", file2, errno);
                    429:                        return(5);
                    430:                }
                    431:                (void) chmod(file2, (int) (stbuf.st_mode | 0666) & 0777);
                    432:                return(0);
                    433:        case 1:
                    434: 
                    435:                /*
                    436:                 * receive file
                    437:                 */
                    438:                DEBUG(4, "receive file - %d\n", type);
                    439: 
                    440:                /*
                    441:                 * expand source and destination file names
                    442:                 * and check access permissions
                    443:                 */
                    444:                if (file1[0] != '~')
                    445:                        if (ckexpf(file1))
                    446:                                 return(6);
                    447:                if (ckexpf(file2))
                    448:                         return(7);
                    449: 
                    450:                /*
                    451:                 * insert JCL card in file
                    452:                 */
                    453:                cfp = syscfile(cfile, s1);
                    454:                (void) fprintf(cfp, 
                    455:                "R %s %s %s %s %s %o %s\n", file1, file2,
                    456:                        User, Optns,
                    457:                        *Sfile ? Sfile : "dummy",
                    458:                        0777, Nuser);
                    459:                (void) fclose(cfp);
                    460:                (void) sprintf(msg, "%s!%s --> %s!%s", Rmtname, file1,
                    461:                    Myname, file2);
                    462:                logent(msg, "QUEUED");
                    463:                break;
                    464:        case 2:
                    465: 
                    466:                /*
                    467:                 * send file
                    468:                 */
                    469:                if (ckexpf(file1))
                    470:                         return(6);
                    471:                /* XQTDIR hook enables 3rd party uux requests (cough) */
                    472:                if (file2[0] != '~' && !EQUALS(Wrkdir, XQTDIR))
                    473:                        if (ckexpf(file2))
                    474:                                 return(7);
                    475:                DEBUG(4, "send file - %d\n", type);
                    476: 
                    477:                if (uidstat(file1, &stbuf) != 0) {
                    478:                        (void) fprintf(stderr,
                    479:                            "can't get status for file %s\n", file1);
                    480:                        return(8);
                    481:                }
                    482:                if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {
                    483:                        (void) fprintf(stderr,
                    484:                            "directory name illegal - %s\n", file1);
                    485:                        return(9);
                    486:                }
                    487: 
                    488:                /*
                    489:                 * make a copy of file in spool directory
                    490:                 */
                    491:                if (Copy || !READANY(file1) ) {
                    492:                        gename(DATAPRE, s2, Grade, dfile);
                    493: 
                    494:                        if (uidxcp(file1, dfile))
                    495:                            return(5);
                    496: 
                    497:                        (void) chmod(dfile, DFILEMODE);
                    498:                        wfcommit(dfile, dfile, s2);
                    499:                } else {
                    500: 
                    501:                        /*
                    502:                         * make a dummy D. name
                    503:                         * cntrl.c knows names < 6 chars are dummy D. files
                    504:                         */
                    505:                        (void) strcpy(dfile, "D.0");
                    506:                }
                    507: 
                    508:                /*
                    509:                 * insert JCL card in file
                    510:                 */
                    511:                cfp = syscfile(cfile, s2);
                    512:                (void) fprintf(cfp, "S  %s %s %s %s %s %o %s %s\n",
                    513:                    file1, file2, User, Optns, dfile,
                    514:                    stbuf.st_mode & 0777, Nuser, Sfile);
                    515:                (void) fclose(cfp);
                    516:                (void) sprintf(msg, "%s!%s --> %s!%s", Myname, file1,
                    517:                    Rmtname, file2);
                    518:                logent(msg, "QUEUED");
                    519:                break;
                    520:        }
                    521:        _Transfer++;
                    522:        return(0);
                    523: }
                    524: 
                    525: 
                    526: /*
                    527:  *     syscfile(file, sys)
                    528:  *     char    *file, *sys;
                    529:  *
                    530:  *     get the cfile for system sys (creat if need be)
                    531:  *     return stream pointer
                    532:  *
                    533:  *     returns
                    534:  *             stream pointer to open cfile
                    535:  *             
                    536:  */
                    537: 
                    538: static FILE    *
                    539: syscfile(file, sys)
                    540: char   *file, *sys;
                    541: {
                    542:        FILE    *cfp;
                    543: 
                    544:        if (gtcfile(file, sys) == FAIL) {
                    545:                gename(CMDPRE, sys, Grade, file);
                    546:                ASSERT(access(file, 0) != 0, Fl_EXISTS, file, errno);
                    547:                cfp = fdopen(creat(file, CFILEMODE), "w");
                    548:                svcfile(file, sys);
                    549:        } else
                    550:                cfp = fopen(file, "a");
                    551:        /*  set Jobid -- C.jobid */
                    552:        (void) strncpy(Jobid, BASENAME(file, '.'), NAMESIZE);
                    553:        Jobid[NAMESIZE-1] = '\0';
                    554:        ASSERT(cfp != NULL, Ct_OPEN, file, errno);
                    555:        return(cfp);
                    556: }
                    557: 
                    558: 
                    559: /*
                    560:  * split - split the name into parts:
                    561:  * sys - system name
                    562:  * fwd - intermediate destinations
                    563:  * file - file part
                    564:  */
                    565: 
                    566: static
                    567: void
                    568: split(arg, sys, fwd, file)
                    569: char *arg, *sys, *fwd, *file;
                    570: {
                    571:     register char *cl, *cr, *n;
                    572:     *sys = *fwd = *file = NULLCHAR;
                    573:        
                    574:     for (n=arg ;; n=cl+1) {
                    575:        cl = strchr(n, '!');
                    576:        if ( cl == NULL) {
                    577:            /* no ! in n */
                    578:            (void) strcpy(file, n);
                    579:            return;
                    580:        }
                    581: 
                    582:        if (PREFIX(Myname, n))
                    583:            continue;
                    584: 
                    585:        cr = strrchr(n, '!');
                    586:        (void) strcpy(file, cr+1);
                    587:        (void) strncpy(sys, n, cl-n);
                    588:        sys[cl-n] = NULLCHAR;
                    589: 
                    590:        if (cr != cl) {
                    591:            /*  more than one ! */
                    592:            (void) strncpy(fwd, cl+1, cr-cl-1);
                    593:            fwd[cr-cl-1] = NULLCHAR;
                    594:        }
                    595:        return;
                    596:     }
                    597:     /*NOTREACHED*/
                    598: }
                    599: 
                    600: 
                    601: /*
                    602:  * generate and execute a uux command
                    603:  */
                    604: 
                    605: ruux(rmt, sys1, file1, sys2, fwd2, file2)
                    606: char *rmt, *sys1, *file1, *sys2, *fwd2, *file2;
                    607: {
                    608:     char cmd[BUFSIZ];
                    609: 
                    610:     if (*Uopts != NULLCHAR)
                    611:        (void) sprintf(cmd, "uux -C %s %s!uucp -C \\(%s\\) ", Ropt, rmt, Uopts);
                    612:     else
                    613:        (void) sprintf(cmd, "uux -C %s %s!uucp -C ", Ropt, rmt);
                    614: 
                    615:     if (*sys1 == NULLCHAR || EQUALS(sys1, Myname)) {
                    616:         if (ckexpf(file1))
                    617:            exit(6);
                    618:        (void) sprintf(cmd+strlen(cmd), " %s!%s ", sys1, file1);
                    619:     }
                    620:     else
                    621:        if (!EQUALS(rmt, sys1))
                    622:            (void) sprintf(cmd+strlen(cmd), " \\(%s!%s\\) ", sys1, file1);
                    623:        else
                    624:            (void) sprintf(cmd+strlen(cmd), " \\(%s\\) ", file1);
                    625: 
                    626:     if (*fwd2 != NULLCHAR) {
                    627:        if (*sys2 != NULLCHAR)
                    628:            (void) sprintf(cmd+strlen(cmd),
                    629:                " \\(%s!%s!%s\\) ", sys2, fwd2, file2);
                    630:        else
                    631:            (void) sprintf(cmd+strlen(cmd), " \\(%s!%s\\) ", fwd2, file2);
                    632:     }
                    633:     else {
                    634:        if (*sys2 == NULLCHAR || EQUALS(sys2, Myname))
                    635:            if (ckexpf(file2))
                    636:                exit(7);
                    637:        (void) sprintf(cmd+strlen(cmd), " \\(%s!%s\\) ", sys2, file2);
                    638:     }
                    639: 
                    640:     DEBUG(2, "cmd: %s\n", cmd);
                    641:     logent(cmd, "QUEUED");
                    642:     system(cmd);
                    643:     return;
                    644: }

unix.superglobalmegacorp.com

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