home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / BBS / MISC / XDEV_117.ZIP / XMSGSUBS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-13  |  14.9 KB  |  530 lines

  1.  
  2. /****************************************************************/
  3. /* Miscellaneous routines to interface with XBBS message areas  */
  4. /* Including routines to interface w/ other Fidonet(tm) structs */
  5. /* Such as *.MSG's and *.PKT's                                    */
  6. /* This should be compiled to .OBJ in the TC environment in     */
  7. /* Compact or Large model...you will get some poss. incor.         */
  8. /* assign. warnings and put_us_in_seenbys is unfinished.        */
  9. /* See msg structures (_msg and _xmsg) in MSGG.H                */
  10. /* This code is Turbo C 2.0                                        */
  11. /****************************************************************/
  12.  
  13. #include "msgg.h"
  14.  
  15. int     pascal makepkthdr (FILE *fp,word o_zone,word o_net,word o_node,
  16.                            word o_point,word d_zone,word d_net,word d_node,
  17.                            word d_point);
  18. int     pascal append_pkt (FILE *fp, struct _msg *msg, char *hold);
  19. char * pascal read_msg_from_pkt (FILE *fp,struct _xmsg *msg);
  20. int     pascal make_msg (char *filename,struct _msg *msg,char *hold);
  21. char *  pascal read_msg (char *filename,struct _xmsg *msg);
  22. FILE *  pascal open_pkt (char *directory, word net, word node);
  23. int     pascal get_mess (struct _xmsg *msg,char *directory,word areano,
  24.                          word messno);
  25. int     pascal put_mess (struct _xmsg *msg,char *directory,word areano,
  26.                          word messno,char appendit);
  27. char *  pascal get_text (char *directory,word areano,struct _xmsg *msg);
  28. word    pascal append_text (char far *hold, char *directory,word areano,
  29.                             ulong *start);
  30. void pascal    strip_seenbys (char *hold);
  31. char * pascal  find_seenbys (char *hold);
  32. void pascal    strip_junk (char *hold);
  33. void pascal just_seenby_numbers (char *hold);
  34.  
  35.  
  36. typedef struct
  37.     {
  38.     word
  39.         orig_node,             /* originating node */
  40.         dest_node,             /* destination node */
  41.         year,                  /* 1989 - nnnnn */
  42.         month,
  43.         day,
  44.         hour,
  45.         minute,
  46.         second,
  47.         rate,                  /* unused */
  48.         ver,                   /* 2 */
  49.         orig_net,              /* originating net */
  50.         dest_net;              /* destination net */
  51.     byte
  52.         product,
  53.         rev_lev,               /* revision level */
  54.         password[8];
  55.      word
  56.         qm_orig_zone,
  57.         qm_dest_zone;
  58.      byte
  59.         TRASH[8];
  60.      word
  61.         orig_zone,             /* originating zone */
  62.         dest_zone,             /* destination zone */
  63.         orig_point,            /* originating point */
  64.         dest_point;            /* destination point */
  65.      long
  66.         pr_data;
  67.      } PACKETHDR;
  68.  
  69.  
  70.  
  71.  
  72. int pascal makepkthdr (FILE *fp,word o_zone,word o_net,word o_node,
  73.                        word o_point,word d_zone,word d_net,word d_node,
  74.                        word d_point) {
  75.  
  76. /* Writes a packet header into the currently open stream fp with the
  77.    address information passed */
  78.  
  79.     PACKETHDR pkt;
  80.     struct date dos_date;
  81.     struct time dos_time;
  82.  
  83.         getdate(&dos_date);
  84.         gettime(&dos_time);
  85.  
  86.         pkt.orig_node=o_node;
  87.         pkt.dest_node=d_node;
  88.         pkt.year=(word)(1989-dos_date.da_year);
  89.         pkt.month=(word)dos_date.da_mon;
  90.         pkt.day=(word)dos_date.da_day;
  91.         pkt.hour=(word)dos_time.ti_hour;
  92.         pkt.minute=(word)dos_time.ti_min;
  93.         pkt.second=(word)(dos_time.ti_sec/2);
  94.         pkt.rate=0;
  95.         pkt.ver=2;
  96.         pkt.orig_net=o_net;
  97.         pkt.dest_net=d_net;
  98.         pkt.product=0;
  99.         pkt.rev_lev=0;
  100.         strset(pkt.password,'\0');
  101.         pkt.qm_orig_zone=o_zone;
  102.         pkt.qm_dest_zone=d_zone;
  103.         strset(pkt.TRASH,'\0');
  104.         pkt.orig_zone=d_zone;
  105.         pkt.dest_zone=d_zone;
  106.         pkt.orig_point=o_point;
  107.         pkt.dest_point=d_point;
  108.         pkt.pr_data=0L;
  109.  
  110.         return(fwrite(&pkt,sizeof(PACKETHDR),1,fp));
  111. }
  112.  
  113.  
  114.  
  115. int pascal append_2pkt (FILE *fp, struct _msg *msg, char *hold) {
  116.  
  117. /* Appends the msg passed to the open packet stream fp */
  118.  
  119.     long pos;
  120.  
  121.     fseek(fp,0L,SEEK_END);
  122.     pos=ftell(fp);
  123.     fseek(fp,(pos-1L),SEEK_SET);
  124.     fwrite(&msg->orig,sizeof(word),1,fp);
  125.     fwrite(&msg->dest,sizeof(word),1,fp);
  126.     fwrite(&msg->orig_net,sizeof(word),1,fp);
  127.     fwrite(&msg->dest_net,sizeof(word),1,fp);
  128.     fwrite(&msg->attr,sizeof(word),1,fp);
  129.     fwrite(&msg->cost,sizeof(int),1,fp);
  130.     fwrite(msg->date,sizeof(char),20,fp);
  131.     fputs(msg->to,fp);
  132.     fputc(0,fp);
  133.     fputs(msg->from,fp);
  134.     fputc(0,fp);
  135.     fputs(msg->subj,fp);
  136.     fputc(0,fp);
  137.     fwrite(hold,sizeof(char),strlen(hold),fp);
  138.     fputc(0,fp);
  139.     fputc(0,fp);
  140.     return 0;
  141. }
  142.  
  143.  
  144.  
  145. int pascal make_msg (char *filename,struct _msg *msg,char *hold) {
  146.  
  147. /* Makes a *.MSG file filename */
  148.  
  149.     FILE *fp;
  150.  
  151.     if((!(fp=fopen(filename,"wb")))) return 0;
  152.     fwrite(msg,sizeof(struct _msg),1,fp);
  153.     fwrite(hold,sizeof(char),strlen(hold),fp);
  154.     fputc(0,fp);
  155.     fclose(fp);
  156.     return 0;
  157. }
  158.  
  159.  
  160.  
  161. char * pascal read_msg (char *filename,struct _xmsg *msg) {
  162.  
  163. /* Reads in a *.MSG file filename.  Returns NULL on error.
  164.    Note that this routine dynamically allocates msg text buffer
  165.    which must be freed by caller (i.e. free(hold) */
  166.  
  167.     FILE *fp;
  168.     struct ffblk f;
  169.     struct date dos_date;
  170.     char *hold;
  171.  
  172.     if(findfirst(filename,&f,0))return 0;        /* File didn't exist */
  173.     if((!(fp=fopen(filename,"rb")))) return 0;
  174.     hold=(char far*)farmalloc(((word)f.ff_fsize-(word)sizeof(struct _msg))+1);
  175.     if (hold==NULL) {
  176.         fclose(fp);
  177.         return 0;
  178.     }
  179.     memset(hold,0,((word)f.ff_fsize-(word)sizeof(struct _msg))+1);
  180.     fread(msg,sizeof(struct _msg),1,fp);
  181.     fread(hold,sizeof(char),(word)f.ff_fsize-(word)sizeof(struct _msg),fp);
  182.     getdate(&dos_date);
  183.     msg->subj[63]=0;
  184.     msg->length=(word)strlen(hold)+1;
  185.     msg->start=0L;         /* Set if needed by caller */
  186.     msg->m_attr=0;         /* Set if needed by caller to match area attrib */
  187.     msg->d_zone=0;       /* Unreliable in *.MSG Format */
  188.     msg->o_zone=0;         /* Unreliable in *.MSG Format */
  189.     msg->d_point=0;      /* Unreliable in *.MSG Format */
  190.     msg->o_point=0;      /* Unreliable in *.MSG Format */
  191.     msg->indate[0]=(char)dos_date.da_year-1989;
  192.     msg->indate[1]=(char)dos_date.da_mon;
  193.     msg->indate[2]=(char)dos_date.da_day;
  194.     msg->indate[3]=0;
  195.     fclose(fp);
  196.     return hold;
  197. }
  198.  
  199.  
  200.  
  201.  
  202. FILE * pascal open_pkt (char *directory, word net, word node) {
  203.  
  204. /* Opens a packet in directory for net/node
  205.    directory is created if it doesn't exist
  206.    packet is created if it doesn't exist
  207.    Returns file handle for packet stream (must be closed by caller) */
  208.  
  209.     FILE *fp;
  210.     char filename[133];
  211.  
  212.     mkdir(directory);
  213.     sprintf(filename,"%s%04x%04x",directory,net,node);
  214.     if((!(fp=fopen(filename,"a+b")))) return NULL;
  215.     return fp;
  216. }
  217.  
  218.  
  219.  
  220. int pascal get_mess (struct _xmsg *msg,char *directory,word areano,word messno) {
  221.  
  222. /* Gets msg header #messno from areano in directory
  223.    Returns 0 on error, 1 on success */
  224.  
  225.  char filename[133];
  226.  FILE *fp;
  227.  int p;
  228.  
  229.  sprintf(filename,"%sXDATA.%03x",directory,areano);
  230.  
  231.  if((!(fp=fopen(filename,"rb"))))return 0;
  232.  fseek(fp,(long)((long)(messno-1)*(long)sizeof(struct _xmsg)),SEEK_SET);
  233.  p=fread(msg,sizeof(struct _xmsg),1,fp);
  234.  fclose(fp);
  235.  return p;
  236. }
  237.  
  238.  
  239.  
  240.  
  241. int pascal put_mess (struct _xmsg *msg,char *directory,word areano,word messno,char appendit) {
  242.  
  243. /* Writes msg header #messno to areano in directory
  244.    If appendit is non-zero, appends the msg header (messno ignored)
  245.    Returns 0 on error, 1 on success */
  246.  
  247.  char filename[133];
  248.  FILE *fp;
  249.  int p;
  250.  
  251.  sprintf(filename,"%sXDATA.%03x",directory,areano);
  252.  if((!(fp=fopen(filename,"a+b")))) return 0;
  253.  if(!appendit) fseek(fp,(long)((long)(messno-1)*(long)sizeof(struct _xmsg)),SEEK_SET);
  254.  else fseek(fp,0L,SEEK_END);
  255.  p=fwrite(msg,sizeof(struct _xmsg),1,fp);
  256.  fclose(fp);
  257.  return p;
  258. }
  259.  
  260.  
  261.  
  262. char * pascal get_text (char *directory,word areano,struct _xmsg *msg) {
  263.  
  264. /* Gets the msg text of msg from areano
  265.    in directory. Note text buffer is dynamically allocated and
  266.    must be freed by caller.  Returns NULL on error. */
  267.  
  268.  char filename[133];
  269.  char *hold;
  270.  FILE *pf;
  271.  
  272.  sprintf(filename,"%sXTEXT.%03x",directory,areano);
  273.  
  274.  if((!(pf=fopen(filename,"rb")))) return NULL;
  275.  fseek(pf,msg->start,SEEK_SET);  /* 2 seeks necessary for some reason */
  276.  fseek(pf,msg->start,SEEK_SET);
  277.  hold=(char far*)farmalloc(msg->length+1);
  278.  if (hold==NULL) {
  279.         fclose(pf);
  280.         return NULL;
  281.  }
  282.  memset(hold,0,msg->length);
  283.  fread(hold,msg->length,1,pf);
  284.  fclose(pf);
  285.  hold[msg->length-1]=0;
  286.  
  287. /*
  288.  
  289.  --This commented-out routine strips out junk chars and makes sure
  290.    there's an ending \r...FYI                                       --
  291.  
  292.  while ((tempo=strstr(hold," \x8d"))) memmove(&tempo[1],&tempo[2],strlen(&tempo[2])+1);
  293.  while ((tempo=strchr(hold,'\x8d'))) *tempo=' ';
  294.  while ((tempo=strchr(hold,'\n'))) memmove(tempo,&tempo[1],strlen(&tempo[1])+1);
  295.  if (hold[strlen(hold)-1]!='\r') strcat(hold,"\r");
  296.  
  297. */
  298.  
  299.  return hold;
  300. }
  301.  
  302.  
  303.  
  304.  
  305. word pascal append_text (char far *hold, char *directory,word areano,ulong *start) {
  306.  
  307. /* Appends text in hold to areano in directory.  Returns 0 on error,
  308.    # of bytes written+1 (msg.length) on success.  Doesn't free
  309.    msg text buffer!  Note that start is set in the caller by this routine,
  310.    and that start must be passed by reference, not value (usu. &msg.start) */
  311.  
  312.  FILE *pf;
  313.  word messlen=0;
  314.  char filename[133];
  315.  
  316.  sprintf(filename,"%sXTEXT.%03x",directory,areano);
  317.  if((!(pf=fopen(filename,"a+b")))) return 0;
  318.  fseek(pf,0,SEEK_END);
  319.  *start=(ulong)ftell(pf);
  320.  messlen+=fwrite(hold,sizeof(char),strlen(hold),pf);
  321.  fputc('\0',pf);
  322.  messlen+=2;
  323.  fclose(pf);
  324.  return (messlen);
  325. }
  326.  
  327.  
  328.  
  329. char * pascal read_msg_from_pkt (FILE *fp,struct _xmsg *msg) {
  330.  
  331. /* This one I'm not totally sure of, and it needs a lot of work on
  332.    error-checking and the like.  It should return the msg text
  333.    and partially fill in the msg structure (with what's available
  334.    in a packed msg header).  You'll need to free the dynamically
  335.    allocated 64K block it uses for the text.  It returns NULL on
  336.    error.  Right now, all it does is increment the file pointer by
  337.    one in event of a grunge, so you can try again at an offset (would
  338.    be slow if run on a totally blasted packet!)  */
  339.  
  340.     char *hold;
  341.     char *tempo;
  342.     char *here;
  343.     word p;
  344.     long pos;
  345.     long origpos;
  346.  
  347.      if(feof(fp)) return NULL;
  348.      pos=ftell(fp);
  349.      origpos=pos;
  350.      hold=(char *)farmalloc(65536L);
  351.      if (hold==NULL) {
  352.         fclose(fp);
  353.         return NULL;
  354.      }
  355.      memset(hold,0,(word)65535);
  356.      p=fread(hold,sizeof(char),(word)65535,fp);
  357.      hold[65535]=0;
  358.      if(p==0) {
  359.         farfree(hold);
  360.         return NULL;
  361.      }
  362.      if(((word)*hold)!=2) {
  363.         printf("\nGrunged msg...uh oh...\n");
  364.         fseek(fp,pos+1L,SEEK_SET);
  365.         farfree(hold);
  366.         return NULL;
  367.      }
  368.      msg->orig=(word)hold[2];
  369.      msg->dest=(word)hold[4];
  370.      msg->orig_net=(word)hold[6];
  371.      msg->dest_net=(word)hold[8];
  372.      msg->attr=(word)hold[10];
  373.      msg->cost=(word)hold[12];
  374.      here=(char *)memchr(&hold[14],0,20);
  375.      if(here==NULL) {
  376.         printf("\nGrunged msg...uh oh...\n");
  377.         fseek(fp,origpos+1L,SEEK_SET);
  378.         farfree(hold);
  379.         return NULL;
  380.      }
  381.      strncpy(msg->date,&hold[14],20);
  382.      msg->date[19]=0;
  383.      pos=pos+24;
  384.      tempo=&hold[24];
  385.      here=(char *)memchr(tempo,0,36);
  386.      if(here==NULL) {
  387.         printf("\nGrunged msg...uh oh...\n");
  388.         fseek(fp,origpos+1L,SEEK_SET);
  389.         farfree(hold);
  390.         return NULL;
  391.      }
  392.      strcpy(msg->to,tempo);
  393.      tempo=here+1;
  394.      pos=pos+strlen(msg->to);
  395.      here=(char *)memchr(tempo,0,36);
  396.      if(here==NULL) {
  397.         printf("\nGrunged msg...uh oh...\n");
  398.         fseek(fp,origpos+1L,SEEK_SET);
  399.         farfree(hold);
  400.         return NULL;
  401.      }
  402.      strcpy(msg->from,tempo);
  403.      tempo=here+1;
  404.      pos=pos+strlen(msg->from);
  405.      here=(char *)memchr(tempo,0,72);
  406.      if(here==NULL) {
  407.         printf("\nGrunged msg...uh oh...\n");
  408.         fseek(fp,origpos+1L,SEEK_SET);
  409.         farfree(hold);
  410.         return NULL;
  411.      }
  412.      strncpy(msg->subj,tempo,64);
  413.      msg->subj[63]=0;
  414.      tempo=here+1;
  415.      pos=pos+strlen(msg->subj);
  416.      here=(char *)memchr(tempo,0,((word)65535-(word)(pos-origpos)));
  417.      pos=pos+strlen(here);
  418.      memmove(hold,here,(word)strlen(here)+1);
  419.      fseek(fp,pos,SEEK_SET);
  420.      return (hold);
  421. }
  422.  
  423.  
  424.  
  425. void pascal strip_seenbys (char *hold) {
  426.  
  427. /* This one accomplishes removal of the SEEN-BYs, if any, in the msg
  428.    body */
  429.  
  430.  
  431.     char *path=NULL;
  432.     char *seenby=NULL;
  433.     char *origin=NULL;
  434.  
  435.         origin=strstr(hold,"\r * Origin:");
  436.         if (!origin) origin=strstr(hold,"\r\n * Origin:");
  437.         if (origin) {
  438.             path=strstr(origin,"\r\01PATH:");
  439.             if(!path) path=strstr(origin,"\r\n\01PATH:");
  440.             seenby=strstr(origin,"\rSEEN-BY:");
  441.             if(!seenby)seenby=strstr(origin,"\r\nSEEN-BY:");
  442.             if (!seenby) seenby=strstr(origin,"\r\01SEEN-BY:");
  443.             if (!seenby) seenby=strstr(origin,"\r\n\01SEEN-BY:");
  444.             if (!path) if (seenby) *seenby=0;
  445.             if (seenby && path) memmove (seenby,path,strlen(path)+1);
  446.         }
  447. }
  448.  
  449.  
  450.  
  451. char * pascal find_seenbys (char *hold) {
  452.  
  453. /* This one just returns where the SEEN-BY's start in the msg text */
  454.  
  455.     char *path=NULL;
  456.     char *seenby=NULL;
  457.     char *origin=NULL;
  458.  
  459.         origin=strstr(hold,"\r * Origin:");
  460.         if (!origin) origin=strstr(hold,"\r\n * Origin:");
  461.         if (origin) {
  462.             path=strstr(origin,"\r\01PATH:");
  463.             if(!path) path=strstr(origin,"\r\n\01PATH:");
  464.             seenby=strstr(origin,"\rSEEN-BY:");
  465.             if(!seenby)seenby=strstr(origin,"\r\nSEEN-BY:");
  466.             if (!seenby) seenby=strstr(origin,"\r\01SEEN-BY:");
  467.             if (!seenby) seenby=strstr(origin,"\r\n\01SEEN-BY:");
  468.         }
  469.         return (seenby);
  470. }
  471.  
  472.  
  473.  
  474. void pascal strip_junk (char *hold) {
  475.  
  476. /* This strips linefeeds and soft cr's (useless junk) from the msg body */
  477.  
  478.   char *tempo;
  479.  
  480.   while ((tempo=strstr(hold," \x8d"))) memmove(&tempo[1],&tempo[2],strlen(&tempo[2])+1);
  481.   while ((tempo=strchr(hold,'\x8d'))) *tempo=' ';
  482.   while ((tempo=strchr(hold,'\n'))) memmove(tempo,&tempo[1],strlen(&tempo[1])+1);
  483.   if (hold[strlen(hold)-1]!='\r') strcat(hold,"\r");
  484. }
  485.  
  486.  
  487.  
  488. void pascal just_seenby_numbers (char *hold) {
  489.  
  490. /* This strips lf's, cr's, the word SEEN-BY, 0x01's and extra spaces from
  491.    the seenby text, leaving you with a "pure" list of seenbys */
  492.  
  493.   char *tempo;
  494.  
  495.   while ((tempo=strchr(hold,'\x8d'))) *tempo=' '; /* In case of idiots */
  496.   while ((tempo=strchr(hold,'\n'))) memmove(tempo,&tempo[1],strlen(&tempo[1])+1);
  497.   while ((tempo=strchr(hold,'\r'))) memmove(tempo,&tempo[1],strlen(&tempo[1])+1);
  498.   while ((tempo=strchr(hold,'\01'))) memmove(tempo,&tempo[1],strlen(&tempo[1])+1);
  499.   while ((tempo=strstr(hold,"SEENBY"))) memmove(tempo,&tempo[6],strlen(&tempo[6])+1);
  500.   while ((tempo=strstr(hold,"  "))) memmove(tempo,&tempo[1],strlen(&tempo[1])+1);
  501. }
  502.  
  503.  
  504. void pascal put_us_in_seenbys (char *hold,word net,word node) {
  505.  
  506. /* This should take a string of seenbys treated by just_seenby_numbers,
  507.    find where the given net/node should go, and put it there.  It's really
  508.    only useful as an example, as it doesn't have the ability to put a list
  509.    of net/nodes in as would be really required.  Note that the array the
  510.    seenbys are in should be oversized enough to accept the insert! */
  511.  
  512.     char *tempo;
  513.     char *temp;
  514.     char *p;
  515.     char s[32];
  516.  
  517.     sprintf(s,"%u/",net);
  518.     tempo=strstr(hold,s);
  519.     if(!tempo) {   /* Our net's not listed, do it the hard way */
  520.         sprintf(s,"%u/%u",net,node);
  521.         temp=strdup(hold);    /* Make temporary copy for strtok()ing */
  522.         p=strtok(temp,"/");
  523.         while (p) {            /* Check each net... */
  524.  
  525.         }
  526.     }
  527.  
  528.   /* UNFINISHED!!! */
  529.  
  530. }