home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / PPPBCKP / SRC / SRC15B51.ZIP / POP.CPP < prev    next >
Text File  |  1997-10-18  |  35KB  |  1,160 lines

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