|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.