|
|
1.1 ! root 1: ! 2: ! 3: ! 4: ! 5: ! 6: ! 7: ! 8: ! 9: ! 10: ! 11: ! 12: ! 13: ! 14: ! 15: ! 16: ! 17: ! 18: ! 19: ! 20: ! 21: ! 22: ! 23: ! 24: ! 25: ! 26: ! 27: ! 28: ! 29: ! 30: ! 31: ! 32: ! 33: ! 34: ! 35: ! 36: ! 37: ! 38: ! 39: ! 40: ! 41: ! 42: ! 43: ! 44: ! 45: ! 46: ! 47: ! 48: ! 49: ! 50: typedef unsigned char u_char; ! 51: typedef unsigned short u_short; ! 52: typedef unsigned int u_int; ! 53: typedef unsigned long u_long; ! 54: typedef unsigned short ushort; ! 55: ! 56: ! 57: ! 58: typedef struct _physadr { int r[1]; } * physadr; ! 59: ! 60: ! 61: ! 62: ! 63: typedef struct label_t { ! 64: int val[12]; ! 65: } label_t; ! 66: ! 67: typedef struct _quad { long val[2]; } quad; ! 68: typedef long daddr_t; ! 69: typedef char * caddr_t; ! 70: typedef u_long ino_t; ! 71: typedef long swblk_t; ! 72: typedef long size_t; ! 73: typedef long time_t; ! 74: typedef short dev_t; ! 75: typedef long off_t; ! 76: typedef u_short uid_t; ! 77: typedef u_short gid_t; ! 78: ! 79: ! 80: ! 81: ! 82: ! 83: ! 84: ! 85: ! 86: ! 87: ! 88: ! 89: ! 90: typedef long fd_mask; ! 91: ! 92: ! 93: ! 94: ! 95: ! 96: typedef struct fd_set { ! 97: fd_mask fds_bits[ (((256)+(( (sizeof( fd_mask) * 8 ) )-1))/( (sizeof( fd_mask) * 8 ) ))]; ! 98: } fd_set; ! 99: ! 100: ! 101: ! 102: ! 103: ! 104: ! 105: ! 106: ! 107: ! 108: ! 109: ! 110: ! 111: ! 112: ! 113: ! 114: ! 115: ! 116: ! 117: ! 118: ! 119: ! 120: ! 121: ! 122: ! 123: ! 124: ! 125: ! 126: ! 127: ! 128: ! 129: ! 130: ! 131: ! 132: ! 133: ! 134: ! 135: ! 136: ! 137: ! 138: ! 139: ! 140: ! 141: ! 142: ! 143: extern struct _iobuf { ! 144: int _cnt; ! 145: ! 146: unsigned char *_ptr; ! 147: unsigned char *_base; ! 148: ! 149: int _bufsiz; ! 150: short _flag; ! 151: char _file; ! 152: ! 153: char *_name; ! 154: ! 155: } _iob[]; ! 156: ! 157: ! 158: ! 159: ! 160: ! 161: ! 162: ! 163: ! 164: ! 165: ! 166: ! 167: ! 168: ! 169: ! 170: ! 171: ! 172: ! 173: ! 174: ! 175: ! 176: ! 177: ! 178: ! 179: ! 180: ! 181: ! 182: ! 183: ! 184: ! 185: ! 186: ! 187: ! 188: ! 189: ! 190: ! 191: ! 192: ! 193: ! 194: struct _iobuf * fopen(); ! 195: struct _iobuf * fdopen(); ! 196: struct _iobuf * freopen(); ! 197: long ftell(); ! 198: char * fgets(); ! 199: ! 200: struct _iobuf * popen(); ! 201: char * gets(); ! 202: ! 203: ! 204: ! 205: ! 206: ! 207: ! 208: ! 209: ! 210: ! 211: ! 212: ! 213: ! 214: ! 215: ! 216: ! 217: ! 218: ! 219: ! 220: ! 221: ! 222: ! 223: ! 224: ! 225: ! 226: ! 227: ! 228: ! 229: ! 230: ! 231: ! 232: ! 233: ! 234: ! 235: ! 236: ! 237: ! 238: ! 239: ! 240: ! 241: ! 242: ! 243: ! 244: ! 245: ! 246: ! 247: ! 248: ! 249: ! 250: ! 251: ! 252: ! 253: ! 254: ! 255: ! 256: ! 257: ! 258: ! 259: extern char _ctype_[]; ! 260: ! 261: ! 262: ! 263: ! 264: ! 265: ! 266: ! 267: ! 268: ! 269: ! 270: ! 271: ! 272: ! 273: ! 274: ! 275: ! 276: ! 277: ! 278: ! 279: ! 280: ! 281: ! 282: ! 283: ! 284: ! 285: ! 286: ! 287: ! 288: ! 289: ! 290: ! 291: ! 292: ! 293: ! 294: ! 295: ! 296: ! 297: ! 298: ! 299: ! 300: ! 301: ! 302: ! 303: ! 304: ! 305: ! 306: ! 307: ! 308: ! 309: ! 310: ! 311: ! 312: ! 313: ! 314: ! 315: ! 316: ! 317: ! 318: ! 319: ! 320: ! 321: ! 322: ! 323: ! 324: ! 325: ! 326: ! 327: ! 328: ! 329: ! 330: ! 331: ! 332: ! 333: ! 334: ! 335: ! 336: ! 337: ! 338: ! 339: ! 340: ! 341: ! 342: ! 343: ! 344: ! 345: ! 346: ! 347: ! 348: ! 349: ! 350: ! 351: ! 352: ! 353: ! 354: ! 355: ! 356: ! 357: ! 358: ! 359: ! 360: ! 361: ! 362: ! 363: ! 364: ! 365: ! 366: ! 367: ! 368: ! 369: ! 370: ! 371: ! 372: ! 373: ! 374: ! 375: ! 376: ! 377: ! 378: ! 379: ! 380: ! 381: ! 382: ! 383: ! 384: ! 385: ! 386: ! 387: ! 388: ! 389: ! 390: ! 391: ! 392: ! 393: int (* signal())(); ! 394: ! 395: ! 396: ! 397: ! 398: ! 399: struct sigvec { ! 400: int (*sv_handler)(); ! 401: int sv_mask; ! 402: int sv_flags; ! 403: }; ! 404: ! 405: ! 406: ! 407: ! 408: ! 409: ! 410: ! 411: struct sigstack { ! 412: char *ss_sp; ! 413: int ss_onstack; ! 414: }; ! 415: ! 416: ! 417: ! 418: ! 419: ! 420: ! 421: ! 422: ! 423: ! 424: ! 425: ! 426: struct sigcontext { ! 427: ! 428: ! 429: ! 430: ! 431: int sc_onstack; ! 432: int sc_mask; ! 433: int sc_pc; ! 434: ! 435: ! 436: ! 437: int sc_regs[32]; ! 438: int sc_mdlo; ! 439: int sc_mdhi; ! 440: ! 441: ! 442: ! 443: int sc_ownedfp; ! 444: int sc_fpregs[32]; ! 445: int sc_fpc_csr; ! 446: int sc_fpc_eir; ! 447: ! 448: ! 449: ! 450: ! 451: ! 452: ! 453: ! 454: int sc_cause; ! 455: int sc_badvaddr; ! 456: int sc_badpaddr; ! 457: }; ! 458: ! 459: ! 460: ! 461: ! 462: ! 463: ! 464: ! 465: ! 466: ! 467: ! 468: ! 469: ! 470: ! 471: ! 472: ! 473: ! 474: ! 475: ! 476: ! 477: ! 478: ! 479: ! 480: ! 481: ! 482: ! 483: ! 484: ! 485: ! 486: ! 487: ! 488: ! 489: ! 490: ! 491: ! 492: ! 493: ! 494: ! 495: ! 496: ! 497: ! 498: ! 499: ! 500: ! 501: ! 502: ! 503: ! 504: ! 505: ! 506: ! 507: ! 508: ! 509: ! 510: ! 511: ! 512: ! 513: ! 514: ! 515: ! 516: ! 517: ! 518: ! 519: ! 520: ! 521: ! 522: ! 523: ! 524: ! 525: ! 526: ! 527: ! 528: ! 529: ! 530: ! 531: ! 532: ! 533: ! 534: ! 535: ! 536: ! 537: ! 538: ! 539: ! 540: ! 541: ! 542: ! 543: ! 544: ! 545: ! 546: ! 547: ! 548: ! 549: ! 550: ! 551: ! 552: ! 553: ! 554: ! 555: ! 556: struct stat ! 557: { ! 558: dev_t st_dev; ! 559: ino_t st_ino; ! 560: unsigned short st_mode; ! 561: short st_nlink; ! 562: uid_t st_uid; ! 563: gid_t st_gid; ! 564: dev_t st_rdev; ! 565: off_t st_size; ! 566: time_t st_atime; ! 567: int st_spare1; ! 568: time_t st_mtime; ! 569: int st_spare2; ! 570: time_t st_ctime; ! 571: int st_spare3; ! 572: long st_blksize; ! 573: long st_blocks; ! 574: long st_spare4[2]; ! 575: }; ! 576: ! 577: ! 578: ! 579: ! 580: ! 581: ! 582: ! 583: ! 584: ! 585: ! 586: ! 587: ! 588: ! 589: ! 590: ! 591: ! 592: ! 593: ! 594: ! 595: ! 596: ! 597: ! 598: ! 599: ! 600: ! 601: ! 602: ! 603: ! 604: ! 605: ! 606: ! 607: ! 608: ! 609: ! 610: ! 611: ! 612: ! 613: ! 614: ! 615: ! 616: ! 617: ! 618: ! 619: ! 620: ! 621: ! 622: ! 623: ! 624: ! 625: ! 626: ! 627: ! 628: ! 629: ! 630: ! 631: ! 632: ! 633: ! 634: ! 635: ! 636: ! 637: ! 638: ! 639: ! 640: ! 641: ! 642: ! 643: ! 644: ! 645: ! 646: ! 647: ! 648: ! 649: ! 650: ! 651: ! 652: ! 653: ! 654: ! 655: ! 656: ! 657: ! 658: ! 659: ! 660: ! 661: ! 662: ! 663: ! 664: ! 665: ! 666: ! 667: ! 668: ! 669: ! 670: ! 671: ! 672: ! 673: ! 674: ! 675: ! 676: ! 677: ! 678: ! 679: ! 680: ! 681: ! 682: ! 683: ! 684: ! 685: ! 686: ! 687: ! 688: ! 689: ! 690: ! 691: ! 692: ! 693: ! 694: ! 695: ! 696: ! 697: ! 698: ! 699: ! 700: ! 701: ! 702: ! 703: ! 704: ! 705: ! 706: ! 707: ! 708: ! 709: ! 710: ! 711: ! 712: ! 713: ! 714: ! 715: ! 716: ! 717: ! 718: ! 719: ! 720: ! 721: ! 722: ! 723: ! 724: ! 725: ! 726: ! 727: ! 728: ! 729: ! 730: ! 731: ! 732: ! 733: ! 734: ! 735: ! 736: ! 737: ! 738: ! 739: ! 740: ! 741: ! 742: extern char *strcat(); ! 743: extern char *strncat(); ! 744: extern char *strcpy(); ! 745: extern char *strncpy(); ! 746: extern int strlen(); ! 747: extern int strcmp(); ! 748: extern int strncmp(); ! 749: extern char *strchr(); ! 750: extern char *strrchr(); ! 751: ! 752: ! 753: typedef struct string { ! 754: char *base; ! 755: char *end; ! 756: char *ptr; ! 757: } string; ! 758: ! 759: ! 760: ! 761: ! 762: ! 763: ! 764: ! 765: ! 766: ! 767: ! 768: extern string *s_new(); ! 769: extern void s_free(); ! 770: extern string *s_append(); ! 771: extern string *s_nappend(); ! 772: extern string *s_array(); ! 773: extern string *s_copy(); ! 774: extern string *s_seq_read(); ! 775: extern char *s_read_line(); ! 776: extern int s_read_to_eof(); ! 777: extern string *s_parse(); ! 778: ! 779: ! 780: ! 781: ! 782: ! 783: ! 784: ! 785: ! 786: ! 787: ! 788: ! 789: ! 790: ! 791: ! 792: ! 793: typedef struct namelist namelist; ! 794: struct namelist { ! 795: namelist *next; ! 796: char *name; ! 797: }; ! 798: ! 799: ! 800: ! 801: ! 802: ! 803: ! 804: ! 805: ! 806: ! 807: ! 808: ! 809: ! 810: ! 811: ! 812: ! 813: ! 814: ! 815: ! 816: ! 817: ! 818: ! 819: ! 820: ! 821: ! 822: ! 823: ! 824: ! 825: ! 826: ! 827: ! 828: ! 829: ! 830: ! 831: ! 832: ! 833: ! 834: ! 835: ! 836: ! 837: ! 838: ! 839: ! 840: ! 841: ! 842: ! 843: ! 844: ! 845: ! 846: ! 847: ! 848: ! 849: ! 850: ! 851: ! 852: ! 853: ! 854: ! 855: ! 856: ! 857: ! 858: ! 859: ! 860: ! 861: ! 862: ! 863: ! 864: ! 865: ! 866: ! 867: ! 868: ! 869: ! 870: ! 871: ! 872: ! 873: ! 874: ! 875: ! 876: ! 877: ! 878: ! 879: ! 880: ! 881: ! 882: ! 883: ! 884: ! 885: ! 886: ! 887: ! 888: ! 889: ! 890: ! 891: ! 892: ! 893: ! 894: ! 895: ! 896: ! 897: ! 898: ! 899: ! 900: ! 901: ! 902: ! 903: ! 904: ! 905: ! 906: ! 907: ! 908: ! 909: ! 910: ! 911: ! 912: ! 913: ! 914: ! 915: ! 916: ! 917: ! 918: ! 919: ! 920: ! 921: ! 922: ! 923: ! 924: ! 925: ! 926: ! 927: ! 928: ! 929: ! 930: ! 931: ! 932: ! 933: ! 934: ! 935: ! 936: ! 937: ! 938: ! 939: ! 940: ! 941: ! 942: ! 943: ! 944: ! 945: ! 946: ! 947: ! 948: ! 949: ! 950: ! 951: ! 952: ! 953: ! 954: ! 955: ! 956: ! 957: ! 958: ! 959: ! 960: ! 961: ! 962: ! 963: ! 964: ! 965: ! 966: ! 967: ! 968: ! 969: ! 970: ! 971: ! 972: ! 973: ! 974: ! 975: ! 976: ! 977: ! 978: ! 979: ! 980: ! 981: ! 982: ! 983: ! 984: ! 985: ! 986: ! 987: ! 988: ! 989: ! 990: ! 991: ! 992: ! 993: ! 994: ! 995: ! 996: ! 997: ! 998: ! 999: ! 1000: ! 1001: ! 1002: ! 1003: ! 1004: ! 1005: ! 1006: ! 1007: ! 1008: ! 1009: ! 1010: ! 1011: ! 1012: ! 1013: ! 1014: ! 1015: ! 1016: ! 1017: ! 1018: ! 1019: ! 1020: ! 1021: ! 1022: ! 1023: ! 1024: ! 1025: ! 1026: ! 1027: ! 1028: ! 1029: ! 1030: ! 1031: ! 1032: ! 1033: ! 1034: ! 1035: ! 1036: ! 1037: ! 1038: ! 1039: ! 1040: ! 1041: ! 1042: ! 1043: ! 1044: ! 1045: ! 1046: ! 1047: ! 1048: ! 1049: ! 1050: ! 1051: ! 1052: ! 1053: ! 1054: ! 1055: ! 1056: ! 1057: ! 1058: ! 1059: ! 1060: ! 1061: ! 1062: ! 1063: ! 1064: ! 1065: ! 1066: ! 1067: ! 1068: ! 1069: ! 1070: ! 1071: ! 1072: ! 1073: ! 1074: ! 1075: ! 1076: ! 1077: ! 1078: ! 1079: ! 1080: ! 1081: ! 1082: ! 1083: ! 1084: ! 1085: ! 1086: ! 1087: ! 1088: ! 1089: ! 1090: ! 1091: ! 1092: ! 1093: ! 1094: ! 1095: ! 1096: ! 1097: ! 1098: ! 1099: ! 1100: ! 1101: ! 1102: ! 1103: ! 1104: ! 1105: ! 1106: ! 1107: ! 1108: ! 1109: ! 1110: ! 1111: ! 1112: ! 1113: ! 1114: ! 1115: ! 1116: ! 1117: ! 1118: ! 1119: ! 1120: ! 1121: ! 1122: ! 1123: ! 1124: ! 1125: ! 1126: ! 1127: ! 1128: ! 1129: ! 1130: ! 1131: ! 1132: ! 1133: ! 1134: ! 1135: ! 1136: ! 1137: ! 1138: ! 1139: ! 1140: ! 1141: ! 1142: ! 1143: ! 1144: ! 1145: ! 1146: ! 1147: ! 1148: ! 1149: ! 1150: ! 1151: ! 1152: ! 1153: ! 1154: ! 1155: ! 1156: ! 1157: ! 1158: ! 1159: ! 1160: ! 1161: ! 1162: ! 1163: ! 1164: ! 1165: ! 1166: ! 1167: ! 1168: ! 1169: ! 1170: ! 1171: ! 1172: ! 1173: ! 1174: ! 1175: ! 1176: ! 1177: ! 1178: ! 1179: ! 1180: ! 1181: ! 1182: ! 1183: ! 1184: ! 1185: ! 1186: ! 1187: ! 1188: ! 1189: ! 1190: ! 1191: ! 1192: ! 1193: ! 1194: ! 1195: ! 1196: ! 1197: ! 1198: ! 1199: ! 1200: ! 1201: ! 1202: ! 1203: ! 1204: ! 1205: ! 1206: ! 1207: ! 1208: ! 1209: ! 1210: ! 1211: ! 1212: ! 1213: ! 1214: ! 1215: ! 1216: ! 1217: ! 1218: ! 1219: ! 1220: ! 1221: ! 1222: ! 1223: ! 1224: ! 1225: ! 1226: ! 1227: ! 1228: ! 1229: ! 1230: ! 1231: ! 1232: ! 1233: ! 1234: ! 1235: ! 1236: ! 1237: ! 1238: ! 1239: ! 1240: ! 1241: ! 1242: ! 1243: ! 1244: ! 1245: ! 1246: ! 1247: ! 1248: ! 1249: ! 1250: ! 1251: ! 1252: ! 1253: ! 1254: ! 1255: ! 1256: ! 1257: ! 1258: ! 1259: ! 1260: ! 1261: ! 1262: ! 1263: ! 1264: ! 1265: ! 1266: ! 1267: ! 1268: ! 1269: ! 1270: ! 1271: ! 1272: ! 1273: ! 1274: ! 1275: ! 1276: ! 1277: ! 1278: ! 1279: ! 1280: ! 1281: ! 1282: ! 1283: ! 1284: ! 1285: ! 1286: ! 1287: ! 1288: ! 1289: ! 1290: ! 1291: ! 1292: ! 1293: ! 1294: ! 1295: ! 1296: ! 1297: ! 1298: ! 1299: ! 1300: ! 1301: ! 1302: ! 1303: ! 1304: ! 1305: ! 1306: ! 1307: ! 1308: ! 1309: ! 1310: ! 1311: ! 1312: struct direct { ! 1313: u_long d_fileno; ! 1314: u_short d_reclen; ! 1315: u_short d_namlen; ! 1316: char d_name[255 + 1]; ! 1317: }; ! 1318: ! 1319: ! 1320: ! 1321: ! 1322: ! 1323: ! 1324: ! 1325: ! 1326: ! 1327: ! 1328: ! 1329: ! 1330: ! 1331: ! 1332: ! 1333: ! 1334: ! 1335: typedef struct _dirdesc { ! 1336: int dd_fd; ! 1337: long dd_loc; ! 1338: long dd_size; ! 1339: long dd_bbase; ! 1340: long dd_entno; ! 1341: long dd_bsize; ! 1342: char *dd_buf; ! 1343: } DIR; ! 1344: ! 1345: ! 1346: extern DIR * opendir(); ! 1347: extern struct direct * readdir(); ! 1348: extern long telldir(); ! 1349: extern void seekdir(); ! 1350: ! 1351: extern void closedir(); ! 1352: ! 1353: ! 1354: ! 1355: ! 1356: ! 1357: ! 1358: ! 1359: ! 1360: ! 1361: ! 1362: ! 1363: ! 1364: ! 1365: ! 1366: ! 1367: ! 1368: ! 1369: ! 1370: ! 1371: ! 1372: ! 1373: ! 1374: ! 1375: ! 1376: ! 1377: ! 1378: ! 1379: ! 1380: ! 1381: typedef int (*SIG_TYP)(); ! 1382: ! 1383: ! 1384: ! 1385: ! 1386: ! 1387: ! 1388: ! 1389: ! 1390: ! 1391: ! 1392: ! 1393: ! 1394: ! 1395: ! 1396: ! 1397: extern char *UPASROOT; ! 1398: int warn = -1; ! 1399: int remove = -1; ! 1400: int cleanup; ! 1401: int verbose; ! 1402: int testmode; ! 1403: int Xonly; ! 1404: int Conly; ! 1405: string *replyaddr; ! 1406: string *dest; ! 1407: int mypid; ! 1408: char **getcmd(); ! 1409: ! 1410: ! 1411: ! 1412: struct { ! 1413: string *dest; ! 1414: time_t time; ! 1415: } destlist[50 ]; ! 1416: int ndest = 0; ! 1417: ! 1418: int debug; ! 1419: ! 1420: ! 1421: ! 1422: ! 1423: ! 1424: ! 1425: ! 1426: ! 1427: ! 1428: ! 1429: ! 1430: ! 1431: ! 1432: ! 1433: ! 1434: ! 1435: ! 1436: ! 1437: ! 1438: ! 1439: ! 1440: usage() ! 1441: { ! 1442: fprintf((& _iob[2]), "smtpsched [-cvt] [-w #days] [-r #days] [-s #scheds] [dir]\n"); ! 1443: exit(1); ! 1444: } ! 1445: ! 1446: main(ac, av) ! 1447: int ac; ! 1448: char *av[]; ! 1449: { ! 1450: direct *dirp; ! 1451: direct d; ! 1452: direct *dp; ! 1453: int max=0; ! 1454: int c; ! 1455: extern int optind; ! 1456: extern char *optarg; ! 1457: ! 1458: mypid = getpid(); ! 1459: ! 1460: ! 1461: ! 1462: ! 1463: signal(13 , (int (*)())1); ! 1464: signal(1 , (int (*)())1); ! 1465: ! 1466: while ((c = getopt(ac, av, "XCcvtr:w:s:d")) != (-1)) ! 1467: switch (c) { ! 1468: case 'X': ! 1469: Xonly = 1; ! 1470: break; ! 1471: case 'C': ! 1472: Conly = 1; ! 1473: break; ! 1474: case 't': ! 1475: testmode = 1; ! 1476: break; ! 1477: case 'v': ! 1478: verbose = 1; ! 1479: break; ! 1480: case 'c': ! 1481: cleanup = 1; ! 1482: break; ! 1483: case 'r': ! 1484: remove = atoi(optarg); ! 1485: break; ! 1486: case 's': ! 1487: max = atoi(optarg); ! 1488: break; ! 1489: case 'w': ! 1490: warn = atoi(optarg); ! 1491: break; ! 1492: case 'd': ! 1493: debug = 1; ! 1494: break; ! 1495: default: ! 1496: usage(); ! 1497: } ! 1498: openlog(); ! 1499: ! 1500: ! 1501: ! 1502: ! 1503: if(chdir("/usr/spool/smtpq")<0){ ! 1504: log("can't chdir to %s\n", "/usr/spool/smtpq"); ! 1505: exit(1); ! 1506: } ! 1507: ! 1508: ! 1509: ! 1510: ! 1511: if(max && toomany(max)<0) ! 1512: exit(0); ! 1513: ! 1514: ! 1515: ! 1516: ! 1517: ! 1518: if(optind!=ac){ ! 1519: for(; optind<ac; optind++) ! 1520: while(dodir(av[optind], 1 ) && !warn && !remove) ! 1521: ; ! 1522: return 0; ! 1523: } ! 1524: ! 1525: ! 1526: ! 1527: ! 1528: ! 1529: ! 1530: ! 1531: dirp = opendir("."); ! 1532: if(dirp<0){ ! 1533: log("couldn't read %s\n", "/usr/spool/smtpq"); ! 1534: exit(1); ! 1535: } ! 1536: while(dp = readdir(dirp)){ ! 1537: d = *dp; ! 1538: if(strcmp(d.d_name, ".")!=0 && strcmp(d.d_name, "..")!=0) ! 1539: dodir(d.d_name, (warn>=0 || remove>=0) ? 2 : 1 ); ! 1540: } ! 1541: closedir(dirp); ! 1542: return 0; ! 1543: } ! 1544: ! 1545: ! 1546: ! 1547: ! 1548: dodir(dname, action) ! 1549: char *dname; ! 1550: { ! 1551: int i; ! 1552: ! 1553: i = dodirdir(dname, action, "X."); ! 1554: i += dodirdir(dname, action, "C."); ! 1555: return i; ! 1556: } ! 1557: ! 1558: ! 1559: ! 1560: ! 1561: ! 1562: dodirdir(dname, action, direction) ! 1563: char *dname; ! 1564: char *direction; ! 1565: { ! 1566: DIR *dirp; ! 1567: direct *dp; ! 1568: int i; ! 1569: int changed=0; ! 1570: int ents=0; ! 1571: static string *ds; ! 1572: static string *ls; ! 1573: extern int errno; ! 1574: ! 1575: ds = (ds ? (*(ds->ptr = ds->base) = '\0' , ds) : s_new()); ! 1576: s_append(ds, dname); ! 1577: ls = (ls ? (*(ls->ptr = ls->base) = '\0' , ls) : s_new()); ! 1578: s_append(ls, direction); ! 1579: s_append(ls, dname); ! 1580: ! 1581: ! 1582: ! 1583: ! 1584: switch(action){ ! 1585: case 0 : ! 1586: for(i=0; i<3; i++){ ! 1587: if(lock( ls->base)==0) ! 1588: break; ! 1589: sleep(5); ! 1590: } ! 1591: if(i==3) ! 1592: return changed; ! 1593: break; ! 1594: case 1 : ! 1595: if(lock( ls->base)<0){ ! 1596: log("couldn't lock %s\n", dname); ! 1597: return changed; ! 1598: } ! 1599: break; ! 1600: case 2 : ! 1601: break; ! 1602: } ! 1603: ! 1604: ! 1605: ! 1606: ! 1607: ! 1608: if(chdir( ds->base)<0){ ! 1609: if(action != 2 ) ! 1610: unlock( ls->base); ! 1611: return changed; ! 1612: } ! 1613: ! 1614: ! 1615: ! 1616: ! 1617: dirp = opendir("."); ! 1618: if(dirp<0){ ! 1619: log("couldn't read directory %s\n", dname); ! 1620: if(chdir("..")<0){ ! 1621: log("can't chdir ..\n"); ! 1622: fflush((& _iob[1])); ! 1623: exit(1); ! 1624: } ! 1625: if(action != 2 ) ! 1626: unlock( ls->base); ! 1627: return changed; ! 1628: } ! 1629: while(dp = readdir(dirp)){ ! 1630: if(strcmp(dp->d_name, ".")!=0 && strcmp(dp->d_name, "..")!=0 ! 1631: && dp->d_name[0] == *direction) { ! 1632: switch(dofile(dname, dp->d_name)){ ! 1633: case 0: ! 1634: ! 1635: changed = 1; ! 1636: break; ! 1637: case 1: ! 1638: ! 1639: ents += 1; ! 1640: break; ! 1641: } ! 1642: } ! 1643: } ! 1644: closedir(dirp); ! 1645: ! 1646: ! 1647: ! 1648: ! 1649: if(chdir("..")<0){ ! 1650: log("can't chdir ..\n"); ! 1651: fflush((& _iob[1])); ! 1652: exit(1); ! 1653: } ! 1654: ! 1655: ! 1656: ! 1657: ! 1658: if(cleanup && ents==0){ ! 1659: log("%s empty\n", ds->base); ! 1660: if(rmdir( ds->base)<0) ! 1661: log("can't unlink: %d\n", errno); ! 1662: } ! 1663: ! 1664: if(action != 2 ) ! 1665: unlock( ls->base); ! 1666: return changed; ! 1667: } ! 1668: ! 1669: ! 1670: ! 1671: ! 1672: ! 1673: ! 1674: ! 1675: dofile(dname, name) ! 1676: char *dname; ! 1677: char *name; ! 1678: { ! 1679: int rv; ! 1680: int fd, ofd; ! 1681: char *ef; ! 1682: extern char *fileoftype(); ! 1683: struct stat sb; ! 1684: time_t now, Edate, Cdate; ! 1685: ! 1686: rv = -1; ! 1687: ! 1688: ! 1689: ! 1690: ! 1691: if(cleanup && inconsistent(name)){ ! 1692: log("%s/%s inconsistent\n", dname, name); ! 1693: unlink(name); ! 1694: return 0; ! 1695: } ! 1696: ! 1697: ! 1698: ! 1699: ! 1700: if(name[1]!='.' || (name[0]!='C' && name[0]!='X')) ! 1701: return 1; ! 1702: ! 1703: ! 1704: ! 1705: ! 1706: ! 1707: if(warn>=0 || remove>=0) { ! 1708: if(checkage(name)==0) { ! 1709: log("%s/%s too old\n", dname, name); ! 1710: doremove(name); ! 1711: return 0; ! 1712: } ! 1713: return 1; ! 1714: } ! 1715: ! 1716: ! 1717: ! 1718: ! 1719: if(cleanup) ! 1720: return 1; ! 1721: ! 1722: ! 1723: ! 1724: ! 1725: ef = fileoftype('E', name); ! 1726: if (name[0]=='C') { ! 1727: now = time((time_t *)0); ! 1728: Cdate = now; ! 1729: Edate = now-4*3600L -1; ! 1730: if (stat(name, &sb)==0) ! 1731: Cdate = sb.st_ctime; ! 1732: if (stat(ef, &sb)==0) ! 1733: Edate = sb.st_mtime; ! 1734: if (now-Cdate>6*3600L && now-Edate<4*3600L ! 1735: || now-Cdate>1*3600L && now-Edate<1*3600L ) { ! 1736: if (verbose) ! 1737: log("ignore %s/%s: not time yet\n", dname, name); ! 1738: if (debug==0) ! 1739: return 1; ! 1740: } ! 1741: } ! 1742: ! 1743: ! 1744: ! 1745: ! 1746: if (testmode) { ! 1747: log("would process %s/%s\n", dname, name); ! 1748: return 1; ! 1749: } ! 1750: ! 1751: ! 1752: ! 1753: ofd = dup(2); ! 1754: close(2); ! 1755: fd = open(ef, 1); ! 1756: if(fd<0) ! 1757: fd = creat(ef, 0666); ! 1758: if(fd>=0){ ! 1759: lseek(fd, 0l, 2); ! 1760: ! 1761: ! 1762: ! 1763: ! 1764: if(name[0]=='C') { ! 1765: rv = dosmtp(dname, name); ! 1766: } else if(name[0]=='X') { ! 1767: rv = dormail(dname, name); ! 1768: } ! 1769: ! 1770: ! 1771: ! 1772: ! 1773: close(2); ! 1774: (void) dup(ofd); ! 1775: close(ofd); ! 1776: } ! 1777: ! 1778: ! 1779: ! 1780: ! 1781: if(rv==0) { ! 1782: doremove(name); ! 1783: return 0; ! 1784: } ! 1785: return 1; ! 1786: } ! 1787: ! 1788: ! 1789: ! 1790: ! 1791: doremove(ctl) ! 1792: char *ctl; ! 1793: { ! 1794: fflush((& _iob[1])); ! 1795: unlink(fileoftype('E', ctl)); ! 1796: unlink(ctl); ! 1797: unlink(fileoftype('D', ctl)); ! 1798: } ! 1799: ! 1800: ! 1801: ! 1802: ! 1803: ! 1804: dormail(dname, ctl) ! 1805: char *dname; ! 1806: char *ctl; ! 1807: { ! 1808: char **av; ! 1809: ! 1810: log("dormail %s/%s\n", dname, ctl); ! 1811: ! 1812: ! 1813: ! 1814: ! 1815: av = getcmd(ctl, "/bin/rmail"); ! 1816: if(av && docmd(ctl, av)==0){ ! 1817: log("success\n"); ! 1818: return 0; ! 1819: } else { ! 1820: log("failure\n"); ! 1821: return -1; ! 1822: } ! 1823: } ! 1824: ! 1825: ! 1826: ! 1827: ! 1828: ! 1829: dosmtp(dname, ctl) ! 1830: char *dname; ! 1831: char *ctl; ! 1832: { ! 1833: static string *cmd; ! 1834: int status, i; ! 1835: char **av; ! 1836: time_t t0, t1; ! 1837: ! 1838: log("dosmtp %s/%s\n", dname, ctl); ! 1839: ! 1840: ! 1841: ! 1842: ! 1843: cmd = (cmd ? (*(cmd->ptr = cmd->base) = '\0' , cmd) : s_new()); ! 1844: s_append(cmd, UPASROOT); ! 1845: s_append(cmd, "/smtp"); ! 1846: av = getcmd(ctl, cmd->base); ! 1847: if (av==0) { ! 1848: log("cmdfail\n", 0); ! 1849: return -1; ! 1850: } ! 1851: ! 1852: ! 1853: ! 1854: ! 1855: for (i=0; i<ndest; i++) { ! 1856: if (strcmp( dest->base, destlist[i].dest->base)==0) { ! 1857: if (destlist[i].time > 5*60 ) { ! 1858: log("passed %s (%d sec)\n", dest->base, destlist[i].time); ! 1859: fprintf((& _iob[2]), "can't contact destination\n"); ! 1860: return -1; ! 1861: } ! 1862: break; ! 1863: } ! 1864: } ! 1865: if (i==ndest) { ! 1866: if (ndest<50 ) ! 1867: ndest++; ! 1868: else ! 1869: i = 0; ! 1870: destlist[i].dest = s_copy( dest->base); ! 1871: destlist[i].time = 0; ! 1872: } ! 1873: if (debug) ! 1874: log("time %d for %s\n", destlist[i].time, dest->base); ! 1875: time(&t0); ! 1876: switch(status=docmd(ctl, av)){ ! 1877: case 0: ! 1878: log("success\n"); ! 1879: destlist[i].time = 0; ! 1880: return 0; ! 1881: ! 1882: case 69 : ! 1883: case 77 : ! 1884: case 67 : ! 1885: case 68 : ! 1886: log("fail %d\n", status); ! 1887: returnmail(ctl, 1); ! 1888: destlist[i].time = 0; ! 1889: return 0; ! 1890: ! 1891: case 73 : ! 1892: case 74 : ! 1893: case 71 : ! 1894: case 72 : ! 1895: case 70 : ! 1896: case 64 : ! 1897: case 65 : ! 1898: case 66 : ! 1899: case 76 : ! 1900: case 75 : ! 1901: log("fail %d\n", status); ! 1902: time(&t1); ! 1903: destlist[i].time += t1-t0; ! 1904: return -1; ! 1905: ! 1906: default: ! 1907: log("fail %d\n", status); ! 1908: time(&t1); ! 1909: destlist[i].time += t1-t0; ! 1910: return -1; ! 1911: } ! 1912: } ! 1913: ! 1914: ! 1915: ! 1916: ! 1917: ! 1918: ! 1919: ! 1920: struct _iobuf * ! 1921: parseline1(ctl) ! 1922: char *ctl; ! 1923: { ! 1924: struct _iobuf *fp; ! 1925: static string *line; ! 1926: ! 1927: fp = fopen(ctl, "r"); ! 1928: if(fp==0) ! 1929: return 0; ! 1930: ! 1931: ! 1932: ! 1933: ! 1934: line = (line ? (*(line->ptr = line->base) = '\0' , line) : s_new()); ! 1935: if(s_read_line(fp, line)==0){ ! 1936: fprintf((& _iob[2]), "smtpsched: error reading ctl file %s\n", ctl); ! 1937: fclose(fp); ! 1938: return 0; ! 1939: } ! 1940: replyaddr = s_parse( (line->ptr = line->base , line), (replyaddr ? (*(replyaddr->ptr = replyaddr->base) = '\0' , replyaddr) : s_new())); ! 1941: dest = s_parse(line, (dest ? (*(dest->ptr = dest->base) = '\0' , dest) : s_new())); ! 1942: return fp; ! 1943: } ! 1944: ! 1945: ! 1946: ! 1947: ! 1948: ! 1949: ! 1950: ! 1951: ! 1952: char ** ! 1953: getcmd(ctl, cmd) ! 1954: char *cmd; ! 1955: { ! 1956: static string *args; ! 1957: struct _iobuf *fp; ! 1958: static char *av[1024]; ! 1959: int ac=0; ! 1960: char *cp; ! 1961: ! 1962: fp = parseline1(ctl); ! 1963: if (fp==0) ! 1964: return 0; ! 1965: ! 1966: ! 1967: ! 1968: ! 1969: av[ac++] = cmd; ! 1970: args = (args ? (*(args->ptr = args->base) = '\0' , args) : s_new()); ! 1971: if(s_read_line(fp, args)==0){ ! 1972: fprintf((& _iob[2]), "smtpsched: error reading ctl file %s\n", ctl); ! 1973: fclose(fp); ! 1974: return 0; ! 1975: } ! 1976: fclose(fp); ! 1977: for(cp = args->base; *cp && ac<1023;){ ! 1978: av[ac++] = cp++; ! 1979: while(*cp && ! (( _ctype_+1)[*cp]&010)) ! 1980: cp++; ! 1981: while( (( _ctype_+1)[*cp]&010)) ! 1982: *cp++ = 0; ! 1983: } ! 1984: av[ac] = 0; ! 1985: return av; ! 1986: } ! 1987: ! 1988: ! 1989: ! 1990: ! 1991: docmd(ctl, av) ! 1992: char *ctl; ! 1993: char **av; ! 1994: { ! 1995: int fd; ! 1996: int pid, status; ! 1997: int n; ! 1998: ! 1999: ! 2000: ! 2001: ! 2002: switch(pid = fork()){ ! 2003: case -1: ! 2004: return 1; ! 2005: case 0: ! 2006: ! 2007: ! 2008: ! 2009: close(0); ! 2010: fd = open(fileoftype('D', ctl), 0); ! 2011: if(fd<0){ ! 2012: perror("smtpsched: error reading data file:\n"); ! 2013: exit(1); ! 2014: } ! 2015: ! 2016: ! 2017: ! 2018: ! 2019: close(1); ! 2020: fd = dup(2); ! 2021: ! 2022: ! 2023: ! 2024: ! 2025: execvp(av[0], av); ! 2026: exit(1); ! 2027: default: ! 2028: ! 2029: ! 2030: ! 2031: while((n = wait(&status))>=0) ! 2032: if(n == pid) ! 2033: break; ! 2034: if(status&0xff) ! 2035: return -1; ! 2036: else ! 2037: return (status>>8)&0xff; ! 2038: } ! 2039: ! 2040: } ! 2041: ! 2042: ! 2043: ! 2044: ! 2045: ! 2046: ! 2047: ! 2048: toomany(max) ! 2049: int max; ! 2050: { ! 2051: struct _iobuf *ifp=0; ! 2052: struct _iobuf *ofp=0; ! 2053: int cur=0; ! 2054: int pid; ! 2055: ! 2056: ! 2057: ! 2058: ! 2059: if(lock(".smtpscheds")<0) ! 2060: return -1; ! 2061: ! 2062: ! 2063: ! 2064: ! 2065: ofp = fopen(".nsmtpscheds", "w"); ! 2066: if(ofp==0){ ! 2067: fprintf((& _iob[2]), "can't open %s\n", ".nsmtpscheds"); ! 2068: goto error; ! 2069: } ! 2070: ifp = fopen(".smtpscheds", "r"); ! 2071: if(ifp!=0){ ! 2072: ! 2073: ! 2074: ! 2075: while(fscanf(ifp, "%d", &pid)==1){ ! 2076: if(kill(pid, 0) == 0){ ! 2077: cur++; ! 2078: if(fprintf(ofp, "%d\n", pid)<0){ ! 2079: fprintf((& _iob[2]), "error writing %s\n", ".nsmtpscheds"); ! 2080: goto error; ! 2081: } ! 2082: } ! 2083: } ! 2084: if(cur >= max) ! 2085: goto error; ! 2086: } ! 2087: ! 2088: ! 2089: ! 2090: ! 2091: if(fprintf(ofp, "%d\n", getpid())<0){ ! 2092: fprintf((& _iob[2]), "error writing %s\n", ".nsmtpscheds"); ! 2093: goto error; ! 2094: } ! 2095: if(ifp!=0) ! 2096: fclose(ifp); ! 2097: if(fclose(ofp)==(-1)) ! 2098: goto error; ! 2099: unlink(".smtpscheds"); ! 2100: if(link(".nsmtpscheds", ".smtpscheds")<0) ! 2101: fprintf((& _iob[2]), "can't link %s to %s file\n", ".smtpscheds", ".nsmtpscheds"); ! 2102: unlink(".nsmtpscheds"); ! 2103: unlock(".smtpscheds"); ! 2104: return 0; ! 2105: error: ! 2106: ! 2107: ! 2108: ! 2109: if(ifp!=0) ! 2110: fclose(ifp); ! 2111: if(ofp!=0) ! 2112: fclose(ofp); ! 2113: unlink(".nsmtpscheds"); ! 2114: unlock(".smtpscheds"); ! 2115: return -1; ! 2116: } ! 2117: ! 2118: ! 2119: ! 2120: ! 2121: ! 2122: ! 2123: ! 2124: ! 2125: inconsistent(file) ! 2126: char *file; ! 2127: { ! 2128: struct stat s; ! 2129: int days; ! 2130: ! 2131: ! 2132: ! 2133: ! 2134: switch(file[0]){ ! 2135: case 'C': ! 2136: case 'X': ! 2137: ! 2138: ! 2139: ! 2140: if(stat(fileoftype('D', file), &s)<0) ! 2141: return 1; ! 2142: break; ! 2143: case 'E': ! 2144: ! 2145: ! 2146: ! 2147: if(stat(fileoftype('X', file), &s)<0 ! 2148: && stat(fileoftype('C', file), &s)<0) ! 2149: return 1; ! 2150: ! 2151: ! 2152: ! 2153: ! 2154: if(stat(fileoftype('D', file), &s)<0) ! 2155: return 1; ! 2156: break; ! 2157: case 'D': ! 2158: ! 2159: ! 2160: ! 2161: if(stat(fileoftype('X', file), &s)==0 ! 2162: || stat(fileoftype('C', file), &s)==0) ! 2163: break; ! 2164: ! 2165: ! 2166: ! 2167: ! 2168: if(stat(file, &s)<0) ! 2169: return 0; ! 2170: days = (time((long *)0) - s.st_ctime)/(24*60*60); ! 2171: if(days>0) ! 2172: return 1; ! 2173: break; ! 2174: default: ! 2175: break; ! 2176: } ! 2177: return 0; ! 2178: } ! 2179: ! 2180: ! 2181: ! 2182: ! 2183: ! 2184: checkage(ctl) ! 2185: char *ctl; ! 2186: { ! 2187: struct stat s; ! 2188: int days; ! 2189: char buf[256]; ! 2190: struct _iobuf *fp; ! 2191: ! 2192: ! 2193: ! 2194: ! 2195: if(stat(ctl, &s)<0) ! 2196: return -1; ! 2197: days = (time((long *)0) - s.st_ctime)/(24*60*60); ! 2198: ! 2199: ! 2200: ! 2201: ! 2202: if(remove>=0 && days>=remove){ ! 2203: fp = parseline1(ctl); ! 2204: if(fp==0) ! 2205: return -1; ! 2206: fclose(fp); ! 2207: ! 2208: log("r %d %d\n", days, remove); ! 2209: return returnmail(ctl, 1); ! 2210: } ! 2211: ! 2212: ! 2213: ! 2214: ! 2215: if(warn>=0 && days>=warn){ ! 2216: fp = parseline1(ctl); ! 2217: if(fp==0) ! 2218: return -1; ! 2219: fclose(fp); ! 2220: ! 2221: log("w %d %d\n", days, warn); ! 2222: returnmail(ctl, 0); ! 2223: } ! 2224: ! 2225: return -1; ! 2226: } ! 2227: ! 2228: ! 2229: ! 2230: ! 2231: returnmail(ctl, warn) ! 2232: char *ctl; ! 2233: { ! 2234: int pid, status; ! 2235: string *cmd; ! 2236: int pfd[2]; ! 2237: char buf[132]; ! 2238: int fd, n; ! 2239: int reads; ! 2240: struct _iobuf *fp; ! 2241: struct _iobuf *ifp; ! 2242: long now; ! 2243: char asct[27]; ! 2244: ! 2245: log("returnmail %s to %s about %s\n", ctl, replyaddr->base, ! 2246: dest->base); ! 2247: ! 2248: if(pipe(pfd)<0) ! 2249: return -1; ! 2250: ! 2251: switch(pid=fork()){ ! 2252: case -1: ! 2253: close(pfd[0]); ! 2254: close(pfd[1]); ! 2255: return -1; ! 2256: case 0: ! 2257: ! 2258: ! 2259: ! 2260: close(0); ! 2261: dup(pfd[0]); ! 2262: close(pfd[1]); ! 2263: execl("/bin/rmail", "/bin/rmail", replyaddr->base, 0); ! 2264: exit(1); ! 2265: default: ! 2266: ! 2267: ! 2268: ! 2269: close(pfd[0]); ! 2270: fp = fdopen(pfd[1], "w"); ! 2271: if(fp==0) { ! 2272: close(pfd[1]); ! 2273: break; ! 2274: } ! 2275: ! 2276: ! 2277: ! 2278: ! 2279: now = time((long *)0); ! 2280: strcpy(asct, ctime(&now)); ! 2281: asct[24] = 0; ! 2282: fprintf(fp, "From postmaster %s remote from \n", asct); ! 2283: ! 2284: ! 2285: ! 2286: ! 2287: if(warn) { ! 2288: fprintf(fp, "Subject: smtp mail failed\n\n"); ! 2289: fprintf(fp, "Your mail to %s is undeliverable.\n", ! 2290: dest->base); ! 2291: } else { ! 2292: fprintf(fp, "Subject: smtp mail warning\n\n"); ! 2293: fprintf(fp, "Your mail to %s is not yet delivered.\n", ! 2294: dest->base); ! 2295: fprintf(fp, "Delivery attempts continue.\n"); ! 2296: } ! 2297: ! 2298: ! 2299: ! 2300: ! 2301: fprintf(fp, "---------- diagnosis ----------\n"); ! 2302: ifp = fopen(fileoftype('E', ctl), "r"); ! 2303: if(ifp!=0){ ! 2304: for(reads=0; reads<20; reads++) { ! 2305: if(fgets(buf, sizeof(buf), ifp)==0) ! 2306: break; ! 2307: fputs(buf, fp); ! 2308: } ! 2309: fclose(ifp); ! 2310: } ! 2311: ! 2312: ! 2313: ! 2314: ! 2315: fprintf(fp, "---------- unsent mail ----------\n"); ! 2316: ifp = fopen(fileoftype('D', ctl), "r"); ! 2317: if(ifp!=0){ ! 2318: for(reads=0; reads<50; reads++) { ! 2319: if(fgets(buf, sizeof(buf), ifp)==0) ! 2320: break; ! 2321: fputs(buf, fp); ! 2322: } ! 2323: fclose(ifp); ! 2324: } ! 2325: fclose(fp); ! 2326: ! 2327: ! 2328: ! 2329: ! 2330: while((n = wait(&status))>=0) ! 2331: if(n == pid) ! 2332: break; ! 2333: return status ? -1 : 0; ! 2334: } ! 2335: close(pfd[1]); ! 2336: return -1; ! 2337: } ! 2338: ! 2339: openlog() ! 2340: { ! 2341: string *f; ! 2342: ! 2343: if (debug) ! 2344: return; ! 2345: f = s_new(); ! 2346: s_append(f, "/usr/spool/smtpq"); ! 2347: s_append(f, "/smtpsched.log"); ! 2348: close(0); ! 2349: if(open("/dev/null", 0)==0){ ! 2350: close(1); ! 2351: close(2); ! 2352: close(3); ! 2353: if(open( f->base, 2)==1 ! 2354: || creat( f->base, 0666)==1){ ! 2355: lseek(1, 0L, 2); ! 2356: dup(1); ! 2357: dup(1); ! 2358: } ! 2359: } ! 2360: s_free(f); ! 2361: } ! 2362: ! 2363: log(f, a, b, c) ! 2364: char *f; ! 2365: { ! 2366: char *dp; ! 2367: struct tm *bp; ! 2368: long thetime; ! 2369: extern struct tm *localtime(); ! 2370: extern char *asctime(); ! 2371: extern long time(); ! 2372: ! 2373: thetime = time((long *)0); ! 2374: bp = localtime(&thetime); ! 2375: dp = asctime(bp); ! 2376: ! 2377: lseek(1, 0L, 2); ! 2378: printf("%d %.12s: ", mypid, dp+4); ! 2379: printf(f, a, b, c); ! 2380: fflush((& _iob[1])); ! 2381: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.