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