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