home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.wwiv.com
/
ftp.wwiv.com.zip
/
ftp.wwiv.com
/
pub
/
PPPBCKP
/
SRC15B19.ZIP
/
POP.C
< prev
next >
Wrap
Text File
|
1997-03-29
|
33KB
|
1,030 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <ctype.h>
#include <mem.h>
#include <conio.h>
#include <io.h>
#include <share.h>
#include <errno.h>
#include <malloc.h>
#include <dir.h>
#include "tcp.h"
#include "pop.h"
#define POP_PORT 110
#define SMTP_PORT 25
#define _TEMP_BUFFER_LEN 1024
#define WAIT_TIME 10
#define TRIES 100
#define blankline(LINE) (strspn(LINE, " \n\t\r")==strlen(LINE))
#define free_Mail_Socket(SOCK) if (SOCK!=NULL) { \
free(SOCK->sock); free(SOCK); SOCK=NULL; }
//#define SMTP_POP_DEBUG
#ifdef SMTP_POP_DEBUG
/* ************************************************************************ */
#define SOCK_READ_ERR(PROTOCOL) \
sock_err: \
switch (PROTOCOL##_stat) { \
case 1 : /* foreign host closed */ \
sprintf(PROTOCOL##_Err_Msg, #PROTOCOL " Ok"); \
sprintf(POPLIB_Err_Msg, "Connection reset: %s.", sockerr(PROTOCOL##_sock->sock)); \
fprintf(stderr, #PROTOCOL " > %s\n", POPLIB_Err_Msg); \
case -1: /* timeout */ \
sprintf(PROTOCOL##_Err_Msg, #PROTOCOL " Ok"); \
sprintf(POPLIB_Err_Msg, "Timeout: %s.", sockerr(PROTOCOL##_sock->sock)); \
fprintf(stderr, #PROTOCOL " > %s\n", POPLIB_Err_Msg); \
}
#define SOCK_GETS(PROTOCOL) sock_wait_input( PROTOCOL##_sock->sock, SOCK_DELAY, NULL, &PROTOCOL##_stat ); \
sock_gets( PROTOCOL##_sock->sock, _temp_buffer, sizeof( _temp_buffer )); \
fprintf(stderr, #PROTOCOL"> %s\n", _temp_buffer); \
strncpy(PROTOCOL##_Err_Msg, &_temp_buffer[5], 100);
#define SMTP_FAIL_ON(NUM, SHUTDOWN) if ( SMTP_Err_Cond == NUM ) { \
fprintf(stderr, "SMTP Failure > '" #NUM "'\n"); \
sock_puts( SMTP_sock->sock, "QUIT" ); \
sock_close( SMTP_sock->sock ); \
sock_wait_closed( SMTP_sock->sock, SOCK_DELAY, NULL, &SMTP_stat ); \
free_Mail_Socket(SMTP_sock); \
strncpy(POPLIB_Err_Msg, "SMTP Error -- SMTP Reply '" #NUM "'", 100); \
SHUTDOWN; \
return(0); \
}
#define SMTP_FAIL_IF(COND, SHUTDOWN) if ( COND ) { \
fprintf(stderr, "SMTP Failure > (" #COND ")\n"); \
sock_puts( SMTP_sock->sock, "QUIT" ); \
sock_close( SMTP_sock->sock ); \
sock_wait_closed( SMTP_sock->sock, SOCK_DELAY, NULL, &SMTP_stat ); \
free_Mail_Socket(SMTP_sock); \
strncpy(POPLIB_Err_Msg, "SMTP Error -- Condition (" #COND ")", 100); \
SHUTDOWN; \
return(0); \
}
#define SMTP_RESET_ON(NUM, SHUTDOWN) if ( SMTP_Err_Cond == NUM ) { \
fprintf(stderr, "SMTP Problem > '" #NUM "'\n"); \
sock_puts( SMTP_sock->sock, "RSET" ); \
sock_wait_input( SMTP_sock->sock, SOCK_DELAY, NULL, &SMTP_stat ); \
sock_gets( SMTP_sock->sock, _temp_buffer, sizeof( _temp_buffer )); \
strncpy(POPLIB_Err_Msg, "SMTP Problem -- SMTP Reply '" #NUM "'", 100); \
SHUTDOWN; \
return(0); \
}
#else
/* ************************************************************************ */
#define SOCK_READ_ERR(PROTOCOL) \
sock_err:
#define SOCK_GETS(PROTOCOL) sock_wait_input( PROTOCOL##_sock->sock, SOCK_DELAY, NULL, &PROTOCOL##_stat ); \
sock_gets( PROTOCOL##_sock->sock, _temp_buffer, sizeof( _temp_buffer )); \
strncpy(PROTOCOL##_Err_Msg, &_temp_buffer[5], 100);
#define SMTP_FAIL_ON(NUM, SHUTDOWN) if ( SMTP_Err_Cond == NUM ) { \
sock_puts( SMTP_sock->sock, "QUIT" ); \
sock_close( SMTP_sock->sock ); \
sock_wait_closed( SMTP_sock->sock, SOCK_DELAY, NULL, &SMTP_stat ); \
free_Mail_Socket(SMTP_sock); \
strncpy(POPLIB_Err_Msg, "SMTP Error -- SMTP Reply '" #NUM "'", 100); \
SHUTDOWN; \
return(0); \
}
#define SMTP_FAIL_IF(COND, SHUTDOWN) if ( COND ) { \
sock_puts( SMTP_sock->sock, "QUIT" ); \
sock_close( SMTP_sock->sock ); \
sock_wait_closed( SMTP_sock->sock, SOCK_DELAY, NULL, &SMTP_stat ); \
free_Mail_Socket(SMTP_sock); \
strncpy(POPLIB_Err_Msg, "SMTP Error -- Condition (" #COND ")", 100); \
SHUTDOWN; \
return(0); \
}
#define SMTP_RESET_ON(NUM, SHUTDOWN) if ( SMTP_Err_Cond == NUM ) { \
sock_puts( SMTP_sock->sock, "RSET" ); \
sock_wait_input( SMTP_sock->sock, SOCK_DELAY, NULL, &SMTP_stat ); \
sock_gets( SMTP_sock->sock, _temp_buffer, sizeof( _temp_buffer )); \
strncpy(POPLIB_Err_Msg, "SMTP Problem -- SMTP Reply '" #NUM "'", 100); \
SHUTDOWN; \
return(0); \
}
#endif
/* ************************************************************************ */
char *POP_Err_Msg = NULL;
static char _POP_err_msg_buf[100] = "";
int SMTP_Err_Cond;
char *SMTP_Err_Msg = NULL;
static char _SMTP_err_msg_buf[100] = "";
char *POPLIB_Err_Msg = NULL;
int WatTCP_initialized = 0;
static char _temp_buffer[_TEMP_BUFFER_LEN];
int POP_stat;
int SMTP_stat;
int SOCK_DELAY;
char pktowner[21];
unsigned char *trim(char *str)
{
int i;
if (str == NULL)
return (str);
for (i = strlen(str) - 1; (i >= 0) && isspace(str[i]); str[i--] = '\0');
while (isspace(str[0]))
strcpy(str, str + 1);
return (str);
}
unsigned char *strrep(char *str, char old, char New)
{
int i;
for (i = 0; str[i]; i++)
if (str[i] == old)
str[i] = New;
return (str);
}
int getnumbers(unsigned char *ascii, unsigned int *d1, unsigned long *d2)
{
char *p;
/* it must return a number after the white space */
if ((p = (char *) _fstrchr((char *) ascii, ' ')) == NULL)
return 0;
/* skip space */
while (*p == ' ')
p++;
*d1 = atoi(p);
if ((p = (char *) _fstrchr(p, ' ')) == NULL)
return 1;
/* skip space */
while (*p == ' ')
p++;
*d2 = atol(p);
return 2;
}
char *fix_quoted_commas(char *string)
{
char *ptr;
int quoted = 0;
ptr = string;
if (ptr) {
while (*ptr != 0) {
if (*ptr == '\"')
quoted = (!quoted);
if (*ptr == ',' && quoted)
*ptr = '│';
ptr = &ptr[1];
}
}
return (string);
}
long sh_lseek(int handle, long offset, int fromwhere)
{
if (handle == -1) {
return (-1L);
}
return (lseek(handle, offset, fromwhere));
}
FILE *fsh_open(char *path, char *fmode)
{
FILE *f;
int count, share, md, fd;
char drive[MAXDRIVE], dir[MAXDIR], file[MAXFILE], ext[MAXEXT];
share = SH_DENYWR;
md = 0;
if (((char *) _fstrchr(fmode, 'w')) != NULL) {
share = SH_DENYRD;
md = O_RDWR | O_CREAT | O_TRUNC;
} else
if (((char *) _fstrchr(fmode, 'a')) != NULL) {
share = SH_DENYRD;
md = O_RDWR | O_CREAT;
} else {
md = O_RDONLY;
}
if (((char *) _fstrchr(fmode, 'b')) != NULL) {
md |= O_BINARY;
}
if (((char *) _fstrchr(fmode, '+')) != NULL) {
md &= ~O_RDONLY;
md |= O_RDWR;
share = SH_DENYRD;
}
fd = open(path, md | share, S_IREAD | S_IWRITE);
if (fd < 0) {
count = 1;
fnsplit(path, drive, dir, file, ext);
if ((access(path, 0)) != -1) {
delay(WAIT_TIME);
fd = open(path, md | share, S_IREAD | S_IWRITE);
while (((fd < 0) && (errno == EACCES)) && (count < TRIES)) {
delay(WAIT_TIME);
count++;
fd = open(path, md | share, S_IREAD | S_IWRITE);
}
}
}
if (fd > 0) {
if (((char *) _fstrchr(fmode, 'a')) != NULL)
sh_lseek(fd, 0L, SEEK_END);
f = fdopen(fd, fmode);
if (!f) {
close(fd);
}
} else
f = 0;
return (f);
}
Mail_Socket *smtp_start(char *host, char *dom)
{
longword h;
Mail_Socket *SMTP_sock = NULL;
if (!SMTP_Err_Msg)
SMTP_Err_Msg = _SMTP_err_msg_buf;
if (!WatTCP_initialized) {
sock_init();
WatTCP_initialized = 1;
}
if (!(h = resolve(host))) {
SMTP_Err_Cond = SMTP_FAILED;
#ifdef SMTP_POP_DEBUG
sprintf(SMTP_Err_Msg, "Cannot resolve host %s", host);
fprintf(stderr, "SMTP> %s\n", SMTP_Err_Msg);
#endif
return NULL;
}
if ((SMTP_sock = (Mail_Socket *) malloc(sizeof(Mail_Socket))) == NULL) {
fprintf(stderr, "\n ■ Insufficient memory to create socket... aborting");
exit(EXIT_FAILURE);
}
if ((SMTP_sock->sock = (tcp_Socket *) malloc(sizeof(tcp_Socket))) == NULL) {
fprintf(stderr, "\n ■ Insufficient memory to create socket... aborting");
free(SMTP_sock);
exit(EXIT_FAILURE);
}
if (!tcp_open(SMTP_sock->sock, 0, h, SMTP_PORT, NULL)) {
SMTP_Err_Cond = SMTP_FAILED;
#ifdef SMTP_POP_DEBUG
sprintf(SMTP_Err_Msg, "Unable to connect to %s", host);
fprintf(stderr, "SMTP> %s\n", SMTP_Err_Msg);
#endif
free(SMTP_sock);
return NULL;
}
sock_mode(SMTP_sock->sock, TCP_MODE_ASCII);
sock_wait_established(SMTP_sock->sock, SOCK_DELAY, NULL, &SMTP_stat);
while (sock_tbused(SMTP_sock->sock) > 0) {
SOCK_GETS(SMTP);
SMTP_FAIL_ON(SMTP_OOPS,);
}
sock_printf(SMTP_sock->sock, "HELO %s", dom);
sock_wait_input(SMTP_sock->sock, SOCK_DELAY, NULL, &SMTP_stat);
while (sock_tbused(SMTP_sock->sock) > 0) {
SOCK_GETS(SMTP);
SMTP_FAIL_ON(SMTP_OOPS,);
SMTP_FAIL_ON(SMTP_SYNTAX,);
SMTP_FAIL_ON(SMTP_PARAM,);
SMTP_FAIL_ON(SMTP_BAD_PARM,);
}
return (SMTP_sock);
SOCK_READ_ERR(SMTP);
return NULL;
}
char *smtp_parse_from_line(FILE * f)
{
int found = 0, done = 0;
rewind(f);
while (!feof(f) && !done) {
fgets(_temp_buffer, sizeof(_temp_buffer), f);
if (*_temp_buffer == '\n')
done = 1;
else
if (strncmpi(_temp_buffer, "from:", 5) == 0 &&
_fstrchr(_temp_buffer, '@') != 0)
found = 1, done = 1;
}
if (found)
return (trim(strdup(&_temp_buffer[5])));
return 0;
}
char **smtp_parse_to_line(FILE * f)
{
int done = 0, current = 0;
char **list = NULL;
char *addr;
rewind(f);
while (!feof(f) && !done) {
fgets(_temp_buffer, sizeof(_temp_buffer), f);
if (*_temp_buffer == '\n')
done = 1;
else
if (strncmpi(_temp_buffer, "to:", 3) == 0 ||
strncmpi(_temp_buffer, "cc:", 3) == 0 ||
strncmpi(_temp_buffer, "bcc:", 4) == 0) {
fix_quoted_commas(_temp_buffer);
addr = strtok(_temp_buffer, ":");
while ((addr = strtok(NULL, ",\n")) != NULL) {
strrep(addr, '│', ',');
list = (char **) realloc(list, sizeof(char *) * ((current) + 2));
list[current] = strdup(addr);
list[current + 1] = NULL;
current++;
}
}
}
return (list);
}
int smtp_send_MAIL_FROM_line(Mail_Socket * SMTP_sock, FILE * f)
{
char *from;
from = smtp_parse_from_line(f);
if (from) {
#ifdef SMTP_POP_DEBUG
fprintf(stderr, "SMTP> %s\n", from);
#endif
sock_printf(SMTP_sock->sock, "MAIL FROM:<%s>", from);
while (sock_tbused(SMTP_sock->sock) > 0) {
SOCK_GETS(SMTP);
SMTP_FAIL_ON(SMTP_OOPS,);
}
if (from)
free(from);
}
return 1;
SOCK_READ_ERR(SMTP);
return 0;
}
#define FREE_ALL for (i=0; to_list[i]!=NULL; i++) free(to_list[i]); if (to_list) free(to_list);
int smtp_send_RCPT_TO_line(Mail_Socket * SMTP_sock, FILE * f)
{
char **to_list;
int i;
to_list = smtp_parse_to_line(f);
for (i = 0; to_list[i] != NULL; i++) {
#ifdef SMTP_POP_DEBUG
fprintf(stderr, "SMTP> %s\n", to_list[i]);
#endif
sock_printf(SMTP_sock->sock, "RCPT TO:<%s>", to_list[i]);
while (sock_tbused(SMTP_sock->sock) > 0) {
SOCK_GETS(SMTP);
SMTP_FAIL_ON(SMTP_OOPS, FREE_ALL);
SMTP_RESET_ON(SMTP_SYNTAX, FREE_ALL);
SMTP_RESET_ON(SMTP_PARAM, FREE_ALL);
SMTP_RESET_ON(SMTP_BAD_SEQ, FREE_ALL);
}
}
FREE_ALL;
return 1;
SOCK_READ_ERR(SMTP);
return 0;
}
#undef FREE_ALL
int smtp_sendf(Mail_Socket * SMTP_sock, FILE * f)
{
int in_header = 1, in_bcc = 0, i, pos;
long nbytes, obytes, rbytes;
char *temp;
if (smtp_send_MAIL_FROM_line(SMTP_sock, f) == 0)
return 0;
if (smtp_send_RCPT_TO_line(SMTP_sock, f) == 0)
return 0;
fseek(f, 0L, SEEK_END);
obytes = ftell(f);
rewind(f);
sock_puts(SMTP_sock->sock, "DATA");
sock_wait_input(SMTP_sock->sock, SOCK_DELAY, NULL, &SMTP_stat);
while (sock_tbused(SMTP_sock->sock) > 0) {
SOCK_GETS(SMTP);
#ifdef SMTP_POP_DEBUG
fprintf(stderr, "> %s\n", _temp_buffer);
#endif
SMTP_FAIL_ON(SMTP_OOPS,);
SMTP_RESET_ON(SMTP_SYNTAX,);
SMTP_RESET_ON(SMTP_PARAM,);
SMTP_RESET_ON(SMTP_COM_NI,);
SMTP_RESET_ON(SMTP_FAILED,);
SMTP_RESET_ON(SMTP_ERROR,);
}
nbytes = 0L;
rbytes = 1024L;
fprintf(stderr, " - ");
pos = wherex();
while (!feof(f)) {
fgets(_temp_buffer, sizeof(_temp_buffer), f);
strrep(_temp_buffer, '\n', '\0');
strrep(_temp_buffer, '\r', '\0');
temp = trim(strdup(_temp_buffer));
if (strlen(temp) == 0)
in_header = 0;
if (temp)
free(temp);
if (in_header && !in_bcc && strncmpi(_temp_buffer, "bcc:", 4) == 0) {
in_bcc = 1;
continue;
}
if (in_bcc)
in_bcc = isspace(*_temp_buffer);
if (in_bcc)
continue;
if (*_temp_buffer == '.') {
movmem(_temp_buffer, _temp_buffer + 1, sizeof(_temp_buffer) - 1);
*_temp_buffer = '.';
#ifdef SMTP_POP_DEBUG
fprintf(stderr, "> %s\n", _temp_buffer);
#endif
}
nbytes += sock_puts(SMTP_sock->sock, _temp_buffer);
nbytes += 2;
if (nbytes > rbytes) {
for (i = wherex(); i > pos; i--)
fprintf(stderr, "\b");
fprintf(stderr, "%ld of %ld bytes", nbytes, obytes);
rbytes += 1024L;
}
}
for (i = wherex(); i > pos; i--)
fprintf(stderr, "\b \b");
fprintf(stderr, "message sent!");
sock_puts(SMTP_sock->sock, ".");
sock_wait_input(SMTP_sock->sock, SOCK_DELAY, NULL, &SMTP_stat);
while (sock_tbused(SMTP_sock->sock) > 0) {
SOCK_GETS(SMTP);
SMTP_FAIL_ON(SMTP_OOPS,);
SMTP_RESET_ON(SMTP_ERROR,);
SMTP_RESET_ON(SMTP_SQUEEZED,);
SMTP_RESET_ON(SMTP_FULL,);
SMTP_RESET_ON(SMTP_FAILED,);
}
return 1;
SOCK_READ_ERR(SMTP);
return 0;
}
int smtp_shutdown(Mail_Socket * SMTP_sock)
{
sock_puts(SMTP_sock->sock, "QUIT");
sock_close(SMTP_sock->sock);
sock_wait_closed(SMTP_sock->sock, SOCK_DELAY, NULL, &SMTP_stat);
sock_err:
free_Mail_Socket(SMTP_sock);
return 1;
}
Mail_Socket *pop_init(char *host)
{
longword h;
Mail_Socket *POP_sock = NULL;
if (!POP_Err_Msg)
POP_Err_Msg = _POP_err_msg_buf;
if (!WatTCP_initialized) {
sock_init();
WatTCP_initialized = 1;
}
if (!(h = resolve(host))) {
#ifdef SMTP_POP_DEBUG
sprintf(POP_Err_Msg, "Cannot resolve host %s", host);
fprintf(stderr, "POP> %s\n", POP_Err_Msg);
#endif
return NULL;
}
if ((POP_sock = (Mail_Socket *) malloc(sizeof(Mail_Socket))) == NULL) {
fprintf(stderr, "\n ■ Insufficient memory to create socket... aborting");
exit(EXIT_FAILURE);
}
if ((POP_sock->sock = (tcp_Socket *) malloc(sizeof(tcp_Socket))) == NULL) {
fprintf(stderr, "\n ■ Insufficient memory to create socket... aborting");
free(POP_sock);
exit(EXIT_FAILURE);
}
if (!tcp_open(POP_sock->sock, 0, h, POP_PORT, NULL)) {
#ifdef SMTP_POP_DEBUG
sprintf(POP_Err_Msg, "Unable to connect to host %s", host);
fprintf(stderr, "POP> %s\n", POP_Err_Msg);
#endif
free(POP_sock);
return NULL;
}
sock_mode(POP_sock->sock, TCP_MODE_ASCII);
sock_wait_established(POP_sock->sock, SOCK_DELAY, NULL, &POP_stat);
sock_wait_input(POP_sock->sock, SOCK_DELAY, NULL, &POP_stat);
sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
#ifdef SMTP_POP_DEBUG
fprintf(stderr, "POP> %s\n", _temp_buffer);
#endif
if (*_temp_buffer != '+') {
#ifdef SMTP_POP_DEBUG
sprintf(POP_Err_Msg, "Host %s unavailable", host);
fprintf(stderr, "POP> %s\n", POP_Err_Msg);
#endif
sock_puts(POP_sock->sock, "QUIT");
sock_close(POP_sock->sock);
sock_wait_closed(POP_sock->sock, SOCK_DELAY, NULL, &POP_stat);
free(POP_sock);
return NULL;
}
return (POP_sock);
SOCK_READ_ERR(POP);
return NULL;
}
int pop_login(Mail_Socket * POP_sock, char *userid, char *password)
{
sprintf(_temp_buffer, "USER %s", userid);
sock_puts(POP_sock->sock, _temp_buffer);
sock_wait_input(POP_sock->sock, SOCK_DELAY, NULL, &POP_stat);
sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
#ifdef SMTP_POP_DEBUG
fprintf(stderr, "> %s\n", _temp_buffer);
#endif
if (*_temp_buffer != '+') {
fprintf(stderr, "\n ■ POP host reports mailbox %s does not exist!", userid);
#ifdef SMTP_POP_DEBUG
sprintf(POP_Err_Msg, "Mailbox %s does not exist", userid);
fprintf(stderr, "POP> %s\n", POP_Err_Msg);
#endif
return 0;
}
sprintf(_temp_buffer, "PASS %s", password);
sock_puts(POP_sock->sock, _temp_buffer);
sock_wait_input(POP_sock->sock, SOCK_DELAY, NULL, &POP_stat);
sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
#ifdef SMTP_POP_DEBUG
fprintf(stderr, "> %s\n", _temp_buffer);
#endif
if (*_temp_buffer != '+') {
fprintf(stderr, "\n ■ POP host reports %s is an incorrect password", password);
#ifdef SMTP_POP_DEBUG
sprintf(POP_Err_Msg, "Password incorrect");
fprintf(stderr, "POP> %s\n", POP_Err_Msg);
#endif
return 0;
}
return 1;
SOCK_READ_ERR(POP);
return 0;
}
int pop_status(Mail_Socket * POP_sock, unsigned int *count, unsigned long *totallength)
{
sock_puts(POP_sock->sock, "STAT");
sock_wait_input(POP_sock->sock, SOCK_DELAY, NULL, &POP_stat);
sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
#ifdef SMTP_POP_DEBUG
fprintf(stderr, "> %s\n", _temp_buffer);
#endif
if ((*_temp_buffer != '+') ||
(getnumbers(_temp_buffer, count, totallength) < 2)) {
#ifdef SMTP_POP_DEBUG
sprintf(POP_Err_Msg, "Unknown error");
fprintf(stderr, "POP> %s\n", POP_Err_Msg);
#endif
return 0;
}
return 1;
SOCK_READ_ERR(POP);
return 0;
}
long pop_length(Mail_Socket * POP_sock, unsigned int msg_num, unsigned long *size)
{
unsigned int dummy;
sprintf(_temp_buffer, "LIST %u", msg_num);
sock_puts(POP_sock->sock, _temp_buffer);
sock_wait_input(POP_sock->sock, SOCK_DELAY, NULL, &POP_stat);
sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
#ifdef SMTP_POP_DEBUG
fprintf(stderr, "> %s\n", _temp_buffer);
#endif
if ((*_temp_buffer != '+') ||
(getnumbers(_temp_buffer, &dummy, size) < 2)) {
#ifdef SMTP_POP_DEBUG
sprintf(POP_Err_Msg, "No message #%u", msg_num);
fprintf(stderr, "POP> %s\n", POP_Err_Msg);
#endif
return 0;
}
return (*size);
SOCK_READ_ERR(POP);
return 0;
}
char *stristr(char *String, char *Pattern)
{
char *pptr, *sptr, *start;
unsigned int slen, plen;
for (start = String, pptr = Pattern, slen = strlen(String),
plen = strlen(Pattern); slen >= plen; start++, slen--) {
while (toupper(*start) != toupper(*Pattern)) {
start++;
slen--;
if (slen < plen)
return (NULL);
}
sptr = start;
pptr = Pattern;
while (toupper(*sptr) == toupper(*pptr)) {
sptr++;
pptr++;
if ('\0' == *pptr)
return (start);
}
}
return (NULL);
}
int pop_top(Mail_Socket * POP_sock, unsigned int msg_num)
{
int okpkt;
/* sprintf(_temp_buffer, "TOP %u 50", msg_num); */
sock_printf(POP_sock->sock, "TOP %u 50\n", msg_num);
sock_wait_input(POP_sock->sock, SOCK_DELAY, NULL, &POP_stat);
sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
#ifdef SMTP_POP_DEBUG
fprintf(stderr, "> %s\n", _temp_buffer);
#endif
if (*_temp_buffer != '+') {
#ifdef SMTP_POP_DEBUG
sprintf(POP_Err_Msg, "Unknown error");
fprintf(stderr, "POP> %s\n", POP_Err_Msg);
#endif
return 0;
}
okpkt = 0;
while (1) {
sock_wait_input(POP_sock->sock, SOCK_DELAY, NULL, &POP_stat);
sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
if (_temp_buffer[0] == '.' && _temp_buffer[1] == 0)
break;
if (strnicmp(_temp_buffer, "begin ", 6) == 0) {
if (okpkt != 4)
okpkt = 1;
if ((stristr(_temp_buffer, ".ZIP") != NULL) ||
(stristr(_temp_buffer, ".ARJ") != NULL) ||
(stristr(_temp_buffer, ".LZH") != NULL))
okpkt = 2;
if ((stristr(_temp_buffer, ".GIF") != NULL) ||
(stristr(_temp_buffer, ".JPG") != NULL))
okpkt = 3;
}
if (strnicmp(_temp_buffer, "from:", 5) == 0) {
if ((stristr(_temp_buffer, "mailer-daemon") != NULL) ||
(stristr(_temp_buffer, "mail delivery") != NULL) ||
(stristr(_temp_buffer, "administrator") != NULL))
okpkt = 4;
else
strncpy(pktowner, &_temp_buffer[6], 20);
}
}
return okpkt;
SOCK_READ_ERR(POP);
return -1;
}
int pop_getf(Mail_Socket * POP_sock, char *fn, unsigned int msg_num)
{
unsigned long size;
long nbytes, rbytes;
int i, pos, ctld;
FILE *fp;
if (!pop_length(POP_sock, msg_num, &size)) {
fprintf(stderr, "\n ■ Unable to retrieve message number %d", msg_num);
return 0;
}
sprintf(_temp_buffer, "RETR %u", msg_num);
sock_puts(POP_sock->sock, _temp_buffer);
sock_wait_input(POP_sock->sock, SOCK_DELAY, NULL, &POP_stat);
sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
#ifdef SMTP_POP_DEBUG
fprintf(stderr, "> %s\n", _temp_buffer);
#endif
if (*_temp_buffer != '+') {
#ifdef SMTP_POP_DEBUG
sprintf(POP_Err_Msg, "No message #%u", msg_num);
fprintf(stderr, "POP> %s\n", POP_Err_Msg);
#endif
return 0;
}
nbytes = 0L;
rbytes = 1024L;
fprintf(stderr, " - ");
pos = wherex();
if ((fp = fsh_open(fn, "w")) == NULL) {
fprintf(stderr, "\n ■ Unable to create %s... aborting!", fn);
return 0;
}
ctld = 1;
while (1) {
sock_wait_input(POP_sock->sock, SOCK_DELAY, NULL, &POP_stat);
sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
if (_temp_buffer[0] == '.' && _temp_buffer[1] == 0)
break;
if ((*_temp_buffer == '\r') || (*_temp_buffer == '\n') || (*_temp_buffer == 0))
ctld = 0;
if (EOF == (nbytes += fprintf(fp, "%s%s\n", ctld ? "0R" : "", _temp_buffer))) {
fclose(fp);
return 0;
}
if (nbytes > rbytes) {
for (i = wherex(); i > pos; i--)
fprintf(stderr, "\b");
fprintf(stderr, "%ld of %ld bytes", nbytes, size);
rbytes += 1024L;
}
}
fclose(fp);
for (i = wherex(); i > pos; i--)
fprintf(stderr, "\b \b");
fprintf(stderr, "message received!");
return 1;
SOCK_READ_ERR(POP);
return 0;
}
int pop_delete(Mail_Socket * POP_sock, unsigned int msg_num)
{
sprintf(_temp_buffer, "DELE %u", msg_num);
sock_puts(POP_sock->sock, _temp_buffer);
sock_wait_input(POP_sock->sock, SOCK_DELAY, NULL, &POP_stat);
sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
#ifdef SMTP_POP_DEBUG
fprintf(stderr, "> %s\n", _temp_buffer);
#endif
if (*_temp_buffer != '+') {
#ifdef SMTP_POP_DEBUG
sprintf(POP_Err_Msg, "No message #%u", msg_num);
fprintf(stderr, "POP> %s\n", POP_Err_Msg);
#endif
return 2;
}
return 1;
SOCK_READ_ERR(POP);
return 0;
}
int pop_shutdown(Mail_Socket * POP_sock)
{
sock_puts(POP_sock->sock, "QUIT");
sock_wait_input(POP_sock->sock, SOCK_DELAY, NULL, &POP_stat);
sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
if (*_temp_buffer != '+') {
#ifdef SMTP_POP_DEBUG
sprintf(POP_Err_Msg, "Unable to update mailbox");
fprintf(stderr, "POP> %s\n", POP_Err_Msg);
#endif
return 0;
} else
fprintf(stderr, "\n ■ Successfully closed and updated mailbox");
sock_close(POP_sock->sock);
sock_wait_closed(POP_sock->sock, SOCK_DELAY, NULL, &POP_stat);
sock_err:
free_Mail_Socket(POP_sock);
return 1;
}
int pop_get_nextf(Mail_Socket * POP_sock, char *fn, int msgnum)
{
switch (pop_getf(POP_sock, fn, msgnum)) {
case -1:
fprintf(stderr, "\n ■ Socket failure... aborting.");
free_Mail_Socket(POP_sock);
exit(EXIT_FAILURE);
case 0:
return 0;
case 1:
break;
}
/* if (!pop_getf(POP_sock, fn, msgnum)) */
/* return 0; */
return(pop_delete(POP_sock, msgnum));
}
int exist(char *s)
{
int i;
struct ffblk ff;
i = findfirst(s, &ff, FA_HIDDEN);
if (i)
return 0;
else
return 1;
}
void main(int argc, char *argv[])
{
unsigned int count;
unsigned long size;
int i, i1, okpkt;
char temp[181], s[21], s1[21];
FILE *fp;
Mail_Socket *pop_sock = NULL;
Mail_Socket *smtp_sock = NULL;
if (strncmpi(argv[1], "-send", strlen(argv[1])) == 0) {
if (argc != 5)
exit(EXIT_FAILURE);
fprintf(stderr, "via %s", argv[2]);
if ((smtp_sock = smtp_start(argv[2], argv[3])) != NULL) {
if ((fp = fsh_open(argv[4], "r")) != NULL) {
if (smtp_sendf(smtp_sock, fp)) {
smtp_shutdown(smtp_sock);
fclose(fp);
exit(EXIT_SUCCESS);
} else {
smtp_shutdown(smtp_sock);
fprintf(stderr, "\n ■ SMTP socket failure during send.");
fclose(fp);
}
} else {
smtp_shutdown(smtp_sock);
fprintf(stderr, "\n ■ Error accessing file %s.", argv[4]);
}
} else
fprintf(stderr, "\n ■ SMTP socket connect failed.");
} else
if (strncmpi(argv[1], "-receive", strlen(argv[1])) == 0) {
if (argc != 7) {
fprintf(stderr, "Received: ");
for (i = 0; i < argc; i++)
fprintf(stderr, "%s ", argv[i]);
exit(EXIT_FAILURE);
}
if ((pop_sock = pop_init(argv[2])) != NULL) {
if (pop_login(pop_sock, argv[3], argv[4])) {
if (pop_status(pop_sock, &count, &size)) {
okpkt = 0;
fprintf(stderr, "\n ■ Account \"%s\" has %u message%s, %lu bytes total.",
argv[3], count, count == 1 ? "" : "s", size);
i1 = 1;
while (i1 <= count) {
okpkt = -1;
okpkt = pop_top(pop_sock, i1);
switch (okpkt) {
case -1:
fprintf(stderr, "\n ■ Error accessing message %d", i1);
break;
case 0:
i = atoi(argv[6]);
if (i == 0)
fprintf(stderr, "\n ■ Non-network message %d left on server.", i1);
else {
i = 0;
sprintf(temp, "%sUNK-%03d.MSG", argv[5], i);
while (exist(temp))
sprintf(temp, "%sUNK-%03d.MSG", argv[5], ++i);
fnsplit(temp, NULL, NULL, s, s1);
fprintf(stderr, "\n ■ Message %3.3d - %-20s - %s%s", i1, "non-network packet", s, s1);
switch (pop_get_nextf(pop_sock, temp, i1)) {
case 0:
fprintf(stderr, "\n ■ Unable to retrieve message %d.", i1);
unlink(temp);
break;
case 1:
break;
case 2:
fprintf(stderr, "\n ■ Unable to delete message %d from host!", i1);
break;
}
}
break;
case 1:
i = 0;
sprintf(temp, "%sPKT-%03d.UUE", argv[5], i);
while (exist(temp))
sprintf(temp, "%sPKT-%03d.UUE", argv[5], ++i);
fnsplit(temp, NULL, NULL, s, s1);
fprintf(stderr, "\n ■ Message %3.3d - %-20s - %s%s", i1, pktowner, s, s1);
switch (pop_get_nextf(pop_sock, temp, i1)) {
case 0:
fprintf(stderr, "\n ■ Unable to retrieve message %d.", i1);
unlink(temp);
break;
case 1:
break;
case 2:
fprintf(stderr, "\n ■ Unable to delete message %d on host!", i1);
break;
}
break;
case 2:
i = 0;
sprintf(temp, "%sARC-%03d.UUE", argv[5], i);
while (exist(temp))
sprintf(temp, "%sARC-%03d.UUE", argv[5], ++i);
fnsplit(temp, NULL, NULL, s, s1);
fprintf(stderr, "\n ■ Message %3.3d - %-20s - %s%s", i1, "archived file", s, s1);
switch (pop_get_nextf(pop_sock, temp, i1)) {
case 0:
fprintf(stderr, "\n ■ Unable to retrieve message %d.", i1);
unlink(temp);
break;
case 1:
break;
case 2:
fprintf(stderr, "\n ■ Unable to delete message %d on host!", i1);
break;
}
break;
case 3:
i = 0;
sprintf(temp, "%sGIF-%03d.UUE", argv[5], i);
while (exist(temp))
sprintf(temp, "%sGIF-%03d.UUE", argv[5], ++i);
fnsplit(temp, NULL, NULL, s, s1);
fprintf(stderr, "\n ■ Message %3.3d - %-20s - %s%s", i1, "graphic/image file", s, s1);
switch (pop_get_nextf(pop_sock, temp, i1)) {
case 0:
fprintf(stderr, "\n ■ Unable to retrieve message %d.", i1);
unlink(temp);
break;
case 1:
break;
case 2:
fprintf(stderr, "\n ■ Unable to delete message %d from host!", i1);
break;
}
break;
case 4:
i = 0;
sprintf(temp, "%sBAD-%03d.UUE", argv[5], i);
while (exist(temp))
sprintf(temp, "%sBAD-%03d.UUE", argv[5], ++i);
fnsplit(temp, NULL, NULL, s, s1);
fprintf(stderr, "\n ■ Message %3.3d - %-20s - %s%s", i1, "mailer-daemon", s, s1);
switch (pop_get_nextf(pop_sock, temp, i1)) {
case 0:
fprintf(stderr, "\n ■ Unable to retrieve message %d.", i1);
unlink(temp);
break;
case 1:
break;
case 2:
fprintf(stderr, "\n ■ Unable to delete message %d from host!", i1);
break;
}
break;
}
i1++;
}
} else
fprintf(stderr, "\n ■ Unknown access error - possibly locked POP mailbox?");
pop_shutdown(pop_sock);
exit(EXIT_SUCCESS);
} else {
fprintf(stderr, "\n ■ Unable to log into POP server!");
pop_shutdown(pop_sock);
}
} else
fprintf(stderr, "\n ■ POP socket connect failed.");
}
exit(EXIT_FAILURE);
}