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

unix.superglobalmegacorp.com

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