home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / PPPBCKP / SRC / SRC15B92.ZIP / POP.CPP < prev    next >
Text File  |  1998-08-08  |  61KB  |  2,026 lines

  1. #include <stdio.h>
  2. #include <stdarg.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <dos.h>
  6. #include <fcntl.h>
  7. #include <sys/stat.h>
  8. #include <ctype.h>
  9. #include <mem.h>
  10. #include <conio.h>
  11. #include <io.h>
  12. #include <share.h>
  13. #include <errno.h>
  14. #include <malloc.h>
  15. #include <dir.h>
  16. extern "C" {
  17. #include "tcp.h"
  18. }
  19. #include "version.h"
  20. #include "retcode.h"
  21.  
  22. #undef MAXPATH
  23. #define MAXPATH 160
  24.  
  25. extern unsigned _stklen = 12000U;
  26.  
  27. #define POP_PORT 110
  28.  
  29. #define SMTP_PORT 25
  30.  
  31. #define SMTP_STATUS   211
  32. #define SMTP_HELP     214
  33. #define SMTP_READY    220
  34. #define SMTP_BYE      221
  35. #define SMTP_OK       250
  36. #define SMTP_WILL_FWD 251
  37.  
  38. #define SMTP_GIMME    354
  39.  
  40. #define SMTP_OOPS     421
  41. #define SMTP_BUSY     450
  42. #define SMTP_ERROR    451
  43. #define SMTP_SQUEEZED 452
  44.  
  45. #define SMTP_SYNTAX   500
  46. #define SMTP_PARAM    501
  47. #define SMTP_COM_NI   502
  48. #define SMTP_BAD_SEQ  503
  49. #define SMTP_BAD_PARM 504
  50. #define SMTP_ACCESS   550
  51. #define SMTP_YOU_FWD  551
  52. #define SMTP_FULL     552
  53. #define SMTP_BAD_NAM  553
  54. #define SMTP_FAILED   554
  55.  
  56.  
  57. #define POP_OK               200
  58. #define POP_NOT_MSG          400
  59. #define POP_BAD_HOST         500
  60. #define POP_HOST_UNAVAILABLE 501
  61. #define POP_BAD_MBOX         510
  62. #define POP_BAD_PASS         511
  63. #define POP_UNKNOWN          599
  64.  
  65.  
  66. #define POPLIB_OK        200
  67. #define POPLIB_BAD_FILE  401
  68. #define POPLIB_BAD_HOST  510
  69. #define POPLIB_S_TIMEOU  510
  70. #define POPLIB_S_CLOSED  511
  71. #define POPLIB_SMTP_ERR  520
  72. #define POPLIB_POP_ERR   521
  73. #define POPLIB_SMTP_PROB 410
  74. #define POPLIB_POP_PROB  411
  75.  
  76. typedef struct {
  77.   tcp_Socket *sock;
  78. } Mail_Socket;
  79.  
  80. typedef struct {
  81.   char msgid[81];
  82. } Message_ID;
  83.  
  84. typedef struct {
  85.   char popname[40];
  86.   char pophost[60];
  87.   char poppass[40];
  88. } ACCT;
  89.  
  90. ACCT *acct;
  91.  
  92. #define _TEMP_BUFFER_LEN 2048
  93. #define LAST(s) s[strlen(s)-1]
  94.  
  95. #define SHARE_LEVEL 10
  96. #define WAIT_TIME 10
  97. #define TRIES 100
  98.  
  99. struct ts_os_ver {
  100.   int maj;
  101.   int min;
  102. };
  103.  
  104. #define DOS     0
  105. #define OS2     1
  106. #define DV      2
  107. #define WINS    3
  108. #define WIN3    4
  109.  
  110. #define MT_DOS  0x01
  111. #define MT_OS2  0x02
  112. #define MT_DV   0x04
  113. #define MT_WINS 0x08
  114. #define MT_WIN3 0x10
  115.  
  116. struct ts_os_ver t_os_ver[5];
  117. int t_os_type;
  118. int t_os;
  119. char t_os_name[41];
  120.  
  121. #define free_Mail_Socket(SOCK) if (SOCK != NULL) {                              \
  122.   farfree(SOCK->sock); farfree(SOCK); SOCK=NULL; }
  123.  
  124. int POP_Err_Cond, SMTP_Err_Cond;
  125. char from_user[81], netdata[161], net_pkt[21], maindir[160], fdlfn[21], id[81];
  126. char LISTNAME[45], MAILFROM[60], PROXY[40], listaddr[25];
  127. char POPHOST[60], POPNAME[40], POPPASS[20], DOMAIN[60], NODEPASS[20];
  128. int WatTCP_initialized = 0, fdl;
  129. char _temp_buffer[_TEMP_BUFFER_LEN];
  130. static int POP_stat, SMTP_stat;
  131. int DEBUG = 1, ALLMAIL, compact_ids = 0;
  132.  
  133. char *version = "Freeware PPP Project POP/SMTP Client " VERSION;
  134.  
  135. char pktowner[36];
  136.  
  137. int aborted = 0, packet_vect = 0, hangup = 0;
  138.  
  139. #define SOCK_READ_ERR(PROTOCOL, ACTION)                                         \
  140.   sock_err:                                                                     \
  141.     switch (PROTOCOL##_stat) {                                                  \
  142.       case 1 :                                                                  \
  143.         PROTOCOL##_Err_Cond = PROTOCOL##_OK;                                    \
  144.         fprintf(stderr, "\n ! "#PROTOCOL"> Session error : %s",                        \
  145.             sockerr(PROTOCOL##_sock->sock));                                    \
  146.         ACTION;                                                                 \
  147.         aborted = 1;                                                            \
  148.         return 0;                                                               \
  149.       case -1:                                                                  \
  150.         PROTOCOL##_Err_Cond = PROTOCOL##_OK;                                    \
  151.         fprintf(stderr, "\n ! "#PROTOCOL"> Timeout : %s",                              \
  152.                 sockerr(PROTOCOL##_sock->sock));                                \
  153.         ACTION;                                                                 \
  154.         aborted = 1;                                                            \
  155.         return 0;                                                               \
  156.     }
  157.  
  158. #define SOCK_GETS(PROTOCOL)                                                     \
  159.   sock_wait_input(PROTOCOL##_sock->sock, sock_delay, NULL, &PROTOCOL##_stat);   \
  160.   sock_gets(PROTOCOL##_sock->sock, _temp_buffer, sizeof(_temp_buffer));         \
  161.   if (DEBUG) fprintf(stderr, "\n"#PROTOCOL"> %s\n", _temp_buffer);                  \
  162.   PROTOCOL##_Err_Cond = atoi(_temp_buffer);                                     \
  163.  
  164. #define SMTP_FAIL_ON(NUM, ACTION)                                               \
  165.   if (SMTP_Err_Cond == NUM) {                                                   \
  166.     if (DEBUG) fprintf(stderr, "\nSMTP Failure> '" #NUM "'\n");                   \
  167.     sock_puts(SMTP_sock->sock, "QUIT");                                         \
  168.     ACTION;                                                                     \
  169.     aborted = 1;                                                                \
  170.     return 0;                                                                   \
  171.   }
  172.  
  173. #define SMTP_RESET_ON(NUM, ACTION)                                              \
  174.   if (SMTP_Err_Cond == NUM) {                                                   \
  175.     if (DEBUG) fprintf(stderr, "\nSMTP Failure> '" #NUM "'\n");                   \
  176.     sock_puts(SMTP_sock->sock, "RSET");                                         \
  177.     sock_wait_input(SMTP_sock->sock, sock_delay, NULL, &SMTP_stat);             \
  178.     sock_gets(SMTP_sock->sock, _temp_buffer, sizeof(_temp_buffer));             \
  179.     ACTION;                                                                     \
  180.     aborted = 1;                                                                \
  181.     return(0);                                                                  \
  182.   }
  183.  
  184. void output(char *fmt,...)
  185. {
  186.   va_list v;
  187.   char s[255];
  188.  
  189.   va_start(v, fmt);
  190.   vsprintf(s, fmt, v);
  191.   va_end(v);
  192.   fputs(s, stderr);
  193. }
  194.  
  195. int detect_multitask(void)
  196. {
  197.   union REGS t_regs;
  198.  
  199.   t_os_type = 0;
  200.   t_os = 0;
  201.  
  202.   if (_osmajor < 10) {
  203.     t_os_ver[DOS].maj = _osmajor;
  204.     t_os_ver[DOS].min = _osminor;
  205.     t_os_type = t_os_type | MT_DOS;
  206.     strcpy(t_os_name, "DOS");
  207.   } else {
  208.     t_os_type = t_os_type | MT_OS2;
  209.     t_os_ver[OS2].maj = _osmajor / 10;
  210.     t_os_ver[OS2].min = _osminor;
  211.     if (t_os_ver[OS2].maj == 3) {
  212.       strcpy(t_os_name, "OS/2 Warp");
  213.     } else {
  214.       strcpy(t_os_name, "OS/2");
  215.     }
  216.   }
  217.  
  218.   t_regs.x.ax = 0x4680;
  219.   int86(0x2F, &t_regs, &t_regs);
  220.  
  221.   if (t_regs.x.ax == 0x0000) {
  222.     t_os_ver[WINS].maj = 3;
  223.     t_os_ver[WINS].min = 0;
  224.     t_os_type = t_os_type | MT_WINS;
  225.   } else {
  226.     t_regs.x.ax = 0x1600;
  227.     int86(0x2F, &t_regs, &t_regs);
  228.     switch (t_regs.h.al) {
  229.       case 0x00:
  230.       case 0x80:
  231.       case 0x01:
  232.       case 0xFF:
  233.         break;
  234.       default:
  235.         t_os_type = t_os_type | MT_WIN3;
  236.         t_os_ver[WIN3].maj = t_regs.h.al;
  237.         t_os_ver[WIN3].min = t_regs.h.ah;
  238.         if (t_os_ver[WIN3].maj == 4) {
  239.           strcpy(t_os_name, "Windows 95");
  240.           t_os_ver[WIN3].maj = t_os_ver[WIN3].maj - 3;
  241.         } else {
  242.           strcpy(t_os_name, "Windows");
  243.         }
  244.         break;
  245.     }
  246.   }
  247.  
  248.   t_regs.x.cx = 0x4445;
  249.   t_regs.x.dx = 0x5351;
  250.   t_regs.x.ax = 0x2B01;
  251.  
  252.   intdos(&t_regs, &t_regs);
  253.   if (t_regs.h.al != 0xFF) {
  254.     t_os_type = t_os_type | MT_DV;
  255.     t_os_ver[DV].maj = t_regs.h.bh;
  256.     t_os_ver[DV].min = t_regs.h.bl;
  257.     strcpy(t_os_name, "DESQview");
  258.   }
  259.   if (t_os_type & MT_DOS)
  260.     t_os = DOS;
  261.   if (t_os_type & MT_DV)
  262.     t_os = DV;
  263.   if (t_os_type & MT_WINS)
  264.     t_os = WINS;
  265.   if (t_os_type & MT_WIN3)
  266.     t_os = WIN3;
  267.   if (t_os_type & MT_OS2)
  268.     t_os = OS2;
  269.   return (t_os - 1);
  270. }
  271.  
  272. void giveup_timeslice(void)
  273. {
  274.   union REGS t_regs;
  275.  
  276.   switch (t_os) {
  277.     case DOS:
  278.       break;
  279.     case OS2:
  280.     case WIN3:
  281.     case WINS:
  282.       t_regs.x.ax = 0x1680;
  283.       int86(0x2f, &t_regs, &t_regs);
  284.       break;
  285.     case DV:
  286.       t_regs.x.ax = 0x1000;
  287.       int86(0x15, &t_regs, &t_regs);
  288.       break;
  289.   }
  290. }
  291.  
  292. unsigned char *trim(unsigned char *str)
  293. {
  294.   int i;
  295.  
  296.   if (str == NULL)
  297.     return (str);
  298.   for (i = strlen(str) - 1; (i >= 0) && isspace(str[i]); str[i--] = '\0');
  299.   while (isspace(str[0]))
  300.     strcpy(str, str + 1);
  301.   return (str);
  302. }
  303.  
  304. char *fix_quoted_commas(char *string)
  305. {
  306.   char *ptr;
  307.   int quoted = 0;
  308.  
  309.   ptr = string;
  310.   if (ptr) {
  311.     while (*ptr != 0) {
  312.       if (*ptr == '\"')
  313.         quoted = (!quoted);
  314.       if (*ptr == ',' && quoted)
  315.         *ptr = '│';
  316.       ptr = &ptr[1];
  317.     }
  318.   }
  319.   return (string);
  320. }
  321.  
  322. int sh_write(int handle, void *buffer, unsigned long length)
  323. {
  324.   if (handle == -1) {
  325.     return (-1);
  326.   }
  327.   return (write(handle, buffer, (unsigned) length));
  328. }
  329.  
  330. int sh_open(char *path, int file_access, unsigned fmode)
  331. {
  332.   int handle, count, share;
  333.   char drive[MAXDRIVE], dir[MAXDIR], file[MAXFILE], ext[MAXEXT];
  334.  
  335.   if ((file_access & O_RDWR) || (file_access & O_WRONLY) || (fmode & S_IWRITE)) {
  336.     share = SH_DENYRW;
  337.   } else {
  338.     share = SH_DENYWR;
  339.   }
  340.   handle = open(path, file_access | share, fmode);
  341.   if (handle < 0) {
  342.     count = 1;
  343.     fnsplit(path, drive, dir, file, ext);
  344.     if (access(path, 0) != -1) {
  345.       delay(WAIT_TIME);
  346.       handle = open(path, file_access | share, fmode);
  347.       while (((handle < 0) && (errno == EACCES)) && (count < TRIES)) {
  348.         if (count % 2)
  349.           delay(WAIT_TIME);
  350.         else
  351.           giveup_timeslice();
  352.         count++;
  353.         handle = open(path, file_access | share, fmode);
  354.       }
  355.     }
  356.   }
  357.   return (handle);
  358. }
  359.  
  360. int sh_close(int f)
  361. {
  362.   if (f != -1)
  363.     close(f);
  364.   return (-1);
  365. }
  366.  
  367. int sh_read(int handle, void *buf, unsigned length)
  368. {
  369.   if (handle == -1) {
  370.     return (-1);
  371.   }
  372.   return (read(handle, buf, length));
  373. }
  374.  
  375. long sh_lseek(int handle, long offset, int fromwhere)
  376. {
  377.   if (handle == -1) {
  378.     return (-1L);
  379.   }
  380.   return (lseek(handle, offset, fromwhere));
  381. }
  382.  
  383. FILE *fsh_open(char *path, char *fmode)
  384. {
  385.   FILE *f;
  386.   int count, share, md, fd;
  387.   char drive[MAXDRIVE], dir[MAXDIR], file[MAXFILE], ext[MAXEXT];
  388.  
  389.   share = SH_DENYWR;
  390.   md = 0;
  391.   if (((char *) _fstrchr(fmode, 'w')) != NULL) {
  392.     share = SH_DENYRD;
  393.     md = O_RDWR | O_CREAT | O_TRUNC;
  394.   } else
  395.     if (((char *) _fstrchr(fmode, 'a')) != NULL) {
  396.     share = SH_DENYRD;
  397.     md = O_RDWR | O_CREAT;
  398.   } else {
  399.     md = O_RDONLY;
  400.   }
  401.   if (((char *) _fstrchr(fmode, 'b')) != NULL) {
  402.     md |= O_BINARY;
  403.   }
  404.   if (((char *) _fstrchr(fmode, '+')) != NULL) {
  405.     md &= ~O_RDONLY;
  406.     md |= O_RDWR;
  407.     share = SH_DENYRD;
  408.   }
  409.   fd = open(path, md | share, S_IREAD | S_IWRITE);
  410.   if (fd < 0) {
  411.     count = 1;
  412.     fnsplit(path, drive, dir, file, ext);
  413.     if ((access(path, 0)) != -1) {
  414.       delay(WAIT_TIME);
  415.       fd = open(path, md | share, S_IREAD | S_IWRITE);
  416.       while (((fd < 0) && (errno == EACCES)) && (count < TRIES)) {
  417.         delay(WAIT_TIME);
  418.         count++;
  419.         fd = open(path, md | share, S_IREAD | S_IWRITE);
  420.       }
  421.     }
  422.   }
  423.   if (fd > 0) {
  424.     if (((char *) _fstrchr(fmode, 'a')) != NULL)
  425.       sh_lseek(fd, 0L, SEEK_END);
  426.     f = fdopen(fd, fmode);
  427.     if (!f) {
  428.       close(fd);
  429.     }
  430.   } else
  431.     f = 0;
  432.   return (f);
  433. }
  434.  
  435. int log_it(int display, char *fmt,...)
  436. {
  437.   va_list v;
  438.   char s[255], fn[161];
  439.   FILE *fp;
  440.  
  441.   sprintf(fn, "%sNEWS.LOG", netdata);
  442.   if ((fp = fsh_open(fn, "at")) == NULL)
  443.     return 1;
  444.   va_start(v, fmt);
  445.   vsprintf(s, fmt, v);
  446.   va_end(v);
  447.   fputs(s, fp);
  448.   fclose(fp);
  449.   if (display)
  450.     fputs(s, stderr);
  451.   return 0;
  452. }
  453.  
  454. Mail_Socket *smtp_start(char *host, char *dom)
  455. {
  456.   longword h;
  457.   Mail_Socket *SMTP_sock = NULL;
  458.  
  459.   if (!WatTCP_initialized) {
  460.     sock_init();
  461.     WatTCP_initialized = 1;
  462.   }
  463.   if (!(h = resolve(host))) {
  464.     if (!(h = resolve(host))) {
  465.       SMTP_Err_Cond = SMTP_FAILED;
  466.       log_it(1, "\n ■ Error : Cannot resolve host %s", host);
  467.       return NULL;
  468.     }
  469.   }
  470.   if ((SMTP_sock = (Mail_Socket *) farmalloc(sizeof(Mail_Socket))) == NULL) {
  471.     log_it(1, "\n ■ Insufficient memory to create socket... aborting");
  472.     exit(EXIT_FAILURE);
  473.   }
  474.   if ((SMTP_sock->sock = (tcp_Socket *) farmalloc(sizeof(tcp_Socket))) == NULL) {
  475.     log_it(1, "\n ■ Insufficient memory to create socket... aborting");
  476.     farfree(SMTP_sock);
  477.     exit(EXIT_FAILURE);
  478.   }
  479.   if (!tcp_open(SMTP_sock->sock, 0, h, SMTP_PORT, NULL)) {
  480.     SMTP_Err_Cond = SMTP_FAILED;
  481.     log_it(1, "\n ■ Error : Unable to connect to %s", host);
  482.     farfree(SMTP_sock);
  483.     return NULL;
  484.   }
  485.   sock_sturdy(SMTP_sock->sock, 100);
  486.   sock_mode(SMTP_sock->sock, TCP_MODE_ASCII);
  487.   sock_wait_established(SMTP_sock->sock, sock_delay, NULL, &SMTP_stat);
  488.  
  489.   sock_wait_input(SMTP_sock->sock, sock_delay, NULL, &SMTP_stat);
  490.   sock_gets(SMTP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  491.   log_it(DEBUG, "\n - SMTP> %s", _temp_buffer);
  492.  
  493.   sprintf(_temp_buffer, "HELO %s", dom);
  494.   sock_puts(SMTP_sock->sock, _temp_buffer);
  495.   sock_wait_input(SMTP_sock->sock, sock_delay, NULL, &SMTP_stat);
  496.   while (sock_tbused(SMTP_sock->sock) > 0) {
  497.     SOCK_GETS(SMTP);
  498.     SMTP_FAIL_ON(SMTP_OOPS,);
  499.     SMTP_FAIL_ON(SMTP_SYNTAX,);
  500.     SMTP_FAIL_ON(SMTP_PARAM,);
  501.     SMTP_FAIL_ON(SMTP_BAD_PARM,);
  502.   }
  503.   SOCK_READ_ERR(SMTP,);
  504.   return (SMTP_sock);
  505. }
  506.  
  507. char *smtp_parse_from_line(FILE * f)
  508. {
  509.   char s[161];
  510.   int found = 0, done = 0, beginfocus, endfocus;
  511.  
  512.   rewind(f);
  513.   while (!feof(f) && !done) {
  514.     fgets(s, 160, f);
  515.     if (*s == '\n')
  516.       done = 1;
  517.     else if ((strncmpi(s, "from:", 5) == 0 &&
  518.            _fstrchr(s, '@') != 0)) {
  519.       found = 1;
  520.       done = 1;
  521.     }
  522.   }
  523.   if (found) {
  524.     if ((beginfocus = _fstrcspn(s, "<")) != strlen(s)) {
  525.       ++beginfocus;
  526.       endfocus = _fstrcspn(s, ">");
  527.       s[endfocus] = NULL;
  528.     } else
  529.       beginfocus = 5;
  530.     return (trim(strdup(&s[beginfocus])));
  531.   }
  532.   return 0;
  533. }
  534.  
  535. char *stripspace(char *str)
  536. {
  537.   char *obuf, *nbuf;
  538.  
  539.   if (str) {
  540.     for (obuf = str, nbuf = str; *obuf; ++obuf) {
  541.       if (!isspace(*obuf))
  542.         *nbuf++ = *obuf;
  543.     }
  544.     *nbuf = NULL;
  545.   }
  546.   return (str);
  547. }
  548.  
  549. unsigned char *trimstr1(unsigned char *s)
  550. {
  551.   int i;
  552.   static char *whitespace = " \r\n\t";
  553.  
  554.   i = strlen(s);
  555.   if (i) {
  556.     while ((i > 0) && (_fstrchr(whitespace, s[i - 1])))
  557.       --i;
  558.     while ((i > 0) && (_fstrchr(whitespace, *s))) {
  559.       memmove(s, s + 1, --i);
  560.     }
  561.     s[i] = 0;
  562.   }
  563.   return (s);
  564. }
  565.  
  566.  
  567. int find_listname(FILE * f)
  568. {
  569.   char *ss = NULL, s[161];
  570.   int found = 0, done = 0;
  571.  
  572.   *LISTNAME = 0;
  573.   rewind(f);
  574.   while (!feof(f) && !done) {
  575.     fgets(s, 160, f);
  576.     if (*s == '\n')
  577.       done = 1;
  578.     else if ((strnicmp(s, "x-reply-to", 10) == 0) && (_fstrchr(s, '@') != 0) &&
  579.           (_fstrchr(s, '\"') != 0)) {
  580.       found = 1;
  581.       done = 1;
  582.     }
  583.   }
  584.   if (found) {
  585.     ss = strtok(s, "\"");
  586.     if (ss) {
  587.       ss = strtok(NULL, "\"");
  588.       trimstr1(ss);
  589.       strcpy(LISTNAME, ss);
  590.     }
  591.     if (ss)
  592.       return 1;
  593.   }
  594.   return 0;
  595. }
  596.  
  597. char **smtp_parse_to_line(FILE * f)
  598. {
  599.   int i, i1, done = 0, current = 0;
  600.   char **list = NULL;
  601.   char *addr, _temp_addr[120], buf[120];
  602.  
  603.   rewind(f);
  604.   while (!feof(f) && !done) {
  605.     fgets(_temp_buffer, sizeof(_temp_buffer), f);
  606.     if (*_temp_buffer == '\n')
  607.       done = 1;
  608.     else
  609.       if ((strncmpi(_temp_buffer, "to:", 3) == 0) ||
  610.           (strncmpi(_temp_buffer, "cc:", 3) == 0) ||
  611.           (strncmpi(_temp_buffer, "bcc:", 4) == 0)) {
  612.       fix_quoted_commas(_temp_buffer);
  613.       addr = strtok(_temp_buffer, ":");
  614.       addr = strtok(NULL, "\r\n");
  615.       trimstr1(addr);
  616.       strcpy(_temp_addr, addr);
  617.       if ((_fstrchr(_temp_addr, ' ')) || (_fstrchr(_temp_addr, ')')) || (_fstrchr(_temp_addr, '\"'))) {
  618.         *buf = i1 = 0;
  619.         i = _fstrcspn(_temp_addr, "@");
  620.         while ((i > 0) && (_temp_addr[i - 1] != ' ') && (_temp_addr[i - 1] != '<'))
  621.           --i;
  622.         while (*_temp_addr && (_temp_addr[i] != ' ') && (_temp_addr[i] != '>'))
  623.           buf[i1++] = _temp_addr[i++];
  624.         buf[i1] = 0;
  625.         addr = buf;
  626.       }
  627.       list = (char **) farrealloc(list, sizeof(char *) * ((current) + 2));
  628.       list[current] = strdup(addr);
  629.       list[current + 1] = NULL;
  630.       current++;
  631.       }
  632.   }
  633.   return (list);
  634. }
  635.  
  636. int smtp_send_MAIL_FROM_line(Mail_Socket * SMTP_sock, FILE * f)
  637. {
  638.   char *from;
  639.  
  640.   from = smtp_parse_from_line(f);
  641.   if (from) {
  642.     if (DEBUG)
  643.       output("\n - SMTP> Mail From:<%s>", from);
  644.     sprintf(_temp_buffer, "MAIL FROM:<%s>", from);
  645.     strcpy(MAILFROM, from);
  646.     sock_puts(SMTP_sock->sock, _temp_buffer);
  647.     free(from);
  648.     while (sock_tbused(SMTP_sock->sock) > 0) {
  649.       SOCK_GETS(SMTP);
  650.       SMTP_FAIL_ON(SMTP_OOPS,);
  651.     }
  652.   }
  653.   SOCK_READ_ERR(SMTP,);
  654.   return 1;
  655. }
  656.  
  657. #define FREE_ALL for (i=0; to_list[i]!=NULL; i++) if (to_list[i]) free(to_list[i]); if (to_list) free(to_list);
  658.  
  659. int smtp_send_RCPT_TO_line(Mail_Socket * SMTP_sock, FILE * f)
  660. {
  661.   char **to_list;
  662.   int i, done = 0;
  663.  
  664.   to_list = smtp_parse_to_line(f);
  665.   for (i = 0; ((to_list[i] != NULL) && (!done)); i++) {
  666.     if ((_fstrchr(to_list[i], '@') == NULL) || (_fstrchr(to_list[i], '.') == NULL)) {
  667.       log_it(1, "\n ! Invalid recipient - %s - aborting message.", to_list[i]);
  668.       sock_puts(SMTP_sock->sock, "RSET");
  669.       done = 1;
  670.     } else {
  671.       log_it(DEBUG, "\n - SMTP> Rcpt To:<%s>", to_list[i]);
  672.       sprintf(_temp_buffer, "RCPT TO:<%s>", to_list[i]);
  673.       sock_puts(SMTP_sock->sock, _temp_buffer);
  674.     }
  675.     while (sock_tbused(SMTP_sock->sock) > 0) {
  676.       SOCK_GETS(SMTP);
  677.       SMTP_FAIL_ON(SMTP_OOPS, FREE_ALL);
  678.       SMTP_RESET_ON(SMTP_SYNTAX, FREE_ALL);
  679.       SMTP_RESET_ON(SMTP_PARAM, FREE_ALL);
  680.       SMTP_RESET_ON(SMTP_BAD_SEQ, FREE_ALL);
  681.     }
  682.   }
  683.  
  684.   SOCK_READ_ERR(SMTP, FREE_ALL);
  685.  
  686.   FREE_ALL;
  687.  
  688.   return 1;
  689. }
  690.  
  691. #undef FREE_ALL
  692.  
  693. void go_back(int from, int to)
  694. {
  695.   int i;
  696.  
  697.   for (i = from; i > to; i--)
  698.     output("\b \b");
  699. }
  700.  
  701. char *trim(char *str)
  702. {
  703.   int i;
  704.  
  705.   if (str == NULL)
  706.     return (str);
  707.  
  708.   for (i = strlen(str) - 1; (i >= 0) && isspace(str[i]); str[i--] = '\0');
  709.  
  710.   while (isspace(str[0]))
  711.     strcpy(str, str + 1);
  712.  
  713.   return (str);
  714. }
  715.  
  716. int smtp_sendf(Mail_Socket * SMTP_sock, FILE *fp, int skip)
  717. {
  718.   int pos, in_header = 1, sent_from = 0;
  719.   long nbytes, obytes, rbytes, cbytes;
  720.   char *temp;
  721.  
  722.   fseek(fp, 0L, SEEK_END);
  723.   obytes = ftell(fp);
  724.   rewind(fp);
  725.   sock_puts(SMTP_sock->sock, "DATA");
  726.   sock_wait_input(SMTP_sock->sock, sock_delay, NULL, &SMTP_stat);
  727.   while (sock_tbused(SMTP_sock->sock) > 0) {
  728.     SOCK_GETS(SMTP);
  729.     if (DEBUG)
  730.       log_it(DEBUG, "\n - SMTP> %s", _temp_buffer);
  731.     SMTP_FAIL_ON(SMTP_OOPS,);
  732.     SMTP_RESET_ON(SMTP_BAD_SEQ,);
  733.     SMTP_RESET_ON(SMTP_SYNTAX,);
  734.     SMTP_RESET_ON(SMTP_PARAM,);
  735.     SMTP_RESET_ON(SMTP_COM_NI,);
  736.     SMTP_RESET_ON(SMTP_FAILED,);
  737.     SMTP_RESET_ON(SMTP_ERROR,);
  738.   }
  739.   nbytes = 0L;
  740.   rbytes = cbytes = 256L;
  741.   pos = wherex();
  742.   output("               ");
  743.   go_back(wherex(), pos);
  744.   while ((feof(fp) == 0) && (fgets(_temp_buffer, sizeof(_temp_buffer), fp))) {
  745.     rip(_temp_buffer);
  746.     trim(temp = strdup(_temp_buffer));
  747.     if (strlen(temp) == 0)
  748.       in_header = 0;
  749.     free(temp);
  750.  
  751.     if (*_temp_buffer == '.') {
  752.       movmem(_temp_buffer, _temp_buffer + 1, sizeof(_temp_buffer) - 1);
  753.       *_temp_buffer = '.';
  754.     }
  755.  
  756.     if ((skip) && (*LISTNAME) && (strncmpi(_temp_buffer, "to:", 3) == 0) && (in_header)) {
  757.       if (!sent_from) {
  758.         sprintf(_temp_buffer, "To: \"Multiple Recipients of Mailing List %s\" <%s>",
  759.             LISTNAME, MAILFROM);
  760.         sent_from = 1;
  761.       } else
  762.         continue;
  763.     }
  764.  
  765.     nbytes += sock_puts(SMTP_sock->sock, _temp_buffer) + 2;
  766.     if (nbytes > 2000L)
  767.       cbytes = 512L;
  768.     if (nbytes > 4000L)
  769.       cbytes = 1024L;
  770.     if (nbytes > 16000L)
  771.       cbytes = 2048L;
  772.     if (nbytes > 32000L)
  773.       cbytes = 4096L;
  774.     if (nbytes > 64000L)
  775.       cbytes = 8192L;
  776.     if (nbytes > rbytes) {
  777.       go_back(wherex(), pos);
  778.       output("%ld/%ld", nbytes, obytes);
  779.       rbytes += cbytes;
  780.     }
  781.     if (kbhit()) {
  782.       go_back(wherex(), pos);
  783.       output(" aborted.");
  784.       aborted = 1;
  785.       return 0;
  786.     }
  787.   }
  788.   sock_puts(SMTP_sock->sock, ".");
  789.   sock_wait_input(SMTP_sock->sock, sock_delay, NULL, &SMTP_stat);
  790.   while (sock_tbused(SMTP_sock->sock) > 0) {
  791.     SOCK_GETS(SMTP);
  792.     SMTP_FAIL_ON(SMTP_OOPS,);
  793.     SMTP_RESET_ON(SMTP_ERROR,);
  794.     SMTP_RESET_ON(SMTP_SQUEEZED,);
  795.     SMTP_RESET_ON(SMTP_FULL,);
  796.     SMTP_RESET_ON(SMTP_FAILED,);
  797.   }
  798.   if (*_temp_buffer == '2')
  799.     log_it(DEBUG, "\n - SMTP> %s", _temp_buffer);
  800.   if (DEBUG) {
  801.     go_back(wherex(), pos);
  802.     output("accepted.");
  803.   }
  804.   return 1;
  805.  
  806.   SOCK_READ_ERR(SMTP,);
  807.   return 0;
  808. }
  809.  
  810.  
  811. int smtp_shutdown(Mail_Socket * SMTP_sock)
  812. {
  813.   if (SMTP_sock->sock) {
  814.     sock_puts(SMTP_sock->sock, "QUIT");
  815.     sock_wait_input(SMTP_sock->sock, sock_delay, NULL, &SMTP_stat);
  816.     sock_gets(SMTP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  817.     sock_close(SMTP_sock->sock);
  818.  
  819.   }
  820.   SOCK_READ_ERR(SMTP, free_Mail_Socket(SMTP_sock));
  821.   return 0;
  822. }
  823.  
  824.  
  825. Mail_Socket *pop_init(char *host)
  826. {
  827.   longword h;
  828.   Mail_Socket *POP_sock = NULL;
  829.  
  830.   if (!WatTCP_initialized) {
  831.     sock_init();
  832.     WatTCP_initialized = 1;
  833.   }
  834.   if (!(h = resolve(host))) {
  835.     if (!(h = resolve(host))) {
  836.       POP_Err_Cond = POP_BAD_HOST;
  837.       log_it(1, "\n ■ Error : Cannot resolve host %s", host);
  838.       return NULL;
  839.     }
  840.   }
  841.   if ((POP_sock = (Mail_Socket *) farmalloc(sizeof(Mail_Socket))) == NULL) {
  842.     log_it(1, "\n ■ Insufficient memory to create socket... aborting.");
  843.     exit(EXIT_FAILURE);
  844.   }
  845.   if ((POP_sock->sock = (tcp_Socket *) farmalloc(sizeof(tcp_Socket))) == NULL) {
  846.     log_it(1, "\n ■ Insufficient memory to create socket... aborting.");
  847.     farfree(POP_sock);
  848.     exit(EXIT_FAILURE);
  849.   }
  850.   if (!tcp_open(POP_sock->sock, 0, h, POP_PORT, NULL)) {
  851.     POP_Err_Cond = POP_BAD_HOST;
  852.     log_it(1, "\n ■ Error : Unable to connect to host %s", host);
  853.     return NULL;
  854.   }
  855.   sock_mode(POP_sock->sock, TCP_MODE_ASCII);
  856.   sock_wait_established(POP_sock->sock, sock_delay, NULL, &POP_stat);
  857.   sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  858.   sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  859.   log_it(DEBUG, "\n - POP> %s", _temp_buffer);
  860.   if (*_temp_buffer != '+') {
  861.     POP_Err_Cond = POP_HOST_UNAVAILABLE;
  862.     log_it(1, "\n ■ Error : Host %s is unavailable.", host);
  863.     return NULL;
  864.   } else {
  865.     POP_Err_Cond = POP_OK;
  866.     log_it(DEBUG, "\n - POP socket initialized.");
  867.     return (POP_sock);
  868.   }
  869.   SOCK_READ_ERR(POP,);
  870.   return (POP_sock);
  871. }
  872.  
  873. int pop_login(Mail_Socket * POP_sock, char *userid, char *password, char *host, int wingate)
  874. {
  875.   if (wingate)
  876.     sprintf(_temp_buffer, "USER %s#%s", userid, host);
  877.   else
  878.     sprintf(_temp_buffer, "USER %s", userid);
  879.   if ((strnicmp(userid, "n1160", 5) == 0) && (strnicmp(host, "edare.ml.org", 12) == 0))
  880.     sprintf(_temp_buffer, "USER %s", userid);
  881.   sock_puts(POP_sock->sock, _temp_buffer);
  882.   sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  883.   sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  884.   log_it(DEBUG, "\n - POP> %s", _temp_buffer);
  885.   if (*_temp_buffer != '+') {
  886.     POP_Err_Cond = POP_BAD_MBOX;
  887.     log_it(1, "\n ■ Error : host report mailbox %s does not exist", userid);
  888.     if (POP_sock->sock) {
  889.       sock_puts(POP_sock->sock, "QUIT");
  890.       sock_close(POP_sock->sock);
  891.     }
  892.     return 0;
  893.   }
  894.   sprintf(_temp_buffer, "PASS %s", password);
  895.   sock_puts(POP_sock->sock, _temp_buffer);
  896.   sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  897.   sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  898.   log_it(DEBUG, "\n - POP> %s", _temp_buffer);
  899.   if (*_temp_buffer != '+') {
  900.     POP_Err_Cond = POP_BAD_PASS;
  901.     log_it(1, "\n ■ Error : Host reports password incorrect or account locked.");
  902.     if (POP_sock->sock) {
  903.       sock_puts(POP_sock->sock, "QUIT");
  904.       sock_close(POP_sock->sock);
  905.     }
  906.     return 0;
  907.   }
  908.   SOCK_READ_ERR(POP,);
  909.   return 1;
  910. }
  911.  
  912. int pop_status(Mail_Socket * POP_sock, unsigned int *count, unsigned long *totallength)
  913. {
  914.   char junk[12];
  915.  
  916.   sock_puts(POP_sock->sock, "STAT");
  917.   sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  918.   sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  919.   if (*_temp_buffer != '+') {
  920.     POP_Err_Cond = POP_UNKNOWN;
  921.     log_it(DEBUG, "\n ■ Error : Unknown POP error.");
  922.     return 0;
  923.   } else
  924.     sscanf(_temp_buffer, "%s %u %lu", junk, count, totallength);
  925.  
  926.   SOCK_READ_ERR(POP,);
  927.   return 1;
  928. }
  929.  
  930. long pop_length(Mail_Socket * POP_sock, unsigned int msg_num, unsigned long *size)
  931. {
  932.   char junk[21];
  933.   unsigned int dummy;
  934.  
  935.   sprintf(_temp_buffer, "LIST %u", msg_num);
  936.   sock_puts(POP_sock->sock, _temp_buffer);
  937.   sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  938.   sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  939.   if (*_temp_buffer != '+') {
  940.     POP_Err_Cond = POP_NOT_MSG;
  941.     log_it(DEBUG, "\n ■ Error : No message #%u", msg_num);
  942.     return 0;
  943.   } else
  944.     sscanf(_temp_buffer, "%s %u %lu", &junk, &dummy, size);
  945.  
  946.   SOCK_READ_ERR(POP,);
  947.   if (*size == 0L) {
  948.     log_it(1, "\n ■ Mailbox contains a zero byte file -- deleting Message #%u!", msg_num);
  949.     sprintf(_temp_buffer, "DELE %u", msg_num);
  950.     sock_puts(POP_sock->sock, _temp_buffer);
  951.     sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  952.     sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  953.     log_it(DEBUG, "\n - POP> %s", _temp_buffer);
  954.     if (*_temp_buffer != '+') {
  955.       POP_Err_Cond = POP_NOT_MSG;
  956.       log_it(1, "\n ■ Error : No message #%u", msg_num);
  957.     }
  958.     sock_puts(POP_sock->sock, "QUIT");
  959.     sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  960.     sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  961.     if (*_temp_buffer != '+') {
  962.       POP_Err_Cond = POP_UNKNOWN;
  963.       log_it(1, "\n ■ Error : Unable to update mailbox.");
  964.     } else
  965.       log_it(DEBUG, "\n ■ Close and Updated mailbox.");
  966.     sock_close(POP_sock->sock);
  967.   }
  968.   return (*size);
  969. }
  970.  
  971. char *stristr(char *String, char *Pattern)
  972. {
  973.   char *pptr, *sptr, *start;
  974.   unsigned int slen, plen;
  975.  
  976.   for (start = String, pptr = Pattern, slen = strlen(String),
  977.        plen = strlen(Pattern); slen >= plen; start++, slen--) {
  978.     while (toupper(*start) != toupper(*Pattern)) {
  979.       start++;
  980.       slen--;
  981.       if (slen < plen)
  982.         return (NULL);
  983.     }
  984.     sptr = start;
  985.  
  986.     pptr = Pattern;
  987.     while (toupper(*sptr) == toupper(*pptr)) {
  988.       sptr++;
  989.       pptr++;
  990.       if ('\0' == *pptr)
  991.         return (start);
  992.     }
  993.   }
  994.   return (NULL);
  995. }
  996.  
  997. int checkspam(char *text)
  998. {
  999.   char fn[161], buf[81], tmp[81];
  1000.   int spam, ok;
  1001.   FILE *fp;
  1002.  
  1003.   spam = 0;
  1004.   sprintf(fn, "%sNOSPAM.TXT", netdata);
  1005.   if ((fp = fsh_open(fn, "r")) != NULL) {
  1006.     while ((!feof(fp)) && (!spam)) {
  1007.       fgets(buf, 80, fp);
  1008.       trimstr1(buf);
  1009.       if (strlen(buf) > 2) {
  1010.         if (buf[0] == '\"') {
  1011.           strcpy(tmp, &(buf[1]));
  1012.           LAST(tmp) = '\0';
  1013.           strcpy(buf, tmp);
  1014.         }
  1015.         if (buf[0] == '[') {
  1016.           if ((strnicmp(buf, "[GLOBAL]", 8) == 0) || (strnicmp(buf, "[MAIL]", 6) == 0))
  1017.             ok = 1;
  1018.           else
  1019.             ok = 0;
  1020.         }
  1021.         if ((ok) && (stristr(text, buf)))
  1022.           spam = 1;
  1023.       }
  1024.     }
  1025.     fclose(fp);
  1026.   }
  1027.   return spam;
  1028. }
  1029.  
  1030. int checkfido(char *text)
  1031. {
  1032.   char fn[161], buf[81], tmp[81];
  1033.   int spam, ok;
  1034.   FILE *fp;
  1035.  
  1036.   spam = 0;
  1037.   sprintf(fn, "%sFIWPKT.TXT", netdata);
  1038.   if ((fp = fsh_open(fn, "r")) != NULL) {
  1039.     while ((!feof(fp)) && (!spam)) {
  1040.       fgets(buf, 80, fp);
  1041.       trimstr1(buf);
  1042.       if (strlen(buf) > 2) {
  1043.         if (buf[0] == '\"') {
  1044.           strcpy(tmp, &(buf[1]));
  1045.           LAST(tmp) = '\0';
  1046.           strcpy(buf, tmp);
  1047.         }
  1048.         if ((ok) && (stristr(text, buf)))
  1049.           spam = 1;
  1050.       }
  1051.     }
  1052.     fclose(fp);
  1053.   }
  1054.   return spam;
  1055. }
  1056.  
  1057. #define MAX_IDS 100
  1058.  
  1059. int compact_msgid(void)
  1060. {
  1061.   char fn[161], oldfn[161];
  1062.   int i, f1, f2, num_ids;
  1063.   Message_ID messageid;
  1064.  
  1065.   num_ids = 0;
  1066.   sprintf(oldfn, "%sMSGID.OLD", netdata);
  1067.   unlink(oldfn);
  1068.   sprintf(fn, "%sMSGID.DAT", netdata);
  1069.   rename(fn, oldfn);
  1070.   f1 = sh_open(oldfn, O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  1071.   if (f1 < 0) {
  1072.     log_it(1, "\n ! Unable to read %s.", oldfn);
  1073.     return 1;
  1074.   }
  1075.   f2 = sh_open(fn, O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  1076.  
  1077.   if (f2 < 0) {
  1078.     log_it(1, "\n ! Unable to create %s.", fn);
  1079.     return 1;
  1080.   }
  1081.   for (i = 50; i < MAX_IDS; i++) {
  1082.     sh_lseek(f1, ((long) (i)) * ((long) sizeof(Message_ID)), SEEK_SET);
  1083.     sh_read(f1, (void *) &messageid, sizeof(Message_ID));
  1084.     sh_lseek(f2, ((long) (num_ids++)) * ((long) sizeof(Message_ID)), SEEK_SET);
  1085.     sh_write(f2, &messageid, sizeof(Message_ID));
  1086.   }
  1087.   f1 = sh_close(f1);
  1088.   f2 = sh_close(f2);
  1089.   unlink(oldfn);
  1090.   return 0;
  1091. }
  1092.  
  1093. int check_messageid(int add, char *msgid)
  1094. {
  1095.   char fn[MAXPATH];
  1096.   int i, f, dupe, num_ids;
  1097.   Message_ID messageid;
  1098.  
  1099.   num_ids = dupe = 0;
  1100.   sprintf(fn, "%sMSGID.DAT", netdata);
  1101.   f = sh_open(fn, O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  1102.   if (f < 0) {
  1103.     log_it(1, "\n ! Unable to create %s.", fn);
  1104.     return -1;
  1105.   }
  1106.   num_ids = (int) (filelength(f) / sizeof(Message_ID));
  1107.  
  1108.   if (num_ids > MAX_IDS)
  1109.     compact_ids = 1;
  1110.   if (!add) {
  1111.     log_it(DEBUG, "\n - Scanning previous %d Message-IDs.", num_ids);
  1112.     for (i = 0; ((i < num_ids) && (!dupe)); i++) {
  1113.       sh_lseek(f, ((long) (i)) * ((long) sizeof(Message_ID)), SEEK_SET);
  1114.       sh_read(f, (void *) &messageid, sizeof(Message_ID));
  1115.       if (strcmp(messageid.msgid, msgid) == 0)
  1116.         dupe = 1;
  1117.     }
  1118.   } else {
  1119.     strncpy(messageid.msgid, msgid, 80);
  1120.     messageid.msgid[81] = '\0';
  1121.     log_it(DEBUG, "\n ■ Adding new Message-ID:%s", messageid.msgid);
  1122.     sh_lseek(f, ((long) (num_ids)) * ((long) sizeof(Message_ID)), SEEK_SET);
  1123.     sh_write(f, &messageid, sizeof(Message_ID));
  1124.   }
  1125.   f = sh_close(f);
  1126.   return dupe;
  1127. }
  1128.  
  1129. int pop_top(Mail_Socket * POP_sock, unsigned int msg_num, int usernum)
  1130. {
  1131.   int okpkt, found_from, found_subj, dupe;
  1132.   char *ss, subject[81];
  1133.  
  1134.   sprintf(_temp_buffer, "TOP %u 40", msg_num);
  1135.   sock_puts(POP_sock->sock, _temp_buffer);
  1136.   sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  1137.   sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  1138.   if (*_temp_buffer != '+') {
  1139.     POP_Err_Cond = POP_NOT_MSG;
  1140.     log_it(1, "\n ■ Error : No message #%u.", msg_num);
  1141.     return -1;
  1142.   }
  1143.   okpkt = -1;
  1144.  
  1145.   dupe = 0;
  1146.   found_from = found_subj = fdl = 0;
  1147.   net_pkt[0] = 0;
  1148.   while (1) {
  1149.     sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  1150.     sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  1151.     if (*_temp_buffer == '.' && _temp_buffer[1] == 0)
  1152.       break;
  1153.     if (usernum == 0) {
  1154.       if (strnicmp(_temp_buffer, "NET: ", 5) == 0)
  1155.         strcpy(net_pkt, &_temp_buffer[5]);
  1156.       if ((strnicmp(_temp_buffer, "begin ", 6) == 0) &&
  1157.           (stristr(_temp_buffer, "WINMAIL") == NULL)) {
  1158.         if (okpkt != 4)
  1159.           okpkt = 1;
  1160.         if ((stristr(_temp_buffer, ".ZIP") != NULL) ||
  1161.             (stristr(_temp_buffer, ".ARJ") != NULL) ||
  1162.             (stristr(_temp_buffer, ".LZH") != NULL))
  1163.           okpkt = 2;
  1164.         if ((stristr(_temp_buffer, ".GIF") != NULL) ||
  1165.             (stristr(_temp_buffer, ".JPG") != NULL))
  1166.           okpkt = 3;
  1167.         if ((okpkt == 2) || (okpkt == 3) || (fdl)) {
  1168.           ss = strtok(_temp_buffer, "6");
  1169.           if (ss) {
  1170.             ss = strtok(NULL, " ");
  1171.             if (ss)
  1172.               ss = strtok(NULL, "\r\n");
  1173.           }
  1174.           if (ss) {
  1175.             strcpy(fdlfn, ss);
  1176.             trimstr1(fdlfn);
  1177.           }
  1178.         }
  1179.       }
  1180.       if (strnicmp(_temp_buffer, "FDL Type:", 9) == 0)
  1181.         fdl = 1;
  1182.     }
  1183.     if ((strnicmp(_temp_buffer, "from:", 5) == 0) && (!found_from)) {
  1184.       if (((stristr(_temp_buffer, "mailer-daemon") != NULL) ||
  1185.            (stristr(_temp_buffer, "mail delivery") != NULL) ||
  1186.            (stristr(_temp_buffer, "administrator") != NULL) ||
  1187.            (stristr(_temp_buffer, from_user) != NULL)) && (usernum == 0))
  1188.         okpkt = 4;
  1189.       else {
  1190.         if (_temp_buffer[6] != 0) {
  1191.           strncpy(pktowner, &_temp_buffer[6], 35);
  1192.           trimstr1(pktowner);
  1193.           pktowner[25] = 0;
  1194.         } else
  1195.           strcpy(pktowner, "Unknown");
  1196.       }
  1197.       found_from = 1;
  1198.     }
  1199.     if ((strnicmp(_temp_buffer, "subject:", 8) == 0) && (!found_subj)) {
  1200.       if (_temp_buffer[9] != 0)
  1201.         strncpy(subject, &_temp_buffer[9], 60);
  1202.       else
  1203.         strcpy(subject, "Unknown");
  1204.       found_subj = 1;
  1205.     }
  1206.     if (usernum == 0) {
  1207.       if ((strnicmp(_temp_buffer, "Message-ID:", 11) == 0) && (!found_subj)) {
  1208.         if (_temp_buffer[11] != 0) {
  1209.           strncpy(id, &_temp_buffer[11], 80);
  1210.           id[81] = '\0';
  1211.           if (check_messageid(0, id))
  1212.             dupe = 1;
  1213.         }
  1214.       }
  1215.     }
  1216.   }
  1217.   if (found_from && found_subj) {
  1218.     if (okpkt == -1) {
  1219.       if ((checkspam(pktowner)) || (checkspam(subject)))
  1220.         okpkt = 5;
  1221.       if ((checkfido(subject)))
  1222.         okpkt = 8;
  1223.     }
  1224.   }
  1225.   if (found_subj) {
  1226.     if ((strnicmp(subject, "subscribe", 9) == 0) ||
  1227.         (strnicmp(subject, "unsubscribe", 11) == 0))
  1228.       okpkt = 6;
  1229.   }
  1230.   if (dupe)
  1231.     okpkt = 7;
  1232.   SOCK_READ_ERR(POP,);
  1233.   return okpkt;
  1234. }
  1235.  
  1236. int pop_getf(Mail_Socket * POP_sock, char *fn, unsigned int msg_num, int usernum)
  1237. {
  1238.   unsigned long size;
  1239.   long nbytes, rbytes;
  1240.   int pos, ctld, length;
  1241.   FILE *fp;
  1242.  
  1243.   if (!pop_length(POP_sock, msg_num, &size))
  1244.     return 0;
  1245.   sprintf(_temp_buffer, "RETR %u", msg_num);
  1246.   sock_puts(POP_sock->sock, _temp_buffer);
  1247.   sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  1248.   sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  1249.   if (*_temp_buffer != '+') {
  1250.     POP_Err_Cond = POP_NOT_MSG;
  1251.     log_it(1, "\n ■ Error : No message #%u", msg_num);
  1252.     return 0;
  1253.   }
  1254.   nbytes = 0L;
  1255.  
  1256.   rbytes = 1024L;
  1257.   output(" : ");
  1258.   pos = wherex();
  1259.   if ((fp = fsh_open(fn, "w")) == NULL) {
  1260.     log_it(1, "\n ■ Unable to create %s... aborting!", fn);
  1261.     return 0;
  1262.   }
  1263.   if (usernum > 0)
  1264.     fprintf(fp, "0RX-WWIV-User: #%d\n", usernum);
  1265.   else if (usernum == -1)
  1266.     fprintf(fp, "0RX-WWIV-List: *%s\n", listaddr);
  1267.   ctld = 1;
  1268.   while (1) {
  1269.     sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  1270.     length = (sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer)));
  1271.     if ((ctld == 1) && (length == 0))
  1272.       ctld = 0;
  1273.     if ((strnicmp(_temp_buffer, "begin ", 6) == 0) &&
  1274.         (stristr(_temp_buffer, "WINMAIL") != NULL))
  1275.       ctld = 2;
  1276.     if ((ctld == 2) && (strnicmp(_temp_buffer, "end", 3) == 0))
  1277.       ctld = 0;
  1278.     if (_temp_buffer[0] == '.' && _temp_buffer[1] == 0)
  1279.       break;
  1280.     if (EOF == (nbytes += fprintf(fp, "%s%s\n", ctld ? "0R" : "", _temp_buffer))) {
  1281.       if (fp != NULL)
  1282.         fclose(fp);
  1283.       return 0;
  1284.     }
  1285.     if (nbytes > rbytes) {
  1286.       go_back(wherex(), pos);
  1287.       output("%ld/%ld", nbytes, size);
  1288.       rbytes += 512L;
  1289.     }
  1290.   }
  1291.   if (fp != NULL)
  1292.     fclose(fp);
  1293.   go_back(wherex(), pos);
  1294.   output("message received!");
  1295.   SOCK_READ_ERR(POP,);
  1296.   return 1;
  1297. }
  1298.  
  1299. int pop_delete(Mail_Socket * POP_sock, unsigned int msg_num)
  1300. {
  1301.   sprintf(_temp_buffer, "DELE %u", msg_num);
  1302.   sock_puts(POP_sock->sock, _temp_buffer);
  1303.   sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  1304.   sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  1305.   log_it(DEBUG, "\n - POP> %s", _temp_buffer);
  1306.   if (*_temp_buffer != '+') {
  1307.     POP_Err_Cond = POP_NOT_MSG;
  1308.     log_it(1, "\n ■ Error : No message #%u", msg_num);
  1309.     return 2;
  1310.   }
  1311.   SOCK_READ_ERR(POP,);
  1312.  
  1313.   return 1;
  1314. }
  1315.  
  1316.  
  1317. int pop_shutdown(Mail_Socket * POP_sock)
  1318. {
  1319.   if (POP_sock->sock) {
  1320.     sock_puts(POP_sock->sock, "QUIT");
  1321.     sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  1322.     sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  1323.     if (*_temp_buffer != '+') {
  1324.       POP_Err_Cond = POP_UNKNOWN;
  1325.       log_it(1, "\n ■ Error : Unable to update mailbox.");
  1326.       return 0;
  1327.     } else
  1328.       log_it(DEBUG, "\n ■ Closed and updated mailbox.");
  1329.     sock_close(POP_sock->sock);
  1330.     return 1;
  1331.   }
  1332. sock_err:
  1333.   free_Mail_Socket(POP_sock);
  1334.  
  1335.   return 0;
  1336. }
  1337.  
  1338. int pop_get_nextf(Mail_Socket * POP_sock, char *fn, int msgnum, int usernum)
  1339. {
  1340.   if (!pop_getf(POP_sock, fn, msgnum, usernum)) {
  1341.     unlink(fn);
  1342.     return 0;
  1343.   }
  1344.   return (pop_delete(POP_sock, msgnum));
  1345. }
  1346.  
  1347. int exist(char *s)
  1348. {
  1349.   int i;
  1350.   struct ffblk ff;
  1351.  
  1352.   i = findfirst(s, &ff, FA_HIDDEN);
  1353.   if (i)
  1354.     return 0;
  1355.   else
  1356.     return 1;
  1357. }
  1358.  
  1359. int find_acct(char *username, char *hostname, char *password)
  1360. {
  1361.   char *ss, fn[161], s[121];
  1362.   int num;
  1363.   FILE *fp;
  1364.  
  1365.   num = 0;
  1366.   sprintf(fn, "%sACCT.INI", netdata);
  1367.   if ((fp = fsh_open(fn, "rt")) == NULL)
  1368.     return 0;
  1369.  
  1370.   while ((fgets(s, 120, fp)) && (num == 0)) {
  1371.     if (strnicmp(s, "ACCT", 4) == 0) {
  1372.       if ((_fstrstr(s, username) != 0) && (_fstrstr(s, hostname) != 0) &&
  1373.           (_fstrstr(s, password) != 0)) {
  1374.         ss = strtok(s, "=");
  1375.         if (ss)
  1376.           trimstr1(s);
  1377.         if (s[4] == '-') {
  1378.           num = -1;
  1379.           strcpy(listaddr, &(s[5]));
  1380.           log_it(DEBUG, "\n ■ Checking mailbox %s on %s for list %s.", username,
  1381.                  hostname, listaddr);
  1382.         } else {
  1383.           num = atoi(&(s[4]));
  1384.           log_it(DEBUG, "\n ■ Checking mailbox %s on %s for user #%d.", username,
  1385.                  hostname, num);
  1386.         }
  1387.       }
  1388.     }
  1389.   }
  1390.   if (fp != NULL)
  1391.     fclose(fp);
  1392.   return num;
  1393. }
  1394.  
  1395. int count_accts(int build)
  1396. {
  1397.   FILE *fp;
  1398.   char *ss, s[101], fn[MAXPATH];
  1399.   int accts = 0;
  1400.  
  1401.   sprintf(fn, "%sACCT.INI", netdata);
  1402.   if ((fp = fsh_open(fn, "rt")) == NULL)
  1403.     return 0;
  1404.  
  1405.   while (fgets(s, 100, fp)) {
  1406.     if (strnicmp(s, "ACCT", 4) == 0) {
  1407.       if (build) {
  1408.         ss = strtok(s, "=");
  1409.         if (ss) {
  1410.           ss = strtok(NULL, "@");
  1411.           trimstr1(ss);
  1412.           if (ss) {
  1413.             strcpy(acct[accts].popname, ss);
  1414.             ss = strtok(NULL, " ");
  1415.             trimstr1(ss);
  1416.             if (ss) {
  1417.               strcpy(acct[accts].pophost, ss);
  1418.               ss = strtok(NULL, " \r\n");
  1419.               trimstr1(ss);
  1420.               if (ss)
  1421.                 strcpy(acct[accts].poppass, ss);
  1422.             }
  1423.           }
  1424.           log_it(DEBUG, "\n - Account : %s - %s - %s", acct[accts].pophost,
  1425.                  acct[accts].popname, acct[accts].poppass);
  1426.         }
  1427.       }
  1428.       ++accts;
  1429.     }
  1430.   }
  1431.   if (fp != NULL)
  1432.     fclose(fp);
  1433.   return accts;
  1434. }
  1435.  
  1436. int parse_net_ini(void)
  1437. {
  1438.   char s[MAXPATH], line[121], *ss;
  1439.   FILE *fp;
  1440.   long fptr;
  1441.  
  1442.   sprintf(s, "%sNET.INI", maindir);
  1443.   if ((fp = fsh_open(s, "rt")) == NULL) {
  1444.     output("\n ■ Unable to open %s.", s);
  1445.     return 1;
  1446.   }
  1447.   *POPHOST = *PROXY = *POPNAME = *POPPASS = *DOMAIN = *NODEPASS = 0;
  1448.   while (fgets(line, 120, fp)) {
  1449.     ss = NULL;
  1450.     stripspace(line);
  1451.     if ((line[0] != ';') && (line[0] != 0) && (line[0] != '\n')) {
  1452.       ss = strtok(line, "=");
  1453.       if (ss) {
  1454.         ss = strtok(NULL, "\r\n");
  1455.         trimstr1(ss);
  1456.         if (strnicmp(line, "POPHOST", 7) == 0) {
  1457.           if (ss) {
  1458.             strcpy(POPHOST, ss);
  1459.             continue;
  1460.           }
  1461.         }
  1462.         if (strnicmp(line, "PROXY", 5) == 0) {
  1463.           if (ss) {
  1464.             strcpy(PROXY, ss);
  1465.             continue;
  1466.           }
  1467.         }
  1468.         if (strnicmp(line, "POPNAME", 7) == 0) {
  1469.           if (ss) {
  1470.             strcpy(POPNAME, ss);
  1471.             continue;
  1472.           }
  1473.         }
  1474.         if (strnicmp(line, "POPPASS", 7) == 0) {
  1475.           if (ss) {
  1476.             strcpy(POPPASS, ss);
  1477.             continue;
  1478.           }
  1479.         }
  1480.         if (strnicmp(line, "DOMAIN", 6) == 0) {
  1481.           if (ss) {
  1482.             strcpy(DOMAIN, ss);
  1483.             continue;
  1484.           }
  1485.         }
  1486.         if (strnicmp(line, "NODEPASS", 8) == 0) {
  1487.           if (ss) {
  1488.             strcpy(NODEPASS, ss);
  1489.             continue;
  1490.           }
  1491.         }
  1492.       }
  1493.     }
  1494.   }
  1495.   if (fp != NULL)
  1496.     fclose(fp);
  1497.   if ((!*POPHOST) || (!*POPNAME) || (!*POPPASS) || (!*DOMAIN))
  1498.     return 1;
  1499.   return 0;
  1500. }
  1501.  
  1502. int copyfile(char *infile, char *outfile)
  1503. {
  1504.   int f1, f2, i;
  1505.   char *b, s[181], s1[21], s2[81], s3[81];
  1506.   struct ftime ft;
  1507.  
  1508.   if ((strcmp(infile, outfile) != 0) && (exist(infile))) {
  1509.     if (exist(outfile)) {
  1510.       fnsplit(outfile, s3, s2, s1, NULL);
  1511.       i = 0;
  1512.       sprintf(s, "%s%s%s.%03d", s3, s2, s1, i);
  1513.       while (exist(s))
  1514.         sprintf(s, "%s%s%s.%03d", s3, s2, s1, ++i);
  1515.       strcpy(outfile, s);
  1516.     }
  1517.     fnsplit(outfile, NULL, NULL, s3, s2);
  1518.     if ((b = (char *) farmalloc(16400)) == NULL)
  1519.       return 1;
  1520.     f1 = open(infile, O_RDONLY | O_BINARY, S_IREAD | S_IWRITE);
  1521.     if (!f1) {
  1522.       farfree(b);
  1523.       return 1;
  1524.     }
  1525.     getftime(f1, &ft);
  1526.     f2 = open(outfile, O_RDWR | O_BINARY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
  1527.     if (!f2) {
  1528.       farfree(b);
  1529.       close(f1);
  1530.       return 1;
  1531.     }
  1532.     i = read(f1, (void *) b, 16384);
  1533.     while (i > 0) {
  1534.       write(f2, (void *) b, i);
  1535.       i = read(f1, (void *) b, 16384);
  1536.     }
  1537.     f1 = close(f1);
  1538.     setftime(f2, &ft);
  1539.     f2 = close(f2);
  1540.     farfree(b);
  1541.   }
  1542.   return 0;
  1543. }
  1544.  
  1545. void move_bad(char *path, char *fn, int why)
  1546. {
  1547.   char src[MAXPATH], dest[MAXPATH];
  1548.  
  1549.   log_it(1, "\n ■ %s failed - SMTP error condition %d", fn, why);
  1550.   sprintf(src, "%s%s", path, fn);
  1551.   sprintf(dest, "%sBAD\\%s", path, fn);
  1552.   if (copyfile(src, dest))
  1553.     unlink(src);
  1554. }
  1555.  
  1556. int isleap(unsigned yr)
  1557. {
  1558.   return yr % 400 == 0 || (yr % 4 == 0 && yr % 100 != 0);
  1559. }
  1560.  
  1561. static unsigned months_to_days(unsigned month)
  1562. {
  1563.   return (month * 3057 - 3007) / 100;
  1564. }
  1565.  
  1566. int jdate(unsigned yr, unsigned mo, unsigned day)
  1567. {
  1568.   int which;
  1569.  
  1570.   which = day + months_to_days(mo);
  1571.   if (mo > 2)
  1572.     which -= isleap(yr) ? 1 : 2;
  1573.  
  1574.   return which;
  1575. }
  1576.  
  1577.  
  1578. void main(int argc, char *argv[])
  1579. {
  1580.   char fn[MAXPATH], temp[181], mqueue[MAXPATH], s[21], s1[21];
  1581.   char nodepass[40], nodename[20], host[60], ext[MAXEXT];
  1582.   char pophost[60], poppass[20], popname[40];
  1583.   int skiplist, checknode, once, failed, ok, f1, i, i1, okpkt, result, usernum, num_accts, accts;
  1584.   int wingate, whichnet, jdater, jdatec, skipit, firstrun;
  1585.   unsigned long size;
  1586.   unsigned count;
  1587.   FILE *fp;
  1588.   struct ffblk ff;
  1589.   struct date dt;
  1590.   Mail_Socket *pop_sock = NULL;
  1591.   Mail_Socket *smtp_sock = NULL;
  1592.  
  1593.   detect_multitask();
  1594.  
  1595.   if (strncmpi(argv[1], "-send", strlen(argv[1])) == 0) {
  1596.     if (argc < 5) {
  1597.       output("\n ■ %s", version);
  1598.       output("\n ■ Invalid arguments for %s\n", argv[0]);
  1599.       exit(EXIT_FAILURE);
  1600.     }
  1601.     if (argc >= 6)
  1602.       DEBUG = atoi(argv[5]);
  1603.     if (argc == 7)
  1604.       skiplist = atoi(argv[6]);
  1605.     else
  1606.       skiplist = 0;
  1607.  
  1608.     strcpy(mqueue, argv[4]);
  1609.     strcpy(netdata, argv[4]);
  1610.     LAST(netdata) = '\0';
  1611.     while (LAST(netdata) != '\\')
  1612.       LAST(netdata) = '\0';
  1613.     output("\n");
  1614.     if ((smtp_sock = smtp_start(argv[2], argv[3])) != NULL) {
  1615.       failed = count = aborted = skipit = 0;
  1616.       firstrun = 1;
  1617.       sprintf(fn, "%s*.*", mqueue);
  1618.       f1 = findfirst(fn, &ff, FA_ARCH);
  1619.       getdate(&dt);
  1620.       jdater = jdate(dt.da_year, dt.da_mon, dt.da_day);
  1621.       while ((count < 3) && (f1 == 0) && (failed < 5) && (!aborted)) {
  1622.         if (count > 1)
  1623.           output(" ■ SMTP pass %d...\n", count);
  1624.         sprintf(fn, "%s%s", mqueue, ff.ff_name);
  1625.         if ((fp = fsh_open(fn, "r")) != NULL) {
  1626.           SMTP_Err_Cond = SMTP_OK;
  1627.           if (DEBUG)
  1628.             output("\n");
  1629.           if (!find_listname(fp))
  1630.             output("\r ■ SND : %-12s : %-18.18s : [Space] aborts : ", ff.ff_name, argv[2]);
  1631.           else
  1632.             output("\r ■ SND : %-12s : %-18.18s : [Space] aborts : ", LISTNAME, argv[2]);
  1633.           ok = 1;
  1634.           if (!smtp_send_MAIL_FROM_line(smtp_sock, fp))
  1635.             ok = 0;
  1636.           if (!smtp_send_RCPT_TO_line(smtp_sock, fp))
  1637.             ok = 0;
  1638.           aborted = result = 0;
  1639.           if (ok) {
  1640.             result = smtp_sendf(smtp_sock, fp, skiplist);
  1641.             if ((!result) || (aborted)) {
  1642.               if ((SMTP_Err_Cond == SMTP_FULL) || (SMTP_Err_Cond == SMTP_FAILED) ||
  1643.                     (SMTP_Err_Cond == SMTP_ACCESS) || (SMTP_Err_Cond == SMTP_BAD_NAM) ||
  1644.                     (SMTP_Err_Cond == SMTP_YOU_FWD))
  1645.                 if (!fp != NULL)
  1646.                   fclose(fp);
  1647.                 move_bad(mqueue, ff.ff_name, SMTP_Err_Cond);
  1648.               ++failed;
  1649.             } else {
  1650.               if (fp != NULL)
  1651.                 fclose(fp);
  1652.               if (!skipit)
  1653.                 unlink(fn);
  1654.             }
  1655.           } else {
  1656.             if (fp != NULL)
  1657.               fclose(fp);
  1658.           }
  1659.         } else
  1660.           log_it(1, "\n ! Unable to open %s.", fn);
  1661.         f1 = findnext(&ff);
  1662.         if ((f1 != 0) && (firstrun)) {
  1663.           sprintf(fn, "%s*.*", mqueue);
  1664.           f1 = findfirst(fn, &ff, FA_ARCH);
  1665.           if (f1 == 0)
  1666.             ++count;
  1667.         }
  1668.         if (f1 != 0) {
  1669.           if (firstrun) {
  1670.             strcat(mqueue, "DIGEST\\");
  1671.             firstrun = 0;
  1672.           }
  1673.           sprintf(fn, "%s*.*", mqueue);
  1674.           f1 = findfirst(fn, &ff, FA_ARCH);
  1675.           skipit = 1;
  1676.           while ((f1 == 0) && (skipit)) {
  1677.             fnsplit(ff.ff_name, NULL, NULL, NULL, ext);
  1678.             jdatec = atoi(&(ext[1]));
  1679.             if (jdatec < jdater) {
  1680.               skipit = 0;
  1681.               break;
  1682.             } else {
  1683.               skipit = 1;
  1684.               log_it(0, "\n ■ Digest %s not ready.", ff.ff_name);
  1685.             }
  1686.             f1 = findnext(&ff);
  1687.           }
  1688.         }
  1689.       }
  1690.       if (failed >= 5)
  1691.         log_it(1, "\n ■ Too many SMTP failures.  Try again later.");
  1692.       smtp_shutdown(smtp_sock);
  1693.     } else
  1694.       log_it(1, "\n ■ SMTP connection failed.");
  1695.     fcloseall();
  1696.   } else if (strncmpi(argv[1], "-r", strlen(argv[1])) == 0) {
  1697.     strcpy(temp, argv[0]);
  1698.     while (LAST(temp) != '\\')
  1699.       LAST(temp) = '\0';
  1700.     strcpy(maindir, temp);
  1701.     if (parse_net_ini()) {
  1702.       output("\n ! Missing critical NET.INI settings!");
  1703.       exit(EXIT_FAILURE);
  1704.     }
  1705.     wingate = 0;
  1706.     strcpy(pophost, POPHOST);
  1707.     strcpy(popname, POPNAME);
  1708.     strcpy(poppass, POPPASS);
  1709.     if (argc < 6) {
  1710.       output("\n ■ %s", version);
  1711.       output("\n ■ Invalid arguments for %s\n", argv[0]);
  1712.       exit(EXIT_FAILURE);
  1713.     }
  1714.     sprintf(from_user, "%s@%s", popname, pophost);
  1715.     DEBUG = atoi(argv[4]);
  1716.     ALLMAIL = atoi(argv[3]);
  1717.     strcpy(netdata, argv[2]);
  1718.     LAST(netdata) = '\0';
  1719.     while (LAST(netdata) != '\\')
  1720.       LAST(netdata) = '\0';
  1721.     POP_Err_Cond = POP_OK;
  1722.     num_accts = accts = usernum = checknode = once = 0;
  1723.     *nodepass = *nodename = 0;
  1724.     if (*NODEPASS) {
  1725.       strcpy(nodepass, NODEPASS);
  1726.       strcpy(nodename, argv[5]);
  1727.       checknode = once = 1;
  1728.     }
  1729.     while ((num_accts >= 0) || (once)) {
  1730.       if (*PROXY) {
  1731.         wingate = 1;
  1732.         strcpy(host, PROXY);
  1733.       } else
  1734.         strcpy(host, pophost);
  1735.       log_it(1, "\n ■ Checking %s... ", pophost);
  1736.       if ((pop_sock = pop_init(host)) != NULL) {
  1737.         if (pop_login(pop_sock, popname, poppass, pophost, wingate)) {
  1738.           if (pop_status(pop_sock, &count, &size)) {
  1739.             okpkt = 0;
  1740.             output("%s has %u message%s (%luK).", popname, count,
  1741.                   count == 1 ? "" : "s", ((size + 1023) / 1024));
  1742.             i1 = 1;
  1743.             pktowner[0] = 0;
  1744.             while (i1 <= count) {
  1745.               okpkt = 0;
  1746.               okpkt = pop_top(pop_sock, i1, usernum);
  1747.               switch (okpkt) {
  1748.                 case -1:
  1749.                   if ((!ALLMAIL) && (!fdl))
  1750.                     log_it(1, "\n ■ Non-network message %d left on server.", i1);
  1751.                   else {
  1752.                     i = 0;
  1753.                     sprintf(temp, "%sUNK-%03d.MSG", argv[2], i);
  1754.                     while (exist(temp))
  1755.                       sprintf(temp, "%sUNK-%03d.MSG", argv[2], ++i);
  1756.                     fnsplit(temp, NULL, NULL, s, s1);
  1757.                     log_it(1, "\n ■ RCV : %3.3d : %-20.20s : %s%s", i1, pktowner[0] == 0 ?
  1758.                            "non-network packet" : pktowner, s, s1);
  1759.                     result = (pop_get_nextf(pop_sock, temp, i1, usernum));
  1760.                     switch (result) {
  1761.                       case 0:
  1762.                         log_it(1, "\n ■ Unable to retrieve message %d.", i1);
  1763.                         fcloseall();
  1764.                         exit(EXIT_FAILURE);
  1765.                       case 1:
  1766.                         break;
  1767.                       case 2:
  1768.                         log_it(1, "\n ■ Unable to delete message %d from host!", i1);
  1769.                         exit(EXIT_FAILURE);
  1770.                     }
  1771.                   }
  1772.                   break;
  1773.                 case 0:
  1774.                   log_it(1, "\n ■ Error accessing message %d", i1);
  1775.                   fcloseall();
  1776.                   exit(EXIT_FAILURE);
  1777.                 case 1:
  1778.                   i = 0;
  1779.                   sprintf(temp, "%sPKT-%03d.UUE", argv[2], i);
  1780.                   while (exist(temp))
  1781.                     sprintf(temp, "%sPKT-%03d.UUE", argv[2], ++i);
  1782.                   fnsplit(temp, NULL, NULL, s, s1);
  1783.                   log_it(1, "\n ■ %s : %3.3d : %-20.20s : %s%s",
  1784.                     *net_pkt ? net_pkt : "RCV", i1, pktowner, s, s1);
  1785.                   result = (pop_get_nextf(pop_sock, temp, i1, usernum));
  1786.                   switch (result) {
  1787.                     case 0:
  1788.                       log_it(1, "\n ■ Unable to retrieve message %d.", i1);
  1789.                       fcloseall();
  1790.                       exit(EXIT_FAILURE);
  1791.                     case 1:
  1792.                       check_messageid(1, id);
  1793.                       break;
  1794.                     case 2:
  1795.                       log_it(1, "\n ■ Unable to delete message %d on host!", i1);
  1796.                       exit(EXIT_FAILURE);
  1797.                   }
  1798.                   break;
  1799.                 case 2:
  1800.                   if ((!ALLMAIL) && (!fdl))
  1801.                     log_it(1, "\n ■ Non-network message %d left on server.", i1);
  1802.                   else {
  1803.                     i = 0;
  1804.                     sprintf(temp, "%sARC-%03d.UUE", argv[2], i);
  1805.                     while (exist(temp))
  1806.                       sprintf(temp, "%sARC-%03d.UUE", argv[2], ++i);
  1807.                     fnsplit(temp, NULL, NULL, s, s1);
  1808.                     if (*fdlfn)
  1809.                       log_it(1, "\n ■ RCV : %3.3d : %-20.20s : %s", i1, "archived file", fdlfn);
  1810.                     else
  1811.                       log_it(1, "\n ■ RCV : %3.3d : %-20.20s : %s%s", i1, "archived file", s, s1);
  1812.                     result = (pop_get_nextf(pop_sock, temp, i1, usernum));
  1813.                     switch (result) {
  1814.                       case 0:
  1815.                         log_it(1, "\n ■ Unable to retrieve message %d.", i1);
  1816.                         fcloseall();
  1817.                         exit(EXIT_FAILURE);
  1818.                       case 1:
  1819.                         check_messageid(1, id);
  1820.                         break;
  1821.                       case 2:
  1822.                         log_it(1, "\n ■ Unable to delete message %d on host!", i1);
  1823.                         exit(EXIT_FAILURE);
  1824.                     }
  1825.                   }
  1826.                   break;
  1827.                 case 3:
  1828.                   if ((!ALLMAIL) && (!fdl))
  1829.                     log_it(1, "\n ■ Non-network message %d left on server.", i1);
  1830.                   else {
  1831.                     i = 0;
  1832.                     sprintf(temp, "%sGIF-%03d.UUE", argv[2], i);
  1833.                     while (exist(temp))
  1834.                       sprintf(temp, "%sGIF-%03d.UUE", argv[2], ++i);
  1835.                     fnsplit(temp, NULL, NULL, s, s1);
  1836.                     log_it(1, "\n ■ RCV : %3.3d : %-20.20s : %s%s", i1, "graphic/image file", s, s1);
  1837.                     result = (pop_get_nextf(pop_sock, temp, i1, usernum));
  1838.                     switch (result) {
  1839.                       case 0:
  1840.                         log_it(1, "\n ■ Unable to retrieve message %d.", i1);
  1841.                         fcloseall();
  1842.                         exit(EXIT_FAILURE);
  1843.                       case 1:
  1844.                         check_messageid(1, id);
  1845.                         break;
  1846.                       case 2:
  1847.                         log_it(1, "\n ■ Unable to delete message %d from host!", i1);
  1848.                         exit(EXIT_FAILURE);
  1849.                     }
  1850.                   }
  1851.                   break;
  1852.                 case 4:
  1853.                   i = 0;
  1854.                   sprintf(temp, "%sBAD-%03d.UUE", argv[2], i);
  1855.                   while (exist(temp))
  1856.                     sprintf(temp, "%sBAD-%03d.UUE", argv[2], ++i);
  1857.                   fnsplit(temp, NULL, NULL, s, s1);
  1858.                   log_it(1, "\n ■ RCV : %3.3d : %-20.20s : %s%s", i1, "mailer-daemon/bounced", s, s1);
  1859.                   result = (pop_get_nextf(pop_sock, temp, i1, usernum));
  1860.                   switch (result) {
  1861.                     case 0:
  1862.                       log_it(1, "\n ■ Unable to retrieve message %d.", i1);
  1863.                       fcloseall();
  1864.                       exit(EXIT_FAILURE);
  1865.                     case 1:
  1866.                       check_messageid(1, id);
  1867.                       break;
  1868.                     case 2:
  1869.                       log_it(1, "\n ■ Unable to delete message %d from host!", i1);
  1870.                       exit(EXIT_FAILURE);
  1871.                   }
  1872.                   break;
  1873.                 case 5:
  1874.                   if ((!ALLMAIL) && (!fdl))
  1875.                     log_it(1, "\n ■ Non-network message %d left on server.", i1);
  1876.                   else {
  1877.                     i = 0;
  1878.                     sprintf(temp, "%sSPM-%03d.MSG", argv[2], i);
  1879.                     while (exist(temp))
  1880.                       sprintf(temp, "%sSPM-%03d.MSG", argv[2], ++i);
  1881.                     fnsplit(temp, NULL, NULL, s, s1);
  1882.                     log_it(1, "\n ■ RCV : %3.3d : %-20.20s : %s%s", i1, "matched NOSPAM.TXT", s, s1);
  1883.                     result = (pop_get_nextf(pop_sock, temp, i1, usernum));
  1884.                     switch (result) {
  1885.                       case 0:
  1886.                         log_it(1, "\n ■ Unable to retrieve message %d.", i1);
  1887.                         fcloseall();
  1888.                         exit(EXIT_FAILURE);
  1889.                       case 1:
  1890.                         check_messageid(1, id);
  1891.                         break;
  1892.                       case 2:
  1893.                         log_it(1, "\n ■ Unable to delete message %d from host!", i1);
  1894.                         exit(EXIT_FAILURE);
  1895.                     }
  1896.                   }
  1897.                   break;
  1898.                 case 6:
  1899.                   if ((!ALLMAIL) && (!fdl))
  1900.                     log_it(1, "\n ■ Non-network message %d left on server.", i1);
  1901.                   else {
  1902.                     i = 0;
  1903.                     sprintf(temp, "%sSUB-%03d.MSG", argv[2], i);
  1904.                     while (exist(temp))
  1905.                       sprintf(temp, "%sSUB-%03d.MSG", argv[2], ++i);
  1906.                     fnsplit(temp, NULL, NULL, s, s1);
  1907.                     log_it(1, "\n ■ RCV : %3.3d : %-20.20s : %s%s", i1, "subscribe request", s, s1);
  1908.                     result = (pop_get_nextf(pop_sock, temp, i1, usernum));
  1909.                     switch (result) {
  1910.                       case 0:
  1911.                         log_it(1, "\n ■ Unable to retrieve message %d.", i1);
  1912.                         fcloseall();
  1913.                         exit(EXIT_FAILURE);
  1914.                       case 1:
  1915.                         check_messageid(1, id);
  1916.                         break;
  1917.                       case 2:
  1918.                         log_it(1, "\n ■ Unable to delete message %d from host!", i1);
  1919.                         exit(EXIT_FAILURE);
  1920.                     }
  1921.                   }
  1922.                   break;
  1923.                 case 7:
  1924.                   if ((!ALLMAIL) && (!fdl))
  1925.                     log_it(1, "\n ■ Duplicate message %d left on server.", i1);
  1926.                   else {
  1927.                     i = 0;
  1928.                     sprintf(temp, "%sDUP-%03d.MSG", argv[2], i);
  1929.                     while (exist(temp))
  1930.                       sprintf(temp, "%sDUP-%03d.MSG", argv[2], ++i);
  1931.                     fnsplit(temp, NULL, NULL, s, s1);
  1932.                     log_it(1, "\n ■ RCV : %3.3d : %-20.20s : %s%s", i1, "duplicate message", s, s1);
  1933.                     result = (pop_get_nextf(pop_sock, temp, i1, usernum));
  1934.                     switch (result) {
  1935.                       case 0:
  1936.                         log_it(1, "\n ■ Unable to retrieve message %d.", i1);
  1937.                         fcloseall();
  1938.                         exit(EXIT_FAILURE);
  1939.                       case 1:
  1940.                         break;
  1941.                       case 2:
  1942.                         log_it(1, "\n ■ Unable to delete message %d from host!", i1);
  1943.                         exit(EXIT_FAILURE);
  1944.                     }
  1945.                   }
  1946.                   break;
  1947.                 case 8:
  1948.                   i = 0;
  1949.                   sprintf(temp, "%sFIW-%03d.MSG", argv[2], i);
  1950.                   while (exist(temp))
  1951.                     sprintf(temp, "%sFIW-%03d.MSG", argv[2], ++i);
  1952.                   fnsplit(temp, NULL, NULL, s, s1);
  1953.                   log_it(1, "\n ■ RCV : %3.3d : %-20.20s : %s%s", i1, pktowner[0] == 0 ?
  1954.                          "non-network packet" : pktowner, s, s1);
  1955.                   result = (pop_get_nextf(pop_sock, temp, i1, usernum));
  1956.                   switch (result) {
  1957.                     case 0:
  1958.                       log_it(1, "\n ■ Unable to retrieve message %d.", i1);
  1959.                       fcloseall();
  1960.                       exit(EXIT_FAILURE);
  1961.                     case 1:
  1962.                       break;
  1963.                     case 2:
  1964.                       log_it(1, "\n ■ Unable to delete message %d from host!", i1);
  1965.                       exit(EXIT_FAILURE);
  1966.                   }
  1967.                   break;
  1968.               }
  1969.               i1++;
  1970.               fcloseall();
  1971.             }
  1972.             if (compact_ids) {
  1973.               log_it(1, "\n ■ Compacting Message-ID database...");
  1974.               compact_msgid();
  1975.               compact_ids = 0;
  1976.             }
  1977.           } else
  1978.             log_it(1, "\n ■ Unknown POP access error - try again later.");
  1979.           pop_shutdown(pop_sock);
  1980.         } else {
  1981.           log_it(1, "\n ■ Unable to log into POP server!");
  1982.           pop_shutdown(pop_sock);
  1983.         }
  1984.       } else
  1985.         log_it(1, "\n ■ POP socket connect failed.");
  1986.       if ((checknode) && (once)) {
  1987.         strcpy(pophost, "filenet.ml.org");
  1988.         strcpy(popname, nodename);
  1989.         strcpy(poppass, nodepass);
  1990.         ALLMAIL = 1;
  1991.         once = 0;
  1992.       } else {
  1993.         if (!accts) {
  1994.           num_accts = count_accts(0);
  1995.           log_it(DEBUG, "\n - Found %d extra account%s.", num_accts, num_accts == 1 ? "" : "s");
  1996.           if (num_accts) {
  1997.             acct = (ACCT *) farmalloc(sizeof(ACCT) * num_accts);
  1998.             if (acct != NULL) {
  1999.               num_accts = count_accts(1);
  2000.             } else {
  2001.               log_it(DEBUG, "\n ! Insufficient memory for extra accounts.");
  2002.               num_accts = 0;
  2003.             }
  2004.             accts = 1;
  2005.           }
  2006.         }
  2007.         if (num_accts) {
  2008.           strcpy(pophost, acct[num_accts - 1].pophost);
  2009.           strcpy(popname, acct[num_accts - 1].popname);
  2010.           strcpy(poppass, acct[num_accts - 1].poppass);
  2011.           ALLMAIL = 1;
  2012.           usernum = find_acct(popname, pophost, poppass);
  2013.           --num_accts;
  2014.         } else
  2015.           num_accts = -1;
  2016.       }
  2017.     }
  2018.     if (acct != NULL) {
  2019.       farfree((void *)acct);
  2020.       acct = NULL;
  2021.     }
  2022.     exit(EXIT_SUCCESS);
  2023.   }
  2024.   exit(EXIT_FAILURE);
  2025. }
  2026.