home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / PPPBCKP / SRC / SRC15B55.ZIP / POP.CPP < prev    next >
Text File  |  1997-10-24  |  35KB  |  1,164 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 <alloc.h>
  15. #include <dir.h>
  16. extern "C" {
  17.   #include "tcp.h"
  18. }
  19. #include "version.h"
  20. #include "retcode.h"
  21.  
  22. #define POP_PORT 110
  23.  
  24. #define SMTP_PORT 25
  25.  
  26. #define SMTP_STATUS   211
  27. #define SMTP_HELP     214
  28. #define SMTP_READY    220
  29. #define SMTP_BYE      221
  30. #define SMTP_OK       250
  31. #define SMTP_WILL_FWD 251
  32.  
  33. #define SMTP_GIMME    354
  34.  
  35. #define SMTP_OOPS     421
  36. #define SMTP_BUSY     450
  37. #define SMTP_ERROR    451
  38. #define SMTP_SQUEEZED 452
  39.  
  40. #define SMTP_SYNTAX   500
  41. #define SMTP_PARAM    501
  42. #define SMTP_COM_NI   502
  43. #define SMTP_BAD_SEQ  503
  44. #define SMTP_BAD_PARM 504
  45. #define SMTP_ACCESS   550
  46. #define SMTP_YOU_FWD  551
  47. #define SMTP_FULL     552
  48. #define SMTP_BAD_NAM  553
  49. #define SMTP_FAILED   554
  50.  
  51.  
  52. #define POP_OK               200
  53. #define POP_NOT_MSG          400
  54. #define POP_BAD_HOST         500
  55. #define POP_HOST_UNAVAILABLE 501
  56. #define POP_BAD_MBOX         510
  57. #define POP_BAD_PASS         511
  58. #define POP_UNKNOWN          599
  59.  
  60.  
  61. #define POPLIB_OK        200
  62. #define POPLIB_BAD_FILE  401
  63. #define POPLIB_BAD_HOST  510
  64. #define POPLIB_S_TIMEOU  510
  65. #define POPLIB_S_CLOSED  511
  66. #define POPLIB_SMTP_ERR  520
  67. #define POPLIB_POP_ERR   521
  68. #define POPLIB_SMTP_PROB 410
  69. #define POPLIB_POP_PROB  411
  70.  
  71. typedef struct {
  72.     tcp_Socket    *sock;
  73. } Mail_Socket;
  74.  
  75. #define _TEMP_BUFFER_LEN 513
  76.  
  77. #define SHARE_LEVEL 10
  78. #define WAIT_TIME 10
  79. #define TRIES 100
  80.  
  81. #define MT_DESQVIEW 0x01
  82. #define MT_WINDOWS  0x02
  83. #define MT_OS2      0x04
  84. #define MT_NB       0x40
  85.  
  86.  
  87. #define free_Mail_Socket(SOCK) if (SOCK != NULL) {                              \
  88.   farfree(SOCK->sock); farfree(SOCK); SOCK=NULL; }
  89.  
  90. extern unsigned _stklen = 6000U;
  91.  
  92. int POP_Err_Cond, SMTP_Err_Cond;
  93. char from_user[41], POPHOST[81];
  94. int WatTCP_initialized = 0;
  95. static char _temp_buffer[_TEMP_BUFFER_LEN];
  96. int POP_stat, SMTP_stat, fdl;
  97. int multitasker = 0, DEBUG = 1, ALLMAIL;
  98.  
  99. char *version = "Freeware PPP Project POP/SMTP Client " VERSION;
  100.  
  101. char pktowner[26];
  102.  
  103. #define SOCK_READ_ERR(PROTOCOL, ACTION)                                         \
  104.   sock_err:                                                                     \
  105.     switch (PROTOCOL##_stat) {                                                  \
  106.       case 1 :                                                                  \
  107.         PROTOCOL##_Err_Cond = PROTOCOL##_OK;                                    \
  108.         if (DEBUG) output(#PROTOCOL"> Session error : %s",                      \
  109.             sockerr(PROTOCOL##_sock->sock));                                    \
  110.         ACTION;                                                                 \
  111.         return 0;                                                               \
  112.       case -1:                                                                  \
  113.         PROTOCOL##_Err_Cond = PROTOCOL##_OK;                                    \
  114.         if (DEBUG) output(#PROTOCOL"> Timeout : %s",                            \
  115.                 sockerr(PROTOCOL##_sock->sock));                                \
  116.         ACTION;                                                                 \
  117.         return 0;                                                               \
  118.     }
  119.  
  120. #define SOCK_GETS(PROTOCOL)                                                     \
  121.   sock_wait_input(PROTOCOL##_sock->sock, sock_delay, NULL, &PROTOCOL##_stat);   \
  122.   sock_gets(PROTOCOL##_sock->sock, _temp_buffer, sizeof(_temp_buffer));         \
  123.   if (DEBUG) fprintf(stderr, #PROTOCOL"> %s\n", _temp_buffer);                  \
  124.   PROTOCOL##_Err_Cond = atoi(_temp_buffer);                                     \
  125.  
  126. #define SMTP_FAIL_ON(NUM, ACTION)                                               \
  127.   if (SMTP_Err_Cond == NUM) {                                                   \
  128.     if (DEBUG) fprintf(stderr, "SMTP Failure> '" #NUM "'\n");                   \
  129.     sock_puts(SMTP_sock->sock, "QUIT");                                         \
  130.     sock_close(SMTP_sock->sock);                                                \
  131.     free_Mail_Socket(SMTP_sock);                                                \
  132.     ACTION;                                                                     \
  133.     return 0;                                                                   \
  134.   }
  135.  
  136. #define SMTP_RESET_ON(NUM, ACTION)                                              \
  137.   if (SMTP_Err_Cond == NUM) {                                                   \
  138.     if (DEBUG) fprintf(stderr, "SMTP Failure> '" #NUM "'\n");                   \
  139.     sock_puts(SMTP_sock->sock, "RSET");                                         \
  140.     sock_wait_input(SMTP_sock->sock, sock_delay, NULL, &SMTP_stat);             \
  141.     sock_gets(SMTP_sock->sock, _temp_buffer, sizeof(_temp_buffer));             \
  142.     ACTION;                                                                     \
  143.     return(0);                                                                  \
  144.   }
  145.  
  146. void output(char *fmt,...)
  147. {
  148.   va_list v;
  149.   char s[255];
  150.  
  151.   va_start(v, fmt);
  152.   vsprintf(s, fmt, v);
  153.   va_end(v);
  154.   fputs(s, stderr);
  155. }
  156.  
  157. int get_dos_version(void)
  158. {
  159.   _AX = 0x3000;
  160.   geninterrupt(0x21);
  161.   if (_AX % 256 >= 10) {
  162.     multitasker |= MT_OS2;
  163.   }
  164.   return (_AX);
  165. }
  166.  
  167. int get_dv_version(void)
  168. {
  169.   int v;
  170.  
  171.   if (multitasker & MT_OS2)
  172.     return 0;
  173.   _AX = 0x2b01;
  174.   _CX = 0x4445;
  175.   _DX = 0x5351;
  176.   geninterrupt(0x21);
  177.   if (_AL == 0xff) {
  178.     return 0;
  179.   } else {
  180.     v = _BX;
  181.     multitasker |= MT_DESQVIEW;
  182.     return v;
  183.   }
  184. }
  185.  
  186. int get_win_version(void)
  187. {
  188.   int v = 0;
  189.  
  190.   __emit__(0x55, 0x06, 0x53);
  191.   _AX = 0x352f;
  192.   geninterrupt(0x21);
  193.   _AX = _ES;
  194.   if (_AX | _BX) {
  195.     _AX = 0x1600;
  196.     geninterrupt(0x2f);
  197.     v = _AX;
  198.     if (v % 256 <= 1)
  199.       v = 0;
  200.   }
  201.   __emit__(0x5b, 0x07, 0x5d);
  202.   if (v != 0)
  203.     multitasker |= MT_WINDOWS;
  204.   return (v);
  205. }
  206.  
  207. int get_nb_version(void)
  208. {
  209.   _AX = 0;
  210.   geninterrupt(0x2A);
  211.   return (_AH);
  212. }
  213.  
  214. void detect_multitask(void)
  215. {
  216.   get_dos_version();
  217.   get_win_version();
  218.   get_dv_version();
  219.   if (multitasker < 2)
  220.     if (get_nb_version())
  221.       multitasker = MT_NB;
  222. }
  223.  
  224. unsigned char *trim(char *str)
  225. {
  226.   int i;
  227.  
  228.   if (str == NULL)
  229.     return (str);
  230.   for (i = strlen(str) - 1; (i >= 0) && isspace(str[i]); str[i--] = '\0');
  231.   while (isspace(str[0]))
  232.     strcpy(str, str + 1);
  233.   return (str);
  234. }
  235.  
  236. unsigned char *strrep(char *str, char old, char New)
  237. {
  238.   int i;
  239.  
  240.   for (i = 0; str[i]; i++)
  241.     if (str[i] == old)
  242.       str[i] = New;
  243.   return (str);
  244. }
  245.  
  246. int getnumbers(unsigned char *ascii, unsigned int *d1, unsigned long *d2)
  247. {
  248.   char *p;
  249.  
  250.   /* it must return a number after the white space */
  251.   if ((p = (char *) strchr((char *) ascii, ' ')) == NULL)
  252.     return 0;
  253.   /* skip space */
  254.   while (*p == ' ')
  255.     p++;
  256.   *d1 = atoi(p);
  257.   if ((p = (char *) strchr(p, ' ')) == NULL)
  258.     return 1;
  259.   /* skip space */
  260.   while (*p == ' ')
  261.     p++;
  262.   *d2 = atol(p);
  263.   return 2;
  264. }
  265.  
  266. char *fix_quoted_commas(char *string)
  267. {
  268.   char *ptr;
  269.   int quoted = 0;
  270.  
  271.   ptr = string;
  272.   if (ptr) {
  273.     while (*ptr != 0) {
  274.       if (*ptr == '\"')
  275.         quoted = (!quoted);
  276.       if (*ptr == ',' && quoted)
  277.         *ptr = '│';
  278.       ptr = &ptr[1];
  279.     }
  280.   }
  281.   return (string);
  282. }
  283.  
  284. long sh_lseek(int handle, long offset, int fromwhere)
  285. {
  286.   if (handle == -1) {
  287.     return (-1L);
  288.   }
  289.   return (lseek(handle, offset, fromwhere));
  290. }
  291.  
  292. FILE *fsh_open(char *path, char *fmode)
  293. {
  294.   FILE *f;
  295.   int count, share, md, fd;
  296.   char drive[MAXDRIVE], dir[MAXDIR], file[MAXFILE], ext[MAXEXT];
  297.  
  298.   share = SH_DENYWR;
  299.   md = 0;
  300.   if (((char *) strchr(fmode, 'w')) != NULL) {
  301.     share = SH_DENYRD;
  302.     md = O_RDWR | O_CREAT | O_TRUNC;
  303.   } else
  304.     if (((char *) strchr(fmode, 'a')) != NULL) {
  305.     share = SH_DENYRD;
  306.     md = O_RDWR | O_CREAT;
  307.   } else {
  308.     md = O_RDONLY;
  309.   }
  310.   if (((char *) strchr(fmode, 'b')) != NULL) {
  311.     md |= O_BINARY;
  312.   }
  313.   if (((char *) strchr(fmode, '+')) != NULL) {
  314.     md &= ~O_RDONLY;
  315.     md |= O_RDWR;
  316.     share = SH_DENYRD;
  317.   }
  318.   fd = open(path, md | share, S_IREAD | S_IWRITE);
  319.   if (fd < 0) {
  320.     count = 1;
  321.     fnsplit(path, drive, dir, file, ext);
  322.     if ((access(path, 0)) != -1) {
  323.       delay(WAIT_TIME);
  324.       fd = open(path, md | share, S_IREAD | S_IWRITE);
  325.       while (((fd < 0) && (errno == EACCES)) && (count < TRIES)) {
  326.         delay(WAIT_TIME);
  327.         count++;
  328.         fd = open(path, md | share, S_IREAD | S_IWRITE);
  329.       }
  330.     }
  331.   }
  332.   if (fd > 0) {
  333.     if (((char *) strchr(fmode, 'a')) != NULL)
  334.       sh_lseek(fd, 0L, SEEK_END);
  335.     f = fdopen(fd, fmode);
  336.     if (!f) {
  337.       close(fd);
  338.     }
  339.   } else
  340.     f = 0;
  341.   return (f);
  342. }
  343.  
  344. Mail_Socket *smtp_start(char *host, char *dom)
  345. {
  346.   longword h;
  347.   Mail_Socket *SMTP_sock = NULL;
  348.  
  349.   if (!WatTCP_initialized) {
  350.     sock_init();
  351.     WatTCP_initialized = 1;
  352.   }
  353.   if (!(h = resolve(host))) {
  354.     if (!(h = resolve(host))) {
  355.       SMTP_Err_Cond = SMTP_FAILED;
  356.       output("\n ■ Error : Cannot resolve host %s", host);
  357.       return NULL;
  358.     }
  359.   }
  360.   if ((SMTP_sock = (Mail_Socket *) farmalloc(sizeof(Mail_Socket))) == NULL) {
  361.     output("\n ■ Insufficient memory to create socket... aborting");
  362.     exit(EXIT_FAILURE);
  363.   }
  364.   if ((SMTP_sock->sock = (tcp_Socket *) farmalloc(sizeof(tcp_Socket))) == NULL) {
  365.     output("\n ■ Insufficient memory to create socket... aborting");
  366.     farfree(SMTP_sock);
  367.     exit(EXIT_FAILURE);
  368.   }
  369.   if (!tcp_open(SMTP_sock->sock, 0, h, SMTP_PORT, NULL)) {
  370.     SMTP_Err_Cond = SMTP_FAILED;
  371.     output("\n ■ Error : Unable to connect to %s", host);
  372.     farfree(SMTP_sock);
  373.     return NULL;
  374.   }
  375.   sock_mode(SMTP_sock->sock, TCP_MODE_ASCII);
  376.   sock_wait_established(SMTP_sock->sock, sock_delay, NULL, &SMTP_stat);
  377.   while (sock_tbused(SMTP_sock->sock) > 0) {
  378.     SOCK_GETS(SMTP);
  379.     SMTP_FAIL_ON(SMTP_OOPS,);
  380.   }
  381.   sock_printf(SMTP_sock->sock, "HELO %s", dom);
  382.   sock_wait_input(SMTP_sock->sock, sock_delay, NULL, &SMTP_stat);
  383.   while (sock_tbused(SMTP_sock->sock) > 0) {
  384.     SOCK_GETS(SMTP);
  385.     SMTP_FAIL_ON(SMTP_OOPS,);
  386.     SMTP_FAIL_ON(SMTP_SYNTAX,);
  387.     SMTP_FAIL_ON(SMTP_PARAM,);
  388.     SMTP_FAIL_ON(SMTP_BAD_PARM,);
  389.   }
  390.   SOCK_READ_ERR(SMTP,);
  391.   return (SMTP_sock);
  392. }
  393.  
  394. char *smtp_parse_from_line(FILE * f)
  395. {
  396.   int found = 0, done = 0;
  397.  
  398.   rewind(f);
  399.   while (!feof(f) && !done) {
  400.     fgets(_temp_buffer, sizeof(_temp_buffer), f);
  401.     if (*_temp_buffer == '\n')
  402.       done = 1;
  403.     else
  404.       if (strncmpi(_temp_buffer, "from:", 5) == 0 &&
  405.           strchr(_temp_buffer, '@') != 0)
  406.       found = 1, done = 1;
  407.   }
  408.   if (found)
  409.     return (trim(strdup(&_temp_buffer[5])));
  410.   return 0;
  411. }
  412.  
  413. char **smtp_parse_to_line(FILE * f)
  414. {
  415.   int done = 0, current = 0;
  416.   char **list = NULL;
  417.   char *addr;
  418.  
  419.   rewind(f);
  420.   while (!feof(f) && !done) {
  421.     fgets(_temp_buffer, sizeof(_temp_buffer), f);
  422.     if (*_temp_buffer == '\n')
  423.       done = 1;
  424.     else if ((strncmpi(_temp_buffer, "to:", 3) == 0) ||
  425.           (strncmpi(_temp_buffer, "cc:", 3) == 0) ||
  426.           (strncmpi(_temp_buffer, "bcc:", 4) == 0)) {
  427.       fix_quoted_commas(_temp_buffer);
  428.       addr = strtok(_temp_buffer, ":");
  429.       while ((addr = strtok(NULL, ",\n")) != NULL) {
  430.         strrep(addr, '│', ',');
  431.         list = (char **) realloc(list, sizeof(char *) * ((current) + 2));
  432.         list[current] = strdup(addr);
  433.         list[current + 1] = NULL;
  434.         current++;
  435.       }
  436.     }
  437.   }
  438.   return (list);
  439. }
  440.  
  441. int smtp_send_MAIL_FROM_line(Mail_Socket * SMTP_sock, FILE * f)
  442. {
  443.   char *from;
  444.  
  445.   from = smtp_parse_from_line(f);
  446.   if (from) {
  447.     if (DEBUG)
  448.       output("\nSMTP> Mail From:<%s>\n", from);
  449.     sock_printf(SMTP_sock->sock, "MAIL FROM:<%s>", from);
  450.     free(from);
  451.     while (sock_tbused(SMTP_sock->sock) > 0) {
  452.       SOCK_GETS(SMTP);
  453.       SMTP_FAIL_ON(SMTP_OOPS,);
  454.     }
  455.   }
  456.   SOCK_READ_ERR(SMTP,);
  457.   return 1;
  458. }
  459.  
  460. unsigned char *trimstr1(unsigned char *s)
  461. {
  462.   int i;
  463.   static char *whitespace = " \r\n\t";
  464.  
  465.   i = strlen(s);
  466.   while ((i > 0) && (strchr(whitespace, s[i - 1])))
  467.     --i;
  468.   while ((i > 0) && (strchr(whitespace, *s))) {
  469.     memmove(s, s + 1, --i);
  470.   }
  471.   s[i] = 0;
  472.   return (s);
  473. }
  474.  
  475. #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);
  476.  
  477. int smtp_send_RCPT_TO_line(Mail_Socket * SMTP_sock, FILE * f)
  478. {
  479.   char **to_list, address[201];
  480.   int i;
  481.  
  482.   to_list = smtp_parse_to_line(f);
  483.   for (i = 0; to_list[i] != NULL; i++) {
  484.     strcpy(address, to_list[i]);
  485.     trimstr1(address);
  486.     if (DEBUG) {
  487.       output("SMTP> Rcpt To:<%s>\n", address);
  488.     }
  489.     sock_printf(SMTP_sock->sock, "RCPT TO:<%s>", address);
  490.     while (sock_tbused(SMTP_sock->sock) > 0) {
  491.       SOCK_GETS(SMTP);
  492.       SMTP_FAIL_ON(SMTP_OOPS, FREE_ALL);
  493.       SMTP_RESET_ON(SMTP_SYNTAX, FREE_ALL);
  494.       SMTP_RESET_ON(SMTP_PARAM, FREE_ALL);
  495.       SMTP_RESET_ON(SMTP_BAD_SEQ, FREE_ALL);
  496.     }
  497.   }
  498.   SOCK_READ_ERR(SMTP, FREE_ALL);
  499.   FREE_ALL;
  500.   return 1;
  501. }
  502.  
  503. void go_back(int from, int to)
  504. {
  505.   int i;
  506.  
  507.   for (i = from; i > to; i--)
  508.     output("\b \b");
  509. }
  510.  
  511.  
  512. #undef FREE_ALL
  513.  
  514. int smtp_sendf(Mail_Socket * SMTP_sock, FILE * f)
  515. {
  516.   int in_header = 1, in_bcc = 0, pos;
  517.   long nbytes, obytes, rbytes;
  518.   char *temp, ch;
  519.  
  520.   if (smtp_send_MAIL_FROM_line(SMTP_sock, f) == 0)
  521.     return 0;
  522.   if (smtp_send_RCPT_TO_line(SMTP_sock, f) == 0)
  523.     return 0;
  524.   fseek(f, 0L, SEEK_END);
  525.   obytes = ftell(f);
  526.   rewind(f);
  527.   sock_puts(SMTP_sock->sock, "DATA");
  528.   sock_wait_input(SMTP_sock->sock, sock_delay, NULL, &SMTP_stat);
  529.   while (sock_tbused(SMTP_sock->sock) > 0) {
  530.     SOCK_GETS(SMTP);
  531.     if (DEBUG)
  532.       output("\nSMTP> %s", _temp_buffer);
  533.     SMTP_FAIL_ON(SMTP_OOPS,);
  534.     SMTP_RESET_ON(SMTP_BAD_SEQ,);
  535.     SMTP_RESET_ON(SMTP_SYNTAX,);
  536.     SMTP_RESET_ON(SMTP_PARAM,);
  537.     SMTP_RESET_ON(SMTP_COM_NI,);
  538.     SMTP_RESET_ON(SMTP_FAILED,);
  539.     SMTP_RESET_ON(SMTP_ERROR,);
  540.   }
  541.   nbytes = 0L;
  542.   rbytes = 1024L;
  543.   output(" : ");
  544.   pos = wherex();
  545.   while (!feof(f)) {
  546.     fgets(_temp_buffer, sizeof(_temp_buffer), f);
  547.     strrep(_temp_buffer, '\n', '\0');
  548.     strrep(_temp_buffer, '\r', '\0');
  549.     temp = trim(strdup(_temp_buffer));
  550.     if (strlen(temp) == 0)
  551.       in_header = 0;
  552.     if (temp)
  553.       free(temp);
  554.     if (in_header && !in_bcc && strncmpi(_temp_buffer, "bcc:", 4) == 0) {
  555.       in_bcc = 1;
  556.       continue;
  557.     }
  558.     if (in_bcc)
  559.       in_bcc = isspace(*_temp_buffer);
  560.     if (in_bcc)
  561.       continue;
  562.     if (*_temp_buffer == '.') {
  563.       movmem(_temp_buffer, _temp_buffer + 1, sizeof(_temp_buffer) - 1);
  564.       *_temp_buffer = '.';
  565.       if (DEBUG)
  566.         output("\nSMTP> %s", _temp_buffer);
  567.     }
  568.     nbytes += sock_puts(SMTP_sock->sock, _temp_buffer);
  569.     tcp_tick(NULL);
  570.     nbytes += 2;
  571.     if (nbytes > rbytes) {
  572.       go_back(wherex(), pos);
  573.       output("%ld/%ld", nbytes, obytes);
  574.       rbytes += 512L;
  575.     }
  576.     while (kbhit()) {
  577.       ch = (getch());
  578.       switch (ch) {
  579.         case 27:
  580.         case 32:
  581.           go_back(wherex(), pos);
  582.           return -1;
  583.         default:
  584.           break;
  585.       }
  586.     }
  587.   }
  588.   sock_puts(SMTP_sock->sock, ".");
  589.   sock_wait_input(SMTP_sock->sock, sock_delay, NULL, &SMTP_stat);
  590.   while (sock_tbused(SMTP_sock->sock) > 0) {
  591.     SOCK_GETS(SMTP);
  592.     SMTP_FAIL_ON(SMTP_OOPS,);
  593.     SMTP_RESET_ON(SMTP_ERROR,);
  594.     SMTP_RESET_ON(SMTP_SQUEEZED,);
  595.     SMTP_RESET_ON(SMTP_FULL,);
  596.     SMTP_RESET_ON(SMTP_FAILED,);
  597.   }
  598.  
  599.   go_back(wherex(), pos);
  600.  
  601.   SOCK_READ_ERR(SMTP,);
  602.  
  603.   return 1;
  604. }
  605.  
  606. void smtp_shutdown(Mail_Socket * SMTP_sock, int cause)
  607. {
  608.   fcloseall();
  609.   sock_puts(SMTP_sock->sock, "QUIT");
  610.   sock_close(SMTP_sock->sock);
  611.   exit(cause);
  612. }
  613.  
  614.  
  615. Mail_Socket *pop_init(char *host)
  616. {
  617.   longword h;
  618.   Mail_Socket *POP_sock = NULL;
  619.  
  620.   if (!WatTCP_initialized) {
  621.     sock_init();
  622.     WatTCP_initialized = 1;
  623.   }
  624.   if (!(h = resolve(host))) {
  625.     if (!(h = resolve(host))) {
  626.       POP_Err_Cond = POP_BAD_HOST;
  627.       output("\n ■ Error : Cannot resolve host %s", host);
  628.       return NULL;
  629.     }
  630.   }
  631.   if ((POP_sock = (Mail_Socket *) farmalloc(sizeof(Mail_Socket))) == NULL) {
  632.     output("\n ■ Insufficient memory to create socket... aborting.");
  633.     exit(EXIT_FAILURE);
  634.   }
  635.   if ((POP_sock->sock = (tcp_Socket *) farmalloc(sizeof(tcp_Socket))) == NULL) {
  636.     output("\n ■ Insufficient memory to create socket... aborting.");
  637.     farfree(POP_sock);
  638.     exit(EXIT_FAILURE);
  639.   }
  640.   if (!tcp_open(POP_sock->sock, 0, h, POP_PORT, NULL)) {
  641.     POP_Err_Cond = POP_BAD_HOST;
  642.     output("\n ■ Error : Unable to connect to host %s", host);
  643.     return NULL;
  644.   }
  645.   sock_mode(POP_sock->sock, TCP_MODE_ASCII);
  646.   sock_wait_established(POP_sock->sock, sock_delay, NULL, &POP_stat);
  647.   sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  648.   sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  649.   if (DEBUG)
  650.     output("\nPOP> %s", _temp_buffer);
  651.   if (*_temp_buffer != '+') {
  652.     POP_Err_Cond = POP_HOST_UNAVAILABLE;
  653.     output("\n ■ Error : Host %s is unavailable.", host);
  654.     return NULL;
  655.   } else {
  656.     POP_Err_Cond = POP_OK;
  657.     output("connection accepted.");
  658.     return (POP_sock);
  659.   }
  660.   SOCK_READ_ERR(POP,);
  661.   return (POP_sock);
  662. }
  663.  
  664. int pop_login(Mail_Socket * POP_sock, char *userid, char *password)
  665. {
  666.   sprintf(_temp_buffer, "USER %s", userid);
  667.   sock_puts(POP_sock->sock, _temp_buffer);
  668.   sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  669.   sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  670.   if (DEBUG)
  671.     output("\nPOP> %s", _temp_buffer);
  672.   if (*_temp_buffer != '+') {
  673.     POP_Err_Cond = POP_BAD_MBOX;
  674.     output("\n ■ Error : host report mailbox %s does not exist", userid);
  675.     if (POP_sock->sock) {
  676.       sock_puts(POP_sock->sock, "QUIT");
  677.       sock_close(POP_sock->sock);
  678.     }
  679.     return 0;
  680.   }
  681.   sprintf(_temp_buffer, "PASS %s", password);
  682.   sock_puts(POP_sock->sock, _temp_buffer);
  683.   sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  684.   sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  685.   if (DEBUG)
  686.     output("\nPOP> %s", _temp_buffer);
  687.   if (*_temp_buffer != '+') {
  688.     POP_Err_Cond = POP_BAD_PASS;
  689.     output("\n ■ Error : Host reports password incorrect or account locked.");
  690.     if (POP_sock->sock) {
  691.       sock_puts(POP_sock->sock, "QUIT");
  692.       sock_close(POP_sock->sock);
  693.     }
  694.     return 0;
  695.   }
  696.   output(" \n ■ Logged in to account %s... ", userid);
  697.   SOCK_READ_ERR(POP,);
  698.   return 1;
  699. }
  700.  
  701. int pop_status(Mail_Socket * POP_sock, unsigned int *count, unsigned long *totallength)
  702. {
  703.   sock_puts(POP_sock->sock, "STAT");
  704.   sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  705.   sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  706.   if (DEBUG)
  707.     output("\nPOP> %s", _temp_buffer);
  708.   if ((*_temp_buffer != '+') ||
  709.       (getnumbers(_temp_buffer, count, totallength) < 2)) {
  710.     POP_Err_Cond = POP_UNKNOWN;
  711.     if (DEBUG)
  712.       output("\n ■ Error : Unknown POP error.");
  713.     return 0;
  714.   } else if (DEBUG)
  715.     output("\n ■ Received POP account status.");
  716.   SOCK_READ_ERR(POP,);
  717.   return 1;
  718. }
  719.  
  720. long pop_length(Mail_Socket * POP_sock, unsigned int msg_num, unsigned long *size)
  721. {
  722.   unsigned int dummy;
  723.  
  724.   sprintf(_temp_buffer, "LIST %u", msg_num);
  725.   sock_puts(POP_sock->sock, _temp_buffer);
  726.   sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  727.   sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  728.   if (DEBUG)
  729.     output("\nPOP> %s", _temp_buffer);
  730.   if ((*_temp_buffer != '+') ||
  731.       (getnumbers(_temp_buffer, &dummy, size) < 2)) {
  732.     POP_Err_Cond = POP_NOT_MSG;
  733.     if (DEBUG)
  734.       output("\n ■ Error : No message #%u", msg_num);
  735.     return 0;
  736.   }
  737.   SOCK_READ_ERR(POP,);
  738.   if (*size == 0L) {
  739.     output("\n ■ Mailbox contains a zero byte file -- deleting Message #%u!", msg_num);
  740.     sprintf(_temp_buffer, "DELE %u", msg_num);
  741.     sock_puts(POP_sock->sock, _temp_buffer);
  742.     sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  743.     sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  744.     if (DEBUG)
  745.       output("\nPOP> %s", _temp_buffer);
  746.     if (*_temp_buffer != '+') {
  747.       POP_Err_Cond = POP_NOT_MSG;
  748.       output("\n ■ Error : No message #%u", msg_num);
  749.     }
  750.     sock_puts(POP_sock->sock, "QUIT");
  751.     sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  752.     sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  753.     if (*_temp_buffer != '+') {
  754.       POP_Err_Cond = POP_UNKNOWN;
  755.       output("\n ■ Error : Unable to update mailbox.");
  756.     } else
  757.       output("\n ■ Closed and updated mailbox on %s.", POPHOST);
  758.     sock_close(POP_sock->sock);
  759.   }
  760.   return (*size);
  761. }
  762.  
  763. char *stristr(char *String, char *Pattern)
  764. {
  765.   char *pptr, *sptr, *start;
  766.   unsigned int slen, plen;
  767.  
  768.   for (start = String, pptr = Pattern, slen = strlen(String),
  769.        plen = strlen(Pattern); slen >= plen; start++, slen--) {
  770.     while (toupper(*start) != toupper(*Pattern)) {
  771.       start++;
  772.       slen--;
  773.       if (slen < plen)
  774.         return (NULL);
  775.     }
  776.     sptr = start;
  777.     pptr = Pattern;
  778.     while (toupper(*sptr) == toupper(*pptr)) {
  779.       sptr++;
  780.       pptr++;
  781.       if ('\0' == *pptr)
  782.         return (start);
  783.     }
  784.   }
  785.   return (NULL);
  786. }
  787.  
  788. int pop_top(Mail_Socket * POP_sock, unsigned int msg_num)
  789. {
  790.   int okpkt, found_from;
  791.  
  792.   sprintf(_temp_buffer, "TOP %u 40", msg_num);
  793.   sock_puts(POP_sock->sock, _temp_buffer);
  794.   sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  795.   sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  796.   if (DEBUG)
  797.     output("\nPOP> %s", _temp_buffer);
  798.   if (*_temp_buffer != '+') {
  799.     POP_Err_Cond = POP_NOT_MSG;
  800.     output("\n ■ Error : No message #%u.", msg_num);
  801.     return -1;
  802.   }
  803.   okpkt = -1;
  804.   found_from = fdl = 0;
  805.   while (1) {
  806.     sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  807.     sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  808.     if (*_temp_buffer == '.' && _temp_buffer[1] == 0)
  809.       break;
  810.     if ((strnicmp(_temp_buffer, "begin ", 6) == 0) &&
  811.         (stristr(_temp_buffer, "WINMAIL") == NULL)) {
  812.       if (okpkt != 4)
  813.         okpkt = 1;
  814.       if ((stristr(_temp_buffer, ".ZIP") != NULL) ||
  815.           (stristr(_temp_buffer, ".ARJ") != NULL) ||
  816.           (stristr(_temp_buffer, ".LZH") != NULL))
  817.         okpkt = 2;
  818.       if ((stristr(_temp_buffer, ".GIF") != NULL) ||
  819.           (stristr(_temp_buffer, ".JPG") != NULL))
  820.         okpkt = 3;
  821.     }
  822.     if (strnicmp(_temp_buffer, "FDL Type:", 9) == 0)
  823.       fdl = 1;
  824.     if ((strnicmp(_temp_buffer, "from:", 5) == 0) && (!found_from)) {
  825.       if ((stristr(_temp_buffer, "mailer-daemon") != NULL) ||
  826.           (stristr(_temp_buffer, "mail delivery") != NULL) ||
  827.           (stristr(_temp_buffer, "administrator") != NULL) ||
  828.           (stristr(_temp_buffer, from_user) != NULL))
  829.         okpkt = 4;
  830.       else
  831.         strncpy(pktowner, &_temp_buffer[6], 25);
  832.       found_from = 1;
  833.     }
  834.   }
  835.   SOCK_READ_ERR(POP,);
  836.   return okpkt;
  837. }
  838.  
  839. int pop_getf(Mail_Socket * POP_sock, char *fn, unsigned int msg_num)
  840. {
  841.   unsigned long size;
  842.   long nbytes, rbytes;
  843.   int pos, ctld, len;
  844.   FILE *fp;
  845.  
  846.   if (!pop_length(POP_sock, msg_num, &size))
  847.     return 0;
  848.   sprintf(_temp_buffer, "RETR %u", msg_num);
  849.   sock_puts(POP_sock->sock, _temp_buffer);
  850.   sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  851.   sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  852.   if (DEBUG)
  853.     output("\nPOP> %s", _temp_buffer);
  854.   if (*_temp_buffer != '+') {
  855.     POP_Err_Cond = POP_NOT_MSG;
  856.     output("\n ■ Error : No message #%u", msg_num);
  857.     return 0;
  858.   }
  859.   nbytes = 0L;
  860.   rbytes = 1024L;
  861.   output(" : ");
  862.   pos = wherex();
  863.   if ((fp = fsh_open(fn, "w")) == NULL) {
  864.     output("\n ■ Unable to create %s... aborting!", fn);
  865.     return 0;
  866.   }
  867.   ctld = 1;
  868.   while (1) {
  869.     sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  870.     len = (sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer)));
  871.     tcp_tick(NULL);
  872.     if ((ctld == 1) && (len == 0))
  873.       ctld = 0;
  874.     if ((strnicmp(_temp_buffer, "begin ", 6) == 0) &&
  875.         (stristr(_temp_buffer, "WINMAIL") != NULL))
  876.       ctld = 2;
  877.     if ((ctld == 2) && (strnicmp(_temp_buffer, "end", 3) == 0))
  878.       ctld = 0;
  879.     if (_temp_buffer[0] == '.' && _temp_buffer[1] == 0)
  880.       break;
  881.     if (EOF == (nbytes += fprintf(fp, "%s%s\n", ctld ? "0R" : "", _temp_buffer))) {
  882.       if (fp != NULL)
  883.         fclose(fp);
  884.       return 0;
  885.     }
  886.     if (nbytes > rbytes) {
  887.       go_back(wherex(), pos);
  888.       output("%ld/%ld", nbytes, size);
  889.       rbytes += 512L;
  890.     }
  891.   }
  892.   if (fp != NULL)
  893.     fclose(fp);
  894.   go_back(wherex(), pos);
  895.   output("message received!");
  896.   SOCK_READ_ERR(POP,);
  897.   return 1;
  898. }
  899.  
  900. int pop_delete(Mail_Socket * POP_sock, unsigned int msg_num)
  901. {
  902.   sprintf(_temp_buffer, "DELE %u", msg_num);
  903.   sock_puts(POP_sock->sock, _temp_buffer);
  904.   sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  905.   sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  906.   if (DEBUG)
  907.     output("\nPOP> %s", _temp_buffer);
  908.   if (*_temp_buffer != '+') {
  909.     POP_Err_Cond = POP_NOT_MSG;
  910.     output("\n ■ Error : No message #%u", msg_num);
  911.     return 2;
  912.   }
  913.   SOCK_READ_ERR(POP,);
  914.   return 1;
  915. }
  916.  
  917.  
  918. int pop_shutdown(Mail_Socket * POP_sock)
  919. {
  920.   if (POP_sock->sock) {
  921.     sock_puts(POP_sock->sock, "QUIT");
  922.     sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
  923.     sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
  924.     if (*_temp_buffer != '+') {
  925.       POP_Err_Cond = POP_UNKNOWN;
  926.       output("\n ■ Error : Unable to update mailbox.");
  927.       return 0;
  928.     } else
  929.       output("\n ■ Closed and updated mailbox on %s.", POPHOST);
  930.     sock_close(POP_sock->sock);
  931.     return 1;
  932.   }
  933. sock_err:
  934.   free_Mail_Socket(POP_sock);
  935.   return 0;
  936. }
  937.  
  938. int pop_get_nextf(Mail_Socket * POP_sock, char *fn, int msgnum)
  939. {
  940.   if (!pop_getf(POP_sock, fn, msgnum))
  941.     return 0;
  942.   return (pop_delete(POP_sock, msgnum));
  943. }
  944.  
  945. int exist(char *s)
  946. {
  947.   int i;
  948.   struct ffblk ff;
  949.  
  950.   i = findfirst(s, &ff, FA_HIDDEN);
  951.   if (i)
  952.     return 0;
  953.   else
  954.     return 1;
  955. }
  956.  
  957. void main(int argc, char *argv[])
  958. {
  959.   unsigned int count;
  960.   unsigned long size;
  961.   int i, i1, okpkt, result;
  962.   char temp[181], s[21], s1[21];
  963.   FILE *fp;
  964.   Mail_Socket *pop_sock = NULL;
  965.   Mail_Socket *smtp_sock = NULL;
  966.  
  967.   detect_multitask();
  968.  
  969.   if (strncmpi(argv[1], "-send", strlen(argv[1])) == 0) {
  970.     if (argc < 5) {
  971.       output("\n ■ %s", version);
  972.       output("\n ■ Invalid arguments for %s\n", argv[0]);
  973.       exit(EXIT_FAILURE);
  974.     }
  975.     output(": %-18.18s : [Space] skips", argv[2]);
  976.     if (argc == 6)
  977.       DEBUG = atoi(argv[5]);
  978.     SMTP_Err_Cond = SMTP_OK;
  979.     if ((smtp_sock = smtp_start(argv[2], argv[3])) != NULL) {
  980.       if ((fp = fsh_open(argv[4], "r")) != NULL) {
  981.         result = (smtp_sendf(smtp_sock, fp));
  982.         switch (result) {
  983.           case 1:
  984.             output("accepted.");
  985.             if (fp != NULL)
  986.               fclose(fp);
  987.             smtp_shutdown(smtp_sock, EXIT_SUCCESS);
  988.             break;
  989.           case 0:
  990.             output(" : SMTP failed.");
  991.             if (fp != NULL)
  992.               fclose(fp);
  993.               exit(EXIT_FAILURE);
  994.           case -1:
  995.             output("SMTP abort.");
  996.             if (fp != NULL)
  997.               fclose(fp);
  998.             smtp_shutdown(smtp_sock, EXIT_FAILURE);
  999.             break;
  1000.         }
  1001.       } else {
  1002.         output("\n ■ Error accessing file %s.", argv[4]);
  1003.         smtp_shutdown(smtp_sock, EXIT_FAILURE);
  1004.       }
  1005.     } else
  1006.       output(" : SMTP failed.");
  1007.   } else if (strncmpi(argv[1], "-receive", strlen(argv[1])) == 0) {
  1008.     if (argc < 8) {
  1009.       output("\n ■ %s", version);
  1010.       output("\n ■ Invalid arguments for %s\n", argv[0]);
  1011.       exit(EXIT_FAILURE);
  1012.     }
  1013.     strcpy(POPHOST, argv[2]);
  1014.     sprintf(from_user, "%s@%s", argv[3], argv[7]);
  1015.     if (argc == 9)
  1016.       DEBUG = atoi(argv[8]);
  1017.     POP_Err_Cond = POP_OK;
  1018.     if ((pop_sock = pop_init(POPHOST)) != NULL) {
  1019.       if (pop_login(pop_sock, argv[3], argv[4])) {
  1020.         if (pop_status(pop_sock, &count, &size)) {
  1021.           okpkt = 0;
  1022.           output("%u message%s (%luK).",
  1023.                  count, count == 1 ? "" : "s", ((size + 1023) / 1024));
  1024.           i1 = 1;
  1025.           ALLMAIL = atoi(argv[6]);
  1026.           while (i1 <= count) {
  1027.             okpkt = 0;
  1028.             okpkt = pop_top(pop_sock, i1);
  1029.             switch (okpkt) {
  1030.               case -1:
  1031.                 if ((!ALLMAIL) && (!fdl))
  1032.                   output("\n ■ Non-network message %d left on server.", i1);
  1033.                 else {
  1034.                   i = 0;
  1035.                   sprintf(temp, "%sUNK-%03d.MSG", argv[5], i);
  1036.                   while (exist(temp))
  1037.                     sprintf(temp, "%sUNK-%03d.MSG", argv[5], ++i);
  1038.                   fnsplit(temp, NULL, NULL, s, s1);
  1039.                   output("\n ■ RCV : %3.3d : %-25s : %s%s", i1, "non-network packet", s, s1);
  1040.                   result = (pop_get_nextf(pop_sock, temp, i1));
  1041.                   switch (result) {
  1042.                     case 0:
  1043.                       output("\n ■ Unable to retrieve message %d.", i1);
  1044.                       fcloseall();
  1045.                       exit(EXIT_FAILURE);
  1046.                     case 1:
  1047.                       break;
  1048.                     case 2:
  1049.                       output("\n ■ Unable to delete message %d from host!", i1);
  1050.                       exit(EXIT_FAILURE);
  1051.                   }
  1052.                 }
  1053.                 break;
  1054.               case 0:
  1055.                 output("\n ■ Error accessing message %d", i1);
  1056.                 fcloseall();
  1057.                 exit(EXIT_FAILURE);
  1058.               case 1:
  1059.                 i = 0;
  1060.                 sprintf(temp, "%sPKT-%03d.UUE", argv[5], i);
  1061.                 while (exist(temp))
  1062.                   sprintf(temp, "%sPKT-%03d.UUE", argv[5], ++i);
  1063.                 fnsplit(temp, NULL, NULL, s, s1);
  1064.                 output("\n ■ RCV : %3.3d : %-25s : %s%s", i1, pktowner, s, s1);
  1065.                 result = (pop_get_nextf(pop_sock, temp, i1));
  1066.                 switch (result) {
  1067.                   case 0:
  1068.                     output("\n ■ Unable to retrieve message %d.", i1);
  1069.                     fcloseall();
  1070.                     exit(EXIT_FAILURE);
  1071.                   case 1:
  1072.                     break;
  1073.                   case 2:
  1074.                     output("\n ■ Unable to delete message %d on host!", i1);
  1075.                     exit(EXIT_FAILURE);
  1076.                 }
  1077.                 break;
  1078.               case 2:
  1079.                 if ((!ALLMAIL) && (!fdl))
  1080.                   output("\n ■ Non-network message %d left on server.", i1);
  1081.                 else {
  1082.                   i = 0;
  1083.                   sprintf(temp, "%sARC-%03d.UUE", argv[5], i);
  1084.                   while (exist(temp))
  1085.                     sprintf(temp, "%sARC-%03d.UUE", argv[5], ++i);
  1086.                   fnsplit(temp, NULL, NULL, s, s1);
  1087.                   output("\n ■ RCV : %3.3d : %-25s : %s%s", i1, "archived file", s, s1);
  1088.                   result = (pop_get_nextf(pop_sock, temp, i1));
  1089.                   switch (result) {
  1090.                     case 0:
  1091.                       output("\n ■ Unable to retrieve message %d.", i1);
  1092.                       fcloseall();
  1093.                       exit(EXIT_FAILURE);
  1094.                     case 1:
  1095.                       break;
  1096.                     case 2:
  1097.                       output("\n ■ Unable to delete message %d on host!", i1);
  1098.                       exit(EXIT_FAILURE);
  1099.                   }
  1100.                 }
  1101.                 break;
  1102.               case 3:
  1103.                 if ((!ALLMAIL) && (!fdl))
  1104.                   output("\n ■ Non-network message %d left on server.", i1);
  1105.                 else {
  1106.                   i = 0;
  1107.                   sprintf(temp, "%sGIF-%03d.UUE", argv[5], i);
  1108.                   while (exist(temp))
  1109.                     sprintf(temp, "%sGIF-%03d.UUE", argv[5], ++i);
  1110.                   fnsplit(temp, NULL, NULL, s, s1);
  1111.                   output("\n ■ RCV : %3.3d : %-25s : %s%s", i1, "graphic/image file", s, s1);
  1112.                   result = (pop_get_nextf(pop_sock, temp, i1));
  1113.                   switch (result) {
  1114.                     case 0:
  1115.                       output("\n ■ Unable to retrieve message %d.", i1);
  1116.                       fcloseall();
  1117.                       exit(EXIT_FAILURE);
  1118.                     case 1:
  1119.                       break;
  1120.                     case 2:
  1121.                       output("\n ■ Unable to delete message %d from host!", i1);
  1122.                       exit(EXIT_FAILURE);
  1123.                   }
  1124.                 }
  1125.                 break;
  1126.               case 4:
  1127.                 i = 0;
  1128.                 sprintf(temp, "%sBAD-%03d.UUE", argv[5], i);
  1129.                 while (exist(temp))
  1130.                   sprintf(temp, "%sBAD-%03d.UUE", argv[5], ++i);
  1131.                 fnsplit(temp, NULL, NULL, s, s1);
  1132.                 output("\n ■ RCV : %3.3d : %-25s : %s%s", i1, "mailer-daemon/bounced", s, s1);
  1133.                 result = (pop_get_nextf(pop_sock, temp, i1));
  1134.                 switch (result) {
  1135.                   case 0:
  1136.                     output("\n ■ Unable to retrieve message %d.", i1);
  1137.                     fcloseall();
  1138.                     exit(EXIT_FAILURE);
  1139.                   case 1:
  1140.                     break;
  1141.                   case 2:
  1142.                     output("\n ■ Unable to delete message %d from host!", i1);
  1143.                     exit(EXIT_FAILURE);
  1144.                 }
  1145.                 break;
  1146.             }
  1147.             i1++;
  1148.             fcloseall();
  1149.           }
  1150.           output("\n ■ Mailbox scan of %d messages completed.", count);
  1151.         } else
  1152.           output("\n ■ Unknown POP access error - try again later.");
  1153.         pop_shutdown(pop_sock);
  1154.         exit(EXIT_SUCCESS);
  1155.       } else {
  1156.         output("\n ■ Unable to log into POP server!");
  1157.         pop_shutdown(pop_sock);
  1158.       }
  1159.     } else
  1160.       output("\n ■ POP socket connect failed.");
  1161.   }
  1162.   exit(EXIT_FAILURE);
  1163. }
  1164.