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