home *** CD-ROM | disk | FTP | other *** search
- /* Scanner for net/echo mail */
-
- #include "msgg.h"
- #include "twindow.h"
- #include "keys.h"
- #include "headedit.h"
-
-
- #define MAXKLUDGE 133
-
- #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)
-
- static struct _address *lastboss; /* Last packet opened to...? */
- static ulong totalmsgs=0;
- static struct _xmsg xmsg; /* The current msg's header */
- static word *anum;
-
- /* Function declarations */
-
- FILE * pascal open_pkt (word zone,word net,word dest,word d_point,char *domain,word attr,word m_attr);
- void pascal close_pkt (FILE *fp);
- static void pascal close_msg_files(void);
- static void pascal open_msg_files(word areanum);
- static void pascal report(void);
- word pascal find_last_scanned (void);
- int pascal write_pkt_msg (FILE *fp,struct _xmsg *amsg,char *text,char *area);
- void pascal export_mail(void);
- static void pascal do_export(word areanum,word startat);
-
- static FILE *dataptr=NULL,*textptr=NULL;
-
-
-
-
- void pascal export_mail (void) {
-
- register word x,y;
- word areanum[4096];
-
- anum=areanum; /* So it can be accessed globally */
- for(x=0;x<4096;x++) anum[x]=0;
- printf("\x1b[2J");
- if(!*outbound) {
- printf("I don't know where your Outbound directory is!");
- return;
- }
- printf("\nExporting mail...\n");
- for(x=0;x<maxareas;x++) {
- if(!(marea[x].attr & ECHO) && !(marea[x].attr & ALTECHO) && !(marea[x].attr & NET) && !(marea[x].attr & ALTERNATE)) continue;
- printf("\nScanning area %s...\n",marea[x].name);
- open_msg_files(marea[x].number);
- if(dataptr && textptr) {
- y=find_last_scanned();
- do_export(x,y);
- close_msg_files();
- }
- }
-
- {
-
- char s[133],out[133];
-
- strcpy(out,outbound);
- out[strlen(out)-1]=0;
- sprintf(s,"%s /c ROUTE.BAT %s",getenv("COMSPEC"),out);
- do_spawn(s);
- }
-
- report();
- }
-
-
-
- void pascal report (void) {
-
- register int x;
-
- printf("\n\n");
- if(!totalmsgs) {
- printf("No messages exported.\n");
- return;
- }
- for(x=0;x<maxareas;x++) {
- if(anum[x]) {
- printf("Exported %u msgs from area #%u %s.\n",anum[x],marea[x].number,marea[x].name);
- }
- }
- printf("\nTotal msgs exported: %lu\n",totalmsgs);
- if(domail!=2 && domail!=4 && domail!=6) get_char();
- }
-
-
-
- void pascal do_export (word areanum,word startat) {
-
- word nummsgs;
- register word x;
- long pos;
- FILE *fp=NULL;
- struct _address thisone;
- char *text=NULL;
- char *area;
- char *lastarea=NULL;
- char aname[133];
- char *p;
-
- thisone.zone=thisone.net=thisone.node=thisone.point=0;
- *thisone.domain=0;
- fseek(dataptr,0L,SEEK_END);
- nummsgs=(word)(ftell(dataptr)/(long)sizeof(struct _xmsg));
- if(startat)startat--;
- fseek(dataptr,(long)startat * (long)sizeof(struct _xmsg),SEEK_SET);
- for(x=startat;x<(nummsgs+2);x++) {
- /* printf("\n!%u!\n",x); */
- pos=ftell(dataptr);
- if(fread(&xmsg,sizeof(struct _xmsg),1,dataptr)!=1) break;
- /* printf("\n?%u?\n",x); */
- if(xmsg.m_attr & MSGSCANNED) continue;
- if(!(xmsg.attr & MSGLOCAL)) goto ExportDone;
- if(xmsg.attr & MSGORPHAN) goto ExportDone;
- if(xmsg.m_attr & MSGDELETED) goto ExportDone;
- if(!(xmsg.m_attr & MSGNET) && !(xmsg.m_attr & MSGECHO)) goto ExportDone;
- /* Got one to export */
- RESETSENT(xmsg); /* Reset sent bit--what the hell, be nice */
- fseek(textptr,xmsg.start,SEEK_SET);
- text=(char *)malloc(xmsg.length+2);
- if(!text)continue;
- *text=0;
- fread(text,1,xmsg.length+1,textptr);
- if(!*text){
- if(text)free(text);
- text=NULL;
- continue;
- }
- /* printf("\n#%u#\n",x); */
- if(xmsg.m_attr & MSGHOST) thisone.node=0;
- if(&thisone!=lastboss || thisone.zone!=xmsg.d_zone || thisone.net!=xmsg.dest_net || thisone.node!=xmsg.dest || thisone.point!=xmsg.d_point) {
- lastboss=NULL;
- thisone.zone=xmsg.d_zone;
- thisone.net=xmsg.dest_net;
- thisone.node=xmsg.dest;
- if(xmsg.m_attr & MSGHOST) thisone.node=0;
- thisone.point=xmsg.d_point;
- *thisone.domain=0;
- }
- area="";
- if((marea[areanum].attr & ECHO) || (marea[areanum].attr & ALTECHO)) {
- if(marea[areanum].thisaddr) {
- thisone.zone=address[(marea[areanum].thisaddr)-1]->zone;
- thisone.net=address[(marea[areanum].thisaddr)-1]->net;
- thisone.node=address[(marea[areanum].thisaddr)-1]->node;
- thisone.point=0;
- strcpy(thisone.domain,address[(marea[areanum].thisaddr)-1]->domain);
- }
- strncpy(aname,marea[areanum].name,133);
- aname[132]=0;
- strupr(aname);
- /* while(p=(strchr(aname,' '))) *p='_'; */
- area=aname;
- }
- if(lastboss!=&thisone || fp==NULL) {
- if(fp)close_pkt(fp);
- fp=open_pkt(thisone.zone,thisone.net,thisone.node,thisone.point,thisone.domain,xmsg.attr,xmsg.m_attr);
- if(!fp) {
- if(text)free(text);
- text=NULL;
- continue;
- }
- }
- lastboss=&thisone;
- xmsg.d_zone=thisone.zone;
- xmsg.dest_net=thisone.net;
- xmsg.dest=thisone.node;
- xmsg.d_point=thisone.point;
- if(lastarea!=area) {
- printf("\n");
- }
- printf("\x1b[KExporting msg #%u (#%u) from %s...\r",x+1,++anum[areanum],marea[areanum].name);
- if(xmsg.m_attr & MSGPACKED) {
- if(unpack_msg(&text)==NULL) {
- if(text) free(text);
- text=NULL;
- continue;
- }
- }
- text[xmsg.length]=0;
- text[xmsg.length-1]=0;
- write_pkt_msg(fp,&xmsg,text,area);
- if(text)free(text);
- text=NULL;
- totalmsgs++;
- lastarea=area;
- ExportDone:
- SETSCANNED(xmsg); /* Rewrite header w/ scanned bit set */
- SETSENT(xmsg); /* Set sent bit */
- if(xmsg.attr & MSGKILL) SETDELETED(xmsg); /* Delete if kill bit set */
- fseek(dataptr,pos,SEEK_SET);
- fwrite(&xmsg,sizeof(struct _xmsg),1,dataptr);
- }
- if(fp)close_pkt(fp);
- lastboss=NULL;
- }
-
-
-
- FILE * pascal open_pkt (word zone,word net,word node,word point,char *domain,word attr,word m_attr) {
-
- static FILE *fp;
- char s[133];
- long pos;
- struct _pkthdr ph;
- struct date dd;
- struct time tt;
-
- /* Open (create if necessary) a packet for address given.
- Return a file handle for the packet positioned to eop */
-
- if(address[0]->zone==zone)sprintf(s,"%s%04x%04x.OUT",outbound,net,node);
- else sprintf(s,"%s.%03x%04x%04x.OUT",outbound,zone,net,node);
- if(m_attr & MSGHOLD) s[strlen(s)-3]='H';
- else if(attr & MSGCRASH) s[strlen(s)-3]='C';
-
- fp=fopen(s,"r+b");
- if(!fp) {
- fp=fopen(s,"wb");
- if(!fp) return NULL; /* Shit */
- getdate(&dd); /* Create header */
- gettime(&tt);
- ph.orig_node=curaddress.node;
- ph.dest_node=node;
- ph.year=dd.da_year;
- ph.month=dd.da_mon;
- ph.day=dd.da_day;
- ph.hour=tt.ti_hour;
- ph.minute=tt.ti_min;
- ph.second=tt.ti_sec;
- ph.rate=0;
- ph.ver=2;
- ph.orig_net=curaddress.net;
- ph.dest_net=net;
- ph.product=0; /* Until I get a product code (snore) */
- ph.rev_lev=2;
- strset(ph.password,0);
- ph.qm_orig_zone=curaddress.zone;
- ph.qm_dest_zone=zone;
- strset(ph.domain,0);
- if(domain && *domain) strncpy(ph.domain,domain,8);
- ph.orig_zone=curaddress.zone;
- ph.dest_zone=zone;
- ph.orig_point=curaddress.point;
- ph.dest_point=point;
- ph.pr_data=0L;
- fwrite(&ph,sizeof(struct _pkthdr),1,fp);
- printf("\nCreated packet %s\n",s);
- }
- else {
- pos=ftell(fp);
- if(pos) fseek(fp,pos-2L,SEEK_SET); /* Position to next msg spot */
- }
- return fp;
- }
-
-
-
- void pascal close_pkt (FILE *fp) {
-
- /* Close a previously opened packet. Add a trailing null-byte before
- doing so. */
-
- fclose(fp);
- fp=NULL;
- }
-
-
-
- int pascal write_pkt_msg (FILE *fp,struct _xmsg *amsg,char *text,char *area) {
-
- char pmsg[192];
- char *p,*pp;
- word x;
- FILE *req;
- struct ffblk f;
-
- /* 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);
- /* memcpy(&pmsg[12],&amsg->cost,2); */ /* Old way, bleach */
- x=(word)(strlen(text)+strlen(amsg->to)+strlen(amsg->from)+strlen(amsg->subj)+4);
- if(area) x+=(word)(strlen(area)+7);
- memcpy(&pmsg[12],&x,2); /* Use cost field for msg length. Here's how it
- works: We add the message text length
- (including AREA: tag and kludges) to the
- variable length header fields (to,from,subj)
- and put this unsigned int into the useless
- cost field of the packed msg. Then an unpacker
- can use that field to speed up unpacking.
- Length should include the msg text-terminating
- null byte */
- memcpy(&pmsg[12],&x,2);
- for(x=0;x<20;x++) if(amsg->date[x]==0) amsg->date[x]=' ';
- amsg->date[19]=0; /* Goddamn opus 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++;
- fwrite(pmsg,x,1,fp);
- if(*area && area) { /* Prepend area tag */
- fwrite("AREA: ",6,1,fp);
- fwrite(area,strlen(area),1,fp);
- fwrite("\r",1,1,fp);
- }
- fwrite(text,strlen(text),1,fp);
- fwrite("\0\0",3,1,fp);
- fseek(fp,(ftell(fp)-2L),SEEK_SET); /* Ready for another msg */
- if(amsg->attr & MSGFRQ) { /* Request */
- if(address[0]->zone==amsg->d_zone) {
- sprintf(pmsg,"%s%04x%04x.REQ",outbound,amsg->dest_net,amsg->dest);
- }
- else sprintf(pmsg,"%s.%03x%04x%04x.REQ",outbound,amsg->d_zone,amsg->dest_net,amsg->dest);
- req=fopen(pmsg,"a+t");
- if(!req) return;
- fseek(req,0L,SEEK_SET);
- strcat(pmsg,amsg->subj);
- p=strtok(pmsg," ");
- while(p) {
- fprintf(req,"%s\n",p);
- }
- fclose(req);
- }
- else if(amsg->attr & MSGFILE) { /* Attach */
- if(address[0]->zone==amsg->d_zone) {
- sprintf(pmsg,"%s%04x%04x.FLO",outbound,amsg->dest_net,amsg->dest);
- }
- else sprintf(pmsg,"%s.%03x%04x%04x.FLO",outbound,amsg->d_zone,amsg->dest_net,amsg->dest);
- if(amsg->m_attr & MSGHOLD) pmsg[strlen(pmsg)-3]='H';
- else if(amsg->attr & MSGCRASH) pmsg[strlen(pmsg)-3]='C';
- req=fopen(pmsg,"a+t");
- if(!req) return;
- fseek(req,0L,SEEK_SET);
- strcpy(pmsg,amsg->subj);
- p=strtok(pmsg," ");
- while (p) {
- pp=NULL;
- do {
- if(findfirst(p,&f,0)) {
- fprintf(req,"%s\n",p);
- break;
- }
- if(!pp) pp=strrchr(p,'\\');
- if(!pp) pp=strrchr(p,'/');
- if(!pp) pp=strrchr(p,':');
- if(pp) {
- pp++;
- *pp=0;
- }
- if(pp)fprintf(req,"%s%s\r\n",p,f.ff_name);
- else fprintf(req,"%s\n",f.ff_name);
- } while(!findnext(&f));
- p=strtok(0," ");
- }
- fprintf(req,"%s\r\n",amsg->subj);
- fclose(req);
- }
- }
-
-
-
- void pascal close_msg_files (void) {
-
- if(dataptr) fclose(dataptr);
- if(textptr) fclose(textptr);
- dataptr=textptr=NULL;
- }
-
-
- word pascal find_last_scanned (void) { /* Speed up someday... */
-
- long pos;
- register word x;
-
- fseek(dataptr,0L,SEEK_END);
- pos=ftell(dataptr);
- x=((word)(pos/(long)sizeof(struct _xmsg))-1);
- for(;x;x--) {
- fseek(dataptr,(long)((long)x*(long)sizeof(struct _xmsg)),SEEK_SET);
- if(fread(&xmsg,sizeof(struct _xmsg),1,dataptr)!=1) break;
- if(xmsg.m_attr & MSGSCANNED) break;
- }
- return x;
- }
-
-
- void pascal open_msg_files (word areanum) {
-
- static word lastarea=0;
- char s[133];
-
- if(lastarea==areanum) return;
- sprintf(s,"%sXDATA.%03x",path,areanum);
- dataptr=fopen(s,"r+b");
- if(!dataptr) {
- lastarea=0;
- return;
- }
- sprintf(s,"%sXTEXT.%03x",path,areanum);
- textptr=fopen(s,"rb");
- if(!textptr) {
- close_msg_files();
- lastarea=0;
- return;
- }
- lastarea=areanum;
- return;
- }