home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / BBS / MISC / XSRC_117.ZIP / XMAILOUT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-09  |  12.7 KB  |  409 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*   XBBS SOURCE CODE copyright (c) 1990 by M. Kimes                        */
  4. /*   All Rights Reserved                                                    */
  5. /*                                                                          */
  6. /*    For complete details of the licensing restrictions, please refer      */
  7. /*    to the License agreement, which is published in its entirety in       */
  8. /*    the in the file LICENSE.XBS.                                          */
  9. /*                                                                          */
  10. /*    USE OF THIS FILE IS SUBJECT TO THE RESTRICTIONS CONTAINED IN THE      */
  11. /*    XBBS LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF            */
  12. /*    THIS AGREEMENT IN ANY OF THE AFOREMENTIONED FILES, OR IF YOU DO       */
  13. /*    NOT HAVE THESE FILES, YOU SHOULD IMMEDIATELY CONTACT M. KIMES         */
  14. /*    AT THE ADDRESS LISTED BELOW.  IN NO EVENT SHOULD YOU PROCEED TO USE   */
  15. /*    THIS FILE WITHOUT HAVING ACCEPTED THE TERMS OF THE XBBS LICENSING     */
  16. /*    AGREEMENT, OR SUCH OTHER AGREEMENT AS YOU ARE ABLE TO REACH WITH      */
  17. /*    M. KIMES                                                              */
  18. /*                                                                          */
  19. /*                                                                          */
  20. /* You can contact M. Kimes at the following address:                       */
  21. /*                                                                          */
  22. /* M. Kimes                         1:380/16.0@FidoNet                      */
  23. /* 542 Merrick                      (318)222-3455 data                      */
  24. /* Shreveport, LA  71104                                                    */
  25. /*                                                                          */
  26. /*                                                                          */
  27. /* Please feel free to contact me at any time to share your comments about  */
  28. /* my software and/or licensing policies.                                   */
  29. /*                                                                          */
  30. /*--------------------------------------------------------------------------*/
  31. /* Scanner for net/echo mail */
  32.  
  33. #include "msg.h"
  34. #include "xext.h"
  35.  
  36. #define MAXKLUDGE 133
  37. /* #define SETSCANNED(x) (x.m_attr |= MSGSCANNED)   */
  38.  
  39. static ulong totalmsgs=0;
  40. static struct _xmsg xmsg;  /* The current msg's header */
  41.  
  42. extern struct _mboard far *marea;
  43. extern word maxareas;
  44.  
  45. /* Function declarations */
  46.  
  47. static int    pascal open_pkt (word zone,word net,word dest,word d_point,char *domain,word attr,word m_attr);
  48. static void   pascal close_pkt (int *fp);
  49. static void   pascal close_msg_files(void);
  50. static void   pascal open_msg_files(word areanum);
  51. static void   pascal report(void);
  52. static int    pascal write_pkt_msg (int fp,struct _xmsg *amsg,char *text,char *area);
  53. static word   pascal do_export(word areanum,word startat);
  54.  
  55.     static int dataptr=-1,textptr=-1;
  56.  
  57.  
  58.  
  59. void pascal export_mail (word areano,word messno) {
  60.  
  61.     register word x,y;
  62.     char temppause,tempsafe;
  63.     struct _mboard far *tempmarea;
  64.     char filename[133];
  65.     struct ffblk f;
  66.  
  67.     tempmarea=marea;
  68.     if(!user.pointid) {
  69.         gprintf(0,say_prompt(586),conf.sysop);
  70.         return;
  71.     }
  72.     else {
  73.         if(nodenumber!=1) sprintf(filename,"%sXPORT%hu\\%04x%04x.PKT",conf.homepath,nodenumber,conf.net,conf.node);
  74.         else sprintf(filename,"%sXPORT\\%04x%04x.PKT",conf.homepath,conf.net,conf.node);
  75.         if(findfirst(filename,&f,0)) {
  76.             gprintf(0,say_prompt(587),conf.zone,conf.net,conf.node,user.pointid,conf.domain);
  77.         }
  78.     }
  79.     temppause=pauser;
  80.     tempsafe=safe;
  81.     pauser=safe=0;
  82.     if(!areano) {
  83.         for(x=0;x<maxareas;x++) {
  84.             gprintf(0,say_prompt(588),marea[x].name);
  85.             inkey();
  86.             open_msg_files(marea[x].number);
  87.             if(dataptr!=-1 && textptr!=-1) {
  88.                 if(!messno) y=lastread[marea[x].number-1]+1;
  89.                 else y=messno;
  90.                 gprintf(0,say_prompt(377),do_export(x,y));
  91.                 close_msg_files();
  92.                 report();
  93.             }
  94.         }
  95.     }
  96.     else {
  97.             marea=&mboard;
  98.             gprintf(0,say_prompt(588),marea[0].name);
  99.             open_msg_files(marea[0].number);
  100.             if(dataptr!=-1 && textptr!=-1) {
  101.                 if(!messno) y=lastread[marea[0].number-1]+1;
  102.                 else y=messno;
  103.                 gprintf(0,say_prompt(377),do_export(0,y));
  104.                 close_msg_files();
  105.             }
  106.             marea=tempmarea;
  107.             printm("\n\n");
  108.     }
  109.     safe=tempsafe;
  110.     pauser=temppause;
  111. }
  112.  
  113.  
  114.  
  115. void pascal report (void) {
  116.  
  117.     printm("\n\n");
  118.     if(!totalmsgs) {
  119.         printm("No messages exported.\n");
  120.         return;
  121.     }
  122.     gprintf(0,"Total msgs exported: %lu\n",totalmsgs);
  123. }
  124.  
  125.  
  126.  
  127. word pascal do_export (word areanum,word startat) {
  128.  
  129.     word nummsgs;
  130.     register word x;
  131.     int fp=-1;
  132.     char *text=NULL;
  133.     char *area="NUL";
  134.     char *lastarea=NULL;
  135.     word anum=0;
  136.     char aname[49];
  137.  
  138.     lseek(dataptr,0L,SEEK_END);
  139.     nummsgs=(word)(tell(dataptr)/(long)sizeof(struct _xmsg));
  140.     if(startat)startat--;
  141.     if(startat>=nummsgs) return 0;
  142.     errno=0;
  143.     lseek(dataptr,(long)startat * (long)sizeof(struct _xmsg),SEEK_SET);
  144.     if(errno==EACCES) {
  145.         sleep(1);
  146.         lseek(dataptr,(long)startat * (long)sizeof(struct _xmsg),SEEK_SET);
  147.     }
  148.     for(x=startat;x<(nummsgs+2);x++) {
  149.         errno=0;
  150.         if(_read(dataptr,&xmsg,sizeof(struct _xmsg))<1) {
  151.             if(errno!=EACCES) break;
  152.             sleep(1);
  153.             if(_read(dataptr,&xmsg,sizeof(struct _xmsg))<1) break;
  154.         }
  155.         if(xmsg.m_attr & MSGDELETED) continue;
  156.         if(xmsg.attr & MSGPRIVATE) {
  157.             if(!(marea[areanum].attr & ECHO) && !(marea[areanum].attr & ALTECHO)) {
  158.                 if(marea[areanum].substat2>user.stat[1]) {
  159.                     if(stricmp(xmsg.to,user.name) && stricmp(xmsg.from,user.name) &&
  160.                         stricmp(xmsg.to,user.handle) && stricmp(xmsg.from,user.handle))
  161.                             continue;
  162.                 }
  163.             }
  164.         }
  165.         if(marea[areanum].attr & NET) {
  166.             if(!(xmsg.attr & MSGPRIVATE)) {
  167.                 if(xmsg.d_zone!=conf.zone || xmsg.dest_net!=conf.net || xmsg.dest!=conf.node || xmsg.d_point!=user.pointid) continue;
  168.             }
  169.         }
  170.  
  171.         /* Got one to export */
  172.         lseek(textptr,xmsg.start,SEEK_SET);
  173.  
  174.         text=(char *)mmalloc(xmsg.length+2);
  175.         if(!text)continue;
  176.         *text=0;
  177.         _read(textptr,text,xmsg.length+1);
  178.         if(!*text){
  179.             if(text)ffree(text);
  180.             text=NULL;
  181.             continue;
  182.         }
  183.         strcpy(aname,marea[areanum].name);
  184.         strupr(aname);
  185. /*        while(p=(strchr(aname,' '))) *p='_';  */
  186.         area=aname;
  187.  
  188.         if(fp==-1) {
  189.             fp=open_pkt(conf.zone,conf.net,conf.node,user.pointid,/* conf.domain */ "XBBS",xmsg.attr,xmsg.m_attr);
  190.             /* Note use of XBBS in domain field to indicate to mailerless point
  191.                that certain "liberties" may be taken with these messages */
  192.             if(fp==-1) {
  193.                 if(text)ffree(text);
  194.                 text=NULL;
  195.                 continue;
  196.             }
  197.         }
  198.         xmsg.d_zone=conf.zone;
  199.         xmsg.dest_net=conf.net;
  200.         xmsg.dest=conf.node;
  201.         xmsg.d_point=user.pointid;
  202.         if(lastarea!=area) {
  203.             lprint("\n");
  204.         }
  205.         fast=1;
  206.         gprintf(LOCALONLY,"\04Exporting msg #%u (#%u) from %s...",x+1,++anum,marea[areanum].name);
  207.         lastread[areanum-1]=x;
  208.         cputs("\r");
  209.         mprint(".");
  210.         inkey();
  211.         if(xmsg.m_attr & MSGPACKED) {
  212.  
  213.            word temp;
  214.  
  215.            temp=msg.length;
  216.            msg.length=xmsg.length;
  217.            if(unpack_msg(&text)==NULL) {
  218.                 if(text) ffree(text);
  219.                 text=NULL;
  220.                 anum--;
  221.                 msg.length=temp;
  222.                 continue;
  223.            }
  224.            msg.length=temp;
  225.         }
  226.         text[xmsg.length]=0;
  227.         text[xmsg.length-1]=0;
  228.         write_pkt_msg(fp,&xmsg,text,area);
  229.         if(text)ffree(text);
  230.         text=NULL;
  231.         totalmsgs++;
  232.         lastarea=area;
  233.     }
  234.     if(fp!=-1)close_pkt(&fp);
  235.     return anum;
  236. }
  237.  
  238.  
  239.  
  240. int pascal open_pkt (word zone,word net,word node,word point,char *domain,word attr,word m_attr) {
  241.  
  242.     static int fp;
  243.     char s[133];
  244.     long pos;
  245.     struct _pkthdr ph;
  246.     struct date dd;
  247.     struct time tt;
  248.  
  249.     /* Open (create if necessary) a packet for address given.
  250.        Return a file handle for the packet positioned to eop */
  251.  
  252.     if(nodenumber==1) sprintf(s,"%sXPORT/%04x%04x.PKT",conf.homepath,net,node);
  253.     else sprintf(s,"%sXPORT%hu/%04x%04x.PKT",conf.homepath,nodenumber,net,node);
  254.  
  255.     fp=oopen(s,O_RDWR | O_DENYWRITE | O_BINARY);
  256.     if(fp==-1) {
  257.         fp=ccreat(s,S_IWRITE);
  258.         if(fp==-1) return -1;        /* Shit */
  259.         getdate(&dd);                /* Create header */
  260.         gettime(&tt);
  261.         ph.orig_node=conf.node;
  262.         ph.dest_node=node;
  263.         ph.year=dd.da_year;
  264.         ph.month=dd.da_mon;
  265.         ph.day=dd.da_day;
  266.         ph.hour=tt.ti_hour;
  267.         ph.minute=tt.ti_min;
  268.         ph.second=tt.ti_sec;
  269.         ph.rate=0;
  270.         ph.ver=2;
  271.         ph.orig_net=conf.net;
  272.         ph.dest_net=net;
  273.         ph.product=0;        /* Until I get a product code (snore) */
  274.         ph.rev_lev=2;
  275.         strset(ph.password,0);
  276.         ph.qm_orig_zone=conf.zone;
  277.         ph.qm_dest_zone=zone;
  278.         strset(ph.domain,0);
  279.         if(domain && *domain) strncpy(ph.domain,domain,8);
  280.         ph.orig_zone=conf.zone;
  281.         ph.dest_zone=zone;
  282.         ph.orig_point=0;
  283.         ph.dest_point=point;
  284.         ph.pr_data=0L;
  285.         _write(fp,&ph,sizeof(struct _pkthdr));
  286.     }
  287.     else {
  288.         lseek(fp,0L,SEEK_END);
  289.         pos=tell(fp);
  290.         if(pos) lseek(fp,pos-2L,SEEK_SET);  /* Position to next msg spot */
  291.     }
  292.     return fp;
  293. }
  294.  
  295.  
  296.  
  297. void pascal close_pkt (int *fp) {
  298.  
  299.     /* Close a previously opened packet. */
  300.  
  301.     cclose(*fp);
  302.     *fp=-1;
  303. }
  304.  
  305.  
  306.  
  307. int pascal write_pkt_msg (int fp,struct _xmsg *amsg,char *text,char *area) {
  308.  
  309.     char pmsg[192];
  310.     char *p;
  311.     word x;
  312.  
  313.     /* Write the message given to the end of the file given as a
  314.        packed msg */
  315.  
  316.     memset(pmsg,192,0);
  317.     *pmsg=0x02;
  318.     pmsg[1]=0x00;
  319.     memcpy(&pmsg[2],&amsg->orig,2);
  320.     memcpy(&pmsg[4],&amsg->dest,2);
  321.     memcpy(&pmsg[6],&amsg->orig_net,2);
  322.     memcpy(&pmsg[8],&amsg->dest_net,2);
  323.     memcpy(&pmsg[10],&amsg->attr,2);
  324. /*  memcpy(&pmsg[12],&amsg->cost,2);  */  /* Old way, bleach */
  325.     x=(word)(strlen(text)+strlen(amsg->to)+strlen(amsg->from)+strlen(amsg->subj)+4);
  326.     if(area && *area) {
  327.         x=(word)(strlen(area)+7);
  328.     }
  329.     memcpy(&pmsg[12],&x,2);   /* Use cost field for msg length.  Here's how it
  330.                                  works:  We add the message text length
  331.                                  (including AREA: tag and kludges) to the
  332.                                  variable length header fields (to,from,subj)
  333.                                  and put this unsigned int into the useless
  334.                                  cost field of the packed msg.  Then an unpacker
  335.                                  can use that field to speed up unpacking.
  336.                                  Length should include the terminating
  337.                                  null bytes */
  338.     for(x=0;x<20;x++) if(amsg->date[x]==0) amsg->date[x]='Q';
  339.     amsg->date[19]=0;                   /* Goddamn qmail anyway...can't count to 20 */
  340.     memcpy(&pmsg[14],amsg->date,20);
  341.     p=&pmsg[34];
  342.     strcpy(p,amsg->to);
  343.     x=34;
  344.     while(*p){
  345.         x++;
  346.         p++;
  347.     }
  348.     p++;
  349.     x++;
  350.     strcpy(p,amsg->from);
  351.     while(*p){
  352.         x++;
  353.         p++;
  354.     }
  355.     x++;
  356.     p++;
  357.     strcpy(p,amsg->subj);
  358.     while(*p){
  359.         x++;
  360.         p++;
  361.     }
  362.     x++;
  363.     p++;
  364.     _write(fp,pmsg,x);
  365.     if(*area && area) {                /* Prepend area tag */
  366.         _write(fp,"AREA:",5);
  367.         _write(fp,area,strlen(area));
  368.         _write(fp,"\r",1);
  369.     }
  370.     _write(fp,text,strlen(text));
  371.     _write(fp,"\0\0",3);
  372.     lseek(fp,(tell(fp)-2L),SEEK_SET);  /* Ready for another msg */
  373.     return 0;
  374. }
  375.  
  376.  
  377.  
  378. void pascal close_msg_files (void) {
  379.  
  380.     if(dataptr!=-1) cclose(dataptr);
  381.     if(textptr!=-1) cclose(textptr);
  382.     dataptr=textptr=-1;
  383. }
  384.  
  385.  
  386.  
  387. void pascal open_msg_files (word areanum) {
  388.  
  389.     static word lastarea=0;
  390.     char s[133];
  391.  
  392.     if(lastarea==areanum) return;
  393.     sprintf(s,"%sXDATA.%03x",messpath,areanum);
  394.     dataptr=oopen(s,O_RDONLY | O_BINARY | O_DENYNONE);
  395.     if(dataptr==-1) {
  396.         lastarea=0;
  397.         return;
  398.     }
  399.     sprintf(s,"%sXTEXT.%03x",messpath,areanum);
  400.     textptr=oopen(s,O_RDONLY | O_BINARY | O_DENYNONE);
  401.     if(textptr==-1) {
  402.         close_msg_files();
  403.         lastarea=0;
  404.         return;
  405.     }
  406.     lastarea=areanum;
  407.     return;
  408. }
  409.