home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.wwiv.com
/
ftp.wwiv.com.zip
/
ftp.wwiv.com
/
pub
/
PPPBCKP
/
SRC
/
SRC15B99.ZIP
/
POP.CPP
< prev
next >
Wrap
Text File
|
1999-01-29
|
63KB
|
2,126 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 <malloc.h>
#include <dir.h>
extern "C" {
#include "tcp.h"
}
#include "version.h"
#include "retcode.h"
#undef MAXPATH
#define MAXPATH 160
#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;
typedef struct {
char msgid[81];
} Message_ID;
typedef struct {
char popname[40];
char pophost[60];
char poppass[40];
} ACCT;
ACCT *acct;
extern unsigned _stklen = 10000U;
typedef struct {
int width;
int amount_per_square;
char square_list[10];
int empty_space, side_char1, side_char2;
long total_items, current_item;
long last_maj_pos, last_min_pos;
} statusbarrec;
#define _TEMP_BUFFER_LEN 2048
#define LAST(s) s[strlen(s)-1]
#define SHARE_LEVEL 10
#define WAIT_TIME 10
#define TRIES 100
struct ts_os_ver {
int maj;
int min;
};
#define DOS 0
#define OS2 1
#define DV 2
#define WINS 3
#define WIN3 4
#define MT_DOS 0x01
#define MT_OS2 0x02
#define MT_DV 0x04
#define MT_WINS 0x08
#define MT_WIN3 0x10
struct ts_os_ver t_os_ver[5];
int t_os_type;
int t_os;
char t_os_name[41];
#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[81], netdata[161], net_pkt[21], maindir[160], fdlfn[21], id[81];
char LISTNAME[45], MAILFROM[60], PROXY[40], listaddr[25];
char POPHOST[60], POPNAME[40], POPPASS[20], DOMAIN[60], NODEPASS[20];
int WatTCP_initialized = 0, fdl;
char _temp_buffer[_TEMP_BUFFER_LEN];
static int POP_stat, SMTP_stat;
int aborted, DEBUG = 1, ALLMAIL, compact_ids = 0, SKIP;
char *version = "Freeware PPP Project POP/SMTP Client " VERSION;
char pktowner[36];
#define SOCK_READ_ERR(PROTOCOL, ACTION) \
sock_err: \
switch (PROTOCOL##_stat) { \
case 1 : \
PROTOCOL##_Err_Cond = PROTOCOL##_OK; \
fprintf(stderr, "\n ! "#PROTOCOL"> Session error : %s", \
sockerr(PROTOCOL##_sock->sock)); \
ACTION; \
aborted = 1; \
exit(EXIT_SUCCESS); \
return 0; \
case -1: \
PROTOCOL##_Err_Cond = PROTOCOL##_OK; \
fprintf(stderr, "\n ! "#PROTOCOL"> Timeout : %s", \
sockerr(PROTOCOL##_sock->sock)); \
ACTION; \
aborted = 1; \
exit(EXIT_SUCCESS); \
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, "\n"#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, "\nSMTP Failure> '" #NUM "'\n"); \
sock_puts(SMTP_sock->sock, "QUIT"); \
ACTION; \
aborted = 1; \
return 0; \
}
#define SMTP_RESET_ON(NUM, ACTION) \
if (SMTP_Err_Cond == NUM) { \
if (DEBUG) fprintf(stderr, "\nSMTP 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; \
aborted = 1; \
return(0); \
}
void output(char *fmt,...)
{
va_list v;
char s[255];
va_start(v, fmt);
vsprintf(s, fmt, v);
va_end(v);
fputs(s, stderr);
}
void go_back(int from, int to)
{
int i;
for (i = from; i > to; i--)
output("\b \b");
}
int detect_multitask(void)
{
union REGS t_regs;
t_os_type = 0;
t_os = 0;
if (_osmajor < 10) {
t_os_ver[DOS].maj = _osmajor;
t_os_ver[DOS].min = _osminor;
t_os_type = t_os_type | MT_DOS;
strcpy(t_os_name, "DOS");
} else {
t_os_type = t_os_type | MT_OS2;
t_os_ver[OS2].maj = _osmajor / 10;
t_os_ver[OS2].min = _osminor;
if (t_os_ver[OS2].maj == 3) {
strcpy(t_os_name, "OS/2 Warp");
} else {
strcpy(t_os_name, "OS/2");
}
}
t_regs.x.ax = 0x4680;
int86(0x2F, &t_regs, &t_regs);
if (t_regs.x.ax == 0x0000) {
t_os_ver[WINS].maj = 3;
t_os_ver[WINS].min = 0;
t_os_type = t_os_type | MT_WINS;
} else {
t_regs.x.ax = 0x1600;
int86(0x2F, &t_regs, &t_regs);
switch (t_regs.h.al) {
case 0x00:
case 0x80:
case 0x01:
case 0xFF:
break;
default:
t_os_type = t_os_type | MT_WIN3;
t_os_ver[WIN3].maj = t_regs.h.al;
t_os_ver[WIN3].min = t_regs.h.ah;
if (t_os_ver[WIN3].maj == 4) {
strcpy(t_os_name, "Windows 95");
t_os_ver[WIN3].maj = t_os_ver[WIN3].maj - 3;
} else {
strcpy(t_os_name, "Windows");
}
break;
}
}
t_regs.x.cx = 0x4445;
t_regs.x.dx = 0x5351;
t_regs.x.ax = 0x2B01;
intdos(&t_regs, &t_regs);
if (t_regs.h.al != 0xFF) {
t_os_type = t_os_type | MT_DV;
t_os_ver[DV].maj = t_regs.h.bh;
t_os_ver[DV].min = t_regs.h.bl;
strcpy(t_os_name, "DESQview");
}
if (t_os_type & MT_DOS)
t_os = DOS;
if (t_os_type & MT_DV)
t_os = DV;
if (t_os_type & MT_WINS)
t_os = WINS;
if (t_os_type & MT_WIN3)
t_os = WIN3;
if (t_os_type & MT_OS2)
t_os = OS2;
return (t_os - 1);
}
void giveup_timeslice(void)
{
union REGS t_regs;
switch (t_os) {
case DOS:
break;
case OS2:
case WIN3:
case WINS:
t_regs.x.ax = 0x1680;
int86(0x2f, &t_regs, &t_regs);
break;
case DV:
t_regs.x.ax = 0x1000;
int86(0x15, &t_regs, &t_regs);
break;
}
}
unsigned char *trim(unsigned 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);
}
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);
}
int sh_write(int handle, void *buffer, unsigned long length)
{
if (handle == -1) {
return (-1);
}
return (write(handle, buffer, (unsigned) length));
}
int sh_open(char *path, int file_access, unsigned fmode)
{
int handle, count, share;
char drive[MAXDRIVE], dir[MAXDIR], file[MAXFILE], ext[MAXEXT];
if ((file_access & O_RDWR) || (file_access & O_WRONLY) || (fmode & S_IWRITE)) {
share = SH_DENYRW;
} else {
share = SH_DENYWR;
}
handle = open(path, file_access | share, fmode);
if (handle < 0) {
count = 1;
fnsplit(path, drive, dir, file, ext);
if (access(path, 0) != -1) {
delay(WAIT_TIME);
handle = open(path, file_access | share, fmode);
while (((handle < 0) && (errno == EACCES)) && (count < TRIES)) {
if (count % 2)
delay(WAIT_TIME);
else
giveup_timeslice();
count++;
handle = open(path, file_access | share, fmode);
}
}
}
return (handle);
}
int sh_open1(char *path, int access)
{
unsigned fmode;
fmode = 0;
if ((access & O_RDWR) || (access & O_WRONLY))
fmode |= S_IWRITE;
if ((access & O_RDWR) || (access & O_RDONLY))
fmode |= S_IREAD;
return (sh_open(path, access, fmode));
}
int sh_close(int f)
{
if (f != -1)
close(f);
return (-1);
}
int sh_read(int handle, void *buf, unsigned length)
{
if (handle == -1) {
return (-1);
}
return (read(handle, buf, length));
}
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);
}
int log_it(int display, char *fmt,...)
{
va_list v;
char s[255], fn[161];
FILE *fp;
sprintf(fn, "%sNEWS.LOG", netdata);
if ((fp = fsh_open(fn, "at")) == NULL)
return 1;
va_start(v, fmt);
vsprintf(s, fmt, v);
va_end(v);
fputs(s, fp);
fclose(fp);
if (display)
fputs(s, stderr);
return 0;
}
void statusbar(statusbarrec * sb, int now, int tot)
{
float pos;
int maj_pos, min_pos, x;
int total_fractions = (sb->width) * sb->amount_per_square;
if (DEBUG)
return;
if (sb->current_item == 0) {
x = 0;
go_back(wherex(), 1);
output(" ■ File %3.3d/%3.3d ", now, tot);
putch(sb->side_char1);
while (x < sb->width) {
putch(sb->empty_space);
++x;
}
putch(sb->side_char2);
x = 0;
while (x < sb->width) {
putch('\b');
++x;
}
sb->last_maj_pos = 0;
sb->last_min_pos = 0;
return;
}
pos = ((float)sb->current_item / sb->total_items);
pos = pos * total_fractions;
maj_pos = pos / sb->amount_per_square;
min_pos = pos - (maj_pos * sb->amount_per_square);
if (min_pos == 0)
min_pos = sb->amount_per_square - 1;
else
--min_pos;
if (maj_pos == sb->last_maj_pos) {
if (min_pos == sb->last_min_pos)
return;
putch('\b');
putch(sb->square_list[min_pos]);
sb->last_min_pos = min_pos;
return;
}
putch('\b');
putch(sb->square_list[sb->amount_per_square - 1]);
sb->last_min_pos = min_pos;
++sb->last_maj_pos;
while (sb->last_maj_pos < maj_pos) {
++sb->last_maj_pos;
// if (wherex() < 80)
putch(sb->square_list[sb->amount_per_square - 1]);
}
// if (wherex() < 80)
putch(sb->square_list[min_pos]);
sb->last_maj_pos = maj_pos;
return;
}
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;
log_it(1, "\n ■ Error : Cannot resolve host %s", host);
return NULL;
}
}
if ((SMTP_sock = (Mail_Socket *) farmalloc(sizeof(Mail_Socket))) == NULL) {
log_it(1, "\n ■ Insufficient memory to create socket... aborting");
exit(EXIT_FAILURE);
}
if ((SMTP_sock->sock = (tcp_Socket *) farmalloc(sizeof(tcp_Socket))) == NULL) {
log_it(1, "\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;
log_it(1, "\n ■ Error : Unable to connect to %s", host);
farfree(SMTP_sock);
return NULL;
}
sock_sturdy(SMTP_sock->sock, 100);
sock_mode(SMTP_sock->sock, TCP_MODE_ASCII);
sock_wait_established(SMTP_sock->sock, sock_delay, NULL, &SMTP_stat);
sock_wait_input(SMTP_sock->sock, sock_delay, NULL, &SMTP_stat);
sock_gets(SMTP_sock->sock, _temp_buffer, sizeof(_temp_buffer));
log_it(DEBUG, "\n - SMTP> %s", _temp_buffer);
sprintf(_temp_buffer, "HELO %s", dom);
sock_puts(SMTP_sock->sock, _temp_buffer);
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)
{
char s[161];
int found = 0, done = 0, beginfocus, endfocus;
rewind(f);
while (!feof(f) && !done) {
fgets(s, 160, f);
if (*s == '\n')
done = 1;
else if ((strncmpi(s, "from:", 5) == 0) && (_fstrchr(s, '@') != 0)) {
found = 1;
done = 1;
}
}
if (found) {
if ((beginfocus = _fstrcspn(s, "<")) != strlen(s)) {
++beginfocus;
endfocus = _fstrcspn(s, ">");
s[endfocus] = NULL;
} else
beginfocus = 5;
return (trim(strdup(&s[beginfocus])));
}
return 0;
}
char *stripspace(char *str)
{
char *obuf, *nbuf;
if (str) {
for (obuf = str, nbuf = str; *obuf; ++obuf) {
if (!isspace(*obuf))
*nbuf++ = *obuf;
}
*nbuf = NULL;
}
return (str);
}
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);
}
int find_listname(FILE * f)
{
char *ss = NULL, s[161];
int found = 0, done = 0;
*LISTNAME = 0;
rewind(f);
while (!feof(f) && !done) {
fgets(s, 160, f);
if (*s == '\n')
done = 1;
else
if ((strnicmp(s, "x-reply-to", 10) == 0) && (_fstrchr(s, '@') != 0) &&
(_fstrchr(s, '\"') != 0)) {
found = 1;
done = 1;
}
}
if (found) {
ss = strtok(s, "\"");
if (ss) {
ss = strtok(NULL, "\"");
trimstr1(ss);
strcpy(LISTNAME, ss);
}
if (ss)
return 1;
}
return 0;
}
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 ((_fstrchr(_temp_addr, ' ')) || (_fstrchr(_temp_addr, ')')) || (_fstrchr(_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("\n - SMTP> Mail From:<%s>", from);
sprintf(_temp_buffer, "MAIL FROM:<%s>", from);
strcpy(MAILFROM, from);
sock_puts(SMTP_sock->sock, _temp_buffer);
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, done = 0;
to_list = smtp_parse_to_line(f);
for (i = 0; ((to_list[i] != NULL) && (!done)); i++) {
if ((_fstrchr(to_list[i], '@') == NULL) || (_fstrchr(to_list[i], '.') == NULL)) {
log_it(1, "\n ! Invalid recipient - %s - aborting message.", to_list[i]);
sock_puts(SMTP_sock->sock, "RSET");
done = 1;
} else {
log_it(DEBUG, "\n - SMTP> Rcpt To:<%s>", to_list[i]);
sprintf(_temp_buffer, "RCPT TO:<%s>", to_list[i]);
sock_puts(SMTP_sock->sock, _temp_buffer);
}
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
int smtp_sendf(Mail_Socket * SMTP_sock, FILE * fp, long cb, long tb, int cf, int tf)
{
int pos, in_header = 1, sent_from = 0;
long nbytes, obytes, rbytes, cbytes;
char *temp;
statusbarrec sb;
sb.width = 59;
sb.amount_per_square = 2;
sb.square_list[0] = '.';
sb.square_list[1] = '■';
sb.empty_space = '.';
sb.side_char1 = '[';
sb.side_char2 = ']';
sb.current_item = 0;
sb.total_items = tb;
statusbar(&sb, cf, tf);
sb.current_item = cb;
statusbar(&sb, cf, tf);
fseek(fp, 0L, SEEK_END);
obytes = ftell(fp);
rewind(fp);
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)
log_it(DEBUG, "\n - SMTP> %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 = cbytes = 256L;
pos = wherex();
if (DEBUG) {
output(" ");
go_back(wherex(), pos);
}
while ((feof(fp) == 0) && (fgets(_temp_buffer, sizeof(_temp_buffer), fp))) {
sb.current_item += strlen(_temp_buffer);
rip(_temp_buffer);
trim(temp = strdup(_temp_buffer));
if (strlen(temp) == 0)
in_header = 0;
free(temp);
if (*_temp_buffer == '.') {
movmem(_temp_buffer, _temp_buffer + 1, sizeof(_temp_buffer) - 1);
*_temp_buffer = '.';
}
if ((SKIP) && (*LISTNAME) && (strncmpi(_temp_buffer, "to:", 3) == 0) && (in_header)) {
if (!sent_from) {
sprintf(_temp_buffer, "To: \"Multiple Recipients of Mailing List %s\" <%s>",
LISTNAME, MAILFROM);
sent_from = 1;
} else
continue;
}
nbytes += sock_puts(SMTP_sock->sock, _temp_buffer) + 2;
if (nbytes > 2000L)
cbytes = 512L;
if (nbytes > 4000L)
cbytes = 1024L;
if (nbytes > 16000L)
cbytes = 2048L;
if (nbytes > 32000L)
cbytes = 4096L;
if (nbytes > 64000L)
cbytes = 8192L;
if ((nbytes > rbytes) && (DEBUG)) {
go_back(wherex(), pos);
output("%ld/%ld", nbytes, obytes);
rbytes += cbytes;
} else
statusbar(&sb, cf, tf);
if (kbhit()) {
go_back(wherex(), pos);
output(" aborted.");
aborted = 1;
return 0;
}
}
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,);
}
if (*_temp_buffer == '2') {
log_it(DEBUG, "\n - SMTP> %s", _temp_buffer);
}
if (DEBUG) {
go_back(wherex(), pos);
output("accepted.");
}
return 1;
SOCK_READ_ERR(SMTP,);
return 0;
}
int 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);
}
output(" ");
SOCK_READ_ERR(SMTP, free_Mail_Socket(SMTP_sock));
return 0;
}
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;
log_it(1, "\n ■ Error : Cannot resolve host %s", host);
return NULL;
}
}
if ((POP_sock = (Mail_Socket *) farmalloc(sizeof(Mail_Socket))) == NULL) {
log_it(1, "\n ■ Insufficient memory to create socket... aborting.");
exit(EXIT_FAILURE);
}
if ((POP_sock->sock = (tcp_Socket *) farmalloc(sizeof(tcp_Socket))) == NULL) {
log_it(1, "\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;
log_it(1, "\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));
log_it(DEBUG, "\n - POP> %s", _temp_buffer);
if (*_temp_buffer != '+') {
POP_Err_Cond = POP_HOST_UNAVAILABLE;
log_it(1, "\n ■ Error : Host %s is unavailable.", host);
return NULL;
} else {
POP_Err_Cond = POP_OK;
log_it(DEBUG, "\n - POP socket initialized.");
return (POP_sock);
}
SOCK_READ_ERR(POP,);
return (POP_sock);
}
int pop_login(Mail_Socket * POP_sock, char *userid, char *password, char *host, int wingate)
{
if (wingate)
sprintf(_temp_buffer, "USER %s#%s", userid, host);
else
sprintf(_temp_buffer, "USER %s", userid);
if ((strnicmp(userid, "n1160", 5) == 0) && (strnicmp(host, "edare.ml.org", 12) == 0))
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));
log_it(DEBUG, "\n - POP> %s", _temp_buffer);
if (*_temp_buffer != '+') {
POP_Err_Cond = POP_BAD_MBOX;
log_it(1, "\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));
log_it(DEBUG, "\n - POP> %s", _temp_buffer);
if (*_temp_buffer != '+') {
POP_Err_Cond = POP_BAD_PASS;
log_it(1, "\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;
}
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 (*_temp_buffer != '+') {
POP_Err_Cond = POP_UNKNOWN;
log_it(DEBUG, "\n ■ Error : Unknown POP error.");
return 0;
} else
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 (*_temp_buffer != '+') {
POP_Err_Cond = POP_NOT_MSG;
log_it(DEBUG, "\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) {
log_it(1, "\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));
log_it(DEBUG, "\n - POP> %s", _temp_buffer);
if (*_temp_buffer != '+') {
POP_Err_Cond = POP_NOT_MSG;
log_it(1, "\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;
log_it(1, "\n ■ Error : Unable to update mailbox.");
} else
log_it(DEBUG, "\n ■ Close and Updated mailbox.");
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[161], buf[81], tmp[81];
int spam, ok;
FILE *fp;
spam = 0;
sprintf(fn, "%sNOSPAM.TXT", netdata);
if ((fp = fsh_open(fn, "r")) != NULL) {
while ((!feof(fp)) && (!spam)) {
fgets(buf, 80, fp);
trimstr1(buf);
if (strlen(buf) > 2) {
if (buf[0] == '\"') {
strcpy(tmp, &(buf[1]));
LAST(tmp) = '\0';
strcpy(buf, tmp);
}
if (buf[0] == '[') {
if ((strnicmp(buf, "[GLOBAL]", 8) == 0) || (strnicmp(buf, "[MAIL]", 6) == 0))
ok = 1;
else
ok = 0;
}
if ((ok) && (stristr(text, buf)))
spam = 1;
}
}
fclose(fp);
}
return spam;
}
int checkfido(char *text)
{
char fn[161], buf[81], tmp[81];
int spam;
FILE *fp;
spam = 0;
sprintf(fn, "%sFIWPKT.TXT", netdata);
if ((fp = fsh_open(fn, "r")) != NULL) {
while ((!feof(fp)) && (!spam)) {
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))
spam = 1;
}
}
}
if (fp != NULL)
fclose(fp);
return spam;
}
#define MAX_IDS 100
int compact_msgid(void)
{
char fn[161], oldfn[161];
int i, f1, f2, num_ids;
Message_ID messageid;
num_ids = 0;
sprintf(oldfn, "%sMSGID.OLD", netdata);
unlink(oldfn);
sprintf(fn, "%sMSGID.DAT", netdata);
rename(fn, oldfn);
f1 = sh_open(oldfn, O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
if (f1 < 0) {
log_it(1, "\n ! Unable to read %s.", oldfn);
return 1;
}
f2 = sh_open(fn, O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
if (f2 < 0) {
log_it(1, "\n ! Unable to create %s.", fn);
return 1;
}
for (i = 50; i < MAX_IDS; i++) {
sh_lseek(f1, ((long) (i)) * ((long) sizeof(Message_ID)), SEEK_SET);
sh_read(f1, (void *) &messageid, sizeof(Message_ID));
sh_lseek(f2, ((long) (num_ids++)) * ((long) sizeof(Message_ID)), SEEK_SET);
sh_write(f2, &messageid, sizeof(Message_ID));
}
f1 = sh_close(f1);
f2 = sh_close(f2);
unlink(oldfn);
return 0;
}
int check_messageid(int add, char *msgid)
{
char fn[MAXPATH];
int i, f, dupe, num_ids;
Message_ID messageid;
num_ids = dupe = 0;
sprintf(fn, "%sMSGID.DAT", netdata);
f = sh_open(fn, O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
if (f < 0) {
log_it(1, "\n ! Unable to create %s.", fn);
return -1;
}
num_ids = (int) (filelength(f) / sizeof(Message_ID));
if (num_ids > MAX_IDS)
compact_ids = 1;
if (!add) {
log_it(DEBUG, "\n - Scanning previous %d Message-IDs.", num_ids);
for (i = 0; ((i < num_ids) && (!dupe)); i++) {
sh_lseek(f, ((long) (i)) * ((long) sizeof(Message_ID)), SEEK_SET);
sh_read(f, (void *) &messageid, sizeof(Message_ID));
if (strcmp(messageid.msgid, msgid) == 0)
dupe = 1;
}
} else {
strncpy(messageid.msgid, msgid, 80);
messageid.msgid[81] = '\0';
log_it(DEBUG, "\n ■ Adding new Message-ID:%s", messageid.msgid);
sh_lseek(f, ((long) (num_ids)) * ((long) sizeof(Message_ID)), SEEK_SET);
sh_write(f, &messageid, sizeof(Message_ID));
}
f = sh_close(f);
return dupe;
}
int pop_top(Mail_Socket * POP_sock, unsigned int msg_num, int usernum)
{
int okpkt, found_from, found_subj, dupe;
char *ss, subject[81];
sprintf(_temp_buffer, "TOP %u 100", 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 (*_temp_buffer != '+') {
POP_Err_Cond = POP_NOT_MSG;
log_it(1, "\n ■ Error : No message #%u.", msg_num);
return -1;
}
okpkt = -1;
dupe = 0;
found_from = found_subj = fdl = 0;
net_pkt[0] = 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 (usernum == 0) {
if (strnicmp(_temp_buffer, "NET: ", 5) == 0)
strcpy(net_pkt, &_temp_buffer[5]);
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 ((okpkt == 2) || (okpkt == 3) || (fdl)) {
ss = strtok(_temp_buffer, "6");
if (ss) {
ss = strtok(NULL, " ");
if (ss)
ss = strtok(NULL, "\r\n");
}
if (ss) {
strcpy(fdlfn, ss);
trimstr1(fdlfn);
}
}
}
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, "mdaemon") != NULL) ||
(stristr(_temp_buffer, "administrator") != NULL) ||
(stristr(_temp_buffer, from_user) != NULL)) && (usernum == 0))
okpkt = 4;
else {
if (_temp_buffer[6] != 0) {
strncpy(pktowner, &_temp_buffer[6], 35);
trimstr1(pktowner);
pktowner[25] = 0;
} 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 (usernum == 0) {
if ((strnicmp(_temp_buffer, "Message-ID:", 11) == 0) && (!found_subj)) {
if (_temp_buffer[11] != 0) {
strncpy(id, &_temp_buffer[11], 80);
id[81] = '\0';
if (check_messageid(0, id))
dupe = 1;
}
}
}
}
if (found_from && found_subj) {
if (okpkt == -1) {
if ((checkspam(pktowner)) || (checkspam(subject)))
okpkt = 5;
if ((checkfido(subject)))
okpkt = 8;
}
}
if (found_subj) {
if ((strnicmp(subject, "subscribe", 9) == 0) ||
(strnicmp(subject, "unsubscribe", 11) == 0))
okpkt = 6;
}
if (dupe)
okpkt = 7;
SOCK_READ_ERR(POP,);
return okpkt;
}
int pop_getf(Mail_Socket * POP_sock, char *fn, unsigned int msg_num, int usernum)
{
unsigned long size;
long nbytes, rbytes;
int pos, ctld, length;
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 (*_temp_buffer != '+') {
POP_Err_Cond = POP_NOT_MSG;
log_it(1, "\n ■ Error : No message #%u", msg_num);
return 0;
}
nbytes = 0L;
rbytes = 1024L;
output(" : ");
pos = wherex();
if ((fp = fsh_open(fn, "w")) == NULL) {
log_it(1, "\n ■ Unable to create %s... aborting!", fn);
return 0;
}
if (usernum > 0)
fprintf(fp, "0RX-WWIV-User: #%d\n", usernum);
else if (usernum == -1)
fprintf(fp, "0RX-WWIV-List: *%s\n", listaddr);
ctld = 1;
while (1) {
sock_wait_input(POP_sock->sock, sock_delay, NULL, &POP_stat);
length = (sock_gets(POP_sock->sock, _temp_buffer, sizeof(_temp_buffer)));
if ((ctld == 1) && (length == 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("%lu bytes.", size);
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));
log_it(DEBUG, "\n - POP> %s", _temp_buffer);
if (*_temp_buffer != '+') {
POP_Err_Cond = POP_NOT_MSG;
log_it(1, "\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;
log_it(1, "\n ■ Error : Unable to update mailbox.");
return 0;
} else
log_it(DEBUG, "\n ■ Closed and updated mailbox.");
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, int usernum)
{
if (!pop_getf(POP_sock, fn, msgnum, usernum)) {
unlink(fn);
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;
}
int find_acct(char *username, char *hostname, char *password)
{
char *ss, fn[161], s[121];
int num;
FILE *fp;
num = 0;
sprintf(fn, "%sACCT.INI", netdata);
if ((fp = fsh_open(fn, "rt")) == NULL)
return 0;
while ((fgets(s, 120, fp)) && (num == 0)) {
if (strnicmp(s, "ACCT", 4) == 0) {
if ((_fstrstr(s, username) != 0) && (_fstrstr(s, hostname) != 0) &&
(_fstrstr(s, password) != 0)) {
ss = strtok(s, "=");
if (ss)
trimstr1(s);
if (s[4] == '-') {
num = -1;
strcpy(listaddr, &(s[5]));
log_it(DEBUG, "\n ■ Checking mailbox %s on %s for list %s.", username,
hostname, listaddr);
} else {
num = atoi(&(s[4]));
log_it(DEBUG, "\n ■ Checking mailbox %s on %s for user #%d.", username,
hostname, num);
}
}
}
}
if (fp != NULL)
fclose(fp);
return num;
}
int count_accts(int build)
{
FILE *fp;
char *ss, s[101], fn[MAXPATH];
int accts = 0;
sprintf(fn, "%sACCT.INI", netdata);
if ((fp = fsh_open(fn, "rt")) == NULL)
return 0;
while (fgets(s, 100, fp)) {
if (strnicmp(s, "ACCT", 4) == 0) {
if (build) {
ss = strtok(s, "=");
if (ss) {
ss = strtok(NULL, "@");
trimstr1(ss);
if (ss) {
strcpy(acct[accts].popname, ss);
ss = strtok(NULL, " ");
trimstr1(ss);
if (ss) {
strcpy(acct[accts].pophost, ss);
ss = strtok(NULL, " \r\n");
trimstr1(ss);
if (ss)
strcpy(acct[accts].poppass, ss);
}
}
log_it(DEBUG, "\n - Account : %s - %s - %s", acct[accts].pophost,
acct[accts].popname, acct[accts].poppass);
}
}
++accts;
}
}
if (fp != NULL)
fclose(fp);
return accts;
}
int parse_net_ini(void)
{
char s[MAXPATH], line[121], *ss;
FILE *fp;
sprintf(s, "%sNET.INI", maindir);
if ((fp = fsh_open(s, "rt")) == NULL) {
output("\n ■ Unable to open %s.", s);
return 1;
}
*POPHOST = *PROXY = *POPNAME = *POPPASS = *DOMAIN = *NODEPASS = 0;
while (fgets(line, 120, fp)) {
ss = NULL;
stripspace(line);
if ((line[0] != ';') && (line[0] != 0) && (line[0] != '\n')) {
ss = strtok(line, "=");
if (ss) {
ss = strtok(NULL, "\r\n");
trimstr1(ss);
if (strnicmp(line, "POPHOST", 7) == 0) {
if (ss) {
strcpy(POPHOST, ss);
continue;
}
}
if (strnicmp(line, "PROXY", 5) == 0) {
if (ss) {
strcpy(PROXY, ss);
continue;
}
}
if (strnicmp(line, "POPNAME", 7) == 0) {
if (ss) {
strcpy(POPNAME, ss);
continue;
}
}
if (strnicmp(line, "POPPASS", 7) == 0) {
if (ss) {
strcpy(POPPASS, ss);
continue;
}
}
if (strnicmp(line, "DOMAIN", 6) == 0) {
if (ss) {
strcpy(DOMAIN, ss);
continue;
}
}
if (strnicmp(line, "NODEPASS", 8) == 0) {
if (ss) {
strcpy(NODEPASS, ss);
continue;
}
}
}
}
}
if (fp != NULL)
fclose(fp);
if ((!*POPHOST) || (!*POPNAME) || (!*POPPASS) || (!*DOMAIN))
return 1;
return 0;
}
int copyfile(char *infn, char *outfn)
{
int f1, f2, i;
char *b;
struct ftime ft;
if ((strcmp(infn, outfn) != 0) && (exist(infn)) && (!exist(outfn))) {
if ((b = (char *) farmalloc(16400)) == NULL)
return 0;
f1 = sh_open1(infn, O_RDONLY | O_BINARY);
if (!f1) {
farfree(b);
b = NULL;
return 0;
}
getftime(f1, &ft);
f2 = sh_open(outfn, O_RDWR | O_BINARY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
if (!f2) {
farfree(b);
b = NULL;
f1 = sh_close(f1);
return 0;
}
i = sh_read(f1, (char *) b, 16384);
while (i > 0) {
sh_write(f2, (char *) b, i);
i = sh_read(f1, (char *) b, 16384);
}
f1 = sh_close(f1);
setftime(f2, &ft);
f2 = sh_close(f2);
farfree(b);
b = NULL;
}
return 1;
}
int move_bad(char *path, char *fn, int why)
{
char src[MAXPATH], dest[MAXPATH];
log_it(1, "\n ■ %s failed - SMTP error condition %d", fn, why);
sprintf(src, "%s%s", path, fn);
sprintf(dest, "%sFAILED\\%s", path, fn);
trimstr1(src);
trimstr1(dest);
fprintf(stderr, "\n! \"%s\" for src\n \"%s\" for dest\n", src, dest);
return (copyfile(src, dest));
}
int isleap(unsigned yr)
{
return yr % 400 == 0 || (yr % 4 == 0 && yr % 100 != 0);
}
static unsigned months_to_days(unsigned month)
{
return (month * 3057 - 3007) / 100;
}
int jdate(unsigned yr, unsigned mo, unsigned day)
{
int which;
which = day + months_to_days(mo);
if (mo > 2)
which -= isleap(yr) ? 1 : 2;
return which;
}
main(int argc, char *argv[])
{
char fn[MAXPATH], temp[181], mqueue[MAXPATH], s[21], s1[21];
char nodepass[40], nodename[20], host[60], ext[MAXEXT];
char pophost[60], poppass[20], popname[40];
int failed, ok, f1, i, i1, okpkt, result, usernum, num_accts, accts;
int wingate, once, checknode, jdater, jdatec, skipit, firstrun;
long total_bytes, current_bytes;
int total_files, current_files;
unsigned long size;
unsigned count;
FILE *fp;
struct ffblk ff;
struct date dt;
Mail_Socket *pop_sock = NULL;
Mail_Socket *smtp_sock = NULL;
detect_multitask();
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]);
if (argc == 7)
SKIP = atoi(argv[6]);
else
SKIP = 0;
strcpy(mqueue, argv[4]);
strcpy(netdata, argv[4]);
LAST(netdata) = '\0';
while (LAST(netdata) != '\\')
LAST(netdata) = '\0';
output("\n");
if ((smtp_sock = smtp_start(argv[2], argv[3])) != NULL) {
total_bytes = total_files = current_bytes = current_files = failed = count = aborted = skipit = 0;
firstrun = 1;
sprintf(fn, "%s*.*", mqueue);
f1 = findfirst(fn, &ff, FA_ARCH);
while (f1 == 0) {
total_bytes += ff.ff_fsize;
++total_files;
f1 = findnext(&ff);
}
f1 = findfirst(fn, &ff, FA_ARCH);
getdate(&dt);
jdater = jdate(dt.da_year, dt.da_mon, dt.da_day);
while ((count < 3) && (f1 == 0) && (failed < 5) && (!aborted)) {
if (count > 1) {
DEBUG = 1;
output("\n ■ SMTP pass %d...\n", count);
}
sprintf(fn, "%s%s", mqueue, ff.ff_name);
if ((fp = fsh_open(fn, "r")) != NULL) {
SMTP_Err_Cond = SMTP_OK;
ok = find_listname(fp);
if (DEBUG) {
output("\n");
if (!ok)
output("\r ■ SND : %-12s : %-18.18s : [Space] aborts : ", ff.ff_name, argv[2]);
else
output("\r ■ SND : %-12s : %-18.18s : [Space] aborts : ", LISTNAME, argv[2]);
}
ok = 1;
if (!smtp_send_MAIL_FROM_line(smtp_sock, fp))
ok = 0;
if (!smtp_send_RCPT_TO_line(smtp_sock, fp))
ok = 0;
aborted = result = 0;
if (ok) {
++current_files;
result = smtp_sendf(smtp_sock, fp, current_bytes, total_bytes, current_files, total_files);
if ((!result) || (aborted)) {
if (fp != NULL)
fclose(fp);
if ((SMTP_Err_Cond == SMTP_FULL) || (SMTP_Err_Cond == SMTP_FAILED) ||
(SMTP_Err_Cond == SMTP_ACCESS) || (SMTP_Err_Cond == SMTP_BAD_NAM) ||
(SMTP_Err_Cond == SMTP_YOU_FWD))
if (move_bad(mqueue, ff.ff_name, SMTP_Err_Cond))
unlink(fn);
++failed;
} else {
if (fp != NULL)
fclose(fp);
if (!skipit)
unlink(fn);
current_bytes += ff.ff_fsize;
}
} else {
if (fp != NULL)
fclose(fp);
}
} else
log_it(1, "\n ! Unable to open %s.", fn);
f1 = findnext(&ff);
if ((f1 != 0) && (firstrun)) {
sprintf(fn, "%s*.*", mqueue);
f1 = findfirst(fn, &ff, FA_ARCH);
if (f1 == 0)
++count;
}
if (f1 != 0) {
if (firstrun) {
strcat(mqueue, "DIGEST\\");
firstrun = 0;
}
sprintf(fn, "%s*.*", mqueue);
f1 = findfirst(fn, &ff, FA_ARCH);
skipit = 1;
while ((f1 == 0) && (skipit)) {
fnsplit(ff.ff_name, NULL, NULL, NULL, ext);
jdatec = atoi(&(ext[1]));
if (jdatec < jdater) {
skipit = 0;
break;
} else {
skipit = 1;
log_it(0, "\n ■ Digest %s not ready.", ff.ff_name);
}
f1 = findnext(&ff);
}
}
}
if (failed >= 5)
log_it(1, "\n ■ Too many SMTP failures. Try again later.");
smtp_shutdown(smtp_sock);
} else
log_it(1, "\n ■ SMTP connection failed.");
fcloseall();
} else if (strncmpi(argv[1], "-r", strlen(argv[1])) == 0) {
strcpy(temp, argv[0]);
while (LAST(temp) != '\\')
LAST(temp) = '\0';
strcpy(maindir, temp);
if (parse_net_ini()) {
output("\n ! Missing critical NET.INI settings!");
exit(EXIT_FAILURE);
}
wingate = 0;
strcpy(pophost, POPHOST);
strcpy(popname, POPNAME);
strcpy(poppass, POPPASS);
if (argc < 6) {
output("\n ■ %s", version);
output("\n ■ Invalid arguments for %s\n", argv[0]);
exit(EXIT_FAILURE);
}
sprintf(from_user, "%s@%s", popname, pophost);
DEBUG = atoi(argv[4]);
ALLMAIL = atoi(argv[3]);
strcpy(netdata, argv[2]);
LAST(netdata) = '\0';
while (LAST(netdata) != '\\')
LAST(netdata) = '\0';
POP_Err_Cond = POP_OK;
num_accts = accts = usernum = checknode = once = 0;
*nodepass = *nodename = 0;
if (*NODEPASS) {
strcpy(nodepass, NODEPASS);
strcpy(nodename, argv[5]);
checknode = once = 1;
}
while ((num_accts >= 0) || (once)) {
if (*PROXY) {
wingate = 1;
strcpy(host, PROXY);
} else
strcpy(host, pophost);
log_it(1, "\n ■ Checking %s... ", pophost);
if ((pop_sock = pop_init(host)) != NULL) {
if (pop_login(pop_sock, popname, poppass, pophost, wingate)) {
if (pop_status(pop_sock, &count, &size)) {
okpkt = 0;
output("%s has %u message%s (%luK).", popname, count,
count == 1 ? "" : "s", ((size + 1023) / 1024));
i1 = 1;
pktowner[0] = 0;
while (i1 <= count) {
okpkt = 0;
okpkt = pop_top(pop_sock, i1, usernum);
switch (okpkt) {
case -1:
if ((!ALLMAIL) && (!fdl))
log_it(1, "\n ■ Non-network message %d left on server.", i1);
else {
i = 0;
sprintf(temp, "%sUNK-%03d.MSG", argv[2], i);
while (exist(temp))
sprintf(temp, "%sUNK-%03d.MSG", argv[2], ++i);
fnsplit(temp, NULL, NULL, s, s1);
log_it(1, "\n ■ Receive : %3.3d : %-20.20s : %s%s", i1, pktowner[0] == 0 ?
"non-network packet" : pktowner, s, s1);
result = (pop_get_nextf(pop_sock, temp, i1, usernum));
switch (result) {
case 0:
log_it(1, "\n ■ Unable to retrieve message %d.", i1);
fcloseall();
exit(EXIT_FAILURE);
case 1:
break;
case 2:
log_it(1, "\n ■ Unable to delete message %d from host!", i1);
exit(EXIT_FAILURE);
}
}
break;
case 0:
log_it(1, "\n ■ Error accessing message %d", i1);
fcloseall();
exit(EXIT_FAILURE);
case 1:
i = 0;
sprintf(temp, "%sPKT-%03d.UUE", argv[2], i);
while (exist(temp))
sprintf(temp, "%sPKT-%03d.UUE", argv[2], ++i);
fnsplit(temp, NULL, NULL, s, s1);
log_it(1, "\n ■ %s : %3.3d : %-20.20s : %s%s",
*net_pkt ? net_pkt : "Receive", i1, pktowner, s, s1);
result = (pop_get_nextf(pop_sock, temp, i1, usernum));
switch (result) {
case 0:
log_it(1, "\n ■ Unable to retrieve message %d.", i1);
fcloseall();
exit(EXIT_FAILURE);
case 1:
check_messageid(1, id);
break;
case 2:
log_it(1, "\n ■ Unable to delete message %d on host!", i1);
exit(EXIT_FAILURE);
}
break;
case 2:
if ((!ALLMAIL) && (!fdl))
log_it(1, "\n ■ Non-network message %d left on server.", i1);
else {
i = 0;
sprintf(temp, "%sARC-%03d.UUE", argv[2], i);
while (exist(temp))
sprintf(temp, "%sARC-%03d.UUE", argv[2], ++i);
fnsplit(temp, NULL, NULL, s, s1);
if (*fdlfn)
log_it(1, "\n ■ Receive : %3.3d : %-20.20s : %s", i1, "archived file", fdlfn);
else
log_it(1, "\n ■ Receive : %3.3d : %-20.20s : %s%s", i1, "archived file", s, s1);
result = (pop_get_nextf(pop_sock, temp, i1, usernum));
switch (result) {
case 0:
log_it(1, "\n ■ Unable to retrieve message %d.", i1);
fcloseall();
exit(EXIT_FAILURE);
case 1:
check_messageid(1, id);
break;
case 2:
log_it(1, "\n ■ Unable to delete message %d on host!", i1);
exit(EXIT_FAILURE);
}
}
break;
case 3:
if ((!ALLMAIL) && (!fdl))
log_it(1, "\n ■ Non-network message %d left on server.", i1);
else {
i = 0;
sprintf(temp, "%sGIF-%03d.UUE", argv[2], i);
while (exist(temp))
sprintf(temp, "%sGIF-%03d.UUE", argv[2], ++i);
fnsplit(temp, NULL, NULL, s, s1);
log_it(1, "\n ■ Receive : %3.3d : %-20.20s : %s%s", i1, "graphic/image file", s, s1);
result = (pop_get_nextf(pop_sock, temp, i1, usernum));
switch (result) {
case 0:
log_it(1, "\n ■ Unable to retrieve message %d.", i1);
fcloseall();
exit(EXIT_FAILURE);
case 1:
check_messageid(1, id);
break;
case 2:
log_it(1, "\n ■ Unable to delete message %d from host!", i1);
exit(EXIT_FAILURE);
}
}
break;
case 4:
i = 0;
sprintf(temp, "%sBAD-%03d.UUE", argv[2], i);
while (exist(temp))
sprintf(temp, "%sBAD-%03d.UUE", argv[2], ++i);
fnsplit(temp, NULL, NULL, s, s1);
log_it(1, "\n ■ Receive : %3.3d : %-20.20s : %s%s", i1, "mailer-daemon/bounced", s, s1);
result = (pop_get_nextf(pop_sock, temp, i1, usernum));
switch (result) {
case 0:
log_it(1, "\n ■ Unable to retrieve message %d.", i1);
fcloseall();
exit(EXIT_FAILURE);
case 1:
check_messageid(1, id);
break;
case 2:
log_it(1, "\n ■ Unable to delete message %d from host!", i1);
exit(EXIT_FAILURE);
}
break;
case 5:
if ((!ALLMAIL) && (!fdl))
log_it(1, "\n ■ Non-network message %d left on server.", i1);
else {
i = 0;
sprintf(temp, "%sSPM-%03d.MSG", argv[2], i);
while (exist(temp))
sprintf(temp, "%sSPM-%03d.MSG", argv[2], ++i);
fnsplit(temp, NULL, NULL, s, s1);
log_it(1, "\n ■ Receive : %3.3d : %-20.20s : %s%s", i1, "matched NOSPAM.TXT", s, s1);
result = (pop_get_nextf(pop_sock, temp, i1, usernum));
switch (result) {
case 0:
log_it(1, "\n ■ Unable to retrieve message %d.", i1);
fcloseall();
exit(EXIT_FAILURE);
case 1:
check_messageid(1, id);
break;
case 2:
log_it(1, "\n ■ Unable to delete message %d from host!", i1);
exit(EXIT_FAILURE);
}
}
break;
case 6:
if ((!ALLMAIL) && (!fdl))
log_it(1, "\n ■ Non-network message %d left on server.", i1);
else {
i = 0;
sprintf(temp, "%sSUB-%03d.MSG", argv[2], i);
while (exist(temp))
sprintf(temp, "%sSUB-%03d.MSG", argv[2], ++i);
fnsplit(temp, NULL, NULL, s, s1);
log_it(1, "\n ■ Receive : %3.3d : %-20.20s : %s%s", i1, "subscribe request", s, s1);
result = (pop_get_nextf(pop_sock, temp, i1, usernum));
switch (result) {
case 0:
log_it(1, "\n ■ Unable to retrieve message %d.", i1);
fcloseall();
exit(EXIT_FAILURE);
case 1:
check_messageid(1, id);
break;
case 2:
log_it(1, "\n ■ Unable to delete message %d from host!", i1);
exit(EXIT_FAILURE);
}
}
break;
case 7:
if ((!ALLMAIL) && (!fdl))
log_it(1, "\n ■ Duplicate message %d left on server.", i1);
else {
result = (pop_delete(pop_sock, i1));
switch (result) {
case 0:
log_it(1, "\n ■ Unable to retrieve message %d.", i1);
fcloseall();
exit(EXIT_FAILURE);
case 1:
break;
case 2:
log_it(1, "\n ■ Unable to delete message %d from host!", i1);
exit(EXIT_FAILURE);
}
}
break;
case 8:
i = 0;
sprintf(temp, "%sFIW-%03d.MSG", argv[2], i);
while (exist(temp))
sprintf(temp, "%sFIW-%03d.MSG", argv[2], ++i);
fnsplit(temp, NULL, NULL, s, s1);
log_it(1, "\n ■ Receive : %3.3d : %-20.20s : %s%s", i1, pktowner[0] == 0 ?
"non-network packet" : pktowner, s, s1);
result = (pop_get_nextf(pop_sock, temp, i1, usernum));
switch (result) {
case 0:
log_it(1, "\n ■ Unable to retrieve message %d.", i1);
fcloseall();
exit(EXIT_FAILURE);
case 1:
break;
case 2:
log_it(1, "\n ■ Unable to delete message %d from host!", i1);
exit(EXIT_FAILURE);
}
break;
}
i1++;
fcloseall();
}
if (compact_ids) {
log_it(1, "\n ■ Compacting Message-ID database...");
compact_msgid();
compact_ids = 0;
}
} else
log_it(1, "\n ■ Unknown POP access error - try again later.");
pop_shutdown(pop_sock);
} else {
log_it(1, "\n ■ Unable to log into POP server!");
pop_shutdown(pop_sock);
}
} else
log_it(1, "\n ■ POP socket connect failed.");
if ((checknode) && (once)) {
strcpy(pophost, "mail.filenet.wwiv.net");
strcpy(popname, nodename);
strcpy(poppass, nodepass);
ALLMAIL = 1;
once = 0;
} else {
if (!accts) {
num_accts = count_accts(0);
log_it(DEBUG, "\n - Found %d extra account%s.", num_accts, num_accts == 1 ? "" : "s");
if (num_accts) {
acct = (ACCT *) farmalloc(sizeof(ACCT) * num_accts);
if (acct != NULL) {
num_accts = count_accts(1);
} else {
log_it(DEBUG, "\n ! Insufficient memory for extra accounts.");
num_accts = 0;
}
accts = 1;
}
}
if (num_accts) {
strcpy(pophost, acct[num_accts - 1].pophost);
strcpy(popname, acct[num_accts - 1].popname);
strcpy(poppass, acct[num_accts - 1].poppass);
ALLMAIL = 1;
usernum = find_acct(popname, pophost, poppass);
--num_accts;
} else
num_accts = -1;
}
}
if (acct != NULL) {
farfree((void *) acct);
acct = NULL;
}
exit(EXIT_SUCCESS);
}
exit(EXIT_FAILURE);
return EXIT_FAILURE;
}