home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / BBS / MISC / HSRC_117.ZIP / MAILOUT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-10-08  |  11.7 KB  |  446 lines

  1. /* Scanner for net/echo mail */
  2.  
  3. #include "msgg.h"
  4. #include "twindow.h"
  5. #include "keys.h"
  6. #include "headedit.h"
  7.  
  8.  
  9. #define MAXKLUDGE 133
  10.  
  11. #define SETSCANNED(x) (x.m_attr |= MSGSCANNED)
  12. #define SETSENT(x) (x.attr |= MSGSENT)
  13. #define RESETSENT(x) (x.attr &= (~MSGSENT))
  14. #define SETDELETED(x) (x.m_attr |= MSGDELETED)
  15.  
  16. static struct _address *lastboss;   /* Last packet opened to...? */
  17. static ulong totalmsgs=0;
  18. static struct _xmsg xmsg;  /* The current msg's header */
  19. static word *anum;
  20.  
  21. /* Function declarations */
  22.  
  23. FILE * pascal open_pkt (word zone,word net,word dest,word d_point,char *domain,word attr,word m_attr);
  24. void   pascal close_pkt (FILE *fp);
  25. static void   pascal close_msg_files(void);
  26. static void   pascal open_msg_files(word areanum);
  27. static void   pascal report(void);
  28. word   pascal find_last_scanned (void);
  29. int    pascal write_pkt_msg (FILE *fp,struct _xmsg *amsg,char *text,char *area);
  30. void   pascal export_mail(void);
  31. static void   pascal do_export(word areanum,word startat);
  32.  
  33.     static FILE *dataptr=NULL,*textptr=NULL;
  34.  
  35.  
  36.  
  37.  
  38. void pascal export_mail (void) {
  39.  
  40.     register word x,y;
  41.     word areanum[4096];
  42.  
  43.     anum=areanum;    /* So it can be accessed globally */
  44.     for(x=0;x<4096;x++) anum[x]=0;
  45.     printf("\x1b[2J");
  46.     if(!*outbound) {
  47.         printf("I don't know where your Outbound directory is!");
  48.         return;
  49.     }
  50.     printf("\nExporting mail...\n");
  51.     for(x=0;x<maxareas;x++) {
  52.         if(!(marea[x].attr & ECHO) && !(marea[x].attr & ALTECHO) && !(marea[x].attr & NET) && !(marea[x].attr & ALTERNATE)) continue;
  53.         printf("\nScanning area %s...\n",marea[x].name);
  54.         open_msg_files(marea[x].number);
  55.         if(dataptr && textptr) {
  56.             y=find_last_scanned();
  57.             do_export(x,y);
  58.             close_msg_files();
  59.         }
  60.     }
  61.  
  62.     {
  63.  
  64.         char s[133],out[133];
  65.  
  66.         strcpy(out,outbound);
  67.         out[strlen(out)-1]=0;
  68.         sprintf(s,"%s /c ROUTE.BAT %s",getenv("COMSPEC"),out);
  69.         do_spawn(s);
  70.     }
  71.  
  72.     report();
  73. }
  74.  
  75.  
  76.  
  77. void pascal report (void) {
  78.  
  79.     register int x;
  80.  
  81.     printf("\n\n");
  82.     if(!totalmsgs) {
  83.         printf("No messages exported.\n");
  84.         return;
  85.     }
  86.     for(x=0;x<maxareas;x++) {
  87.         if(anum[x]) {
  88.             printf("Exported %u msgs from area #%u %s.\n",anum[x],marea[x].number,marea[x].name);
  89.         }
  90.     }
  91.     printf("\nTotal msgs exported: %lu\n",totalmsgs);
  92.     if(domail!=2 && domail!=4 && domail!=6) get_char();
  93. }
  94.  
  95.  
  96.  
  97. void pascal do_export (word areanum,word startat) {
  98.  
  99.     word nummsgs;
  100.     register word x;
  101.     long pos;
  102.     FILE *fp=NULL;
  103.     struct _address thisone;
  104.     char *text=NULL;
  105.     char *area;
  106.     char *lastarea=NULL;
  107.     char aname[133];
  108.     char *p;
  109.  
  110.     thisone.zone=thisone.net=thisone.node=thisone.point=0;
  111.     *thisone.domain=0;
  112.     fseek(dataptr,0L,SEEK_END);
  113.     nummsgs=(word)(ftell(dataptr)/(long)sizeof(struct _xmsg));
  114.     if(startat)startat--;
  115.     fseek(dataptr,(long)startat * (long)sizeof(struct _xmsg),SEEK_SET);
  116.     for(x=startat;x<(nummsgs+2);x++) {
  117. /* printf("\n!%u!\n",x); */
  118.         pos=ftell(dataptr);
  119.         if(fread(&xmsg,sizeof(struct _xmsg),1,dataptr)!=1) break;
  120. /* printf("\n?%u?\n",x); */
  121.         if(xmsg.m_attr & MSGSCANNED) continue;
  122.         if(!(xmsg.attr & MSGLOCAL)) goto ExportDone;
  123.         if(xmsg.attr & MSGORPHAN) goto ExportDone;
  124.         if(xmsg.m_attr & MSGDELETED) goto ExportDone;
  125.         if(!(xmsg.m_attr & MSGNET) && !(xmsg.m_attr & MSGECHO)) goto ExportDone;
  126.         /* Got one to export */
  127.         RESETSENT(xmsg);   /* Reset sent bit--what the hell, be nice */
  128.         fseek(textptr,xmsg.start,SEEK_SET);
  129.         text=(char *)malloc(xmsg.length+2);
  130.         if(!text)continue;
  131.         *text=0;
  132.         fread(text,1,xmsg.length+1,textptr);
  133.         if(!*text){
  134.             if(text)free(text);
  135.             text=NULL;
  136.             continue;
  137.         }
  138. /* printf("\n#%u#\n",x); */
  139.         if(xmsg.m_attr & MSGHOST) thisone.node=0;
  140.         if(&thisone!=lastboss || thisone.zone!=xmsg.d_zone || thisone.net!=xmsg.dest_net || thisone.node!=xmsg.dest || thisone.point!=xmsg.d_point) {
  141.             lastboss=NULL;
  142.             thisone.zone=xmsg.d_zone;
  143.             thisone.net=xmsg.dest_net;
  144.             thisone.node=xmsg.dest;
  145.             if(xmsg.m_attr & MSGHOST) thisone.node=0;
  146.             thisone.point=xmsg.d_point;
  147.             *thisone.domain=0;
  148.         }
  149.         area="";
  150.         if((marea[areanum].attr & ECHO) || (marea[areanum].attr & ALTECHO)) {
  151.             if(marea[areanum].thisaddr) {
  152.                 thisone.zone=address[(marea[areanum].thisaddr)-1]->zone;
  153.                 thisone.net=address[(marea[areanum].thisaddr)-1]->net;
  154.                 thisone.node=address[(marea[areanum].thisaddr)-1]->node;
  155.                 thisone.point=0;
  156.                 strcpy(thisone.domain,address[(marea[areanum].thisaddr)-1]->domain);
  157.             }
  158.             strncpy(aname,marea[areanum].name,133);
  159.             aname[132]=0;
  160.             strupr(aname);
  161. /*            while(p=(strchr(aname,' '))) *p='_';  */
  162.             area=aname;
  163.         }
  164.         if(lastboss!=&thisone || fp==NULL) {
  165.             if(fp)close_pkt(fp);
  166.             fp=open_pkt(thisone.zone,thisone.net,thisone.node,thisone.point,thisone.domain,xmsg.attr,xmsg.m_attr);
  167.             if(!fp) {
  168.                 if(text)free(text);
  169.                 text=NULL;
  170.                 continue;
  171.             }
  172.         }
  173.         lastboss=&thisone;
  174.         xmsg.d_zone=thisone.zone;
  175.         xmsg.dest_net=thisone.net;
  176.         xmsg.dest=thisone.node;
  177.         xmsg.d_point=thisone.point;
  178.         if(lastarea!=area) {
  179.             printf("\n");
  180.         }
  181.         printf("\x1b[KExporting msg #%u (#%u) from %s...\r",x+1,++anum[areanum],marea[areanum].name);
  182.         if(xmsg.m_attr & MSGPACKED) {
  183.            if(unpack_msg(&text)==NULL) {
  184.                 if(text) free(text);
  185.                 text=NULL;
  186.                 continue;
  187.            }
  188.         }
  189.         text[xmsg.length]=0;
  190.         text[xmsg.length-1]=0;
  191.         write_pkt_msg(fp,&xmsg,text,area);
  192.         if(text)free(text);
  193.         text=NULL;
  194.         totalmsgs++;
  195.         lastarea=area;
  196. ExportDone:
  197.         SETSCANNED(xmsg);    /* Rewrite header w/ scanned bit set */
  198.         SETSENT(xmsg);      /* Set sent bit */
  199.         if(xmsg.attr & MSGKILL) SETDELETED(xmsg); /* Delete if kill bit set */
  200.         fseek(dataptr,pos,SEEK_SET);
  201.         fwrite(&xmsg,sizeof(struct _xmsg),1,dataptr);
  202.     }
  203.     if(fp)close_pkt(fp);
  204.     lastboss=NULL;
  205. }
  206.  
  207.  
  208.  
  209. FILE * pascal open_pkt (word zone,word net,word node,word point,char *domain,word attr,word m_attr) {
  210.  
  211.     static FILE *fp;
  212.     char s[133];
  213.     long pos;
  214.     struct _pkthdr ph;
  215.     struct date dd;
  216.     struct time tt;
  217.  
  218.     /* Open (create if necessary) a packet for address given.
  219.        Return a file handle for the packet positioned to eop */
  220.  
  221.     if(address[0]->zone==zone)sprintf(s,"%s%04x%04x.OUT",outbound,net,node);
  222.     else sprintf(s,"%s.%03x%04x%04x.OUT",outbound,zone,net,node);
  223.     if(m_attr & MSGHOLD) s[strlen(s)-3]='H';
  224.     else if(attr & MSGCRASH) s[strlen(s)-3]='C';
  225.  
  226.     fp=fopen(s,"r+b");
  227.     if(!fp) {
  228.         fp=fopen(s,"wb");
  229.         if(!fp) return NULL;        /* Shit */
  230.         getdate(&dd);                /* Create header */
  231.         gettime(&tt);
  232.         ph.orig_node=curaddress.node;
  233.         ph.dest_node=node;
  234.         ph.year=dd.da_year;
  235.         ph.month=dd.da_mon;
  236.         ph.day=dd.da_day;
  237.         ph.hour=tt.ti_hour;
  238.         ph.minute=tt.ti_min;
  239.         ph.second=tt.ti_sec;
  240.         ph.rate=0;
  241.         ph.ver=2;
  242.         ph.orig_net=curaddress.net;
  243.         ph.dest_net=net;
  244.         ph.product=0;        /* Until I get a product code (snore) */
  245.         ph.rev_lev=2;
  246.         strset(ph.password,0);
  247.         ph.qm_orig_zone=curaddress.zone;
  248.         ph.qm_dest_zone=zone;
  249.         strset(ph.domain,0);
  250.         if(domain && *domain) strncpy(ph.domain,domain,8);
  251.         ph.orig_zone=curaddress.zone;
  252.         ph.dest_zone=zone;
  253.         ph.orig_point=curaddress.point;
  254.         ph.dest_point=point;
  255.         ph.pr_data=0L;
  256.         fwrite(&ph,sizeof(struct _pkthdr),1,fp);
  257. printf("\nCreated packet %s\n",s);
  258.     }
  259.     else {
  260.         pos=ftell(fp);
  261.         if(pos) fseek(fp,pos-2L,SEEK_SET);  /* Position to next msg spot */
  262.     }
  263.     return fp;
  264. }
  265.  
  266.  
  267.  
  268. void pascal close_pkt (FILE *fp) {
  269.  
  270.     /* Close a previously opened packet.  Add a trailing null-byte before
  271.        doing so. */
  272.  
  273.     fclose(fp);
  274.     fp=NULL;
  275. }
  276.  
  277.  
  278.  
  279. int pascal write_pkt_msg (FILE *fp,struct _xmsg *amsg,char *text,char *area) {
  280.  
  281.     char pmsg[192];
  282.     char *p,*pp;
  283.     word x;
  284.     FILE *req;
  285.     struct ffblk f;
  286.  
  287.     /* Write the message given to the end of the file given as a
  288.        packed msg */
  289.  
  290.     memset(pmsg,192,0);
  291.     *pmsg=0x02;
  292.     pmsg[1]=0x00;
  293.     memcpy(&pmsg[2],&amsg->orig,2);
  294.     memcpy(&pmsg[4],&amsg->dest,2);
  295.     memcpy(&pmsg[6],&amsg->orig_net,2);
  296.     memcpy(&pmsg[8],&amsg->dest_net,2);
  297.     memcpy(&pmsg[10],&amsg->attr,2);
  298. /*    memcpy(&pmsg[12],&amsg->cost,2);  */  /* Old way, bleach */
  299.     x=(word)(strlen(text)+strlen(amsg->to)+strlen(amsg->from)+strlen(amsg->subj)+4);
  300.     if(area) x+=(word)(strlen(area)+7);
  301.     memcpy(&pmsg[12],&x,2);   /* Use cost field for msg length.  Here's how it
  302.                                  works:  We add the message text length
  303.                                  (including AREA: tag and kludges) to the
  304.                                  variable length header fields (to,from,subj)
  305.                                  and put this unsigned int into the useless
  306.                                  cost field of the packed msg.  Then an unpacker
  307.                                  can use that field to speed up unpacking.
  308.                                  Length should include the msg text-terminating
  309.                                  null byte */
  310.     memcpy(&pmsg[12],&x,2);
  311.     for(x=0;x<20;x++) if(amsg->date[x]==0) amsg->date[x]=' ';
  312.     amsg->date[19]=0;                   /* Goddamn opus anyway... */
  313.     memcpy(&pmsg[14],amsg->date,20);    
  314.     p=&pmsg[34];
  315.     strcpy(p,amsg->to);
  316.     x=34;
  317.     while(*p){
  318.         x++;
  319.         p++;
  320.     }
  321.     p++;
  322.     x++;
  323.     strcpy(p,amsg->from);
  324.     while(*p){
  325.         x++;
  326.         p++;
  327.     }
  328.     x++;
  329.     p++;
  330.     strcpy(p,amsg->subj);
  331.     while(*p){
  332.         x++;
  333.         p++;
  334.     }
  335.     x++;
  336.     p++;
  337.     fwrite(pmsg,x,1,fp);
  338.     if(*area && area) {                /* Prepend area tag */
  339.         fwrite("AREA: ",6,1,fp);
  340.         fwrite(area,strlen(area),1,fp);
  341.         fwrite("\r",1,1,fp);
  342.     }
  343.     fwrite(text,strlen(text),1,fp);
  344.     fwrite("\0\0",3,1,fp);
  345.     fseek(fp,(ftell(fp)-2L),SEEK_SET);  /* Ready for another msg */
  346.     if(amsg->attr & MSGFRQ) {           /* Request */
  347.         if(address[0]->zone==amsg->d_zone) {
  348.             sprintf(pmsg,"%s%04x%04x.REQ",outbound,amsg->dest_net,amsg->dest);
  349.         }
  350.         else sprintf(pmsg,"%s.%03x%04x%04x.REQ",outbound,amsg->d_zone,amsg->dest_net,amsg->dest);
  351.         req=fopen(pmsg,"a+t");
  352.         if(!req) return;
  353.         fseek(req,0L,SEEK_SET);
  354.         strcat(pmsg,amsg->subj);
  355.         p=strtok(pmsg," ");
  356.         while(p) {
  357.             fprintf(req,"%s\n",p);
  358.         }
  359.         fclose(req);
  360.     }
  361.     else if(amsg->attr & MSGFILE) {        /* Attach */
  362.         if(address[0]->zone==amsg->d_zone) {
  363.             sprintf(pmsg,"%s%04x%04x.FLO",outbound,amsg->dest_net,amsg->dest);
  364.         }
  365.         else sprintf(pmsg,"%s.%03x%04x%04x.FLO",outbound,amsg->d_zone,amsg->dest_net,amsg->dest);
  366.         if(amsg->m_attr & MSGHOLD) pmsg[strlen(pmsg)-3]='H';
  367.         else if(amsg->attr & MSGCRASH) pmsg[strlen(pmsg)-3]='C';
  368.         req=fopen(pmsg,"a+t");
  369.         if(!req) return;
  370.         fseek(req,0L,SEEK_SET);
  371.         strcpy(pmsg,amsg->subj);
  372.         p=strtok(pmsg," ");
  373.         while (p) {
  374.             pp=NULL;
  375.             do {
  376.                 if(findfirst(p,&f,0)) {
  377.                     fprintf(req,"%s\n",p);
  378.                     break;
  379.                 }
  380.                 if(!pp) pp=strrchr(p,'\\');
  381.                 if(!pp) pp=strrchr(p,'/');
  382.                 if(!pp) pp=strrchr(p,':');
  383.                 if(pp) {
  384.                     pp++;
  385.                     *pp=0;
  386.                 }
  387.                 if(pp)fprintf(req,"%s%s\r\n",p,f.ff_name);
  388.                 else fprintf(req,"%s\n",f.ff_name);
  389.             } while(!findnext(&f));
  390.             p=strtok(0," ");
  391.         }
  392.         fprintf(req,"%s\r\n",amsg->subj);
  393.         fclose(req);
  394.     }
  395. }
  396.  
  397.  
  398.  
  399. void pascal close_msg_files (void) {
  400.  
  401.     if(dataptr) fclose(dataptr);
  402.     if(textptr) fclose(textptr);
  403.     dataptr=textptr=NULL;
  404. }
  405.  
  406.  
  407. word pascal find_last_scanned (void) {    /* Speed up someday... */
  408.  
  409.     long pos;
  410.     register word x;
  411.  
  412.     fseek(dataptr,0L,SEEK_END);
  413.     pos=ftell(dataptr);
  414.     x=((word)(pos/(long)sizeof(struct _xmsg))-1);
  415.     for(;x;x--) {
  416.         fseek(dataptr,(long)((long)x*(long)sizeof(struct _xmsg)),SEEK_SET);
  417.         if(fread(&xmsg,sizeof(struct _xmsg),1,dataptr)!=1) break;
  418.         if(xmsg.m_attr & MSGSCANNED) break;
  419.     }
  420.     return x;
  421. }
  422.  
  423.  
  424. void pascal open_msg_files (word areanum) {
  425.  
  426.     static word lastarea=0;
  427.     char s[133];
  428.  
  429.     if(lastarea==areanum) return;
  430.     sprintf(s,"%sXDATA.%03x",path,areanum);
  431.     dataptr=fopen(s,"r+b");
  432.     if(!dataptr) {
  433.         lastarea=0;
  434.         return;
  435.     }
  436.     sprintf(s,"%sXTEXT.%03x",path,areanum);
  437.     textptr=fopen(s,"rb");
  438.     if(!textptr) {
  439.         close_msg_files();
  440.         lastarea=0;
  441.         return;
  442.     }
  443.     lastarea=areanum;
  444.     return;
  445. }
  446.