home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / MSGDP206.SZH / FIDO.C < prev    next >
Text File  |  1991-01-07  |  11KB  |  442 lines

  1. /**
  2.  
  3.  * fido/opus style message base support functions for msged
  4.  
  5.  * released into the PUBLIC DOMAIN 30 jul 1990 by jim nutt
  6.  
  7. **/
  8.  
  9. #define CHUNKSZ 10
  10. #define TEXTLEN 96
  11. #define BUFLEN  4096
  12.  
  13. #if defined(__MSC__) || defined(__TURBOC__)
  14. #include <sys\types.h>
  15. #include <fcntl.h>
  16. #endif
  17. #include <sys\stat.h>
  18. #include <dos.h>
  19. #include "msged.h"
  20. #include "date.h"
  21.  
  22. int _pascal dir_findnext(struct _dta * dta);
  23. int _pascal dir_findfirst(char * filename, int attribute, struct _dta * dta);
  24.  
  25. typedef struct _dosdate {
  26.     unsigned int day:5;
  27.     unsigned int mon:4;
  28.     unsigned int year:7;
  29.     unsigned int sec:5;
  30.     unsigned int min:6;
  31.     unsigned int hour:5;
  32. } DOSDATE;
  33.  
  34. void _pascal normalize(char *s);
  35. static int cdecl compare(const void *i, const void *j);
  36.  
  37. typedef struct _fidoheader {
  38.     char from[36];          /* who from,            */
  39.     char to[36];            /* who to,          */
  40.     char subj[72];          /* message subject,     */
  41.     char date[20];          /* creation date,       */
  42.     int times;          /* number of times read,        */
  43.     int dest;           /* destination node,        */
  44.     int orig;           /* originating node     */
  45.     int cost;           /* actual cost this msg     */
  46.     int orig_net;           /* originating net      */
  47.     int dest_net;           /* destination net      */
  48.     DOSDATE written;        /* when it was written      */
  49.     DOSDATE arrived;        /* when it arrived      */
  50.     unsigned int reply;         /* thread to previous msg       */
  51.     struct _attributes attrib;  /* message attributes       */
  52.     int up;              /* thread to next msg      */
  53. } FIDOHEADER;
  54.  
  55. int _pascal fido_writetext(char *text, int n)
  56.  
  57. {
  58.     char    path[PATHLEN];
  59.     FIDOHEADER msghead;
  60.     static  FILE   *fp;
  61.  
  62.     if (fp == NULL) {
  63.         sprintf(path, "%s/%d.MSG", arealist[area].path,n);
  64.         if ((fp = fopen(path, "rb")) == NULL)
  65.             return (FALSE);
  66.         fread(&msghead,sizeof msghead,1,fp);
  67.         fp = freopen(path,"wb",fp);
  68.         fwrite(&msghead, sizeof msghead,1,fp);
  69.     }
  70.  
  71.     if (text == NULL) {
  72.         fputc(0,fp);
  73.         fclose(fp);
  74.         fp = NULL;
  75.         return(TRUE);
  76.     }
  77.  
  78.     fputs(text,fp);
  79.     fflush(fp);
  80.     return(TRUE);
  81. }
  82.  
  83. int _pascal fido_writeheader(MSG *m)
  84.  
  85. {
  86.     char    path[PATHLEN];
  87.     FIDOHEADER msghead;
  88.     FILE   *fp;
  89.     time_t  now = time(NULL);
  90.     struct  tm *ts;
  91.     int     n = m->msgnum;
  92.  
  93.     ts = localtime(&now);
  94.  
  95.     do {
  96.         sprintf(path, "%s/%d.MSG", arealist[area].path,n);
  97.  
  98.         if (m->new) {
  99.             if ((fp = fopen(path,"rb")) != NULL) {
  100.                 fclose(fp);
  101.                 fp = NULL;
  102.                 n = ++m->msgnum;
  103.             }
  104.             else {
  105.                 if ((fp = fopen(path,"wb")) == NULL)
  106.                     return(FALSE);
  107.             }
  108.         }
  109.         else {
  110.             if ((fp = fopen(path,"r+b")) == NULL) {
  111.                 if ((fp = fopen(path,"wb")) == NULL) {
  112.                     return(FALSE);
  113.                 }
  114.             }
  115.             else
  116.                 fseek(fp,0l,SEEK_SET);
  117.         }
  118.     } while (fp == NULL);
  119.  
  120.     memset(&msghead,0,sizeof msghead);
  121.     msghead.attrib = m->attrib;
  122.     msghead.reply = m->replyto;
  123.     msghead.up = m->replyfrom;
  124.     msghead.times = m->times_read;
  125.     msghead.cost = m->cost;
  126.  
  127.     msghead.dest_net = m->to.net;
  128.     msghead.dest = m->to.node;
  129.  
  130.     memcpy(msghead.to,m->isto,min(sizeof msghead.to,strlen(m->isto)));
  131.     memcpy(msghead.from,m->isfrom,min(sizeof msghead.from,strlen(m->isfrom)));
  132.     memcpy(msghead.subj,m->subj,min(sizeof msghead.subj,strlen(m->subj)));
  133.     memcpy(msghead.date, mtime(m->timestamp), 20);
  134.  
  135.     msghead.orig_net = m->from.net;
  136.     msghead.orig = m->from.node;
  137.  
  138.     if (opusdate) {
  139.         msghead.written.year = ts->tm_year - 80;
  140.         msghead.written.mon = ts->tm_mon + 1;
  141.         msghead.written.day = ts->tm_mday;
  142.         msghead.written.hour = ts->tm_hour;
  143.         msghead.written.min = ts->tm_min;
  144.         msghead.written.sec = ts->tm_sec / 2;
  145.         msghead.arrived = msghead.written;
  146.     }
  147.  
  148.     fwrite((char *) &msghead, sizeof(FIDOHEADER), 1, fp);
  149.     fclose(fp);
  150.     return(TRUE);
  151. }
  152.  
  153. MSG *pascal fido_readheader(int n)
  154.  
  155. {
  156.     FIDOHEADER msghead;
  157.     char    path[PATHLEN];
  158.     int     fd = 0;
  159.     MSG    *m;
  160.  
  161.     memset(&msghead,0,sizeof msghead);
  162.     if ((m = (MSG *) calloc(1,sizeof(MSG))) == NULL)
  163.         outamemory();
  164.  
  165.     sprintf(path, "%s/%d.MSG", arealist[area].path,n);
  166.  
  167. #if defined(__MSC__) || defined(__TURBOC__)
  168.     if ((fd = open(path, O_RDONLY|O_BINARY)) == -1) {      /*WRA*/
  169. #else
  170.     if ((fd = dos_open(path, 0)) == -1) {
  171. #endif
  172.         free(m);
  173.         return (NULL);
  174.     }
  175.  
  176.     m->msgnum = n;
  177.  
  178.     read(fd, (char *) &(msghead), (int) sizeof(FIDOHEADER));
  179.  
  180.     m->from.net = msghead.orig_net;
  181.     m->from.node = msghead.orig;
  182.     m->to.net = msghead.dest_net;
  183.     m->to.node = msghead.dest;
  184.  
  185.     memset(path, 0, sizeof path);
  186.     memcpy(path,msghead.date,sizeof msghead.date);
  187.     m->timestamp = parsedate(path);
  188.  
  189.     if ((m->isto = (char *) calloc(1,sizeof msghead.to + 1)) == NULL) outamemory();
  190.     memcpy(m->isto,msghead.to,sizeof msghead.to);
  191.     if ((m->isfrom = (char *) calloc(1,sizeof msghead.from + 1)) == NULL) outamemory();
  192.     memcpy(m->isfrom,msghead.from,sizeof msghead.from);
  193.     if ((m->subj = (char *) calloc(1,sizeof msghead.subj + 1)) == NULL) outamemory();
  194.     memcpy(m->subj,msghead.subj,sizeof msghead.subj);
  195.     m->attrib = msghead.attrib;
  196.     m->replyto = msghead.reply;
  197.     m->replyfrom = msghead.up;
  198.     m->from.zone = thisnode.zone;
  199.     m->to.zone = thisnode.zone;
  200.     m->cost = msghead.cost;
  201.     m->times_read = msghead.times;
  202.     m->text = NULL;
  203.     m->to.fidonet = 1;
  204.     m->from.fidonet = 1;
  205.     close(fd);
  206.     return(m);
  207. }
  208.  
  209. static int cdecl compare(const void *i, const void *j)
  210.  
  211. {
  212.     return(* (int *) i - * (int *) j);
  213. }
  214.  
  215. int _pascal fido_scan(AREA *a)
  216.  
  217. {
  218.     struct _dta fileinfo;
  219.     char    path[PATHLEN];
  220.     int     cnt = 0;
  221.     int lastalloc = 0, c = 10;
  222.     int     msgnum,l;
  223.     FILE   *fp = NULL;
  224.     int     status;
  225.     int *t = NULL;
  226.  
  227.     if (messages != NULL)
  228.         free(messages);
  229.  
  230.     messages = NULL;
  231.  
  232.     sprintf(path,"%s/*.msg",a->path);
  233.  
  234.     a->last = 0;
  235.  
  236.     status = dir_findfirst1(path,0,&fileinfo);
  237.  
  238.     while (status != -1) {
  239.         if (fileinfo.size > sizeof(FIDOHEADER)) {
  240.             msgnum = atoi(fileinfo.name);
  241.             cnt++;
  242.  
  243.             if (cnt >= lastalloc) {
  244.                 t = calloc((lastalloc += CHUNKSZ), sizeof(int));
  245.                 if (t == NULL) outamemory();
  246.                 if (messages != NULL)
  247.                     memcpy(t,messages,sizeof(int) * cnt);
  248.             }
  249.  
  250.             if (t) {
  251.                 if ((messages != NULL) && (c != lastalloc)) {
  252.                     free(messages);
  253.                     c = lastalloc;
  254.                 }
  255.                 messages = t;
  256.                 messages[cnt - 1] = msgnum;
  257.             }
  258.         }
  259.         if (t == NULL) {
  260.             cnt--;
  261.             break;
  262.         }
  263.         status = dir_findnext1(&fileinfo);
  264.     }
  265.  
  266.     qsort(messages,cnt,sizeof(int),compare); /* put them in order */
  267.  
  268.     sprintf(path, "%s/%s",a->path, lastread);
  269.  
  270.     fp = fopen(path, "rb");
  271.     if (fp != NULL) {
  272.         if (fread(&c, 2, 1, fp) == 1) {
  273.             if (fread(&l,2,1,fp) != 1)
  274.                l = c;
  275.         }
  276.         else
  277.             l = c = 0;
  278.         fclose(fp);
  279.     }
  280.     else {
  281.         l = c = 0;
  282.         if ((fp = fopen(path, "wb")) != NULL) {
  283.             fputc(0, fp);
  284.             fputc(0, fp);
  285.             fputc(0, fp);
  286.             fputc(0, fp);
  287.             fclose(fp);
  288.         }
  289.     }
  290.  
  291.     if (cnt != 0) {
  292.  
  293.         a->first = messages[0];
  294.         a->last = (a->msgtype==0) ? messages[cnt - 1] : cnt;
  295.  
  296.         if (c == 0)
  297.             msgnum = 0;
  298.         else
  299.             for (msgnum = cnt - 1; (msgnum > -1) && (messages[msgnum] != c); msgnum--)
  300.             /* null statement */;
  301.         a->current = (msgnum == -1) ? cnt-1 : msgnum;
  302.  
  303.         if (l == 0)
  304.             msgnum = 0;
  305.         else
  306.             for (msgnum = cnt - 1; (msgnum > -1) && (messages[msgnum] != l); msgnum--)
  307.             /* null statement */;
  308.         a->lastread = (msgnum == -1) ? cnt-1 : msgnum ;
  309.     }
  310.     else
  311.         a->current = a->lastread = a->first = a->last = 0;
  312.  
  313.     return (cnt);
  314. }
  315.  
  316. char *pascal fido_readtext(int n)
  317.  
  318. {
  319.     static  char *buffer = NULL;
  320.     static  char *next = NULL;
  321.     static  char *end = NULL;
  322.     static  int fd = 0;
  323.     static  unsigned int s;
  324.     char    path[PATHLEN];
  325.     int     i, l;
  326.     char    *t = NULL;
  327.     char    *text = NULL;
  328.     char    eol = '\0';
  329.  
  330.  
  331.     if (n < 0) {
  332.         close(fd);
  333.         fd = s = 0;
  334.         next = NULL;
  335.         return(NULL);
  336.     }
  337.  
  338.     if (fd == 0) {
  339.  
  340.         sprintf(path, "%s/%d.MSG", arealist[area].path, n);
  341.  
  342.         s = BUFLEN;
  343.  
  344.         if (buffer == NULL)
  345.             buffer = (char *) calloc(sizeof(char),s);
  346.         else
  347.             memset(buffer,0,s);
  348.  
  349. #if defined(__MSC__) || defined(__TURBOC__)
  350.         if ((fd = open(path, O_RDONLY|O_BINARY)) == -1) {  /*WRA*/
  351. #else
  352.         if ((fd = dos_open(path, 0)) == -1) {
  353. #endif
  354.             return (NULL);
  355.         }
  356.         lseek(fd,(long) sizeof(FIDOHEADER), SEEK_SET);
  357.     }
  358.  
  359.     if (next == NULL) {
  360.         i = read(fd, buffer, s - 1);
  361.         if (i < 1) {
  362.             close(fd);
  363.             next = NULL;
  364.             s = 0;
  365.             fd = 0;
  366.             return(NULL);
  367.         }
  368.         next = buffer;
  369.         while (i && (*next == '\0'))
  370.             i--, next++;
  371.         normalize(next);
  372.         end = buffer + strlen(buffer);
  373.     }
  374.  
  375.     t = memchr(next,'\n',(int) (end - next));
  376.  
  377.     if (t == NULL) {
  378.         l = strlen(next);
  379.         memcpy(buffer,next,l+1);
  380.         i = read(fd,buffer+l, s - l - 1);
  381.         if (i < 1) {
  382.             next = NULL;
  383.             return(strdup(buffer));
  384.         }
  385.         *(buffer + l + i) = '\0';
  386.         normalize(buffer+l);
  387.         end = buffer + strlen(buffer);
  388.         next = buffer;
  389.         t = memchr(next,'\n',s);
  390.     }
  391.  
  392.     if (t != NULL) {
  393.         eol = *(t+1);
  394.         *(t+1) = '\0';
  395.     }
  396.  
  397.     text = strdup(next);
  398.  
  399.     if (t != NULL) {
  400.         *(t+1) = eol;
  401.         next = t+1;
  402.     }
  403.     else
  404.         next = NULL;
  405.  
  406.     return(text);
  407. }
  408.  
  409. int _pascal fido_setlast(AREA a)
  410.  
  411. {
  412.     FILE   *fp;
  413.     char    path[PATHLEN];
  414.     int     i = 1;
  415.  
  416.     sprintf(path, "%s/%s", a.path, lastread);
  417.     if ((fp = fopen(path, "w+b")) == NULL)
  418.         return(FALSE);
  419.     fseek(fp,0l,SEEK_SET);
  420.     if (messages) {
  421.         fwrite((char *) &messages[a.current], sizeof(int), 1, fp);
  422.         fwrite((char *) &messages[a.lastread], sizeof(int), 1, fp);
  423.     }
  424.     else {
  425.         fwrite(&i, sizeof(int), 1, fp);
  426.         fwrite(&i, sizeof(int), 1, fp);
  427.     }
  428.     fclose(fp);
  429.     return(TRUE);
  430. }
  431.  
  432.  
  433. int _pascal fido_delete(int n)
  434.  
  435. {
  436.     char path[TEXTLEN];
  437.  
  438.     sprintf(path, "%s/%d.msg", arealist[area].path, msgnum(n));
  439.     remove(path);
  440.     return(TRUE);
  441. }
  442.