home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.wwiv.com
/
ftp.wwiv.com.zip
/
ftp.wwiv.com
/
pub
/
PPPBCKP
/
SRC
/
SRC15B66.ZIP
/
POP.CPP
< prev
next >
Wrap
Text File
|
1997-11-16
|
39KB
|
1,307 lines
#include <stdio.h>
#include <stdarg.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 <alloc.h>
#include <dir.h>
extern "C" {
#include "tcp.h"
}
#include "version.h"
#include "retcode.h"
#define SIZE_OF_EMULATOR 415
#define FILL_CHAR 0xFF
#define POP_PORT 110
#define SMTP_PORT 25
#define SMTP_STATUS 211
#define SMTP_HELP 214
#define SMTP_READY 220
#define SMTP_BYE 221
#define SMTP_OK 250
#define SMTP_WILL_FWD 251
#define SMTP_GIMME 354
#define SMTP_OOPS 421
#define SMTP_BUSY 450
#define SMTP_ERROR 451
#define SMTP_SQUEEZED 452
#define SMTP_SYNTAX 500
#define SMTP_PARAM 501
#define SMTP_COM_NI 502
#define SMTP_BAD_SEQ 503
#define SMTP_BAD_PARM 504
#define SMTP_ACCESS 550
#define SMTP_YOU_FWD 551
#define SMTP_FULL 552
#define SMTP_BAD_NAM 553
#define SMTP_FAILED 554
#define POP_OK 200
#define POP_NOT_MSG 400
#define POP_BAD_HOST 500
#define POP_HOST_UNAVAILABLE 501
#define POP_BAD_MBOX 510
#define POP_BAD_PASS 511
#define POP_UNKNOWN 599
#define POPLIB_OK 200
#define POPLIB_BAD_FILE 401
#define POPLIB_BAD_HOST 510
#define POPLIB_S_TIMEOU 510
#define POPLIB_S_CLOSED 511
#define POPLIB_SMTP_ERR 520
#define POPLIB_POP_ERR 521
#define POPLIB_SMTP_PROB 410
#define POPLIB_POP_PROB 411
typedef struct {
tcp_Socket *sock;
} Mail_Socket;
#define _TEMP_BUFFER_LEN 2048
#define LAST(s) s[strlen(s)-1]
#define SHARE_LEVEL 10
#define WAIT_TIME 10
#define TRIES 100
#define MT_DESQVIEW 0x01
#define MT_WINDOWS 0x02
#define MT_OS2 0x04
#define MT_NB 0x40
#define free_Mail_Socket(SOCK) if (SOCK != NULL) { \
farfree(SOCK->sock); farfree(SOCK); SOCK=NULL; }
int POP_Err_Cond, SMTP_Err_Cond;
char from_user[41], net_data[MAXPATH], POPHOST[81];
int WatTCP_initialized = 0, fdl;
char _temp_buffer[_TEMP_BUFFER_LEN];
static POP_stat, SMTP_stat;
int multitasker = 0, DEBUG = 1, ALLMAIL;
char *version = "Freeware PPP Project POP/SMTP Client " VERSION;
char pktowner[26];
#define SOCK_READ_ERR(PROTOCOL, ACTION) \
sock_err: \
switch (PROTOCOL##_stat) { \
case 1 : \
PROTOCOL##_Err_Cond = PROTOCOL##_OK; \
fprintf(stderr, #PROTOCOL"> Session error : %s", \
sockerr(PROTOCOL##_sock->sock)); \
ACTION; \
return 0; \
case -1: \
PROTOCOL##_Err_Cond = PROTOCOL##_OK; \
fprintf(stderr, #PROTOCOL"> Timeout : %s", \
sockerr(PROTOCOL##_sock->sock)); \
ACTION; \
return 0; \
}
#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)); \
if (DEBUG) fprintf(stderr, #PROTOCOL"> %s\n", _temp_buffer); \
PROTOCOL##_Err_Cond = atoi(_temp_buffer); \
#define SMTP_FAIL_ON(NUM, ACTION) \
if (SMTP_Err_Cond == NUM) { \
if (DEBUG) fprintf(stderr, "SMTP Failure> '" #NUM "'\n"); \
sock_puts(SMTP_sock->sock, "QUIT"); \
sock_close(SMTP_sock->sock); \
free_Mail_Socket(SMTP_sock); \
ACTION; \
return 0; \
}
#define SMTP_RESET_ON(NUM, ACTION) \
if (SMTP_Err_Cond == NUM) { \
if (DEBUG) fprintf(stderr, "SMTP Failure> '" #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)); \
ACTION; \
return(0); \
}
void init_stack_count(void)
{
char far *sp;
extern unsigned __brklvl;
sp = (char *)MK_FP(_SS, _SP - 1 );
while( sp > (char far *) SIZE_OF_EMULATOR ) {
*sp = FILL_CHAR;
sp--;
}
return;
}
void stack_count( void )
{
unsigned count= 0;
char far *sp;
sp = (char *)MK_FP( _SS, SIZE_OF_EMULATOR+1);
if (_SP > SIZE_OF_EMULATOR) {
while (sp < MK_FP(_SS,_SP)) {
if (*sp != (char) FILL_CHAR)
break;
count++;
sp++;
}
}
if (DEBUG)
fprintf(stderr, "\n ! Stack not used = %u bytes\n" , count);
return;
}
void output(char *fmt,...)
{
va_list v;
char s[255];
va_start(v, fmt);
vsprintf(s, fmt, v);
va_end(v);
fputs(s, stderr);
}
int get_dos_version(void)
{
_AX = 0x3000;
geninterrupt(0x21);
if (_AX % 256 >= 10) {
multitasker |= MT_OS2;
}
return (_AX);
}
int get_dv_version(void)
{
int v;
if (multitasker & MT_OS2)
return 0;
_AX = 0x2b01;
_CX = 0x4445;
_DX = 0x5351;
geninterrupt(0x21);
if (_AL == 0xff) {
return 0;
} else {
v = _BX;
multitasker |= MT_DESQVIEW;
return v;
}
}
int get_win_version(void)
{
int v = 0;
__emit__(0x55, 0x06, 0x53);
_AX = 0x352f;
geninterrupt(0x21);
_AX = _ES;
if (_AX | _BX) {
_AX = 0x1600;
geninterrupt(0x2f);
v = _AX;
if (v % 256 <= 1)
v = 0;
}
__emit__(0x5b, 0x07, 0x5d);
if (v != 0)
multitasker |= MT_WINDOWS;
return (v);
}
int get_nb_version(void)
{
_AX = 0;
geninterrupt(0x2A);
return (_AH);
}
void detect_multitask(void)
{
get_dos_version();
get_win_version();
get_dv_version();
if (multitasker < 2)
if (get_nb_version())
multitasker = MT_NB;
}
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);
}
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 (!WatTCP_initialized) {
sock_init();
WatTCP_initialized = 1;
}
if (!(h = resolve(host))) {
if (!(h = resolve(host))) {
SMTP_Err_Cond = SMTP_FAILED;
output("\n ■ Error : Cannot resolve host %s", host);
return NULL;
}
}
if ((SMTP_sock = (Mail_Socket *) farmalloc(sizeof(Mail_Socket))) == NULL) {
output("\n ■ Insufficient memory to create socket... aborting");
exit(EXIT_FAILURE);
}
if ((SMTP_sock->sock = (tcp_Socket *) farmalloc(sizeof(tcp_Socket))) == NULL) {
output("\n ■ Insufficient memory to create socket... aborting");
farfree(SMTP_sock);
exit(EXIT_FAILURE);
}
if (!tcp_open(SMTP_sock->sock, 0, h, SMTP_PORT, NULL)) {
SMTP_Err_Cond = SMTP_FAILED;
output("\n ■ Error : Unable to connect to %s", host);
farfree(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,);
}
SOCK_READ_ERR(SMTP,);
return (SMTP_sock);
}
char *smtp_parse_from_line(FILE * f)
{
int found = 0, done = 0, beginfocus, endfocus;
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) {
if ((beginfocus = _fstrcspn(_temp_buffer, "<")) != strlen(_temp_buffer)) {
++beginfocus;
endfocus = _fstrcspn(_temp_buffer, ">");
_temp_buffer[endfocus] = NULL;
} else
beginfocus = 5;
return (trim(strdup(&_temp_buffer[beginfocus])));
}
return 0;
}
unsigned char *trimstr1(unsigned char *s)
{
int i;
static char *whitespace = " \r\n\t";
i = strlen(s);
if (i) {
while ((i > 0) && (_fstrchr(whitespace, s[i - 1])))
--i;
while ((i > 0) && (_fstrchr(whitespace, *s))) {
memmove(s, s + 1, --i);
}
s[i] = 0;
}
return (s);
}
char **smtp_parse_to_line(FILE * f)
{
int i, i1, done = 0, current = 0;
char **list = NULL;
char *addr, _temp_addr[120], buf[120];
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, ":");
addr = strtok(NULL, "\r\n");
trimstr1(addr);
strcpy(_temp_addr, addr);
if ((strchr(_temp_addr, ' ')) || (strchr(_temp_addr, ')')) || (strchr(_temp_addr, '\"'))) {
*buf = i1 = 0;
i = _fstrcspn(_temp_addr, "@");
while ((i > 0) && (_temp_addr[i - 1] != ' ') && (_temp_addr[i - 1] != '<'))
--i;
while (*_temp_addr && (_temp_addr[i] != ' ') && (_temp_addr[i] != '>'))
buf[i1++] = _temp_addr[i++];
buf[i1] = 0;
addr = buf;
}
list = (char **) farrealloc(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) {
if (DEBUG)
output("\nSMTP> Mail From:<%s>\n", from);
sock_printf(SMTP_sock->sock, "MAIL FROM:<%s>", from);
free(from);
while (sock_tbused(SMTP_sock->sock) > 0) {
SOCK_GETS(SMTP);
SMTP_FAIL_ON(SMTP_OOPS,);
}
}
SOCK_READ_ERR(SMTP,);
return 1;
}
#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);
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++) {
if (DEBUG) {
output("SMTP> Rcpt To:<%s>\n", to_list[i]);
}
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);
}
}
SOCK_READ_ERR(SMTP, FREE_ALL);
FREE_ALL;
return 1;
}
#undef FREE_ALL
void go_back(int from, int to)
{
int i;
for (i = from; i > to; i--)
output("\b \b");
}
int smtp_sendf(Mail_Socket * SMTP_sock, FILE * f)
{
int in_header = 1, in_bcc = 0, pos;
long nbytes, obytes, rbytes;
char *temp, ch;
/*
if (smtp_send_MAIL_FROM_line(SMTP_sock, f) == 0)
return 0;
if (smtp_send_RCPT_TO_line(SMTP_sock, f) == 0)
return 0;
*/
smtp_send_MAIL_FROM_line(SMTP_sock, f);
smtp_send_RCPT_TO_line(SMTP_sock, f);
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);
if (DEBUG)
output("\nSMTP> %s", _temp_buffer);
SMTP_FAIL_ON(SMTP_OOPS,);
SMTP_RESET_ON(SMTP_BAD_SEQ,);
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;
output(" : ");
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 = '.';
if (DEBUG)
output("\nSMTP> %s", _temp_buffer);
}
nbytes += sock_puts(SMTP_sock->sock, _temp_buffer);
tcp_tick(SMTP_sock->sock);
nbytes += 2;
if (nbytes > rbytes) {
go_back(wherex(), pos);
output("%ld/%ld", nbytes, obytes);
rbytes += 512L;
}
while (kbhit()) {
ch = (getch());
switch (ch) {
case 27:
case 32:
go_back(wherex(), pos);
return -1;
default:
break;
}
}
}
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,);
}
go_back(wherex(), pos);
SOCK_READ_ERR(SMTP,);
return 1;
}
void smtp_shutdown(Mail_Socket * SMTP_sock)
{
if (SMTP_sock->sock) {
sock_puts(SMTP_sock->sock, "QUIT");
sock_wait_input(SMTP_sock->sock, sock_delay, NULL, &SMTP_stat);
sock_gets(SMTP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
sock_close(SMTP_sock->sock);
sock_err:
free_Mail_Socket(SMTP_sock);
}
}
Mail_Socket *pop_init(char *host)
{
longword h;
Mail_Socket *POP_sock = NULL;
if (!WatTCP_initialized) {
sock_init();
WatTCP_initialized = 1;
}
if (!(h = resolve(host))) {
if (!(h = resolve(host))) {
POP_Err_Cond = POP_BAD_HOST;
output("\n ■ Error : Cannot resolve host %s", host);
return NULL;
}
}
if ((POP_sock = (Mail_Socket *) farmalloc(sizeof(Mail_Socket))) == NULL) {
output("\n ■ Insufficient memory to create socket... aborting.");
exit(EXIT_FAILURE);
}
if ((POP_sock->sock = (tcp_Socket *) farmalloc(sizeof(tcp_Socket))) == NULL) {
output("\n ■ Insufficient memory to create socket... aborting.");
farfree(POP_sock);
exit(EXIT_FAILURE);
}
if (!tcp_open(POP_sock->sock, 0, h, POP_PORT, NULL)) {
POP_Err_Cond = POP_BAD_HOST;
output("\n ■ Error : Unable to connect to host %s", host);
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));
if (DEBUG)
output("\nPOP> %s", _temp_buffer);
if (*_temp_buffer != '+') {
POP_Err_Cond = POP_HOST_UNAVAILABLE;
output("\n ■ Error : Host %s is unavailable.", host);
return NULL;
} else {
POP_Err_Cond = POP_OK;
output("connection accepted.");
return (POP_sock);
}
SOCK_READ_ERR(POP,);
return (POP_sock);
}
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));
if (DEBUG)
output("\nPOP> %s", _temp_buffer);
if (*_temp_buffer != '+') {
POP_Err_Cond = POP_BAD_MBOX;
output("\n ■ Error : host report mailbox %s does not exist", userid);
if (POP_sock->sock) {
sock_puts(POP_sock->sock, "QUIT");
sock_close(POP_sock->sock);
}
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));
if (DEBUG)
output("\nPOP> %s", _temp_buffer);
if (*_temp_buffer != '+') {
POP_Err_Cond = POP_BAD_PASS;
output("\n ■ Error : Host reports password incorrect or account locked.");
if (POP_sock->sock) {
sock_puts(POP_sock->sock, "QUIT");
sock_close(POP_sock->sock);
}
return 0;
}
output(" \n ■ Logged into account %s : ", userid);
SOCK_READ_ERR(POP,);
return 1;
}
int pop_status(Mail_Socket * POP_sock, unsigned int *count, unsigned long *totallength)
{
char junk[12];
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));
if (DEBUG)
output("\nPOP> %s", _temp_buffer);
if (*_temp_buffer != '+') {
POP_Err_Cond = POP_UNKNOWN;
if (DEBUG)
output("\n ■ Error : Unknown POP error.");
return 0;
} else {
if (DEBUG)
output("\n ■ POP status : %s", _temp_buffer);
sscanf(_temp_buffer, "%s %u %lu", junk, count, totallength);
}
SOCK_READ_ERR(POP,);
return 1;
}
long pop_length(Mail_Socket * POP_sock, unsigned int msg_num, unsigned long *size)
{
char junk[21];
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));
if (DEBUG)
output("\nPOP> %s", _temp_buffer);
if (*_temp_buffer != '+') {
POP_Err_Cond = POP_NOT_MSG;
if (DEBUG)
output("\n ■ Error : No message #%u", msg_num);
return 0;
} else
sscanf(_temp_buffer, "%s %u %lu", &junk, &dummy, size);
SOCK_READ_ERR(POP,);
if (*size == 0L) {
output("\n ■ Mailbox contains a zero byte file -- deleting Message #%u!", 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));
if (DEBUG)
output("\nPOP> %s", _temp_buffer);
if (*_temp_buffer != '+') {
POP_Err_Cond = POP_NOT_MSG;
output("\n ■ Error : No message #%u", msg_num);
}
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 != '+') {
POP_Err_Cond = POP_UNKNOWN;
output("\n ■ Error : Unable to update mailbox.");
} else
output("\n ■ Closed and updated mailbox on %s.", POPHOST);
sock_close(POP_sock->sock);
}
return (*size);
}
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 checkspam(char *text)
{
char fn[MAXPATH], buf[81], tmp[81];
int ok;
FILE *fp;
ok = 0;
sprintf(fn, "%sNOSPAM.TXT", net_data);
if ((fp = fsh_open(fn, "r")) != NULL) {
while (fgets(buf, 80, fp)) {
trimstr1(buf);
if (strlen(buf) > 2) {
if (buf[0] == '\"') {
strcpy(tmp, &(buf[1]));
LAST(tmp) = '\0';
strcpy(buf, tmp);
}
if (stristr(text, buf))
ok = 1;
}
}
fclose(fp);
}
return ok;
}
int pop_top(Mail_Socket * POP_sock, unsigned int msg_num)
{
int okpkt, found_from, found_subj;
char subject[80];
sprintf(_temp_buffer, "TOP %u 40", 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));
if (DEBUG)
output("\nPOP> %s", _temp_buffer);
if (*_temp_buffer != '+') {
POP_Err_Cond = POP_NOT_MSG;
output("\n ■ Error : No message #%u.", msg_num);
return -1;
}
okpkt = -1;
found_from = found_subj = fdl = 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 == '.' && _temp_buffer[1] == 0)
break;
if ((strnicmp(_temp_buffer, "begin ", 6) == 0) &&
(stristr(_temp_buffer, "WINMAIL") == NULL)) {
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, "FDL Type:", 9) == 0)
fdl = 1;
if ((strnicmp(_temp_buffer, "from:", 5) == 0) && (!found_from)) {
if ((stristr(_temp_buffer, "mailer-daemon") != NULL) ||
(stristr(_temp_buffer, "mail delivery") != NULL) ||
(stristr(_temp_buffer, "administrator") != NULL) ||
(stristr(_temp_buffer, from_user) != NULL))
okpkt = 4;
else {
if (_temp_buffer[6] != 0)
strncpy(pktowner, &_temp_buffer[6], 25);
else
strcpy(pktowner, "Unknown");
}
found_from = 1;
}
if ((strnicmp(_temp_buffer, "subject:", 8) == 0) && (!found_subj)) {
if (_temp_buffer[9] != 0)
strncpy(subject, &_temp_buffer[9], 60);
else
strcpy(subject, "Unknown");
found_subj = 1;
}
}
if (found_from && found_subj) {
if ((checkspam(pktowner)) || (checkspam(subject)))
okpkt = 5;
}
SOCK_READ_ERR(POP,);
return okpkt;
}
int pop_getf(Mail_Socket * POP_sock, char *fn, unsigned int msg_num)
{
unsigned long size;
long nbytes, rbytes;
int pos, ctld, len;
FILE *fp;
if (!pop_length(POP_sock, msg_num, &size))
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));
if (DEBUG)
output("\nPOP> %s", _temp_buffer);
if (*_temp_buffer != '+') {
POP_Err_Cond = POP_NOT_MSG;
output("\n ■ Error : No message #%u", msg_num);
return 0;
}
nbytes = 0L;
rbytes = 1024L;
output(" : ");
pos = wherex();
if ((fp = fsh_open(fn, "w")) == NULL) {
output("\n ■ Unable to create %s... aborting!", fn);
return 0;
}
ctld = 1;
while (1) {
sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
len = (sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer)));
if ((ctld == 1) && (len == 0))
ctld = 0;
if ((strnicmp(_temp_buffer, "begin ", 6) == 0) &&
(stristr(_temp_buffer, "WINMAIL") != NULL))
ctld = 2;
if ((ctld == 2) && (strnicmp(_temp_buffer, "end", 3) == 0))
ctld = 0;
if (_temp_buffer[0] == '.' && _temp_buffer[1] == 0)
break;
if (EOF == (nbytes += fprintf(fp, "%s%s\n", ctld ? "0R" : "", _temp_buffer))) {
if (fp != NULL)
fclose(fp);
return 0;
}
if (nbytes > rbytes) {
go_back(wherex(), pos);
output("%ld/%ld", nbytes, size);
rbytes += 512L;
}
}
if (fp != NULL)
fclose(fp);
go_back(wherex(), pos);
output("message received!");
SOCK_READ_ERR(POP,);
return 1;
}
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));
if (DEBUG)
output("\nPOP> %s", _temp_buffer);
if (*_temp_buffer != '+') {
POP_Err_Cond = POP_NOT_MSG;
output("\n ■ Error : No message #%u", msg_num);
return 2;
}
SOCK_READ_ERR(POP,);
return 1;
}
int pop_shutdown(Mail_Socket * POP_sock)
{
if (POP_sock->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 != '+') {
POP_Err_Cond = POP_UNKNOWN;
output("\n ■ Error : Unable to update mailbox.");
return 0;
} else
output("\n ■ Closed and updated mailbox on %s.", POPHOST);
sock_close(POP_sock->sock);
return 1;
}
sock_err:
free_Mail_Socket(POP_sock);
return 0;
}
int pop_get_nextf(Mail_Socket * POP_sock, char *fn, int msgnum)
{
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, failed;
unsigned long size;
int i, i1, f1, okpkt, result;
char temp[181], fn[MAXPATH], mqueue[MAXPATH], s[21], s1[21];
FILE *fp;
struct ffblk ff;
Mail_Socket *pop_sock = NULL;
Mail_Socket *smtp_sock = NULL;
detect_multitask();
init_stack_count();
if (strncmpi(argv[1], "-send", strlen(argv[1])) == 0) {
if (argc < 5) {
output("\n ■ %s", version);
output("\n ■ Invalid arguments for %s\n", argv[0]);
exit(EXIT_FAILURE);
}
if (argc == 6)
DEBUG = atoi(argv[5]);
strcpy(mqueue, argv[4]);
if (DEBUG)
output("\n ■ Scanning %s", mqueue);
output("\n");
if ((smtp_sock = smtp_start(argv[2], argv[3])) != NULL) {
sprintf(fn, "%s*.*", mqueue);
count = failed = 0;
while ((++count < 3) && (failed < 5)) {
f1 = findfirst(fn, &ff, FA_ARCH);
if ((count > 1) && (f1 == 0))
output(" ■ SMTP transfer - pass %d...\n", count);
while ((f1 == 0) && (failed < 5) && (smtp_sock != NULL)) {
sprintf(temp, "%s%s", mqueue, ff.ff_name);
if ((fp = fsh_open(temp, "r")) != NULL) {
SMTP_Err_Cond = SMTP_OK;
if (DEBUG)
output("\n");
output("\r ■ SND : %-12.12s : %-18.18s : [Space] skips", ff.ff_name, argv[2]);
result = (smtp_sendf(smtp_sock, fp));
switch (result) {
case 1:
output("accepted.");
fclose(fp);
unlink(temp);
failed = 0;
break;
case 0:
output(" : failed.");
++failed;
fclose(fp);
break;
case -1:
output(" : aborted.");
fclose(fp);
break;
}
} else {
output("\n ■ Error accessing file %s.", argv[4]);
++failed;
}
f1 = findnext(&ff);
}
}
smtp_shutdown(smtp_sock);
if (failed >= 5)
output("\n ■ Too many SMTP failures... try again later.");
} else
output("\n ■ SMTP connection failed.");
} else if (strncmpi(argv[1], "-receive", strlen(argv[1])) == 0) {
if (argc < 8) {
output("\n ■ %s", version);
output("\n ■ Invalid arguments for %s\n", argv[0]);
exit(EXIT_FAILURE);
}
strcpy(POPHOST, argv[2]);
sprintf(from_user, "%s@%s", argv[3], argv[7]);
if (argc == 9)
DEBUG = atoi(argv[8]);
POP_Err_Cond = POP_OK;
if ((pop_sock = pop_init(POPHOST)) != NULL) {
if (pop_login(pop_sock, argv[3], argv[4])) {
if (pop_status(pop_sock, &count, &size)) {
okpkt = 0;
output("%u message%s (%luK).",
count, count == 1 ? "" : "s", ((size + 1023) / 1024));
i1 = 1;
ALLMAIL = atoi(argv[6]);
strcpy(net_data, argv[5]);
LAST(net_data) = '\0';
while (LAST(net_data) != '\\')
LAST(net_data) = '\0';
while (i1 <= count) {
okpkt = 0;
okpkt = pop_top(pop_sock, i1);
switch (okpkt) {
case -1:
if ((!ALLMAIL) && (!fdl))
output("\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);
output("\n ■ RCV : %3.3d : %-25s : %s%s", i1, "non-network packet", s, s1);
result = (pop_get_nextf(pop_sock, temp, i1));
switch (result) {
case 0:
output("\n ■ Unable to retrieve message %d.", i1);
fcloseall();
exit(EXIT_FAILURE);
case 1:
break;
case 2:
output("\n ■ Unable to delete message %d from host!", i1);
exit(EXIT_FAILURE);
}
}
break;
case 0:
output("\n ■ Error accessing message %d", i1);
fcloseall();
exit(EXIT_FAILURE);
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);
output("\n ■ RCV : %3.3d : %-25s : %s%s", i1, pktowner, s, s1);
result = (pop_get_nextf(pop_sock, temp, i1));
switch (result) {
case 0:
output("\n ■ Unable to retrieve message %d.", i1);
fcloseall();
exit(EXIT_FAILURE);
case 1:
break;
case 2:
output("\n ■ Unable to delete message %d on host!", i1);
exit(EXIT_FAILURE);
}
break;
case 2:
if ((!ALLMAIL) && (!fdl))
output("\n ■ Non-network message %d left on server.", i1);
else {
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);
output("\n ■ RCV : %3.3d : %-25s : %s%s", i1, "archived file", s, s1);
result = (pop_get_nextf(pop_sock, temp, i1));
switch (result) {
case 0:
output("\n ■ Unable to retrieve message %d.", i1);
fcloseall();
exit(EXIT_FAILURE);
case 1:
break;
case 2:
output("\n ■ Unable to delete message %d on host!", i1);
exit(EXIT_FAILURE);
}
}
break;
case 3:
if ((!ALLMAIL) && (!fdl))
output("\n ■ Non-network message %d left on server.", i1);
else {
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);
output("\n ■ RCV : %3.3d : %-25s : %s%s", i1, "graphic/image file", s, s1);
result = (pop_get_nextf(pop_sock, temp, i1));
switch (result) {
case 0:
output("\n ■ Unable to retrieve message %d.", i1);
fcloseall();
exit(EXIT_FAILURE);
case 1:
break;
case 2:
output("\n ■ Unable to delete message %d from host!", i1);
exit(EXIT_FAILURE);
}
}
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);
output("\n ■ RCV : %3.3d : %-25s : %s%s", i1, "mailer-daemon/bounced", s, s1);
result = (pop_get_nextf(pop_sock, temp, i1));
switch (result) {
case 0:
output("\n ■ Unable to retrieve message %d.", i1);
fcloseall();
exit(EXIT_FAILURE);
case 1:
break;
case 2:
output("\n ■ Unable to delete message %d from host!", i1);
exit(EXIT_FAILURE);
}
break;
case 5:
if ((!ALLMAIL) && (!fdl))
output("\n ■ Non-network message %d left on server.", i1);
else {
i = 0;
sprintf(temp, "%sSPM-%03d.MSG", argv[5], i);
while (exist(temp))
sprintf(temp, "%sSPM-%03d.MSG", argv[5], ++i);
fnsplit(temp, NULL, NULL, s, s1);
output("\n ■ RCV : %3.3d : %-25s : %s%s", i1, "matched NOSPAM.TXT", s, s1);
result = (pop_get_nextf(pop_sock, temp, i1));
switch (result) {
case 0:
output("\n ■ Unable to retrieve message %d.", i1);
fcloseall();
exit(EXIT_FAILURE);
case 1:
break;
case 2:
output("\n ■ Unable to delete message %d from host!", i1);
exit(EXIT_FAILURE);
}
}
break;
}
i1++;
fcloseall();
}
output("\n ■ Mailbox scan of %d messages completed.", count);
} else
output("\n ■ Unknown POP access error - try again later.");
pop_shutdown(pop_sock);
stack_count();
exit(EXIT_SUCCESS);
} else {
output("\n ■ Unable to log into POP server!");
pop_shutdown(pop_sock);
}
} else
output("\n ■ POP socket connect failed.");
}
stack_count();
exit(EXIT_FAILURE);
}