home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / MSGDP206.SZH / QUICK.C < prev    next >
Text File  |  1990-11-20  |  12KB  |  563 lines

  1.  /**
  2.  
  3.  * support for quickbbs style message bases
  4.  *
  5.  * released into the PUBLIC DOMAIN 30 Jul 1990 by jim nutt
  6.  
  7. **/
  8.  
  9.  
  10. #define CHUNKSZ 32
  11.  
  12. #include <time.h>
  13.  
  14. #include "msged.h"
  15. #include "date.h"
  16.  
  17. #ifdef __MSC__
  18. #include <sys/types.h>
  19. #endif
  20. #include <sys/stat.h>
  21.  
  22. void _pascal normalize(char *t);
  23.  
  24. int qlast[200];
  25. int qcur[200];
  26.  
  27. struct qinfo {
  28.     int     low;
  29.     int     high;
  30.     int     active;
  31.     int     areas[200];
  32. };
  33.  
  34. struct qidx {
  35.     int     number;
  36.     char    board;
  37. };
  38.  
  39. struct qmsg {
  40.     int     number;
  41.     int    replyto;
  42.     int    replyfrom;
  43.     int     times_read;
  44.     unsigned int start;
  45.     unsigned int count;
  46.     int    destnet;
  47.     int    destnode;
  48.     int    orignet;
  49.     int    orignode;
  50.     char    destzone;
  51.     char    origzone;
  52.     int    cost;
  53.     /* message attributes */
  54.     unsigned int deleted:1;
  55.     unsigned int outnet:1;
  56.     unsigned int netmail:1;
  57.     unsigned int private:1;
  58.     unsigned int recvd:1;
  59.     unsigned int echo:1;
  60.     unsigned int local:1;
  61.     unsigned int xx1:1;
  62.     unsigned int killsent:1;
  63.     unsigned int sent:1;
  64.     unsigned int attach:1;
  65.     unsigned int crash:1;
  66.     unsigned int rreq:1;
  67.     unsigned int areq:1;
  68.     unsigned int rrcpt:1;
  69.     unsigned int xx2:1;
  70.     char    board;
  71.     char    posttime[6];
  72.     char    postdate[9];
  73.     char    whoto[36];
  74.     char    whofrom[36];
  75.     char    subject[73];
  76. };
  77.  
  78. struct qtoidx {
  79.     char    length;
  80.     char    text[35];
  81. };
  82.  
  83. struct qtext {
  84.     char length;
  85.     char text[BLOCKLEN];
  86. };
  87.  
  88. static  struct qinfo info;
  89. static  struct qmsg header;
  90.  
  91. static    char path[80];
  92. static  long start = -1;
  93. static  long count = 0;
  94. static  int  position = 0;
  95. static     FILE *infofp = NULL;
  96. static     FILE *idxfp = NULL;
  97. static     FILE *textfp = NULL;
  98. static     FILE *hdrfp = NULL;
  99. static     FILE *toidxfp = NULL;
  100.  
  101. int   _pascal quick_delete(int n)
  102.  
  103. {
  104.     struct qidx index;
  105.  
  106.     header.deleted = 1;
  107.  
  108.     if (fseek(hdrfp, (long) (messages[n] * (long) sizeof header), SEEK_SET))
  109.         return FALSE;
  110.  
  111.     fwrite(&header, sizeof header, 1, hdrfp);
  112.     fflush(hdrfp);
  113.  
  114.     fseek(idxfp, messages[n] * (long) sizeof index, SEEK_SET);
  115.     index.board = (char) arealist[area].board;
  116.     index.number = -1;
  117.     fwrite(&index,1,sizeof index,idxfp);
  118.     fflush(idxfp);
  119.  
  120.     start = count = 0;
  121.     position = 0;
  122.  
  123.     return(TRUE);
  124. }
  125.  
  126. int   _pascal quick_writetext(char *text, int n)
  127.  
  128. {
  129.     struct qtext block;
  130.     char *s;
  131.     static char buf[768];
  132.     struct stat b;
  133.     static int f = 0;
  134.  
  135.     if (f == 0) {
  136.         f = 1;
  137.         fstat(fileno(textfp),&b);
  138.         start = b.st_size / sizeof block;
  139.         count = 0;
  140.     }
  141.  
  142.     if (text == NULL) {
  143.         n = position;
  144.         memset(block.text,0,sizeof block.text);
  145.         strcpy(block.text,buf);
  146.         block.length = (char) strlen(buf);
  147.         fseek(textfp,(long) (start + count) * (long) sizeof block, SEEK_SET);
  148.         fwrite(&block,1,sizeof block,textfp);
  149.         fflush(textfp);
  150.         header.start = (unsigned int) start;
  151.         header.count = (unsigned int) ++count;
  152.         fseek(hdrfp, (long) n * (long) sizeof header, SEEK_SET);
  153.         fwrite(&header, sizeof header, 1, hdrfp);
  154.         fflush(hdrfp);
  155.         f = 0;
  156.         memset(buf,0,sizeof buf);
  157.         return(TRUE);
  158.     }
  159.  
  160.     strcat(buf,text);
  161.     while (strlen(buf) > sizeof block.text) {
  162.         s = buf + sizeof block.text;
  163.         memcpy(block.text,buf,sizeof block.text);
  164.         strcpy(buf,s);
  165.         block.length = sizeof block.text;
  166.         fseek(textfp,(long) (start + count) * (long) sizeof block, SEEK_SET);
  167.         fwrite(&block,sizeof block,1,textfp);
  168.         fflush(textfp);
  169.         count++;
  170.     }
  171.  
  172.     return(TRUE);
  173. }
  174.  
  175. MSG  *pascal quick_readheader(int n)
  176.  
  177. {
  178.     struct stat b;
  179.     char path[80];
  180.     MSG *m;
  181.     long i;
  182.  
  183.     memset(path,0,sizeof path);
  184.     fstat(fileno(hdrfp),&b);
  185.  
  186.     i = (long) (messages[n]) * (long) sizeof header;
  187.     if (i > b.st_size)
  188.         return(NULL);
  189.  
  190.     position = messages[n];
  191.  
  192.     fseek(hdrfp, i, SEEK_SET);
  193.     if (fread(&header, sizeof header, 1, hdrfp) != 1)
  194.         return(NULL);
  195.  
  196.     start = (long) header.start;
  197.     count = (long) header.count;
  198.  
  199.     fstat(fileno(textfp),&b);
  200.     if (((start + count) * (long) sizeof(struct qtext)) > b.st_size)
  201.         return(NULL);
  202.  
  203.     if (header.deleted)
  204.         return (NULL);
  205.  
  206.     m = (MSG *) calloc(1, sizeof(MSG));
  207.  
  208.     m->msgnum = header.number;
  209.  
  210.     m->isfrom = (char *) calloc(header.whofrom[0] + 1,sizeof(char));
  211.     strncpy(m->isfrom,header.whofrom+1,header.whofrom[0]);
  212.  
  213.     m->isto = (char *) calloc(header.whoto[0] + 1,sizeof(char));
  214.     strncpy(m->isto,header.whoto+1,header.whoto[0]);
  215.  
  216.     m->subj = (char *) calloc(header.subject[0] + 1,sizeof(char));
  217.     strncpy(m->subj,header.subject+1,header.subject[0]);
  218.  
  219.     strncpy(path,header.postdate + 1, header.postdate[0]);
  220.     strcat(path," ");
  221.     strncat(path,header.posttime + 1, header.posttime[0]);
  222.     m->timestamp = parsedate(path);
  223.  
  224.     m->attrib.private = header.private;
  225.     m->attrib.crash = header.crash;
  226.     m->attrib.recvd = header.recvd;
  227.     m->attrib.sent = header.sent;
  228.     m->attrib.attached = header.attach;
  229.     m->attrib.forward = 0;
  230.     m->attrib.orphan = 0;
  231.     m->attrib.killsent = header.killsent;
  232.     m->attrib.local = header.local;
  233.     m->attrib.hold = header.xx1;
  234.     m->attrib.direct = header.xx2;
  235.     m->attrib.freq = 0;
  236.     m->attrib.rreq = header.rreq;
  237.     m->attrib.rcpt = header.rrcpt;
  238.     m->attrib.areq = header.areq;
  239.     m->attrib.ureq = 0;
  240.  
  241.     m->to.zone = header.destzone;
  242.     m->to.net = header.destnet;
  243.     m->to.node = header.destnode;
  244.  
  245.     m->from.zone = header.destzone;
  246.     m->from.net = header.destnet;
  247.     m->from.node = header.destnode;
  248.  
  249.     m->to.fidonet = m->from.fidonet = 1;
  250.  
  251.     return(m);
  252. }
  253.  
  254. int   _pascal quick_writeheader(MSG *m)
  255.  
  256. {
  257.     struct qidx index;
  258.     struct tm *ts;
  259.     struct stat b;
  260.     FILE *fp;
  261.     int c = arealist[area].current;
  262.  
  263.     memset(&header,0,sizeof header);
  264.     header.number = m->msgnum;
  265.     header.start = (unsigned int) start;
  266.     header.count = (unsigned int) count;
  267.  
  268.     if (m->new) {
  269.         c = arealist[area].messages - 1;
  270.         fstat(fileno(hdrfp),&b);
  271.         messages[c] = (int) (b.st_size / sizeof header);
  272.         start = (unsigned long) (header.start = 0);
  273.         count = (unsigned long) (header.count = 0);
  274.         info.areas[arealist[area].board-1]++;
  275.         info.active++;
  276.         header.number = ++info.high;
  277.     }
  278.  
  279.     position = messages[c];
  280.  
  281.     header.replyto = 0;
  282.     header.replyfrom = 0;
  283.     header.times_read = m->times_read;
  284.     header.destzone = (char) m->to.zone;
  285.     header.destnet = m->to.net;
  286.     header.destnode = m->to.node;
  287.     header.origzone = (char) m->from.zone;
  288.     header.orignet = m->from.net;
  289.     header.orignode = m->from.node;
  290.     header.cost = m->cost;
  291.  
  292.     header.deleted = 0;
  293.     header.outnet = 0;
  294.     header.netmail = 0;
  295.     header.echo = 0;
  296.     if (arealist[area].netmail) {
  297.         header.netmail = 1;
  298.         header.outnet = 1;
  299.     }
  300.     if (arealist[area].echomail)
  301.         header.echo = 1;
  302.     header.private = m->attrib.private;
  303.     header.recvd = m->attrib.recvd;
  304.     header.local = 1;
  305.     header.xx1 = 0;
  306.     header.killsent = m->attrib.killsent;
  307.     header.sent = m->attrib.sent;
  308.     header.attach = m->attrib.attached;
  309.     header.crash = m->attrib.crash;
  310.     header.rreq = m->attrib.rreq;
  311.     header.areq = m->attrib.areq;
  312.     header.rrcpt = m->attrib.rcpt;
  313.     header.xx2 = m->attrib.direct;
  314.     header.board = (char) arealist[area].board;
  315.  
  316.     ts = localtime(&m->timestamp);
  317.     header.posttime[0] = 5;
  318.     sprintf(header.posttime+1,"%02d:%02d",ts->tm_hour, ts->tm_min);
  319.     header.postdate[0] = 8;
  320.     sprintf(header.postdate + 1,"%02d-%02d-%02d",ts->tm_mon+1,ts->tm_mday,ts->tm_year);
  321.  
  322.     header.whoto[0] = (char) min(strlen(m->isto), sizeof(header.whoto) - 1);
  323.     memcpy(header.whoto+1,m->isto,header.whoto[0]);
  324.     header.whofrom[0] = (char) min(strlen(m->isfrom), sizeof(header.whofrom));
  325.     memcpy(header.whofrom+1,m->isfrom,header.whofrom[0]);
  326.     header.subject[0] = (char) min(strlen(m->subj), sizeof(header.subject) - 1);
  327.     memcpy(header.subject+1,m->subj, header.subject[0]);
  328.     
  329.     fseek(hdrfp, (long) position * (long) sizeof header, SEEK_SET);
  330.     fwrite(&header, sizeof header, 1, hdrfp);
  331.  
  332.     fseek(infofp,0l,SEEK_SET);
  333.     fwrite(&info,sizeof info, 1, infofp);
  334.  
  335.     index.number = header.number;
  336.     index.board = (char) arealist[area].board;
  337.     fseek(idxfp,(long) position * (long) sizeof(struct qidx),SEEK_SET);
  338.     fwrite(&index,sizeof index,1,idxfp);
  339.  
  340.     fflush(idxfp);
  341.     fflush(infofp);
  342.     fflush(hdrfp);
  343.  
  344.     strcpy(path,quickbbs);
  345.     strcat(path,"msgtoidx.bbs");
  346.     if ((fp = fopen(path,"r+b")) == NULL)
  347.         if ((fp = fopen(path,"w+b")) == NULL)
  348.             return(TRUE);
  349.  
  350.     fseek(fp,(long) position * (long) sizeof(header.whoto), SEEK_SET);
  351.     fwrite(header.whoto,sizeof(header.whoto),1,fp);
  352.     fclose(fp);
  353.  
  354.     return(TRUE);
  355. }
  356.  
  357. char *pascal quick_readtext(int n)
  358.  
  359. {
  360.     struct qtext text;
  361.  
  362.     static int b = -1;
  363.     static int c = -1;
  364.  
  365.     static char *next = NULL;
  366.     char *t,*t2,ch = '\0';
  367.  
  368.     static char *s = NULL;
  369.  
  370.     if (n < 0) {
  371.         b = c = -1;
  372.         next = NULL;
  373.         if (s) free(s);
  374.         s = NULL;
  375.         return NULL;
  376.     }
  377.  
  378.     if ((next == NULL) && (s != NULL)) {
  379.         free(s);
  380.         b = c = -1;
  381.         s = NULL;
  382.         return(NULL);
  383.     }
  384.  
  385.     if (s == NULL) {
  386.  
  387.         if (b == -1) {
  388.             b = (int) (start = (long) header.start);
  389.             c = (int) (count = (long) header.count);
  390.         }
  391.  
  392.         if ((c < 1) || (b < 0)) {
  393.             b = c = -1;
  394.             return NULL;
  395.         }
  396.  
  397.         if ((s = (char *) malloc((size_t) count * sizeof text + 1)) == NULL) {
  398.             b = c = -1;
  399.             return NULL;
  400.         }
  401.  
  402.         memset(s,0,c * sizeof text + 1);
  403.  
  404.         fseek(textfp, (long) (start * (long) sizeof text), SEEK_SET);
  405.         while (c) {
  406.             memset(text.text,0,sizeof text);
  407.             fread(&text, sizeof text, 1, textfp);
  408.             strncat(s,text.text,text.length);
  409.             c--;
  410.         }
  411.         normalize(s);
  412.         next = s;
  413.     }
  414.  
  415.     t = next;
  416.     next = strchr(t,'\n');
  417.     if (next) {
  418.         ch = *(next+1);
  419.         *(next+1) = '\0';
  420.     }
  421.  
  422.     t2 = strdup(t);
  423.  
  424.     if (next) {
  425.         *(next+1) = ch;
  426.         next++;
  427.     }
  428.  
  429.     return(t2);
  430. }
  431.  
  432. int   _pascal quick_setlast(AREA a)
  433.  
  434. {
  435.     FILE *fp;
  436.  
  437.     strcpy(path,quickbbs);
  438.     strcat(path,"lastread.bbs");
  439.  
  440.     qlast[a.board-1] = messages[a.lastread];
  441.     qcur[a.board-1] = messages[a.current];
  442.  
  443.     if ((fp = fopen(path,"wb")) != NULL) {
  444.         fwrite(qlast,1,sizeof qlast,fp);
  445.         fclose(fp);
  446.     }
  447.  
  448.     strcpy(path,quickbbs);
  449.     strcat(path,"current.bbs");
  450.  
  451.     if ((fp = fopen(path,"wb")) != NULL) {
  452.         fwrite(qcur,1,sizeof qcur,fp);
  453.         fclose(fp);
  454.     }
  455.  
  456.     return(TRUE);
  457. }
  458.  
  459. int   _pascal quick_scan(AREA *a)
  460.  
  461. {
  462.     struct qidx  index;
  463.     FILE *fp;
  464.     int i, i2, idx;
  465.     int  *t;
  466.  
  467.     position = 0;
  468.  
  469.     if (infofp != NULL) fclose(infofp);
  470.     strcpy(path,quickbbs);
  471.     strcat(path,"msginfo.bbs");
  472.  
  473.     if ((infofp = fopen(path,"r+b")) == NULL)
  474.         if ((infofp = fopen(path,"w+b")) == NULL)
  475.             return(0);
  476.  
  477.     if (idxfp != NULL) fclose(idxfp);
  478.     strcpy(path,quickbbs);
  479.     strcat(path,"msgidx.bbs");
  480.     if ((idxfp = fopen(path,"r+b")) == NULL)
  481.         if ((idxfp = fopen(path,"w+b")) == NULL)
  482.             return(0);
  483.  
  484.     if (textfp != NULL) fclose(textfp);
  485.     strcpy(path,quickbbs);
  486.     strcat(path,"msgtxt.bbs");
  487.     if ((textfp = fopen(path,"r+b")) == NULL)
  488.         if ((textfp = fopen(path,"w+b")) == NULL)
  489.             return(0);
  490.  
  491.     if (hdrfp != NULL) fclose(hdrfp);
  492.     strcpy(path,quickbbs);
  493.     strcat(path,"msghdr.bbs");
  494.     if ((hdrfp = fopen(path,"r+b")) == NULL)
  495.         if ((hdrfp = fopen(path,"w+b")) == NULL)
  496.             return(0);
  497.  
  498.     if (toidxfp != NULL) fclose(toidxfp);
  499.     strcpy(path,quickbbs);
  500.     strcat(path,"msgtoidx.bbs");
  501.     if ((toidxfp = fopen(path,"r+b")) == NULL)
  502.         if ((toidxfp = fopen(path,"r+b")) == NULL)
  503.             return(0);
  504.  
  505.     if (messages != NULL)
  506.         free(messages);
  507.  
  508.     messages = NULL;
  509.  
  510.     rewind(infofp);
  511.     if (fread(&info, (unsigned) sizeof info, 1, infofp) != 1)
  512.         memset(&info,0,sizeof info);
  513.  
  514.     i = 0; i2 = 0; idx = 0;
  515.     rewind(idxfp);
  516.     while ((fread(&index, (unsigned) sizeof index, 1, idxfp) == 1)) {
  517.         if ((index.board == (char) a->board) && (index.number > 0)) {
  518.             if (i >= i2) {
  519.                 t = realloc(messages, (i2+=CHUNKSZ) * sizeof(int));
  520.                 if (t == NULL)
  521.                     break;
  522.                 messages = t;
  523.             }
  524.             messages[i++] = idx;
  525.         }
  526.         idx++;
  527.     }
  528.  
  529.     a->first = 0;
  530.     a->last = i;
  531.  
  532.     strcpy(path,quickbbs);
  533.     strcat(path,"lastread.bbs");
  534.     if ((fp = fopen(path,"rb")) != NULL) {
  535.         fread(qlast,1,sizeof qlast,fp);
  536.         a->lastread = qlast[a->board - 1];
  537.         fclose(fp);
  538.     }
  539.  
  540.     strcpy(path,quickbbs);
  541.     strcat(path,"current.bbs");
  542.     if ((fp = fopen(path,"rb")) != NULL) {
  543.         fread(qcur,1,sizeof qcur,fp);
  544.         a->current = qcur[a->board - 1];
  545.         fclose(fp);
  546.     }
  547.     else
  548.         a->current = a->lastread;
  549.  
  550.     for (i2 = i-1; i2 && (messages[i2] != a->lastread); i2--) ;
  551.     if (i2) a->lastread = i2;
  552.  
  553.     for (i2 = i-1; i2 && (messages[i2] != a->current); i2--) ;
  554.     if (i2) a->current = i2;
  555.  
  556.     if (a->lastread >= i) a->lastread = i - 1;
  557.     if (a->current >= i) a->current = i - 1;
  558.  
  559.     info.areas[a->board-1] = i;
  560.  
  561.     return(i);
  562. }
  563.