home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 2 BBS
/
02-BBS.zip
/
XGRP_000.SZH
/
EMAILIN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-22
|
62KB
|
1,808 lines
/* net/echo/groupmail tosser/forwarder */
/* NOTE: this code maintains but *does not use* SEEN-BYs. This code
*eliminates* current ^aPATH lines and replaces/merges them with
^aNPTH lines (5-D). Tiny Seenbys are the default; use them wherever
possible and cut down on useless overhead. Fingers down the throat
of echopol. Long live TJ and other anarchistic SOBs like himself. */
#include <limits.h>
#include "xgroup.h"
#define MAXKLUDGE 256
#define MAXARCEXTS 7
#define IS_UNKNOWN 1
#define IS_INSECURE 2
#define IS_ADUPE 3
#define IS_NOFORWARD 4
/* local-only functions */
static int _fastcall bitch_and_moan_again (ADDR *addr,char *area);
static int _fastcall bitch_and_moan (ADDR *addr,char *area);
static int _fastcall crack_pkt (char *pktname);
static int _fastcall import (char *buff,XMSG *msg,ECHOREC *currecho,
GROUP *currgroup,word msgnum);
static int _fastcall get_msg (word buflen,char *buff,char **text,int fp,
XMSG *msg);
static void _fastcall report (void);
static int _fastcall open_msg_files (word areano);
static int _fastcall forward (char *buff,XMSG *xmsg,ECHOREC *currecho,
GROUP *currgroup,ADDR *pktaddr);
static int _fastcall unknown (char *buff,XMSG *xmsg,char *area);
static int _fastcall insecure (char *buff,XMSG *xmsg,char *area);
static int _fastcall isadupe (char *buff,XMSG *xmsg,char *area);
static int _fastcall is_notforwarded (char *buff,XMSG *xmsg);
static int _fastcall open_pkt (ADDR *addr,ADDR *faddr,int which);
static word _fastcall find_last_scanned (int dataptr);
static int _fastcall write_pkt_msg (int fp,XMSG *amsg,SB *opth,ADDR *naddr,
ADDR *maddr,char *text,char *area,
SB *sb);
word _fastcall make_message (char *text,XMSG *xmsg);
/* local-only vars */
static int dataptr = -1,textptr = -1,grunged_date = 0, grunged_area = 0,
grunged_seenbys = 0;
static word netimported = 0,netforwarded = 0,unknownmsgs = 0,
insecuremsgs = 0,numdupes = 0,notforwarded = 0,numassholes = 0;
static char *newpath,*pathline,*seenby,*area,*kludge,*origin,
to_domain[39],from_domain[39];
static long msgidcrc,serialno,numpassthru = 0L,numechoforwarded = 0L;
/* external var references */
extern char buffer[1024];
extern GROUP *group;
extern CONTROLS control;
extern ADDR *myaddr;
extern ECHOREC *echos;
extern ASSHOLE *assholes;
extern TONAMES *tonames;
extern char *groupin;
extern char *groupout;
extern char *grouphold;
extern char *msgdir;
extern char *outbound;
extern char *inbound;
extern char *archive;
extern char *unarchive;
extern word packsize;
extern word netarea;
extern DUPES *dupes;
extern word nextdupe,maxdupes;
extern char founddupes;
extern char *putmsgs;
void _fastcall echo_import_mail (void) {
FILEFINDBUF f;
int search_handle,num_matches,x = 0;
static char arcext[MAXARCEXTS][3] = {
"MO","TU","WE","TH","FR","SA","SU"};
char arcfile[257] = "",*p;
GROUP *currgroup;
long diskspace;
struct __sizeinfo__ {
long id;
long sectors;
long alloc;
long avail;
word bytes;
} sz;
/* move groupmail files to groupin dir */
printf("\nSearching for and moving group files...");
search_handle = 1;
num_matches = 1;
sprintf(buffer,"%s/*.*",inbound);
if(!DosFindFirst(buffer,&search_handle,0,&f,
sizeof(FILEFINDBUF),&num_matches,0L)) {
do {
p = strrchr(f.achName,'.'); /* verify it's a group file */
if(!p) {
goto ContHere; /* can't be a group file */
}
*p = 0;
currgroup = group;
while(currgroup) {
if(!stricmp(f.achName,currgroup->id)) break;
currgroup = currgroup->next;
}
*p = '.';
if(!currgroup) {
goto ContHere; /* not a group file */
}
p++;
if(ext_reserved(p)) { /* check various reserved extensions */
goto ContHere; /* not a group file */
}
/* is a group file; move it */
if(toupper(*groupin) == toupper(*inbound)) {
sprintf(buffer,"%s/%s %s/%s",inbound,f.achName,groupin,f.achName);
p = strchr(buffer,' ');
*p = 0;
p++;
DosMove(buffer,p,0L);
}
else {
sprintf(buffer,"COPY %s/%s %s/%s > NUL",inbound,f.achName,groupin,f.achName);
system(buffer);
sprintf(buffer,"%s/%s",inbound,f.achName);
my_unlink(buffer);
}
ContHere:
num_matches = 1;
} while(!DosFindNext(search_handle,&f,sizeof(FILEFINDBUF),
&num_matches));
DosFindClose(search_handle);
}
printf("\nImporting net/echomail -- forwarding groupmail...");
search_handle = 1;
num_matches = 1;
sprintf(buffer,"%s/*.?UT",inbound);
if(!DosFindFirst(buffer,&search_handle,0,&f,
sizeof(FILEFINDBUF),&num_matches,0L)) {
do {
sprintf(buffer,"%s/%s",inbound,f.achName);
if(!access(buffer,6)) {
crack_pkt(buffer);
}
else {
printf("\nSkipped %s--no read/write access",f.achName);
logf("Skipped %s--no read/write access",f.achName);
}
num_matches = 1;
} while(!DosFindNext(search_handle,&f,sizeof(FILEFINDBUF),
&num_matches));
DosFindClose(search_handle);
}
DoPackets:
search_handle = 1;
num_matches = 1;
sprintf(buffer,"%s/*.PKT",inbound);
if(!DosFindFirst(buffer,&search_handle,0,&f,
sizeof(FILEFINDBUF),&num_matches,0L)) {
do {
DosQFSInfo(0,1,&sz,sizeof(sz));
diskspace = sz.avail * sz.sectors * sz.bytes;
if(diskspace < f.cbFile * 2L) {
printf("\nProbably insufficient diskspace to process \"%s\"",f.achName);
printf("\nFilesize: %ld Diskspace: %ld",f.cbFile,diskspace);
logf("Probably insufficient diskspace to process \"%s\"",f.achName);
logf("Filesize: %ld Diskspace: %ld",f.cbFile,diskspace);
goto SkipPkt;
}
sprintf(buffer,"%s/%s",inbound,f.achName);
if(!access(buffer,6)) {
crack_pkt(buffer);
}
else {
printf("\nSkipped %s--no read/write access",f.achName);
logf("Skipped %s--no read/write access",f.achName);
}
SkipPkt:
num_matches = 1;
} while(!DosFindNext(search_handle,&f,sizeof(FILEFINDBUF),
&num_matches));
DosFindClose(search_handle);
}
DoArchives:
while(x < MAXARCEXTS) {
search_handle = 1;
num_matches = 1;
sprintf(buffer,"%s/*.%s?",inbound,arcext[x]);
if(!DosFindFirst(buffer,&search_handle,0,&f,
sizeof(FILEFINDBUF),&num_matches,0L)) {
do {
if(!f.cbFile) goto NextOne;
if(!stricmp(arcfile,f.achName)) goto NextOne;
sprintf(buffer,"%s/%s",inbound,f.achName);
if(access(buffer,6)) {
printf("\nSkipped %s--no read/write access",f.achName);
logf("Skipped %s--no read/write access",f.achName);
goto NextOne;
}
DosQFSInfo(0,1,&sz,sizeof(sz));
diskspace = sz.avail * sz.sectors * sz.bytes;
if(diskspace < f.cbFile * 3L) {
printf("\nProbably insufficient diskspace to process \"%s\"",f.achName);
printf("\nFilesize: %ld Diskspace: %ld",f.cbFile,diskspace);
logf("Probably insufficient diskspace to process \"%s\"",f.achName);
logf("Filesize: %ld Diskspace: %ld",f.cbFile,diskspace);
goto NextOne;
}
printf("\nAttempting to crack archive \"%s\"\n",f.achName);
switch_to(inbound);
strcpy(arcfile,f.achName);
sprintf(buffer,"%s %s\\%s *.PKT",unarchive,inbound,f.achName);
system(buffer);
switch_back();
/* This godawful kludge so it'll run under DOS */
DosFindClose(search_handle);
sprintf(buffer,"%s/*.PKT",inbound);
search_handle = 1;
num_matches = 1;
if(!DosFindFirst(buffer,&search_handle,0,&f,
sizeof(FILEFINDBUF),&num_matches,0L)) {
DosFindClose(search_handle);
sprintf(buffer,"%s/%s",inbound,arcfile);
my_unlink(buffer);
goto DoPackets;
}
else {
printf("\nUnarchive attempt failed");
logf("Unarchive of \"%s\" failed",f.achName);
goto NextOne;
}
goto DoArchives;
NextOne:
num_matches = 1;
} while(!DosFindNext(search_handle,&f,sizeof(FILEFINDBUF),
&num_matches));
DosFindClose(search_handle);
}
x++;
}
if(dataptr != -1) close(dataptr);
if(textptr != -1) close(textptr);
sprintf(buffer,"%s/UNKNOWN.$$$",inbound);
p = &buffer[strlen(buffer) + 1];
sprintf(p,"%s/UNKNOWN.PKT",inbound);
my_rename(buffer,p);
report();
}
static void _fastcall report (void) {
GROUP *currgroup;
ECHOREC *currecho;
long totalmsgs = 0L;
printf("\n");
currgroup = group;
while(currgroup) {
if(currgroup->forwarded) {
totalmsgs += (long)currgroup->forwarded;
logf("Forwarded %u msg%s for group #%u \"%s\"",
currgroup->forwarded,&"s"[currgroup->forwarded == 1],
currgroup->areano,currgroup->id);
}
if(currgroup->imported) {
totalmsgs += (long)currgroup->imported;
logf("Imported %u msg%s into group #%u \"%s\"",
currgroup->imported,&"s"[currgroup->imported == 1],
currgroup->areano,currgroup->id);
}
currgroup = currgroup->next;
}
currecho = echos;
while(currecho) {
if(currecho->imported) {
totalmsgs += (long)currecho->imported;
logf("Imported %u msg%s into echo #%u \"%s\"",
currecho->imported,&"s"[currecho->imported == 1],
currecho->areano,currecho->tag);
}
if(currecho->forwarded) {
logf("Forwarded %u msg%s from echo #%u \"%s\"",
currecho->forwarded,&"s"[currecho->forwarded == 1],
currecho->areano,currecho->tag);
}
currecho = currecho->next;
}
if(numpassthru) logf("%u echo msg%s in pass-thru area(s)",
numpassthru,&"s"[numpassthru == 1]);
if(numechoforwarded) logf("%lu total echomail msg%s were forwarded",
numechoforwarded,&"s"[numechoforwarded == 1]);
if(unknownmsgs) logf("%u echo msg%s in unknown area(s) (to UNKNOWN.PKT)",
unknownmsgs,&"s"[unknownmsgs == 1]);
totalmsgs += unknownmsgs;
if(insecuremsgs) logf("%u echo msg%s from unlisted nodes (to INSECURE.$$$)",
insecuremsgs,&"s"[insecuremsgs == 1]);
totalmsgs += insecuremsgs;
if(numdupes) {
if(!control.keepdupes) logf("%u dupe echo msg%s rejected",
numdupes,&"s"[numdupes == 1]);
else logf("%u dupe msg%s rejected (to AREDUPES.$$$)",
numdupes,&"s"[numdupes == 1]);
}
totalmsgs += numdupes;
if(netimported) logf("Imported %u msg%s into #%u netmail",
netimported,&"s"[netimported == 1],netarea);
totalmsgs += netimported;
if(netforwarded) logf("%lu total netmail msg%s forwarded",
netforwarded,&"s"[netforwarded == 1]);
totalmsgs += netforwarded;
if(notforwarded) logf("%lu total netmail msg%s *not* forwarded",
notforwarded,&"s"[notforwarded == 1]);
if(control.keepnoforwards) logf("(Unforwarded msgs in FORWARD.$$$)");
totalmsgs += netforwarded;
if(numassholes) logf("%u asshole msg%s were not imported",numassholes,
&"s"[numassholes == 1]);
totalmsgs += numassholes;
if(totalmsgs) {
logf("Total msgs processed: %lu",totalmsgs);
}
}
static int _fastcall crack_pkt (char *pktname) {
int fp,temp,islocal,isass;
long len;
char *buff,*text,*lastassarea = NULL,*lastdupearea = NULL,*p;
word buflen,msgsprocd = 0,x;
XMSG msg;
PKTHDR pi;
OLDPKTHDR *opi;
ADDR *ainfo,*achk,pktaddr,nchk;
ECHOREC *currecho = NULL;
GROUP *currgroup = NULL;
ASSHOLE *anass;
TONAMES *aname;
printf("\nProcessing packet \"%s\"",pktname);
buff = strdup(pktname);
if(!buff) return -2;
pktname = buff;
fp = sopen(pktname,O_RDONLY | O_BINARY,SH_DENYWR);
if(fp == -1) {
printf("\nCouldn't open packet \"%s\"\n",pktname);
logf("Couldn't open packet \"%s\"\n",pktname);
my_free(pktname);
return -1; /* Return Can't Open */
}
lseek(fp,0L,SEEK_END); /* Get packet size */
len = tell(fp);
if(len <= (long)sizeof(PKTHDR) + 2L) {
close(fp);
my_unlink(pktname);
printf("\nShort packet discarded");
my_free(pktname);
return 0; /* Ignore 'short' packet */
}
if((len - (long)sizeof(PKTHDR)) < 65500L)
buflen = (word)((len - (long)sizeof(PKTHDR)) + 1L);
else buflen = 65501U; /* Set minimum buff length */
buff = (char *)malloc(buflen + 1); /* Allocate text buff */
if(!buff) {
close(fp);
my_free(pktname);
printf("\nOut of memory\n");
return -2; /* Return OOM */
}
memset(&pi,0,sizeof(PKTHDR));
lseek(fp,0L,SEEK_SET);
lseek(fp,0L,SEEK_SET);
read(fp,&pi,sizeof(PKTHDR)); /* Get packet header */
if(pi.version != 2) { /* not type 2; can't handle it */
return -4;
}
opi = (OLDPKTHDR *)π
if(pi.subver == 2) { /* it's a type 2.2 (FSC-0045) */
pktaddr.zone = pi.ozone;
pktaddr.net = pi.onet;
pktaddr.node = pi.onode;
pktaddr.point = pi.opoint;
if(pi.odomain) pktaddr.domain = strdup(pi.odomain);
else pktaddr.domain = NULL;
if(pktaddr.domain) {
p = strchr(pktaddr.domain,'.');
if(p) {
*p = 0;
if(!*pktaddr.domain) {
my_free(pktaddr.domain);
pktaddr.domain = NULL;
}
}
}
pktaddr.next = NULL;
if(pktaddr.zone != 0 || pktaddr.net != 0 || pktaddr.node != 0 ||
pktaddr.point != 0 || (pktaddr.domain && *pktaddr.domain))
guess_rest(&pktaddr,myaddr);
}
else {
pktaddr.zone = opi->qm_orig_zone;
pktaddr.net = opi->orig_net;
pktaddr.node = opi->orig_node;
pktaddr.point = opi->orig_point;
if(!pktaddr.zone) pktaddr.zone = opi->orig_zone;
pktaddr.domain = NULL;
pktaddr.next = NULL;
if(pktaddr.zone != 0 || pktaddr.net != 0 || pktaddr.node != 0 ||
pktaddr.point != 0 || (pktaddr.domain && *pktaddr.domain))
guess_rest(&pktaddr,myaddr);
}
logf("Processing packet \"%s\" from %u:%u/%u.%u@%s",pktname,
pktaddr.zone,pktaddr.net,pktaddr.node,pktaddr.point,
((pktaddr.domain) ? pktaddr.domain : ""));
printf(" from %u:%u/%u.%u@%s",pktaddr.zone,pktaddr.net,
pktaddr.node,pktaddr.point,
((pktaddr.domain) ? pktaddr.domain : ""));
printf("\n\x1b[K");
while(!eof(fp)) {
ContHere:
islocal = isass = 0;
temp = get_msg(buflen,buff,&text,fp,&msg);
if(temp == -3) {
continue;
}
if(temp == -1) {
close(fp);
my_free(buff);
my_unlink(pktname);
my_free(pktname);
printf("\x1b[s\x1b[1;1H\x1b[KMinor error\x1b[u");
logf("Encountered minor error");
return -3; /* Return 'minor' error */
}
if(temp < 0) break; /* End of packet */
msgsprocd++;
if(!text || !*text) {
printf("\x1b[s\x1b[1;1H\x1b[KNULL message discarded.\x1b[u");
continue; /* NULL message */
}
if(!temp) {
if(!area || !*area) { /* is netmail */
nchk.zone = msg.d_zone;
nchk.net = msg.dest_net;
nchk.node = msg.dest;
nchk.point = msg.d_point;
if(*to_domain) nchk.domain = strdup(to_domain);
else nchk.domain = NULL;
nchk.next = NULL;
guess_rest(&nchk,myaddr);
ainfo = myaddr;
while(ainfo) {
if(ainfo->zone == nchk.zone && ainfo->net == nchk.net &&
ainfo->node == nchk.node && ainfo->point == nchk.point &&
(!nchk.domain || !strnicmp(nchk.domain,ainfo->domain,8))) {
if(tonames) {
aname = tonames;
while(aname) {
if(!stricmp(msg.to,aname->to)) {
if(aname->msg) { /* export as *.MSG */
make_message(text,&msg);
}
else if(aname->route) { /* forward somewhere else */
msg.dest = aname->addr->node;
msg.dest_net = aname->addr->net;
msg.d_zone = aname->addr->zone;
msg.d_point = aname->addr->point;
if(aname->addr->domain) strncpy(to_domain,aname->addr->domain,38);
else *to_domain = 0;
to_domain[38] = 0;
forward(text,&msg,NULL,NULL,aname->addr);
}
else if(aname->prog) { /* spawn program as */
/* prog *.MSG-filename */
word msgno;
char obj[18];
union rr {
long lret;
struct ints {
int cpid;
int cret;
} i;
} ret;
char *args[5];
msgno = make_message(text,&msg);
if(!msgno) {
logf("Couldn't create *.MSG file for To: \"%s\"...imported",msg.to);
break;
}
if(putmsgs) sprintf(buffer,"%s/%u.MSG",putmsgs,msgno);
else sprintf(buffer,"%u.MSG",msgno);
if(strstr(aname->prgname,".CMD")) {
args[0] = "CMD.EXE";
msgno = 1;
}
else msgno = 0;
args[msgno++] = aname->prgname;
args[msgno++] = buffer;
args[msgno] = "";
if(!DosExecPgm(obj,18,4,&args[1],NULL,(long *)&ret.lret,args[0])) {
printf("Spawned \"%s\" detached\n",aname->prgname);
logf("Spawned \"%s\" detached",aname->prgname);
}
else logf("Couldn't spawn \"%s\"",aname->prgname);
}
goto ContHere;
}
aname = aname->next;
}
}
netimported++;
temp = import(text,&msg,NULL,NULL,msgsprocd); /* import netmail */
break;
}
if(ainfo->zone == nchk.zone && ainfo->net == nchk.net &&
(!nchk.domain || !strnicmp(nchk.domain,ainfo->domain,8))) {
islocal = 1;
}
ainfo = ainfo->next;
}
my_free(nchk.domain);
if(!ainfo) { /* forward netmail */
if(islocal) {
if(!control.nolocalfor) {
printf("\nForwarding \"local\" msg");
netforwarded++;
forward(text,&msg,NULL,NULL,&pktaddr);
printf("\nForwarded message addr to %u:%u/%u.%u@%s",
msg.d_zone,msg.dest_net,msg.dest,msg.d_point,
to_domain);
logf("Forwarded message addr to %u:%u/%u.%u@%s",
msg.d_zone,msg.dest_net,msg.dest,msg.d_point,
to_domain);
}
else if(!control.keepnoforwards) {
printf("\nTrashed message addr to %u:%u/%u.%u@%s",
msg.d_zone,msg.dest_net,msg.dest,msg.d_point,
to_domain);
logf("Trashed message addr to %u:%u/%u.%u@%s",
msg.d_zone,msg.dest_net,msg.dest,msg.d_point,
to_domain);
}
else {
is_notforwarded(text,&msg);
notforwarded++;
}
}
else {
if(!control.noforward) {
netforwarded++;
printf("\nForwarding \"foreign\" msg");
forward(text,&msg,NULL,NULL,&pktaddr);
printf("\nForwarded message addr to %u:%u/%u.%u@%s",
msg.d_zone,msg.dest_net,msg.dest,msg.d_point,
to_domain);
logf("Forwarded message addr to %u:%u/%u.%u@%s",
msg.d_zone,msg.dest_net,msg.dest,msg.d_point,
to_domain);
}
else if(!control.keepnoforwards) {
printf("\nTrashed message addr to %u:%u/%u.%u@%s",
msg.d_zone,msg.dest_net,msg.dest,msg.d_point,
to_domain);
logf("Trashed message addr to %u:%u/%u.%u@%s",
msg.d_zone,msg.dest_net,msg.dest,msg.d_point,
to_domain);
}
else {
is_notforwarded(text,&msg);
notforwarded++;
}
}
}
}
else { /* is either echo or groupmail */
if(grunged_area) {
if(pktaddr.zone != 0 || pktaddr.net != 0 || pktaddr.node != 0 ||
pktaddr.point != 0 || (pktaddr.domain && *pktaddr.domain))
bitch_and_moan(&pktaddr,area);
}
if(grunged_seenbys) {
if(pktaddr.zone != 0 || pktaddr.net != 0 || pktaddr.node != 0 ||
pktaddr.point != 0 || (pktaddr.domain && *pktaddr.domain))
bitch_and_moan_again(&pktaddr,area);
}
currecho = echos;
while(currecho) {
if(!stricmp(currecho->tag,area)) {
break;
}
currecho = currecho->next;
}
if(!currecho) {
currgroup = group;
while(currgroup) {
if(!stricmp(currgroup->id,area)) {
break;
}
currgroup = currgroup->next;
}
}
if(currecho) { /* is echomail */
achk = currecho->addr;
if(pktaddr.zone != 0 || pktaddr.net != 0 || pktaddr.node != 0 ||
pktaddr.point != 0 || (pktaddr.domain && *pktaddr.domain)) {
while(achk) {
if(achk->zone == pktaddr.zone && achk->net == pktaddr.net &&
achk->node == pktaddr.node && achk->point == pktaddr.point &&
(!achk->domain || !strnicmp(pktaddr.domain,achk->domain,8))) {
break;
}
achk = achk->next;
}
}
if(!control.nodupes && msgidcrc && serialno) {
if(lastdupearea != currecho->tag) {
load_dupes(currecho->areano);
lastdupearea = currecho->tag;
}
if(dupes) {
for(x = 0;x < maxdupes;x++) {
if(dupes[x].msgidcrc && dupes[x].serialno) {
if(dupes[x].msgidcrc == msgidcrc &&
dupes[x].serialno == serialno) {
founddupes = 1;
numdupes++;
if(control.keepdupes) {
isadupe(text,&msg,area);
}
goto ContHere;
}
}
}
}
}
anass = NULL;
if(!control.noassholes) {
if(lastassarea != currecho->tag) {
load_assholes(currecho->areano);
lastassarea = currecho->tag;
}
if(assholes) {
anass = assholes;
while(anass && anass->name) {
if(anass->subj) {
char *p;
p = msg.subj;
while(!strnicmp(p,"RE:",3)) {
p += 3;
while(*p && *p == ' ') p++;
}
if(!stricmp(p,anass->name)) {
if(anass->del || anass->noin) {
isass = 1;
break;
}
}
}
else {
if(anass->from) {
if(!stricmp(msg.from,anass->name)) {
if(anass->del || anass->noin) {
isass = 1;
break;
}
}
}
if(anass->to) {
if(!stricmp(msg.to,anass->name)) {
if(anass->del || anass->noin) {
isass = 1;
break;
}
}
}
}
anass = anass->next;
}
}
}
if(isass) numassholes++;
if((!achk && currecho->addr) && !isass) { /* not from listed node */
insecure(text,&msg,area);
}
else {
if(dupes && !control.nodupes && msgidcrc && serialno) {
founddupes = 1;
dupes[nextdupe].msgidcrc = msgidcrc;
dupes[nextdupe].serialno = serialno;
nextdupe++;
if(nextdupe >= maxdupes) nextdupe = 0;
}
if(currecho->addr && currecho->addr->next) { /* feeding more than one node */
if(!isass || (!anass || !anass->del) || !control.assexport) {
currecho->forwarded++;
numechoforwarded++;
temp = forward(text,&msg,currecho,NULL,&pktaddr);
}
}
if(!isass) {
currecho->imported++;
temp = import(text,&msg,currecho,NULL,msgsprocd);
}
}
}
else if(currgroup) { /* is groupmail */
if(currgroup->uplink) { /* forward toward topstar */
currgroup->forwarded++;
forward(text,&msg,NULL,currgroup,&pktaddr);
}
else temp = import(text,&msg,NULL,currgroup,msgsprocd); /* we are topstar */
}
else { /* unknown area */
unknown(text,&msg,area);
}
}
}
}
close(fp); /* Close packet */
my_unlink(pktname); /* Get rid of packet after unpacking */
my_free(buff);
my_free(pktname);
if(assholes) free_assholes();
if(dupes) free_dupes();
return 0; /* Return success */
}
static int _fastcall import (char *buff,XMSG *xmsg,ECHOREC *currecho,
GROUP *currgroup,word msgnum) {
/* Put msg in XBBS base */
static word lastarea = 0;
char *hold;
word temp,thisarea = 0,x;
time_t tt;
struct tm *t;
long pos;
if(!currecho && !currgroup) {
thisarea = netarea;
xmsg->m_attr |= MSGNET;
}
else {
if(currecho) thisarea = currecho->areano;
else if(currgroup) thisarea = currgroup->areano;
xmsg->m_attr |= MSGECHO;
}
if(!thisarea) {
numpassthru++;
return 0; /* pass-thru */
}
if(lastarea != thisarea) { /* close msg areas, reopen */
printf("\n\x1b[K");
if(open_msg_files(thisarea)) return -1;
lastarea = thisarea;
}
x = 0;
while(x < 50) {
if(lseek(textptr,0L,SEEK_END) != -1L) break;
DosSleep(100L);
x++;
}
if(x >= 50) {
printf("\nLocking conflict; can't import msg\n");
return -1;
}
locking(textptr,LK_LOCK,65535L);
xmsg->start = tell(textptr);
if(packsize && xmsg->length > packsize && !control.keepsbs && !control.keeppath) {
temp = strlen(buff);
if(temp > 65100U) {
buff[65099U] = 0;
temp = 65100U;
}
hold = (char *)malloc(temp + 256);
if(!hold) {
write(textptr,buff,temp);
}
else {
hold = pack_msg(hold,xmsg);
if(!hold) {
write(textptr,buff,temp);
}
else {
xmsg->m_attr |= MSGPACKED;
write(textptr,hold,xmsg->length);
}
my_free(hold);
}
}
else {
if(control.keeppath) {
xmsg->length = 0;
if(newpath) {
xmsg->length += write(textptr,newpath,strlen(newpath));
xmsg->length += write(textptr,"\r",1);
}
}
xmsg->length += write(textptr,buff,strlen(buff));
if(control.keepsbs) {
if(seenby) {
xmsg->length += write(textptr,"\r",1);
xmsg->length += write(textptr,seenby,strlen(seenby));
}
}
if(control.keeppath) {
if(pathline) {
xmsg->length += write(textptr,"\r",1);
xmsg->length += write(textptr,pathline,strlen(pathline));
}
}
}
write(textptr,"\0",2);
lseek(textptr,xmsg->start,SEEK_SET);
locking(textptr,LK_UNLCK,65535L);
tt = time(NULL);
t = localtime(&tt);
xmsg->indate[0] = (char)(t->tm_year - 89);
xmsg->indate[1] = (char)(t->tm_mon + 1);
xmsg->indate[2] = (char)t->tm_mday;
xmsg->indate[3] = 0;
if(currgroup) { /* set up attribs so msg can be scanned out later */
printf("#%u (%u) -> group \"%s\"\r",msgnum,currgroup->imported,
currgroup->id);
xmsg->m_attr &= (~(MSGDELETED | MSGGSCAN | MSGSCANNED));
xmsg->attr |= MSGLOCAL;
xmsg->attr &= (~(MSGSENT | MSGREAD | MSGCRASH | MSGKILL | MSGORPHAN));
}
else { /* set up attribs so msg is never reexported */
if(currecho)
printf("#%u (%u) -> echo \"%s\"\r",msgnum,currecho->imported,
currecho->tag);
else printf("#%u (%u) -> netmail\r",msgnum,netimported);
xmsg->attr |= MSGORPHAN;
xmsg->attr &= (~MSGLOCAL);
}
xmsg->length++;
x = 0;
while(x < 50) {
if(lseek(dataptr,0L,SEEK_END) != -1L) break;
DosSleep(100L);
x++;
}
if(x >= 50) {
printf("\nLocking conflict; can't import msg\n");
return -1;
}
locking(dataptr,LK_LOCK,(long)sizeof(XMSG));
pos = tell(dataptr);
write(dataptr,xmsg,sizeof(XMSG));
lseek(dataptr,pos,SEEK_SET);
locking(dataptr,LK_UNLCK,(long)sizeof(XMSG));
return 0;
}
static int _fastcall get_msg (word buflen,char *buff,char **text,
int fp,XMSG *xmsg) {
char *p,*endptr,*tempo,first_grunged = 0;
long pos;
word len,*temp,chk;
Again:
grunged_seenbys = grunged_area = grunged_date = 0;
msgidcrc = serialno = 0L;
newpath = NULL;
memset(xmsg,0,sizeof(XMSG));
*to_domain = 0;
*from_domain = 0;
if(eof(fp)) return -2;
pos = tell(fp);
chk = read(fp,buff,buflen);
if(!chk || chk == 65535U) return -2;
buff[buflen] = 0;
p = buff;
if(*p != (char)'\02' || p[1] != (char)'\0') {
if(eof(fp) || (*p == (char)'\0' && p[1] == (char)'\0')) return -2;
while(*p != (char)'\02' && p < (buff + buflen)) {
p++;
pos++;
}
lseek(fp,pos,SEEK_SET);
if(first_grunged) {
logf("Hmph. Grunged packet...");
first_grunged++;
}
goto Again;
}
p += 2;
temp = (word *)p;
xmsg->orig = *temp;
p += 2;
temp = (word *)p;
xmsg->dest = *temp;
p += 2;
temp = (word *)p;
xmsg->orig_net = *temp;
p += 2;
temp = (word *)p;
xmsg->dest_net = *temp;
p += 2;
temp = (word *)p;
xmsg->attr = *temp;
p += 2;
xmsg->cost = 0;
p += 2;
strncpy(xmsg->date,p,20);
xmsg->date[19] = 0;
while(*p) p++; /* <--This goddamn kludge thanks to QMail, the broken wonder */
p++;
strncpy(xmsg->to,p,36);
xmsg->to[35] = 0;
while(*p) p++;
p++;
strncpy(xmsg->from,p,36);
xmsg->from[35] = 0;
while(*p) p++;
p++;
strncpy(xmsg->subj,p,64);
xmsg->subj[63] = 0;
while(*p) p++;
p++;
*text = p;
while(*p) p++;
p++; /* Should be start of next msg */
endptr = p;
pos += (long)(endptr - buff);
lseek(fp,pos,SEEK_SET); /* Now positioned to start of next msg */
if(!*xmsg->to && !*xmsg->from && !*xmsg->subj) { /* grunged msg */
return -3;
}
len = strlen(*text);
if(!len) {
return -3;
}
if(strlen(xmsg->date) < 19) {
int x;
if(control.delbaddate) return -3; /* ignore broken dates */
grunged_date = 1;
for(x = 0; x < 19;x++) if(!xmsg->date[x]) xmsg->date[x] = 'Q';
}
p = *text;
while (*p) { /* Strip linefeeds and soft cr's FAST */
if(*p == '\x8d' || *p == '\n') {
memmove(p,&p[1],len - (word)((long)p - (long)*text));
len--;
if(!len) break;
continue;
}
p++;
}
if(!strnicmp(*text,"\01AREA:",6)) {
tempo = *text;
memmove(tempo,&tempo[1],strlen(tempo));
grunged_area = 1;
}
if(!strnicmp(*text,"AREA:",5)) { /* Echo area tag */
area = *text;
while(**text && **text != '\r') {
(*text)++;
}
if(**text) {
**text = 0; /* area now = area tag line */
(*text)++; /* text = true start of msg body if any */
}
while(**text == '\r' && **text) (*text)++; /* Skip leading cr's in body */
area += 5;
lstrip(area);
rstrip(area); /* Points directly to tag */
}
else area = NULL;
if (area) { /* Do ECHO specific BS */
origin = pathline = seenby = kludge = NULL;
tempo = *text; /* They oughta outlaw EID's */
while ((tempo = strstr(tempo,"\01EID:")))
memmove(tempo,strchr(&tempo[1],'\r'),strlen(strchr(&tempo[1],'\r'))+1);
tempo = *text; /* and VIA's */
while ((tempo = strstr(tempo,"\01VIA")))
memmove(tempo,strchr(&tempo[1],'\r'),strlen(strchr(&tempo[1],'\r'))+1);
while(**text == '\r' && **text) (*text)++; /* Skip leading cr's in body */
if((tempo = strstr(*text,"\01NPTH "))) { /* isolate new path */
if(tempo == *text || (tempo > buff && *(tempo - 1) == '\r'))
newpath = tempo;
tempo = newpath;
if(tempo) {
while((tempo = strchr(tempo,'\r'))) {
if(strnicmp(&tempo[1],"\01NPTH ",6)) tempo++;
else {
*tempo = 0;
tempo++;
*text = tempo;
while(**text == '\r' && **text)
(*text)++; /* Skip leading cr's in body */
break;
}
}
}
}
if(!strncmp(*text," * Origin: ",11)) **text = 0; /* Nothin' but origin */
origin = strstr(*text,"\r * Origin:"); /* find origin line */
if (origin) { /* Ain't one; oh, well, screw it */
while(tempo = strstr(&origin[1],"\r * Origin:")) origin = tempo; /* Find last */
pathline = strstr(origin,"\r\01PATH:"); /* Find the PATH line */
seenby = strstr(origin,"\rSEEN-BY:"); /* Find start of SEEN-BYs */
if (!seenby) {
seenby = strstr(origin,"\r\01SEEN-BY:");
if(seenby) {
grunged_seenbys = 1;
while(tempo = strstr(seenby,"\r\01SEEN-BY:")) {
memmove(seenby,&seenby[1],strlen(seenby));
}
}
}
if(pathline) {
*pathline = 0;
pathline++;
}
if(seenby) {
*seenby = 0;
seenby++;
}
}
}
{ /* Fill in header address info from kludges */
char message[MAXKLUDGE];
if ((p=strstr(*text,"\01FMPT "))) {
strncpy(message,p,MAXKLUDGE);
message[MAXKLUDGE-1] = 0;
p = message;
xmsg->o_point = (word)atol(&p[5]);
}
if ((p=strstr(*text,"\01TOPT "))) {
strncpy(message,p,MAXKLUDGE);
message[MAXKLUDGE-1] = 0;
p = message;
xmsg->d_point = (word)atol(&p[5]);
}
if ((p=strstr(*text,"\01INTL "))) {
strncpy(message,p,MAXKLUDGE);
message[MAXKLUDGE-1] = 0;
p = message;
strtok(p," :");
strtok(0," ");
tempo = strtok(0,":");
if(tempo) {
if ((word)atol(tempo)) {
xmsg->o_zone = (word)atol(tempo);
}
}
}
if((p = strstr(*text,"\01MSGID: "))) {
if((p - 1) < *text || *(p - 1) == '\r') {
ADDR addr;
char temp,*ptr;
memset(&addr,0,sizeof(ADDR));
addr.domain = NULL;
p += 8;
p = skip_white(p);
/* calculate MSGID dupechecking stuff */
tempo = p;
p = skip_nonwhite(p);
if(*p) {
temp = *p;
*p = 0;
msgidcrc = crc32str(tempo,0);
#ifdef DEBUG
logf("MSGID addr: \"%s\" crc: %ld",tempo,msgidcrc);
#endif
*p = temp;
p++;
if(*p) {
ptr = p;
serialno = strtol(p,&ptr,16);
#ifdef DEBUG
logf("MSGID serialno: \"%0.8s\" #: %ld",p,serialno);
#endif
if((serialno == LONG_MAX || serialno == LONG_MIN) &&
errno == ERANGE) serialno = 0L;
}
p = tempo;
}
if(!parse_addr(&p,&addr,myaddr)) {
if(!addr.zone || !addr.net || !*addr.domain) {
guess_rest(&addr,myaddr);
}
xmsg->o_zone = addr.zone;
xmsg->orig_net = addr.net;
xmsg->orig = addr.node;
xmsg->o_point = addr.point;
strncpy(from_domain,addr.domain,38);
from_domain[38] = 0;
p = strchr(from_domain,'.');
if(p) *p = 0;
my_free(addr.domain);
}
}
}
if((p = strstr(*text,"\01MSGTO: "))) {
if((p - 1) < *text || *(p - 1) == '\r') {
ADDR addr;
memset(&addr,0,sizeof(ADDR));
addr.domain = NULL;
p += 8;
p = skip_white(p);
if(!parse_addr(&p,&addr,myaddr)) {
if(!addr.zone || !addr.net || !*addr.domain) {
guess_rest(&addr,myaddr);
}
xmsg->d_zone = addr.zone;
xmsg->dest_net = addr.net;
xmsg->dest = addr.node;
xmsg->d_point = addr.point;
strncpy(to_domain,addr.domain,38);
to_domain[38] = 0;
p = strchr(to_domain,'.');
if(p) *p = 0;
my_free(addr.domain);
}
}
}
}
if(!control.keepsbs && !control.keeppath && !control.keepdupes) {
p = *text + (strlen(*text) - 1); /* strip trailing blank lines */
while(*p == '\r' && p > *text && *(p-1) == '\r') {
*p = 0;
p--;
}
if(seenby || pathline) {
p = *text + (strlen(*text) + 1);
if(!pathline || seenby < pathline) {
memmove(p,seenby,strlen(seenby) + 1);
if(pathline) {
p = seenby + (strlen(seenby) + 1);
memmove(p,pathline,strlen(pathline) + 1);
}
}
else {
memmove(p,pathline,strlen(pathline) + 1);
if(seenby) {
p = pathline + (strlen(pathline) + 1);
memmove(p,seenby,strlen(seenby) + 1);
}
}
}
}
xmsg->length = strlen(*text);
xmsg->m_attr = 0;
if(area) xmsg->m_attr |= MSGECHO; /* Is echo */
else xmsg->m_attr |= MSGNET; /* Is net */
return 0;
}
static int _fastcall open_msg_files (word areano) {
int tries;
if(dataptr != -1) close(dataptr);
if(textptr != -1) close(textptr);
sprintf(buffer,"%s/XTEXT.%03x",msgdir,areano);
tries = 0;
do {
textptr = sopen(buffer,O_RDWR | O_BINARY | O_CREAT,SH_DENYNO,S_IWRITE | S_IREAD);
if(textptr == -1 && errno == EACCES) tries++;
else break;
} while(tries < 120);
sprintf(buffer,"%s/XDATA.%03x",msgdir,areano);
tries = 0;
do {
dataptr = sopen(buffer,O_RDWR | O_BINARY | O_CREAT,SH_DENYNO,S_IWRITE | S_IREAD);
if(dataptr == -1 && errno == EACCES) tries++;
else break;
} while(tries < 120);
if(dataptr == -1 || textptr == -1) {
if(dataptr != -1) close(dataptr);
if(textptr != -1) close(textptr);
dataptr = textptr = -1;
printf("\nCan't open message base file(s)\n");
logf("Can't open message base files");
return -1; /* Error opening message area */
}
lseek(dataptr,0L,SEEK_END);
lseek(textptr,0L,SEEK_END);
return 0;
}
static int _fastcall forward (char *buff,XMSG *xmsg,ECHOREC *currecho,
GROUP *currgroup,ADDR *pktaddr) {
ADDR taddr,faddr,*maddr,*curraddr,*naddr = NULL,*ca,*na;
int fp;
SB *sb = NULL,*opth = NULL,*gate = NULL;
if(!currecho && !currgroup) { /* net msg */
taddr.net = xmsg->dest_net;
taddr.node = xmsg->dest;
taddr.point = xmsg->d_point;
taddr.zone = xmsg->d_zone;
taddr.domain = strdup(to_domain);
faddr.net = xmsg->orig_net;
faddr.node = xmsg->orig;
faddr.zone = xmsg->o_zone;
faddr.domain = strdup(from_domain);
taddr.next = faddr.next = NULL;
guess_rest(&taddr,myaddr);
guess_rest(&faddr,myaddr);
fp = open_pkt(&taddr,&faddr,0);
if(fp != -1) {
write_pkt_msg(fp,xmsg,NULL,NULL,NULL,buff,NULL,NULL);
}
my_free(faddr.domain);
my_free(taddr.domain);
if(fp != -1) close(fp);
return -1;
}
else if(currecho) { /* echo msg */
maddr = best_guess(currecho->addr,myaddr);
xmsg->o_zone = maddr->zone;
xmsg->o_point = maddr->point;
xmsg->orig_net = maddr->net;
xmsg->orig = maddr->node;
if(pathline) {
opth = parse_oldpath(pathline);
if(!opth) return -1;
}
if(newpath) {
naddr = parse_newpath(newpath);
if(!naddr) {
my_free(opth);
return -1;
}
ca = myaddr;
while(ca) {
na = naddr;
while(na) { /* see if we're already in path */
if(ca->zone == na->zone && ca->net == na->net &&
ca->node == na->node && ca->point == na->point &&
!stricmp(ca->domain,na->domain)) {
my_free(opth);
free_addresses(naddr);
return -1;
}
na = na->next;
}
ca = ca->next;
}
}
if(seenby) {
sb = parse_seenbys(seenby,currecho,pktaddr);
if(!sb) {
my_free(opth);
if(naddr) free_addresses(naddr);
printf("\nRED ALERT\n");
return -1;
}
gate = make_tinysbs(currecho,pktaddr);
if(!gate) {
my_free(opth);
if(naddr) free_addresses(naddr);
my_free(sb);
return -1;
}
}
curraddr = currecho->addr;
while(curraddr) {
if(curraddr->zone == pktaddr->zone && curraddr->net == pktaddr->net &&
curraddr->node == pktaddr->node && curraddr->point == pktaddr->point &&
(!stricmp(curraddr->domain,pktaddr->domain))) {
goto ContHere;
}
na = naddr;
while(na) { /* see if he's already in path */
if(curraddr->zone == na->zone && curraddr->net == na->net &&
curraddr->node == na->node && curraddr->point == na->point &&
(!stricmp(curraddr->domain,na->domain))) {
goto ContHere;
}
na = na->next;
}
fp = open_pkt(curraddr,maddr,0);
if(fp != -1) {
xmsg->d_zone = curraddr->zone;
xmsg->dest_net = curraddr->net;
xmsg->dest = curraddr->node;
xmsg->d_point = curraddr->point;
if(curraddr->zone == maddr->zone && !stricmp(curraddr->domain,maddr->domain)) {
write_pkt_msg(fp,xmsg,opth,naddr,maddr,buff,currecho->tag,sb);
}
else {
write_pkt_msg(fp,xmsg,opth,naddr,maddr,buff,currecho->tag,gate);
}
}
close(fp);
ContHere:
curraddr = curraddr->next;
}
my_free(opth);
if(naddr) free_addresses(naddr);
my_free(sb);
my_free(gate);
}
else { /* group msg */
fp = open_pkt(currgroup->uplink,NULL,0);
if(fp != -1) {
write_pkt_msg(fp,xmsg,NULL,NULL,NULL,buff,currgroup->id,NULL);
}
else return -1;
close(fp);
}
return 0;
}
static int _fastcall bitch_and_moan (ADDR *addr,char *area) {
int fp;
time_t t;
struct tm *tt;
XMSG xmsg;
static char bitch_text[] = "Your node is passing messages with a control-a (^a, CTRL-A, ASCII 1)\r" \
"in front of the AREA: tag in echo \"%s\".\r" \
"Reference FTS-0004 and FSC-0043 for more technical information.\r" \
"Please take the necessary steps to fix this incompatibility.\r\r" \
" Thanks,\r XGROUP\r";
static char bitch_msg[384];
memset(&xmsg,0,sizeof(XMSG));
strcpy(xmsg.to,"Sysop");
strcpy(xmsg.from,"XGroup");
strcpy(xmsg.subj,"Invalid (broken) messages from your node");
t = time(NULL);
tt = localtime(&t);
strftime(bitch_msg,21,"%a %d %b %y %H:%M",tt);
strncpy(xmsg.date,bitch_msg,20);
xmsg.date[19] = 0;
xmsg.d_zone = addr->zone;
xmsg.dest = addr->node;
xmsg.dest_net = addr->net;
xmsg.d_point = addr->point;
strncpy(to_domain,addr->domain,8);
to_domain[8] = 0;
xmsg.attr |= (MSGKILL | MSGLOCAL | MSGPRIVATE);
fp = open_pkt(addr,NULL,0);
if(fp != -1) {
sprintf(bitch_msg,bitch_text,area);
write_pkt_msg(fp,&xmsg,NULL,NULL,NULL,bitch_msg,NULL,NULL);
}
else return -1;
close(fp);
return 0;
}
static int _fastcall bitch_and_moan_again (ADDR *addr,char *area) {
int fp;
time_t t;
struct tm *tt;
XMSG xmsg;
static char bitch_text[] = "Your node is passing messages with a control-a (^a, CTRL-A, ASCII 1)\r" \
"in front of the SEEN-BY lines in echo \"%s\".\r" \
"Reference FTS-0004 and FSC-0043 for more technical information.\r" \
"Please take the necessary steps to fix this incompatibility.\r\r" \
" Thanks,\r XGROUP\r";
static char bitch_msg[384];
memset(&xmsg,0,sizeof(XMSG));
strcpy(xmsg.to,"Sysop");
strcpy(xmsg.from,"XGroup");
strcpy(xmsg.subj,"Invalid (broken) messages from your node");
t = time(NULL);
tt = localtime(&t);
strftime(bitch_msg,21,"%a %d %b %y %H:%M",tt);
strncpy(xmsg.date,bitch_msg,20);
xmsg.date[19] = 0;
xmsg.d_zone = addr->zone;
xmsg.dest = addr->node;
xmsg.dest_net = addr->net;
xmsg.d_point = addr->point;
strncpy(to_domain,addr->domain,8);
to_domain[8] = 0;
xmsg.attr |= (MSGKILL | MSGLOCAL | MSGPRIVATE);
fp = open_pkt(addr,NULL,0);
if(fp != -1) {
sprintf(bitch_msg,bitch_text,area);
write_pkt_msg(fp,&xmsg,NULL,NULL,NULL,bitch_msg,NULL,NULL);
}
else return -1;
close(fp);
return 0;
}
static int _fastcall unknown (char *buff,XMSG *xmsg,char *area) {
ADDR addr;
int fp;
addr.zone = addr.net = addr.node = addr.point = 0;
addr.domain = NULL;
fp = open_pkt(&addr,&addr,IS_UNKNOWN);
if(fp != -1) {
if(seenby) {
seenby--;
*seenby = '\r';
}
if(pathline) {
pathline--;
*pathline = '\r';
}
if(newpath && *buff) {
newpath[strlen(newpath)] = '\r';
}
write_pkt_msg(fp,xmsg,NULL,NULL,NULL,buff,area,NULL);
unknownmsgs++;
}
else return -1;
close(fp);
return 0;
}
static int _fastcall insecure (char *buff,XMSG *xmsg,char *area) {
ADDR addr;
int fp;
addr.zone = addr.net = addr.node = addr.point = 0;
addr.domain = NULL;
fp = open_pkt(&addr,&addr,IS_INSECURE);
if(fp != -1) {
if(seenby) {
seenby--;
*seenby = '\r';
}
if(pathline) {
pathline--;
*pathline = '\r';
}
if(newpath && *buff) {
newpath[strlen(newpath)] = '\r';
}
write_pkt_msg(fp,xmsg,NULL,NULL,NULL,buff,area,NULL);
insecuremsgs++;
}
else return -1;
close(fp);
return 0;
}
static int _fastcall isadupe (char *buff,XMSG *xmsg,char *area) {
ADDR addr;
int fp;
addr.zone = addr.net = addr.node = addr.point = 0;
addr.domain = NULL;
fp = open_pkt(&addr,&addr,IS_ADUPE);
if(fp != -1) {
if(seenby) {
seenby--;
*seenby = '\r';
}
if(pathline) {
pathline--;
*pathline = '\r';
}
if(newpath && *buff) {
newpath[strlen(newpath)] = '\r';
}
write_pkt_msg(fp,xmsg,NULL,NULL,NULL,buff,area,NULL);
}
else return -1;
close(fp);
return 0;
}
static int _fastcall is_notforwarded (char *buff,XMSG *xmsg) {
ADDR addr;
int fp;
addr.zone = addr.net = addr.node = addr.point = 0;
addr.domain = NULL;
fp = open_pkt(&addr,&addr,IS_NOFORWARD);
if(fp != -1) {
write_pkt_msg(fp,xmsg,NULL,NULL,NULL,buff,NULL,NULL);
}
else return -1;
close(fp);
return 0;
}
static int _fastcall open_pkt (ADDR *addr,ADDR *faddr,int which) {
int fp;
long pos;
PKTHDR ph;
ADDR *maddr;
static char currout[1027];
char *p;
/* Open (create if necessary) a packet for address given.
Return a file handle for the packet positioned to eop */
if(which == IS_UNKNOWN) {
sprintf(buffer,"%s/UNKNOWN.$$$",inbound);
}
else if(which == IS_INSECURE) {
sprintf(buffer,"%s/INSECURE.$$$",inbound);
}
else if(which == IS_ADUPE) {
sprintf(buffer,"%s/AREDUPES.$$$",inbound);
}
else if(which == IS_NOFORWARD) {
sprintf(buffer,"%s/FORWARD.$$$",inbound);
}
else {
if(!control.xbbsos2) {
strcpy(currout,outbound);
if(addr->domain && *addr->domain && stricmp(myaddr->domain,addr->domain)) {
p = strrchr(currout,'\\');
if(p) p++;
else p = &currout[strlen(currout)];
strcat(currout,addr->domain);
}
if(myaddr->zone != addr->zone) {
sprintf(&currout[strlen(currout)],".%03x",addr->zone);
DosMkDir(currout,0L);
}
sprintf(buffer,"%s/%04x%04x.OUT",currout,addr->net,addr->node);
}
else {
sprintf(buffer,"%s/P.%u.%u.%u.%u.%0.8s",outbound,addr->zone,addr->net,
addr->node,addr->point,addr->domain);
}
}
fp = sopen(buffer,O_RDWR | O_BINARY | O_CREAT,SH_DENYWR,S_IREAD | S_IWRITE);
if(fp != -1) {
lseek(fp,0L,SEEK_END);
if(!tell(fp)) {
memset(&ph,0,sizeof(PKTHDR));
ph.version = 2;
ph.subver = 2;
ph.dnode = addr->node;
ph.dnet = addr->net;
ph.dzone = addr->zone;
ph.dpoint = addr->point;
if(addr->domain) strncpy(ph.ddomain,addr->domain,8);
if(!faddr) maddr = best_guess(addr,myaddr);
else maddr = faddr;
ph.onode = maddr->node;
ph.onet = maddr->net;
ph.ozone = maddr->zone;
ph.opoint = maddr->point;
if(maddr->domain) strncpy(ph.odomain,maddr->domain,8);
write(fp,&ph,sizeof(PKTHDR));
write(fp,"\0",2);
}
pos = tell(fp);
if(pos) lseek(fp,pos - 2L,SEEK_SET); /* Position to next msg spot */
}
return fp;
}
static int _fastcall write_pkt_msg (int fp,XMSG *amsg,SB *opth,ADDR *naddr,
ADDR *maddr,char *text,char *area,
SB *sb) {
char pmsg[192],*p;
word x;
/* long pos; */
/* Write the message given to the end of the file given as a
packed msg */
memset(pmsg,192,0);
*pmsg = 0x02;
pmsg[1] = 0x00;
memcpy(&pmsg[2],&amsg->orig,2);
memcpy(&pmsg[4],&amsg->dest,2);
memcpy(&pmsg[6],&amsg->orig_net,2);
memcpy(&pmsg[8],&amsg->dest_net,2);
memcpy(&pmsg[10],&amsg->attr,2);
x = 0;
memcpy(&pmsg[12],&x,2);
for(x = 0;x < 20;x++) if(!amsg->date[x]) amsg->date[x]=' ';
amsg->date[19] = 0; /* Goddamn qmail anyway... */
memcpy(&pmsg[14],amsg->date,20);
p = &pmsg[34];
strcpy(p,amsg->to);
x = 34;
while(*p){
x++;
p++;
}
p++;
x++;
strcpy(p,amsg->from);
while(*p){
x++;
p++;
}
x++;
p++;
strcpy(p,amsg->subj);
while(*p){
x++;
p++;
}
x++;
p++;
write(fp,pmsg,x);
if(area && *area) { /* Prepend area tag */
write(fp,"AREA: ",6);
write(fp,area,strlen(area));
write(fp,"\r",1);
}
if(area && *area && (opth || naddr || maddr))
spit_newpath(opth,naddr,maddr,fp);
write(fp,text,strlen(text));
if(area && *area && sb)
spit_seenbys(sb,fp);
write(fp,"\0\0",3);
/*
pos = tell(fp);
if(pos) lseek(fp,pos - 2L,SEEK_SET); // Position to next msg spot
*/
return 1;
}