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

1.1       root        1: /*     @(#)uucleanup.c 1.6
                      2: 
                      3:  *     uucleanup - This is a program based on the heuristics
                      4:  *     by Brian Redman for cleaning up and doing something
                      5:  *     useful with old files left in the uucp queues.
                      6:  *     It also will send warning messags to users where requests are not
                      7:  *     going out due to failure to contact the remote system.
                      8:  *
                      9:  *     This program knows a lot about the construction and
                     10:  *     contents of the C., D. and X. files.  In addition, it
                     11:  *     thinks it knows what mail and netnews data files look like.
                     12:  *
                     13:  *     At present, this is what is done:
                     14:  *     For WARNING messages:
                     15:  *     C. files of age given by -W option are read, looking for
                     16:  *             either user files to be sent or received, or
                     17:  *             mail to be sent.  (Other remote execution that
                     18:  *             does not involve sending user files is not checked
                     19:  *             for now.)  In either of the cases, the user is
                     20:  *             informed by mail that the request is not being
                     21:  *             processed due to lack of communications with the remote
                     22:  *             system, and the request will be deleted in the future
                     23:  *             if it the condition remains for several more days.
                     24:  *
                     25:  *     For DELETIONS:
                     26:  *     C. files - if they reference only D. files, the C. is
                     27:  *             merely deleted, because the D. files are usually
                     28:  *             mail or news, and the later D. processing will
                     29:  *             take care of them.
                     30:  *             - if they reference files from the file system,
                     31:  *             a message is constructed that will contain a
                     32:  *             lines like
                     33:  *                We can't contact the remote.
                     34:  *
                     35:  *                local!file -> remote!otherfile
                     36:  *
                     37:  *                can't be executed.
                     38:  *     X. files - merely deleted at present - D.s will be taken
                     39:  *             care of later. Besides, some of the D.s are
                     40:  *             missing or else the X. wouldn't be left around.
                     41:  *     D. files - mail type data is sent to a local person if that
                     42:  *             is where it originated.  If not, it is returned to the
                     43:  *             sender -- assumed to be from the first From line.  If
                     44:  *             a sender can't be determing, the file is merely deleted.
                     45:  *             - rnews: if locally generated, just delete.  If remote,
                     46:  *             the X. got lost, so execute rnews.
                     47:  *     other files - just delete them.
                     48:  *
                     49:  *     Deletions and executions are logged in
                     50:  *     (CLEANUPLOG)--/usr/spool/uucp/.Admin/uucleanup
                     51: */
                     52: 
                     53: #include       "uucp.h"
                     54: VERSION(@(#)uucleanup.c        1.6);
                     55: 
                     56: #ifdef V7
                     57: #define O_RDONLY       0
                     58: #endif
                     59: 
                     60: #define USAGE  "[-oDAYS] [-mSTRING] [-Cdays] [-Ddays] [-Wdays] [-Xdays] [-xLEVEL] [-sSYSTEM]"
                     61: 
                     62: extern int _age();             /* find the age of a file */
                     63: extern void oprocess(), xprocess(), cprocess();
                     64: extern void dXprocess(), dNprocess(), dMprocess(), dDprocess(), wprocess(); 
                     65: extern int toWho(), sendMail(), execRnews();
                     66: extern void logit();
                     67: 
                     68: /* need these dummys to satisy some .o files */
                     69: cleanup(){}
                     70: void systat(){}
                     71: void logent(){}
                     72: 
                     73: 
                     74: /* types of D. files */
                     75: #define D_MAIL 1
                     76: #define D_NEWS 2
                     77: #define D_XFILE        3
                     78: #define D_DATA 4
                     79: #define FULLNAME(full,dir,file)        (void) sprintf(full, "%s/%s", dir, file);
                     80: 
                     81: int _Ddays = 7;                        /* D. limit */
                     82: int _Cdays = 7;                        /* C. limit */
                     83: int _Xdays = 2;                        /* X. limit */
                     84: int _Odays = 2;                        /* O. limit */
                     85: int _Wdays = 1;                        /* Warning limit for C. files */
                     86: char _ShortLocal[6];           /* 5 char or less version of local name */
                     87: 
                     88: char *_Undeliverable[] = {
                     89: "Subject: Undeliverable Mail\n",
                     90: "This mail message is undeliverable.\n",
                     91: "(Probably to or from system '%s')\n",
                     92: "It was sent to you or by you.\n",
                     93: "Sorry for the inconvenience.\n",
                     94: "",
                     95: };
                     96: 
                     97: #define CANT1  2       /* first line to fill in */
                     98: #define CANT2  3       /* second line to fill in */
                     99: char *_CantContact[] = {
                    100: "Subject: Job Killed By uucp\n",
                    101: "We can't contact machine '%s'.\n",
                    102: " ",   /* uucleanup will fill in variable text here */
                    103: " ",   /* fill in jobid of killed job */
                    104: "",
                    105: };
                    106: 
                    107: #define WARN1  2
                    108: #define WARN2  5
                    109: #define WARN3  6
                    110: char *_Warning[] = {
                    111: "Subject: Warning From uucp\n",
                    112: "We have been unable to contact machine '%s' since you queued your job.\n",
                    113: " ",   /*  wprocess FILLS IN THIS LINE OF TEXT */
                    114: "The job will be deleted in several days if the problem is not corrected.\n",
                    115: "If you care to kill the job, execute the following command:\n",
                    116: " ",   /*  wprocess FILLS IN THIS LINE WITH:  uustat -kJOBid */
                    117: " ",   /* FILL IN THE -m STRING IF SPECIFIED */
                    118: "",
                    119: };
                    120: 
                    121: main(argc, argv, envp)
                    122: char *argv[];
                    123: char **envp;
                    124: {
                    125:        DIR *spooldir, *subdir;
                    126:        char f[MAXFULLNAME], subf[MAXFULLNAME];
                    127:        char fullname[MAXFULLNAME];
                    128:        int pass = 0;   /* pass counter - multi passes through directory */
                    129:        char soptName[MAXFULLNAME];     /* name from -s option */
                    130:        int i, value;
                    131: 
                    132:        soptName[0] = NULLCHAR;
                    133:        (void) strcpy(Logfile, CLEANUPLOGFILE);
                    134:        uucpname(Myname);
                    135:        (void) strncpy(_ShortLocal, Myname, 5);
                    136:        _ShortLocal[5] = NULLCHAR;
                    137:        (void) strcpy(Progname, "uucleanup");
                    138:        while ((i = getopt(argc, argv, "C:D:W:X:m:o:s:x:")) != EOF) {
                    139:                switch(i){
                    140:                case 's':       /* for debugging - choose system */
                    141:                        (void) strcpy(soptName, optarg);
                    142:                        break;
                    143:                case 'x':
                    144:                        Debug = atoi(optarg);
                    145:                        if (Debug <= 0)
                    146:                                Debug = 1;
                    147:                        break;
                    148:                case 'm':
                    149:                        _Warning[WARN3] = optarg;
                    150:                        break;
                    151:                default:
                    152:                        (void) fprintf(stderr, "\tusage: %s %s\n",
                    153:                            Progname, USAGE);
                    154:                        exit(1);
                    155: 
                    156:                case 'C':
                    157:                case 'D':
                    158:                case 'W':
                    159:                case 'X':
                    160:                case 'o':
                    161:                    value = atoi(optarg);
                    162:                    if (value < 1) {
                    163:                        fprintf(stderr," Options: CDWXo require value > 0\n");
                    164:                        exit(1);
                    165:                    }
                    166:                    switch(i) {
                    167:                    case 'C':
                    168:                        _Cdays = value;
                    169:                        break;
                    170:                    case 'D':
                    171:                        _Ddays = value;
                    172:                        break;
                    173:                    case 'W':
                    174:                        _Wdays = value;
                    175:                        break;
                    176:                    case 'X':
                    177:                        _Xdays = value;
                    178:                        break;
                    179:                    case 'o':
                    180:                        _Odays = value;
                    181:                        break;
                    182:                    }
                    183:                    break;
                    184:                }
                    185:        }
                    186: 
                    187:        if (argc != optind) {
                    188:                (void) fprintf(stderr, "\tusage: %s %s\n", Progname, USAGE);
                    189:                exit(1);
                    190:        }
                    191: 
                    192:        DEBUG(5, "Progname (%s): STARTED\n", Progname);
                    193:        DEBUG(5, "Myname (%s), ", Myname);
                    194:        DEBUG(5, "_ShortLocal (%s)\n", _ShortLocal);
                    195:        DEBUG(5, "Days C.(%d), ", _Cdays);
                    196:        DEBUG(5, "D.(%d), ", _Ddays);
                    197:        DEBUG(5, "W.(%d), ", _Wdays);
                    198:        DEBUG(5, "X.(%d), ", _Xdays);
                    199:        DEBUG(5, "other (%d)\n", _Odays);
                    200: 
                    201:        if (chdir(SPOOL) != 0) {
                    202:            (void) fprintf(stderr, "CAN'T CHDIR (%s): errno (%d)\n",
                    203:                SPOOL, errno);
                    204:                exit(1);
                    205:        }
                    206:        if ( (spooldir = opendir(SPOOL)) == NULL) {
                    207:            (void) fprintf(stderr, "CAN'T OPEN (%s): errno (%d)\n",
                    208:                SPOOL, errno);
                    209:                exit(1);
                    210:        }
                    211: 
                    212:        while (gnamef(spooldir, f) == TRUE) {
                    213:            if (EQUALSN("LCK..", f, 5))
                    214:                continue;
                    215: 
                    216:            if (*soptName && !EQUALS(soptName, f))
                    217:                continue;
                    218: 
                    219:            if (DIRECTORY(f)) {
                    220:                (void) strcpy(Rmtname, f);
                    221:                pass = 0;
                    222:                /*
                    223:                 * pass 1 - process old C. and X. files
                    224:                 * pass 2 - process D.s that are going to X.
                    225:                 * pass 3 - processs D. mail and netnews and other D.s
                    226:                 * pass 4 - process other
                    227:                 */
                    228:                while ( (++pass < 5) && (subdir = opendir(f)) ) {
                    229:                    DEBUG(7, "Directory: %s\n", f);
                    230:                    while (gnamef(subdir, subf) == TRUE) {
                    231:                        DEBUG(9, "file: %s\n", subf);
                    232:                        FULLNAME(fullname, f, subf);
                    233:                        switch (pass) {
                    234:                        case 1:
                    235:                            if (EQUALSN(subf, "C.", 2)
                    236:                            &&  _age(fullname) >=_Cdays)
                    237:                                        cprocess(fullname);
                    238:                            else if (EQUALSN(subf, "C.", 2)
                    239:                            &&  _age(fullname) ==_Wdays)
                    240:                                        wprocess(f, subf);
                    241:                            else if (EQUALSN(subf, "X.", 2)
                    242:                            &&  _age(fullname) >=_Xdays)
                    243:                                        xprocess(fullname);
                    244:                            break;
                    245: 
                    246:                        case 2: /* pass 2 */
                    247:                            if (EQUALSN(subf, "D.", 2)
                    248:                            &&  _age(fullname) >= _Ddays
                    249:                            && dType(fullname) == D_XFILE)
                    250:                                        dXprocess(fullname);
                    251:                            break;
                    252: 
                    253:                        case 3: /* pass 3 */
                    254:                            if (EQUALSN(subf, "D.", 2)
                    255:                            &&  _age(fullname) >= _Ddays)
                    256:                                switch (dType(fullname)) {
                    257:                                case D_MAIL:
                    258:                                        dMprocess(f, subf);
                    259:                                        break;
                    260:                                case D_NEWS:
                    261:                                        dNprocess(f, subf);
                    262:                                        break;
                    263:                                case D_DATA:
                    264:                                        dDprocess(fullname);
                    265:                                        break;
                    266:                                default:        /* do nothing */
                    267:                                        break;
                    268:                                }
                    269:                            break;
                    270:                        case 4:
                    271:                            if ( _age(fullname) >= _Odays
                    272:                                 && !EQUALSN(subf, "C.", 2)
                    273:                                 && !EQUALSN(subf, "D.", 2)
                    274:                                 && !EQUALSN(subf, "X.", 2) )
                    275:                                        oprocess(fullname);
                    276:                            break;
                    277:                        }
                    278:                    }
                    279:                    closedir(subdir);
                    280:                }
                    281:            }
                    282:        }
                    283:        exit(0);
                    284: }
                    285: 
                    286: /* xprocess - X. file processing -- just remove the X. for now */
                    287: 
                    288: void
                    289: xprocess(fullname)
                    290: char *fullname;
                    291: {
                    292:        char text[BUFSIZ];
                    293: 
                    294:        DEBUG(5, "xprocess(%s), ", fullname);
                    295:        DEBUG(5, "unlink(%s)\n", fullname);
                    296:        (void) sprintf(text, "xprocess: unlink(%s)", fullname);
                    297:        errno = 0;
                    298:        (void) unlink(fullname);
                    299:        logit(text, errno);
                    300: }
                    301: 
                    302: /*
                    303:  * cprocess - Process old C. files
                    304:  *
                    305:  */
                    306: 
                    307: #define CMFMT  "\n\t%s!%s -> %s!%s   (Date %2.2d/%2.2d)\n\nCan't be executed."
                    308: #define XFMT  "\n\t%s!%s  (Date %2.2d/%2.2d)\n"
                    309: #define WFMT  "\n\t%s!%s -> %s!%s   (Date %2.2d/%2.2d)\n"
                    310: void
                    311: cprocess(fullname)
                    312: char *fullname;
                    313: {
                    314:        struct stat s;
                    315:        register struct tm *tp;
                    316:        char buf[BUFSIZ], user[9];
                    317:        char file1[BUFSIZ], file2[BUFSIZ], file3[BUFSIZ], type[2], opt[256];
                    318:        char text[BUFSIZ], text1[BUFSIZ], text2[BUFSIZ];
                    319:        FILE *fp;
                    320:        int ret;
                    321: 
                    322:        DEBUG(5, "cprocess(%s)\n", fullname);
                    323: 
                    324: 
                    325:        fp = fopen(fullname, "r");
                    326:        if (fp == NULL) {
                    327:                DEBUG(5, "Can't open file (%s), ", fullname);
                    328:                DEBUG(5, "errno=%d -- skip it!\n", errno);
                    329:                return;
                    330:        }
                    331:        if (fstat(fileno(fp), &s) != 0) {
                    332:            /* can't happen; _age() did stat of this file and file is opened */
                    333:            (void) fclose(fp);
                    334:            return;
                    335:        }
                    336:        tp = localtime(&s.st_mtime);
                    337: 
                    338:        if (s.st_size == 0) { /* dummy C. for polling */
                    339:                DEBUG(5, "dummy C. -- unlink(%s)\n", fullname);
                    340:                (void) sprintf(text, "dDprocess: dummy C. unlinked(%s)",
                    341:                        fullname);
                    342:                errno = 0;
                    343:                (void) unlink(fullname);
                    344:                logit(text, errno);
                    345:                (void) fclose(fp);
                    346:                return;
                    347:        }
                    348: 
                    349:        /* Read the C. file and process it */
                    350:        while (fgets(buf, BUFSIZ, fp) != NULL) {
                    351:            buf[strlen(buf)-1] = NULLCHAR; /* remove \n */
                    352:            if (sscanf(buf,"%s%s%s%s%s%s", type, file1, file2,
                    353:              user, opt, file3) <5) {
                    354:                (void) sprintf(text, "cprocess: Bad C. %s, unlink(%s)",
                    355:                    buf, fullname);
                    356:                break;
                    357:            }
                    358: 
                    359:            *text = NULLCHAR;
                    360:            ret = 0;
                    361:            /* fill in line 3 of text */
                    362:            (void) sprintf(text2, "Job (%s) killed!\n",
                    363:                BASENAME(fullname, '/')+2);
                    364:            _CantContact[CANT2] = text2;
                    365:            if (*type == 'S') {
                    366:                if (EQUALSN(file1, "D.", 2))
                    367:                /* generated file (mail/news) I think */
                    368:                /* D. processing will return it later */
                    369:                    continue;
                    370: 
                    371:                /* some data was requested -- tell user */
                    372:                
                    373:                (void) sprintf(text1, CMFMT, Myname, file1, Rmtname, file2,
                    374:                    tp->tm_mon + 1, tp->tm_mday);
                    375:                _CantContact[CANT1] = text1;
                    376:                ret = sendMail((char *) NULL, user, "", _CantContact);
                    377:            }
                    378:            else if (*type == 'R') {
                    379:                (void) sprintf(text1, CMFMT, Rmtname, file1, Myname, file2,
                    380:                    tp->tm_mon + 1, tp->tm_mday);
                    381:                _CantContact[CANT1] = text1;
                    382:                ret = sendMail((char *) NULL, user, "", _CantContact);
                    383:            }
                    384:        }
                    385: 
                    386:        if (!*text) {
                    387:            (void) sprintf(text,
                    388:                "cprocess: C. %s, mail returned (%d), unlink(%s)",
                    389:                    buf, ret, fullname);
                    390:        }
                    391:        DEBUG(3, "text (%s)\n", text);
                    392: 
                    393:        errno = 0;
                    394:        (void) unlink(fullname);
                    395:        logit(text, errno);
                    396: 
                    397:        (void) fclose(fp);
                    398:        return;
                    399: }
                    400: 
                    401: /*
                    402:  * wprocess - send warning messages for C. == Wdays
                    403:  */
                    404: 
                    405: void
                    406: wprocess(dir, file)
                    407: char *dir, *file;
                    408: {
                    409:        struct stat s;
                    410:        register struct tm *tp;
                    411:        char fullname[BUFSIZ], xfile[BUFSIZ], xF_file[BUFSIZ];
                    412:        char buf[BUFSIZ], user[BUFSIZ];
                    413:        char file1[BUFSIZ], file2[BUFSIZ], file3[BUFSIZ], type[2], opt[256];
                    414:        char text[BUFSIZ], text1[BUFSIZ], text2[BUFSIZ];
                    415:        char *realuser, uline_m[NAMESIZE], uline_u[BUFSIZ], retaddr[BUFSIZ];
                    416:        FILE *fp, *xfp;
                    417:        int ret;
                    418: 
                    419:        FULLNAME(fullname, dir, file);
                    420:        DEBUG(5, "wprocess(%s)\n", fullname);
                    421: 
                    422:        fp = fopen(fullname, "r");
                    423:        if (fp == NULL) {
                    424:                DEBUG(4, "Can't open file (%s), ", fullname);
                    425:                DEBUG(4, "errno=%d -- skip it!\n", errno);
                    426:                return;
                    427:        }
                    428:        if (fstat(fileno(fp), &s) != 0) {
                    429:            /* can't happen; _age() did stat of this file and file is opened */
                    430:            (void) fclose(fp);
                    431:            return;
                    432:        }
                    433:        tp = localtime(&s.st_mtime);
                    434: 
                    435:        if (s.st_size == 0) { /* dummy C. for polling */
                    436:                DEBUG(5, "dummy C. -- skip(%s)\n", fullname);
                    437:                (void) fclose(fp);
                    438:                return;
                    439:        }
                    440: 
                    441:        /* read C. and process it */
                    442:        while (fgets(buf, BUFSIZ, fp) != NULL) {
                    443:            buf[strlen(buf)-1] = NULLCHAR; /* remove \n */
                    444:            if (sscanf(buf,"%s%s%s%s%s%s", type, file1, file2,
                    445:              user, opt, file3) <5) {
                    446:                DEBUG(5, "short line (%s): ", buf);
                    447:                DEBUG(5, "bad D. -- skip(%s)\n", fullname);
                    448:                (void) fclose(fp);
                    449:                return;
                    450:            }
                    451: 
                    452:            /* set up the 6th text line of the mail message */
                    453:            (void) sprintf(text2,
                    454:                    "\n\tuustat -k%s\n", BASENAME(fullname, '/')+2);
                    455: 
                    456:            _Warning[WARN2] = text2;
                    457:            if (*type == 'S') { /* Send type C. file processing */
                    458:                if (EQUALSN(file2, "X.", 2)) {
                    459:                    /* this is a uux job - tell user about it */
                    460:                    FULLNAME(xfile, dir, file1);
                    461:                    if ( (xfp = fopen(xfile, "r")) == NULL) {
                    462:                        /* Can't read X. file ??? - just skip */
                    463:                        DEBUG(3, "Can't read %s\n", xfile);
                    464:                        break;
                    465:                    }
                    466:                    *retaddr = *uline_u = *uline_m = *text = NULLCHAR;
                    467:                    while (fgets(buf, BUFSIZ, xfp) != NULL) {
                    468:                        buf[strlen(buf)-1] = NULLCHAR; /* remove \n */
                    469:                        switch(*buf) {
                    470:                        case 'F':       /* save the file name */
                    471:                            FULLNAME(xF_file, dir, &buf[2]);
                    472:                            break;
                    473:                        case 'R':       /* save return address */
                    474:                            sscanf(buf+2, "%s", retaddr);
                    475:                            DEBUG(7, "retaddr (%s)\n", retaddr);
                    476:                            break;
                    477:                        case 'U':       /* save machine, user */
                    478:                            sscanf(buf+2, "%s%s", uline_u, uline_m);
                    479:                            break;
                    480:                        }
                    481:                        if (buf[0] != 'C')
                    482:                            continue;
                    483:                        realuser = uline_u;
                    484:                        if (*retaddr != NULLCHAR)
                    485:                            realuser = retaddr;
                    486:                        if (*realuser == NULLCHAR)
                    487:                                strcpy(realuser, user);
                    488:                        if (!EQUALS(uline_m, Myname))
                    489:                            sprintf(user, "%s!%s", uline_m, realuser);
                    490:                        else
                    491:                            strcpy(user, realuser);
                    492:                        
                    493:                        (void) sprintf(text1, XFMT, Rmtname,
                    494:                            EQUALSN(&buf[2], "rmail", 5) ? &buf[3] :  &buf[2],
                    495:                            tp->tm_mon + 1, tp->tm_mday);
                    496:                        _Warning[WARN1] = text1;
                    497:                        if (EQUALSN(&buf[2], "rmail", 5) )
                    498:                            /* this is mail; append user mail (xF_file) */
                    499:                            ret = sendMail((char *) NULL, user, xF_file, _Warning);
                    500:                        else
                    501:                            ret = sendMail((char *) NULL, user, "", _Warning);
                    502:                        break;
                    503:                    }
                    504:                    (void) fclose(xfp);
                    505:                    break;
                    506:                }
                    507: 
                    508:                if (EQUALSN(file1, "D.", 2))
                    509:                /* generated file (mail/news) I think */
                    510:                /* D. processing will return it later */
                    511:                    continue;
                    512: 
                    513:                /* some data was requested -- tell user */
                    514:                
                    515:                /* set up the 2nd text line of the mail message */
                    516:                (void) sprintf(text1, WFMT, Myname, file1, Rmtname, file2,
                    517:                    tp->tm_mon + 1, tp->tm_mday);
                    518:                _Warning[WARN1] = text1;
                    519:                ret = sendMail((char *) NULL, user, "", _Warning);
                    520:            }
                    521: 
                    522:            else if (*type == 'R') {    /* Receive C. file processing */
                    523:                if (EQUALSN(file1, "D.", 2) && EQUALSN(file2, "D.", 2))
                    524:                    continue;
                    525:                (void) sprintf(text1, WFMT, Rmtname, file1, Myname, file2,
                    526:                    tp->tm_mon + 1, tp->tm_mday);
                    527:                _Warning[WARN1] = text1;
                    528:                ret = sendMail((char *) NULL, user, "", _Warning);
                    529:            }
                    530:        }       /* end while - read C. lines loop */
                    531: 
                    532:        (void) sprintf(text,
                    533:                "wprocess: %s: %s, warning message sent to %s, returned (%d)",
                    534:                    fullname, buf, user, ret);
                    535:        DEBUG(3, "text (%s)\n", text);
                    536: 
                    537:        logit(text, errno);
                    538: 
                    539:        (void) fclose(fp);
                    540:        return;
                    541: }
                    542: /*
                    543:  * oprocess - some unknown file just remove the file
                    544:  */
                    545: 
                    546: void
                    547: oprocess(fullname)
                    548: char *fullname;
                    549: {
                    550: 
                    551:        char text[BUFSIZ];
                    552: 
                    553:        DEBUG(5, "oprocess(%s), ", fullname);
                    554:        DEBUG(5, "unlink(%s)\n", fullname);
                    555:        (void) sprintf(text, "oprocess: unlink(%s)", fullname);
                    556:        errno = 0;
                    557:        (void) unlink(fullname);
                    558:        logit(text, errno);
                    559: }
                    560: 
                    561: /*
                    562:  * dDprocess - random D. file (not mail or rnews)
                    563:  *--just delete it for now
                    564:  */
                    565: 
                    566: void
                    567: dDprocess(fullname)
                    568: char *fullname;
                    569: {
                    570:        char text[BUFSIZ];
                    571: 
                    572:        DEBUG(5, "dDprocess(%s), ", fullname);
                    573:        DEBUG(5, "unlink(%s)\n", fullname);
                    574:        (void) sprintf(text, "dDprocess: unlink(%s)", fullname);
                    575:        errno = 0;
                    576:        (void) unlink(fullname);
                    577:        logit(text, errno);
                    578: }
                    579: 
                    580: /*
                    581:  * dXprocess - process D. files that are destined for X. on remote
                    582:  * --for now just delete it
                    583:  */
                    584: 
                    585: void
                    586: dXprocess(fullname)
                    587: char *fullname;
                    588: {
                    589:        char text[BUFSIZ];
                    590: 
                    591:        DEBUG(5, "dXprocess(%s), ", fullname);
                    592:        DEBUG(5, "  unlink(%s)\n", fullname);
                    593:        (void) sprintf(text, "dXprocess: unlink(%s)", fullname);
                    594:        errno = 0;
                    595:        (void) unlink(fullname);
                    596:        logit(text, errno);
                    597: }
                    598: 
                    599: /*
                    600:  * dMprocess - process ophan D. mail files
                    601:  * There are two types: ones generated locally and
                    602:  * others that are from remotes.  They can be identified
                    603:  * by the system name following the D.
                    604:  * Local ones have the local name.
                    605:  */
                    606: 
                    607: void
                    608: dMprocess(dir, file)
                    609: char *dir, *file;
                    610: {
                    611:        int ret;
                    612:        char fullname[MAXFULLNAME];
                    613:        char *toUser, *toSystem;
                    614:        char text[BUFSIZ];
                    615: 
                    616:        (void) sprintf(fullname, "%s/%s", dir, file);
                    617:        DEBUG(5, "dMprocess(%s)\n", fullname);
                    618: 
                    619: 
                    620:        if (PREFIX(_ShortLocal, &file[2])) {
                    621:            DEBUG(5, "  Local file %s: ", file);
                    622:        }
                    623:        else {
                    624:            DEBUG(5, "  Remote file %s: ", file);
                    625:        }
                    626:        if (toWho(fullname, &toUser, &toSystem)) {
                    627:            DEBUG(5, "toUser %s, ", toUser);
                    628:            DEBUG(5, "toSystem %s  ", toSystem);
                    629:            ret = sendMail(toSystem, toUser, fullname, _Undeliverable);
                    630:            DEBUG(5, "Mail sent, unlink(%s)\n", fullname);
                    631:            (void) sprintf(text,
                    632:                "dMprocess: mail %s to %s!%s, returned (%d),  unlink(%s)",
                    633:                fullname, toSystem, toUser, ret, fullname);
                    634:            errno = 0;
                    635:            (void) unlink(fullname);
                    636:            logit(text, errno);
                    637:        }
                    638: }
                    639: 
                    640: /*
                    641:  * dNprocess - process ophan D. netnews files
                    642:  * There are two types: ones generated locally and
                    643:  * others that are from remotes.  They can be identified
                    644:  * by the system name following the D.
                    645:  * Local ones have the local name.
                    646:  */
                    647: 
                    648: void
                    649: dNprocess(dir, file)
                    650: char *dir, *file;
                    651: {
                    652:        char fullname[MAXFULLNAME];
                    653:        char text[BUFSIZ];
                    654:        int ret;
                    655: 
                    656:        (void) sprintf(fullname, "%s/%s", dir, file);
                    657:        DEBUG(5, "dNprocess(%s)\n", fullname);
                    658: 
                    659: 
                    660:        if (PREFIX(_ShortLocal, &file[2])) {
                    661:            /* just delete it, the C. is gone */
                    662:            DEBUG(5, "  Local file %s, ", file);
                    663:            DEBUG(5, "unlink(%s)\n", fullname);
                    664:            (void) unlink(fullname);
                    665:            (void) sprintf(text, "dNprocess: Local news item unlink(%s)",
                    666:                fullname);
                    667:            errno = 0;
                    668:            (void) unlink(fullname);
                    669:            logit(text, errno);
                    670:        }
                    671:        else {
                    672:            /* execute rnews with this file - the X. is missing */
                    673:            DEBUG(5, "  Remote file %s, ", file);
                    674:            DEBUG(5, "exec rnews(%s), ", fullname);
                    675:            ret = execRnews(fullname);
                    676:            DEBUG(5, "unlink(%s)\n", fullname);
                    677:            (void) sprintf(text,
                    678:                "dNprocess: Remote - exec rnews %s: returned (%d), unlink(%s)",
                    679:                fullname, ret, fullname);
                    680:            errno = 0;
                    681:            (void) unlink(fullname);
                    682:            logit(text, errno);
                    683:        }
                    684: 
                    685: }
                    686: 
                    687: 
                    688: 
                    689: static long _sec_per_day = 86400L;
                    690: 
                    691: /*
                    692:  * _age - find the age of "file" in days
                    693:  * return:
                    694:  *     age of file
                    695:  *     0 - if stat fails
                    696:  */
                    697: 
                    698: int
                    699: _age(fullname)
                    700: char *fullname;
                    701: {
                    702:        static time_t ptime = 0;
                    703:        time_t time();
                    704:        struct stat stbuf;
                    705: 
                    706:        if (!ptime)
                    707:                (void) time(&ptime);
                    708:        if (stat(fullname, &stbuf) != -1) {
                    709:                return ((int)((ptime - stbuf.st_mtime)/_sec_per_day));
                    710:        }
                    711:        else
                    712:                return(0);
                    713: }
                    714: 
                    715: /*
                    716:  * dType - return the type of D. file
                    717:  * return:
                    718:  *     FAIL - can't read D. file
                    719:  *     D_MAIL - mail message D. file
                    720:  *     D_NEWS - netnews D. file
                    721:  *     D_DATA - other kind of D. file
                    722:  *     D_XFILE - destined for X. on destination machine
                    723:  */
                    724: 
                    725: /* NLINES - number of lines of D. file to read to determine type */
                    726: #define NLINES 10
                    727: 
                    728: int
                    729: dType(fullname)
                    730: char *fullname;
                    731: {
                    732:        char buf[BUFSIZ];
                    733:        FILE *fp;
                    734:        int i, type;
                    735: 
                    736:        fp = fopen(fullname, "r");
                    737:        if (fp == NULL) {
                    738:                DEBUG(4, "Can't open file (%s), ", fullname);
                    739:                DEBUG(4, "errno=%d -- skip it!\n", errno);
                    740:                return(FAIL);
                    741:        }
                    742:        type = D_DATA;
                    743: 
                    744:        /* read first NLINES lines to determine file type */
                    745:        for (i=0; i<NLINES; i++) {
                    746:            DEBUG(9, "buf: %s\n", buf);
                    747:            if (fgets(buf, BUFSIZ, fp) == NULL)
                    748:                break;  /* no more lines */
                    749:            if (EQUALSN(buf, "From ", 5)) {
                    750:                type = D_MAIL;
                    751:                break;
                    752:            }
                    753:            if (EQUALSN(buf, "U ", 2)) {
                    754:                type = D_XFILE;
                    755:                break;
                    756:            }
                    757:            if (EQUALSN(buf, "Newsgroups: ", 12)) {
                    758:                type = D_NEWS;
                    759:                break;
                    760:            }
                    761:        }
                    762: 
                    763:        (void) fclose(fp);
                    764:        return(type);
                    765: }
                    766: 
                    767: /*
                    768:  * sendMail - send mail file and message to user (local or remote)
                    769:  * return:
                    770:  *     the return from the pclose - mail exit status
                    771:  */
                    772: static char *salute[] = {
                    773:        "Frankly,",
                    774:        "Honestly,",
                    775:        "Candidly,",
                    776:        "Guilelessly,",
                    777:        "Purely,",
                    778:        "Scrupulously,",
                    779:        "Ingenuously,",
                    780:        "Innocently,",
                    781:        "Childishly,",
                    782:        "Artlessly,",
                    783:        "Bluntly,",
                    784:        "Naively,",
                    785:        "Sympathetically,",
                    786:        "Sufferingly,",
                    787:        "Enduringly,",
                    788:        "Pathetically,",
                    789:        "Gustily,",
                    790:        "Heartily,",
                    791:        "Warmly,",
                    792:        "Passionately,",
                    793:        "Profoundly,",
                    794:        "Wistfully,",
                    795:        "Rabidly,",
                    796:        "Hysterically,",
                    797:        "Impetously,",
                    798:        "Feverishly,",
                    799: };
                    800: 
                    801: sendMail(system, user, file, mtext)
                    802: char *system, *user, *file;
                    803: char *mtext[];
                    804: {
                    805:        register FILE *fp, *fi;
                    806:        char cmd[BUFSIZ];
                    807:        static int rstart = 0;
                    808:        long time();
                    809: 
                    810:        DEBUG(5, "Mail %s to ", file);
                    811:        DEBUG(5, "%s\n", user);
                    812: 
                    813:        if (system != NULL && *system != '\0')
                    814:                (void) sprintf(cmd, "%s mail %s!%s", PATH, system, user);
                    815:        else
                    816:                (void) sprintf(cmd, "%s mail %s", PATH, user);
                    817:        DEBUG(7, "sendMail: %s\n", cmd);
                    818:        if ((fp = popen(cmd, "w")) == NULL)
                    819:                return(-errno);
                    820:        while (*mtext[0] )
                    821:            (void) fprintf(fp, *mtext++, Rmtname);
                    822: 
                    823:        if (rstart == 0) {
                    824:                srand((int)time((long *)0));
                    825:                rstart = 1;
                    826:        }
                    827:        (void) fprintf(fp, "\n\t%s\n\t%s!uucp\n",
                    828:                salute[rand()%sizeof(salute)/sizeof(salute[0])], Myname);
                    829:        if (*file) {
                    830:            if ((fi= fopen(file, "r")) == NULL) /* never happen;I read once */
                    831:                 return(pclose(fp));
                    832:            (void) fprintf(fp,
                    833:                "##### Data File: ############################\n");
                    834:            xfappend(fi, fp);
                    835:            (void) fclose(fi);
                    836:        }
                    837:        return(pclose(fp));
                    838: }
                    839: 
                    840: /*
                    841:  * execRnews - execute rnews command with stdin file
                    842:  * return:
                    843:  *     the return from the pclose - rnews exit status
                    844:  */
                    845: 
                    846: execRnews(file)
                    847: char *file;
                    848: {
                    849:        register FILE *fp, *fi;
                    850:        char cmd[BUFSIZ];
                    851: 
                    852:        DEBUG(5, "Rnews %s\n", file);
                    853: 
                    854:        (void) sprintf(cmd, "%s rnews ", PATH);
                    855:        if ((fp = popen(cmd, "w")) == NULL)
                    856:                return(-errno);
                    857: 
                    858:        if ( (fi = fopen(file, "r")) == NULL) /* never happen - I read once */
                    859:                return(pclose(fp));
                    860:        xfappend(fi, fp);
                    861:        (void) fclose(fi);
                    862: 
                    863:        return(pclose(fp));
                    864: }
                    865: 
                    866: /*
                    867:  * toWho - figure out who to send this dead mail to
                    868:  *     It is a guess;
                    869:  *     If there is a local address, send it there.
                    870:  *     If not, send it back where it came from.
                    871:  * return:
                    872:  *     0 - could not find system and user information
                    873:  *     1 - found it
                    874:  */
                    875: 
                    876: int
                    877: toWho(file, user, system)
                    878: char *file;    /* the D. mail message file */
                    879: char **system; /* pointer to the system name */
                    880: char **user;   /* pointer to the user name */
                    881: {
                    882:        char buf[BUFSIZ];
                    883:        FILE *fp;
                    884:        int i;
                    885:        static char fuser[BUFSIZ], fsystem[MAXBASENAME+1];  /* from first From */
                    886:        static char luser[BUFSIZ], lsystem[MAXBASENAME+1];  /* from other From */
                    887: 
                    888:        *fuser = NULLCHAR;
                    889:        DEBUG(5, "toWho(%s)\n", file);
                    890:        fp = fopen(file, "r");
                    891:        for (i=0; i<NLINES; i++) {
                    892:            if (fgets(buf, BUFSIZ, fp) == NULL)
                    893:                break;  /* no more lines */
                    894:            DEBUG(9, "buf: %s\n", buf);
                    895:            if (!analFrom(buf, luser, lsystem))
                    896:                continue;
                    897:            if ( !*fuser) {
                    898:                (void) strcpy(fuser, luser);
                    899:                (void) strcpy(fsystem, lsystem);
                    900:            }
                    901:            if (EQUALS(Myname, lsystem)) {
                    902:                *user = luser;
                    903:                *system = lsystem;
                    904:                (void) fclose(fp);
                    905:                return(1);
                    906:            }
                    907:        }
                    908: 
                    909:        /* could not find local user - use first line */
                    910:        (void) fclose(fp);
                    911:        if (!*fuser)    /* didn't find all information */
                    912:            return(0);
                    913:        *user = fuser;
                    914:        *system = fsystem;
                    915:        return(1);
                    916: }
                    917: 
                    918: /* analFrom - analyze From line
                    919:  * return:
                    920:  *     0 - didn't find both from and remote from info
                    921:  *     1 - found info.
                    922:  */
                    923: 
                    924: int
                    925: analFrom(line, user, system)
                    926: char *line, *user, *system;
                    927: {
                    928:        char *s;
                    929:        int i;
                    930: 
                    931:        if (!PREFIX("From ", line) && !PREFIX(">From ", line))
                    932:            return(0);
                    933:        
                    934:        s = strchr(line, ' ') + 1;
                    935:        for (i = 0;  *s && *s != ' ' && *s != '\n'; i++)
                    936:            user[i] = *s++;
                    937:        user[i] = NULLCHAR;
                    938: 
                    939:        /* look for "remote from" */
                    940:        while (*s && ((s = strchr(s, ' ')) != NULL)) {
                    941:            s++;
                    942:            if (PREFIX("remote from ", s)) {    /* found it */
                    943:                s = s + strlen("remote from ");
                    944:                for (i = 0; (i<MAXBASENAME) && *s && *s != ' ' && *s != '\n'; i++)
                    945:                    system[i] = *s++;
                    946:                system[i] = NULLCHAR;
                    947:                return(1);
                    948:            }
                    949:        }
                    950:        return(0);
                    951: }
                    952: 
                    953: 
                    954: 
                    955: static FILE    *_Lf = NULL;
                    956: 
                    957: /*
                    958:  * Make log entry
                    959:  *     text    -> ptr to text string
                    960:  *     status  errno number
                    961:  * Returns:
                    962:  *     none
                    963:  */
                    964: 
                    965: void
                    966: logit(text, status)
                    967: register char  *text;
                    968: int status;
                    969: {
                    970: 
                    971:        if (Nstat.t_pid == 0)
                    972:                Nstat.t_pid = getpid();
                    973: 
                    974:        if (_Lf == NULL) {
                    975:                _Lf = fopen(Logfile, "a");
                    976:                if (_Lf == NULL)
                    977:                        return;
                    978:                setbuf(_Lf, CNULL);
                    979:        }
                    980:        (void) fseek(_Lf, 0L, 2);
                    981:        (void) fprintf(_Lf, "%s ", Rmtname);
                    982:        (void) fprintf(_Lf, "(%s,%d,%d) ", timeStamp(), Nstat.t_pid, Seqn);
                    983:        (void) fprintf(_Lf, "%s (%d)\n", text, status);
                    984:        return;
                    985: }
                    986: 
                    987: 

unix.superglobalmegacorp.com

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