home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 2 BBS
/
02-BBS.zip
/
XGRP_000.SZH
/
NMAILOUT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-22
|
18KB
|
606 lines
/* netmail scanner */
#include "xgroup.h"
#define MAXKLUDGE 256
#define SETSCANNED(x) (x.m_attr |= MSGSCANNED)
#define SETSENT(x) (x.attr |= MSGSENT)
#define RESETSENT(x) (x.attr &= (~MSGSENT))
#define SETDELETED(x) (x.m_attr |= MSGDELETED)
/* function declarations specific to this module */
static int _fastcall open_pkt (ADDR *addr);
static word _fastcall find_last_scanned (int dataptr);
static int _fastcall write_pkt_msg (int fp,XMSG *amsg,char *text);
static void _fastcall report(void);
static int _fastcall do_export(word areano,word startat,int dataptr,
int textptr);
static int _fastcall do_attach_or_request (XMSG *amsg,ADDR *addr);
/* external var references */
extern GROUP *group;
extern CONTROLS control;
extern ADDR *myaddr;
extern ECHOREC *echos;
extern char *groupin;
extern char *groupout;
extern char *grouphold;
extern char *msgdir;
extern char *archive;
extern char *unarchive;
extern char *outbound;
extern char *inbound;
extern word packsize;
extern char buffer[1024];
extern word netarea;
void _fastcall net_export_mail (void) {
word y,totalmsgs;
int dataptr,textptr;
struct stat st;
printf("\nScanning net area #%u...",netarea);
sprintf(buffer,"%s/XDATA.%03x",msgdir,netarea);
if(stat(buffer,&st)) st.st_size = 0L;
if(!st.st_size) {
printf("no msgs\n");
my_unlink(buffer);
sprintf(buffer,"%s/XTEXT.%03x",msgdir,netarea);
my_unlink(buffer);
return;
}
else printf("%lu msg%s\n",st.st_size / (long)sizeof(XMSG),
&"s"[((st.st_size / (long)sizeof(XMSG)) == 1L)]);
dataptr = sopen(buffer,O_RDWR | O_BINARY,SH_DENYNO);
if(dataptr == -1) {
printf("\r\nCouldn't open data file\r\n");
return;
}
sprintf(buffer,"%s/XTEXT.%03x",msgdir,netarea);
textptr = sopen(buffer,O_RDWR | O_BINARY,SH_DENYNO);
if(textptr == -1) {
close(dataptr);
printf("\r\nCouldn't open text file\r\n");
return;
}
y = find_last_scanned(dataptr);
totalmsgs = do_export(netarea,y,dataptr,textptr);
close(textptr);
close(dataptr);
printf("\n");
if(totalmsgs)
logf("Exported %u msg%s from net area #%u",totalmsgs,
&"s"[totalmsgs == 1],netarea);
}
static int _fastcall do_export (word areano,word startat,int dataptr,
int textptr) {
word x,nummsgs,totalmsgs = 0,tries,test;
long pos;
int fp;
char *text = NULL,*p;
XMSG xmsg;
ADDR addr;
addr.domain = NULL;
tries = 0;
while(tries < 50) {
if(lseek(dataptr,0L,SEEK_END) != -1L) break;
DosSleep(100L);
tries++;
}
if(tries >= 50) {
printf("\nLocking conflict; aborting...(#4)\n");
return totalmsgs;
}
nummsgs = (word)(tell(dataptr) / (long)sizeof(XMSG));
if(startat) startat--;
for(x = startat;x < nummsgs;x++) {
tries = 0;
while(tries < 50) {
if(lseek(dataptr,(long)x * (long)sizeof(XMSG),SEEK_SET) != -1L) break;
DosSleep(100L);
tries++;
}
if(tries >= 50) {
printf("\nLocking conflict; aborting...(#5)\n");
return totalmsgs;
}
pos = tell(dataptr);
tries = 0;
while(tries < 50) {
if((size_t)read(dataptr,&xmsg,sizeof(XMSG)) == sizeof(XMSG)) break;
DosSleep(100L);
tries++;
lseek(dataptr,pos,SEEK_SET);
}
if(tries >= 50) {
printf("\nLocking conflict; aborting...(#6)\n");
return totalmsgs;
}
if(xmsg.m_attr & MSGSCANNED) continue;
if(xmsg.m_attr & MSGDELETED) goto ExportDone;
if(!(xmsg.m_attr & MSGNET)) goto ExportDone;
if(!(xmsg.attr & MSGLOCAL)) goto ExportDone;
if(xmsg.attr & MSGORPHAN) goto ExportDone;
/* Got one to export */
RESETSENT(xmsg); /* Reset sent bit--what the hell, be nice */
tries = 0;
while(tries < 50) {
if(lseek(textptr,xmsg.start,SEEK_SET) != -1L) break;
DosSleep(100L);
tries++;
}
if(tries >= 50) {
printf("\nLocking conflict; aborting...(#7)\n");
return totalmsgs;
}
text = (char *)malloc(xmsg.length + 2);
if(!text) {
printf("\nOut of memory\n");
continue;
}
tries = 0;
while(tries < 50) {
*text = 0;
test = (word)read(textptr,text,xmsg.length + 1);
if(test != 65535U) {
if(test >= (xmsg.length - 1)) break;
}
DosSleep(100L);
tries++;
lseek(textptr,xmsg.start,SEEK_SET);
}
if(tries >= 50) {
printf("\nLocking conflict; aborting...(#8)\n");
return totalmsgs;
}
if(!*text){
if(text) my_free(text);
text = NULL;
printf("\nDidn't get any text\n");
continue;
}
if(xmsg.m_attr & MSGPACKED) {
if(unpack_msg(&text) == NULL) {
if(text) my_free(text);
text = NULL;
continue;
}
}
addr.zone = xmsg.d_zone;
addr.net = xmsg.dest_net;
addr.node = xmsg.dest;
addr.point = xmsg.d_point;
addr.domain = NULL;
addr.next = NULL;
if((p = strstr(text,"\01MSGTO: "))) {
if((p - 1) < text || *(p - 1) == '\r') {
p += 8;
p = skip_white(p);
parse_addr(&p,&addr,myaddr);
}
else guess_rest(&addr,myaddr);
}
else guess_rest(&addr,myaddr);
if((xmsg.attr & MSGFILE) || (xmsg.attr & MSGFRQ) || (xmsg.attr & MSGURQ)) {
do_attach_or_request(&xmsg,&addr);
}
fp = open_pkt(&addr);
if(fp == -1) {
if(text) my_free(text);
if(addr.domain) my_free(addr.domain);
addr.domain = NULL;
text = NULL;
continue;
}
if(addr.zone == myaddr->zone && addr.point == myaddr->point &&
addr.net == myaddr->net && addr.node == myaddr->node &&
(!addr.domain || !stricmp(addr.domain,myaddr->domain))) {
logf("Netmail msg #%u skipped; seems to be misaddressed",
x + 1);
my_free(text);
my_free(addr.domain);
addr.domain = NULL;
text = NULL;
close(fp);
continue;
}
printf("\x1b[K#%u (#%u) -> %u:%u/%u.%u@%s\r",
x+1,++totalmsgs,addr.zone,addr.net,addr.node,addr.point,
addr.domain);
logf("Exported netmail msg #%u -> %u:%u/%u.%u@%s",
x+1,addr.zone,addr.net,addr.node,addr.point,
addr.domain);
my_free(addr.domain);
addr.domain = NULL;
text[xmsg.length] = 0;
text[xmsg.length-1] = 0;
write_pkt_msg(fp,&xmsg,text);
close(fp);
my_free(text);
text = NULL;
SETSENT(xmsg); /* Set sent bit */
if(xmsg.attr & MSGKILL) SETDELETED(xmsg); /* delete if so marked*/
ExportDone:
SETSCANNED(xmsg); /* Rewrite header w/ echos-scanned bit set */
tries = 0;
while(tries < 50) {
if(lseek(dataptr,pos,SEEK_SET) != -1L) break;
DosSleep(100L);
tries++;
}
if(tries < 50) {
locking(dataptr,LK_LOCK,(long)sizeof(XMSG));
write(dataptr,&xmsg,sizeof(XMSG));
lseek(dataptr,pos,SEEK_SET);
locking(dataptr,LK_UNLCK,(long)sizeof(XMSG));
}
}
return totalmsgs;
}
static int _fastcall open_pkt (ADDR *addr) {
int fp;
long pos;
PKTHDR ph;
ADDR *maddr;
static char currout[257];
char *p;
/* Open (create if necessary) a packet for address given.
Return a file handle for the packet positioned to eop */
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);
maddr = best_guess(addr,myaddr);
ph.onode = maddr->node;
ph.onet = maddr->net;
ph.ozone = maddr->zone;
ph.opoint = maddr->point;
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 */
}
else printf("\nCouldn't open packet \"%s\"\n",buffer);
return fp;
}
static int _fastcall write_pkt_msg (int fp,XMSG *amsg,char *text) {
char pmsg[192],*p;
word x;
/* 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]='Q';
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);
write(fp,text,strlen(text));
write(fp,"\0\0",3);
lseek(fp,(tell(fp) - 2L),SEEK_SET); /* Ready for another msg */
return 1;
}
static word _fastcall find_last_scanned (int dataptr) { /* Speed up someday... */
long pos;
register word x;
int tries;
XMSG xmsg;
tries = 0;
while(tries < 50) {
if(lseek(dataptr,0L,SEEK_END) != -1L) break;
DosSleep(100L);
tries++;
}
if(tries >= 50) {
printf("\nLocking conflict; aborting... (#1)\n");
return 0;
}
pos = tell(dataptr);
x = (word)((pos / (long)sizeof(XMSG)) - 1L);
for(;x;x--) {
tries = 0;
while(tries < 50) {
if(lseek(dataptr,(long)x * (long)sizeof(XMSG),SEEK_SET) != -1L) break;
DosSleep(100L);
tries++;
}
if(tries >= 50) {
printf("Locking contention...(#2)\n");
continue;
}
tries = 0;
while(tries < 50) {
if((size_t)read(dataptr,&xmsg,sizeof(XMSG)) == sizeof(XMSG)) break;
DosSleep(100L);
tries++;
lseek(dataptr,(long)x * (long)sizeof(XMSG),SEEK_SET);
}
if(tries >= 50) {
printf("Locking contention...(#3)\n");
continue;
}
if(xmsg.m_attr & MSGSCANNED) break;
}
return x;
}
static int _fastcall do_attach_or_request (XMSG *amsg,ADDR *addr) {
int req = -1,search_handle,num_matches;
char namebuf[257],*p,*pp,newsubj[70] = "",flavor = 'N',tempbuf[516];
struct stat st;
FILEFINDBUF f;
static char currout[257];
if(amsg->attr & MSGFRQ) { /* Request */
amsg->attr &= (~MSGFRQ);
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(namebuf,"%s/%04x%04x.OUT",currout,addr->net,addr->node);
}
else {
sprintf(namebuf,"%s/R.%u.%u.%u.%u.%s",outbound,addr->zone,
addr->net,addr->node,addr->point,addr->domain);
}
req = sopen(namebuf,O_CREAT | O_RDWR | O_BINARY,SH_DENYWR,S_IWRITE);
if(req == -1) return -1;
lseek(req,0L,SEEK_END);
strcpy(namebuf,amsg->subj);
lstrip(namebuf);
rstrip(namebuf);
p = strtok(namebuf," ");
while(p) {
ffprintf(req,"%s\r\n",p);
p = strtok(0," ");
if(p) lstrip(p);
}
close(req);
}
else if(amsg->attr & MSGFILE) { /* Attach */
amsg->attr &= (~MSGFILE);
if(!control.xbbsos2) {
sprintf(namebuf,"%s/%04x%04x.FLO",currout,addr->net,addr->node);
if(amsg->m_attr & MSGHOLD) namebuf[strlen(namebuf)-3]='H';
else if(amsg->attr & MSGCRASH) namebuf[strlen(namebuf)-3]='C';
}
else {
if(amsg->m_attr & MSGHOLD) flavor = 'H';
else if(amsg->attr & MSGCRASH) flavor = 'C';
sprintf(namebuf,"%s/%c.%u.%u.%u.%u.%s",outbound,flavor,addr->zone,
addr->net,addr->node,addr->point,addr->domain);
}
req = sopen(namebuf,O_RDWR | O_BINARY | O_CREAT,SH_DENYWR,S_IWRITE);
if(req == -1) return -1;
lseek(req,0L,SEEK_END);
strcpy(namebuf,amsg->subj);
lstrip(namebuf);
rstrip(namebuf);
p = strtok(namebuf," ");
while(p && *p) {
while(pp = strchr(p,'\\')) *pp = '/';
pp = strrchr(p,'/');
if(!pp) pp = strrchr(p,':');
if(!pp) pp = p;
strcat(newsubj,pp);
if(!strchr(p,'*') && !strchr(p,'?')) {
ffprintf(req,"%s\r\n",p);
}
else { /* expand wildcards */
search_handle = 1;
num_matches = 1;
if(!DosFindFirst(p,&search_handle,0,&f,
sizeof(FILEFINDBUF),&num_matches,0L)) {
*pp = 0;
do {
sprintf(tempbuf,"%s%s",p,f.achName);
ffprintf(req,"%s\r\n",tempbuf);
num_matches = 1;
} while(!DosFindNext(search_handle,&f,sizeof(FILEFINDBUF),
&num_matches));
DosFindClose(search_handle);
}
}
p = strtok(0," ");
if(p) lstrip(p);
if(p && *p) strcat(newsubj," ");
}
if(*newsubj) strcpy(amsg->subj,newsubj);
close(req);
}
else if(amsg->attr & MSGURQ) { /* update request */
amsg->attr &= (~MSGURQ);
if(!control.xbbsos2) {
sprintf(namebuf,"%s/%04x%04x.REQ",currout,addr->net,addr->node);
}
else {
sprintf(namebuf,"%s/R.%u.%u.%u.%u.%s",outbound,addr->zone,
addr->net,addr->node,addr->point,addr->domain);
}
req = sopen(namebuf,O_CREAT | O_RDWR | O_BINARY,SH_DENYWR,S_IWRITE);
if(req == -1) return -1;
lseek(req,0L,SEEK_END);
strcpy(namebuf,amsg->subj);
lstrip(namebuf);
rstrip(namebuf);
p = strtok(namebuf," ");
while(p) {
while(pp = strchr(p,'\\')) *pp = '/';
if(strchr(p,'*') || strchr(p,'?') || !stat(p,&st)) {
pp = strrchr(p,'/');
if(!pp) pp = strrchr(p,':');
if(!pp) pp = p;
strcat(newsubj,pp);
}
if(!strchr(p,'*') && !strchr(p,'?')) {
ffprintf(req,"%s +%lu\r\n",pp,st.st_mtime);
}
else { /* expand wildcards */
search_handle = 1;
num_matches = 1;
if(!DosFindFirst(p,&search_handle,0,&f,
sizeof(FILEFINDBUF),&num_matches,0L)) {
*pp = 0;
do {
sprintf(tempbuf,"%s%s",p,f.achName);
if(!stat(tempbuf,&st)) {
ffprintf(req,"%s +%lu\r\n",f.achName,st.st_mtime);
}
num_matches = 1;
} while(!DosFindNext(search_handle,&f,sizeof(FILEFINDBUF),
&num_matches));
DosFindClose(search_handle);
}
}
p = strtok(0," ");
if(p) lstrip(p);
if(p && *p) strcat(newsubj," ");
}
close(req);
if(*newsubj) strcat(amsg->subj,newsubj);
}
return 0;
}