home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 2 BBS
/
02-BBS.zip
/
XGRP_000.SZH
/
GMAILIN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-21
|
21KB
|
671 lines
/* groupmail tosser (implemented per FSC-0036) */
#include "xgroup.h"
#define MAXKLUDGE 256
/* local-only functions */
static int _fastcall crack_pkt (char *pktname,GROUP *ginfo);
static int _fastcall import (GROUP *ginfo,char *buff,XMSG *msg,int dataptr,
int textptr);
static int _fastcall get_msg (word buflen,char *buff,char **text,int fp,
XMSG *msg);
static void _fastcall report (void);
/* global vars created here */
char buffer[1024];
/* local-only variables */
static char to_domain[39],from_domain[39];
/* 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 *outbound;
extern char *inbound;
extern char *archive;
extern char *unarchive;
extern word packsize;
extern word netarea;
void _fastcall group_import_mail (void) {
FILEFINDBUF f;
GROUP *currgroup = group;
int search_handle,num_matches,handle;
char *p,arcname[257];
struct __info__ {
word create_date;
word create_time;
word last_date;
word last_time;
word write_date;
word write_time;
long size;
long allocation;
word attrib;
} info,info2;
/* clean up stray packets in groupin dir */
sprintf(buffer,"%s/*.PKT",groupout);
search_handle = 1; /* for bound purposes */
num_matches = 1;
if(!DosFindFirst(buffer,&search_handle,0,&f,
sizeof(FILEFINDBUF),&num_matches,0L)) {
do {
sprintf(buffer,"%s/%s",groupout,f.achName);
my_unlink(buffer);
num_matches = 1;
} while(!DosFindNext(search_handle,&f,sizeof(FILEFINDBUF),
&num_matches));
DosFindClose(search_handle);
}
printf("\nImporting groupmail...");
while(currgroup) {
Again:
sprintf(buffer,"%s/%s.*",groupin,currgroup->id);
search_handle = 1; /* for bound purposes */
num_matches = 1;
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;
}
p++;
if(ext_reserved(p)) { /* check various reserved extensions */
goto ContHere;
}
if(stricmp(p,"YG0") > 0 && currgroup->uplink) {
/* group file, not msgs */
/* at this time, not doing */
/* anything with them but */
/* passing them through... */
if(toupper(*groupin) == toupper(*groupout)) {
sprintf(buffer,"%s/%s %s/%s",groupin,f.achName,groupout,f.achName);
p = strchr(buffer,' ');
*p = 0;
p++;
DosMove(buffer,p,0L);
logf("Non-msg group file %s located",f.achName);
}
else {
sprintf(buffer,"COPY %s/%s %s/%s > NUL",groupin,f.achName,groupout,f.achName);
system(buffer);
sprintf(buffer,"%s/%s",groupin,f.achName);
my_unlink(buffer);
}
}
/* crack archive */
switch_to(groupin);
sprintf(buffer,"%s %s\\%s *.PKT",unarchive,groupin,f.achName);
system(buffer);
switch_back();
DosFindClose(search_handle);
search_handle = 1;
num_matches = 1;
strcpy(arcname,f.achName);
sprintf(buffer,"%s/*.PKT",groupin);
if(!DosFindFirst(buffer,&search_handle,0,&f,
sizeof(FILEFINDBUF),&num_matches,0L)) {
/* update group date file in inbound dir */
sprintf(buffer,"%s/%s",groupin,arcname);
handle = sopen(buffer,O_RDONLY | O_BINARY,SH_DENYNO);
if(handle == -1 || DosQFileInfo(handle,1,&info,sizeof(struct __info__))) {
printf("\07Warning: could not revise timestamp on group date file %s\n",currgroup->id);
}
else {
close(handle);
sprintf(buffer,"%s/%s.!",groupin,currgroup->id);
handle = sopen(buffer,O_RDWR | O_BINARY | O_CREAT,SH_DENYWR,S_IREAD | S_IWRITE);
if(handle == -1) {
printf("\07Warning: could not revise timestamp on group date file %s\n",currgroup->id);
}
else {
if(DosQFileInfo(handle,1,&info2,sizeof(struct __info__))) {
printf("\07Warning: could not revise timestamp on group date file %s\n",currgroup->id);
}
else {
if(info.write_date > info2.write_date || (info.write_date == info2.write_date && info.write_time > info2.write_time)) {
DosSetFileInfo(handle,1,&info,12);
}
}
close(handle);
}
}
/* move archive to groupout directory (pass it on) */
if(currgroup->uplink && currgroup->numdays) {
if(toupper(*groupin) == toupper(*groupout)) {
sprintf(buffer,"%s/%s %s/%s",groupin,arcname,
groupout,arcname);
p = strchr(buffer,' ');
*p = 0;
p++;
DosMove(buffer,p,0L);
}
else {
sprintf(buffer,"COPY %s/%s %s/%s > NUL",groupin,arcname,
groupout,arcname);
system(buffer);
sprintf(buffer,"%s/%s",groupin,arcname);
my_unlink(buffer);
}
}
do { /* process packets */
sprintf(buffer,"%s/%s",groupin,f.achName);
crack_pkt(buffer,currgroup);
num_matches = 1;
} while(!DosFindNext(search_handle,&f,sizeof(FILEFINDBUF),
&num_matches));
DosFindClose(search_handle);
}
else {
if(grouphold) {
if(toupper(*groupin) == toupper(*grouphold)) {
sprintf(buffer,"%s/%s %s/%s",groupin,f.achName,grouphold,f.achName);
p = strchr(buffer,' ');
*p = 0;
p++;
DosMove(buffer,p,0L);
}
else {
sprintf(buffer,"COPY %s/%s %s/%s",groupin,f.achName,grouphold,f.achName);
system(buffer);
sprintf(buffer,"%s/%s",groupin,f.achName);
my_unlink(buffer);
}
}
else {
sprintf(buffer,"%s/%s",groupin,f.achName);
my_unlink(buffer);
}
}
goto Again;
ContHere:
num_matches = 1;
} while(!DosFindNext(search_handle,&f,sizeof(FILEFINDBUF),
&num_matches));
DosFindClose(search_handle);
}
currgroup = currgroup->next;
}
report();
}
void _fastcall report (void) {
GROUP *currgroup = group;
long totalmsgs = 0L;
printf("\n");
while(currgroup) {
if(currgroup->imported) {
totalmsgs += (long)currgroup->imported;
logf("Imported %u msg%s to area #%u \"%s\"",
currgroup->imported,&"s"[currgroup->imported == 1],
currgroup->areano,currgroup->id);
}
currgroup = currgroup->next;
}
if(totalmsgs) {
logf("Total msgs imported: %lu",totalmsgs);
}
}
int _fastcall crack_pkt (char *pktname,GROUP *ginfo) {
int fp,dataptr,textptr;
long len;
char *buff,*text;
word buflen;
int temp;
XMSG msg;
PKTHDR pi;
fp = sopen(pktname,O_RDONLY | O_BINARY,SH_DENYWR);
if(fp == -1) 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.\n");
return 0; /* Ignore 'short' packet */
}
lseek(fp,0L,SEEK_SET);
if((len - (long)sizeof(PKTHDR)) < 65533L)
buflen = (word)((len - (long)sizeof(PKTHDR)) + 1L);
else buflen = 65534U; /* Set minimum buff length */
buff = (char *)malloc(buflen + 1); /* Allocate text buff */
if(!buff) {
close(fp);
return -2; /* Return OOM */
}
read(fp,&pi,sizeof(PKTHDR)); /* Get packet header */
if(pi.version != 2) { /* not type 2; can't handle it */
return -4;
}
sprintf(buffer,"%s/XTEXT.%03x",msgdir,ginfo->areano);
textptr = sopen(buffer,O_RDWR | O_BINARY | O_CREAT,SH_DENYWR,S_IWRITE | S_IREAD);
sprintf(buffer,"%s/XDATA.%03x",msgdir,ginfo->areano);
dataptr = sopen(buffer,O_RDWR | O_BINARY | O_CREAT,SH_DENYWR,S_IWRITE | S_IREAD);
if(dataptr == -1 || textptr == -1) {
if(dataptr != -1) close(dataptr);
if(textptr != -1) close(textptr);
printf("\nCan't open message base file(s)\n");
return -4; /* Error opening message area */
}
lseek(dataptr,0L,SEEK_END);
lseek(textptr,0L,SEEK_END);
printf("\n\x1b[K");
while(!eof(fp)) {
temp = get_msg(buflen,buff,&text,fp,&msg);
if(temp == -3) {
continue;
}
if(temp == -1) {
close(fp);
my_free(buff);
my_unlink(pktname);
return -3; /* Return 'minor' error */
}
if(temp < 0) break; /* End of packet */
if(!text || !*text) {
printf("\x1b[s\x1b[1;1H\x1b[KNULL message discarded\x1b[u");
continue; /* NULL message */
}
if(!temp) {
printf("%u\r");
temp = import(ginfo,buff,&msg,dataptr,textptr);
}
}
close(fp); /* Close packet */
close(dataptr);
close(textptr);
my_unlink(pktname); /* Get rid of packet after unpacking */
my_free(buff);
return 0; /* Return success */
}
int _fastcall import (GROUP *ginfo,char *buff,XMSG *xmsg,int dataptr,
int textptr) {
/* Put msg in XBBS base */
char *hold;
word temp;
time_t tt;
struct tm *t;
int x;
long pos;
ginfo->imported++;
if(!ginfo->areano) return 0; /* pass-thru */
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) {
temp = strlen(buff);
if(temp > 65100U) {
buff[65099U] = 0;
temp = 65100U;
}
hold = (char *)malloc(temp + 256);
if(!hold) {
printf("\nInsufficient memory for compression\n");
write(textptr,buff,temp);
}
else {
hold = pack_msg(hold,xmsg);
if(!hold) {
printf("\nCompression failed\n");
write(textptr,buff,temp);
}
else {
xmsg->m_attr |= MSGPACKED;
write(textptr,hold,xmsg->length);
}
my_free(hold);
}
}
else write(textptr,buff,strlen(buff));
write(textptr,"\0",1);
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;
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;
}
int _fastcall get_msg (word buflen,char *buff,char **text,int fp,XMSG *xmsg) {
char *p,*pathline,*seenby,*area,*kludge,*endptr,*tempo,*origin;
long pos;
word len,*temp,chk;
Again:
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 != '\02' || p[1] != '\0') {
if(eof(fp) || (*p == '\0' && p[1] == '\0')) return -2;
while(*p != '\02' && p < (buff + buflen)) {
p++;
pos++;
}
lseek(fp,pos,SEEK_SET);
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) { /* grunged msg (no text) */
return -3;
}
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,"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 = NULL;
pathline = NULL;
seenby = NULL;
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);
while(**text == '\r' && **text) (*text)++; /* Skip leading cr's in body */
if(!strncmp(*text," * Origin: ",11)) **text = 0; /* Nothin' but origin */
origin = strstr(*text,"\r * Origin:"); /* Find the 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(pathline) {
*pathline = 0;
pathline = NULL;
}
else {
if (seenby) {
*seenby = 0; /* Mercifully kill SEEN-BYs */
seenby = NULL;
}
}
}
if (*text[strlen(*text)-1] != '\r') strcat(*text,"\r"); /* Assure trailing cr for appearance */
xmsg->attr |= MSGORPHAN; /* Orphan stripped msgs so they never go back out */
}
{ /* 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,"\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;
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->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);
}
}
}
}
p = *text + (strlen(*text) - 1); /* strip trailing blank lines */
while(*p == '\r' && p > *text && *(p-1) == '\r') {
*p = 0;
p--;
}
xmsg->length = strlen(*text);
if(area) xmsg->m_attr |= MSGECHO; /* Is echo */
else xmsg->m_attr |= MSGNET; /* Is net */
xmsg->attr &= (~MSGLOCAL); /* Isn't local! */
xmsg->attr |= MSGORPHAN; /* NEVER reexport */
return 0;
}
int _fastcall ext_reserved (char *ext) {
static char res_ext[][4] = {
"ARC","ZIP","FLE","TIC","PAK","PKA","LZH","ZOO","DWC","PKT",
"ARJ","COM","EXE","BIN","SYS","TXT","DOC","LST","DAT","DBF",
"IDX","!","INI","CTL","CFG","MAP","INF","HLP","OVL","MSG",
"OUT","HUT","DUT","NUT","DB","C","ASM","BAK",""
};
register int x = 0;
while(*res_ext[x]) {
if(!stricmp(ext,res_ext[x])) return -1;
x++;
}
return 0;
}