home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / W / WWIVSOR.ZIP / SUBACC.C < prev    next >
C/C++ Source or Header  |  1995-04-25  |  11KB  |  479 lines

  1. /*****************************************************************************
  2.  
  3.                 WWIV Version 4
  4.                     Copyright (C) 1988-1995 by Wayne Bell
  5.  
  6. Distribution of the source code for WWIV, in any form, modified or unmodified,
  7. without PRIOR, WRITTEN APPROVAL by the author, is expressly prohibited.
  8. Distribution of compiled versions of WWIV is limited to copies compiled BY
  9. THE AUTHOR.  Distribution of any copies of WWIV not compiled by the author
  10. is expressly prohibited.
  11.  
  12.  
  13. *****************************************************************************/
  14.  
  15.  
  16. #ifndef NOT_BBS
  17.  
  18. #include "vars.h"
  19.  
  20. #pragma hdrstop
  21.  
  22. #include "subxtr.h"
  23.  
  24. #endif
  25.  
  26.  
  27. /****************************************************************************/
  28.  
  29. #ifndef MAX_TO_CACHE
  30. #define MAX_TO_CACHE 15             /* max postrecs to hold in cache */
  31. #endif
  32.  
  33. static postrec *cache;              /* points to sub cache memory */
  34. static int believe_cache;           /* non-zero if cache is valid */
  35. static unsigned short cache_start;  /* starting msgnum of cache */
  36. static unsigned short last_msgnum;  /* last msgnum read */
  37. static int sub_f=-1;                /* file handle for .sub file, if open */
  38. static char subdat_fn[81];          /* filename of .sub file */
  39.  
  40. /****************************************************************************/
  41.  
  42. void close_sub(void)
  43. {
  44.   if (sub_f>=0) {
  45.     sub_f=sh_close(sub_f);
  46.   }
  47. }
  48.  
  49. /****************************************************************************/
  50.  
  51. int open_sub(int wr)
  52. {
  53.   postrec p;
  54.  
  55.   if (sub_f>=0)
  56.     close_sub();
  57.  
  58.   if (wr) {
  59. #if (NOT_BBS == 2)
  60.     sub_f = open_wc(subdat_fn);
  61. #else
  62.     sub_f = sh_open1(subdat_fn, O_RDWR|O_BINARY|O_CREAT);
  63. #endif
  64.     if (sub_f>=0) {
  65.  
  66.       /* re-read info from file, to be safe */
  67.       believe_cache = 0;
  68.       sh_lseek(sub_f, 0L, SEEK_SET);
  69.       sh_read(sub_f, &p, sizeof(postrec));
  70.       nummsgs=p.owneruser;
  71.     }
  72.   } else {
  73.     sub_f = sh_open1(subdat_fn, O_RDONLY|O_BINARY);
  74.   }
  75.  
  76.   return(sub_f);
  77. }
  78.  
  79. /****************************************************************************/
  80.  
  81. int iscan1(int si, int quick)
  82. /*
  83.  * Initializes use of a sub value (subboards[], not usub[]).  If quick, then
  84.  * don't worry about anything detailed, just grab qscan info.
  85.  */
  86. {
  87.   postrec p;
  88.  
  89.   /* make sure we have cache space */
  90.   if (!cache) {
  91.     cache=malloca(MAX_TO_CACHE*sizeof(postrec));
  92.     if (!cache)
  93.       return(0);
  94.   }
  95.  
  96.   /* forget it if an invalid sub # */
  97.   if ((si<0) || (si>=num_subs))
  98.     return(0);
  99.  
  100.   /* skip this stuff if being called from the WFC cache code */
  101.   if (!quick) {
  102.  
  103. #ifndef NOT_BBS
  104.     /* go to correct net # */
  105.     if (xsubs[si].num_nets)
  106.       set_net_num(xsubs[si].nets[0].net_num);
  107.     else
  108.       set_net_num(0);
  109. #endif
  110.  
  111.     /* see if a sub has changed */
  112.     read_status();
  113.     if (subchg)
  114.       curlsub=-1;
  115.  
  116.     /* if already have this one set, nothing more to do */
  117.     if (si==curlsub)
  118.       return(1);
  119.   }
  120.  
  121.   /* sub cache no longer valid */
  122.   believe_cache=0;
  123.  
  124.   /* set sub filename */
  125.   sprintf(subdat_fn,"%s%s.SUB",syscfg.datadir,subboards[si].filename);
  126.  
  127.   /* open file, and create it if necessary */
  128.   if (open_sub(0)<0) {
  129.     if (open_sub(1)<0)
  130.       return(0);
  131.     p.owneruser=0;
  132.     sh_write(sub_f,(void *) &p,sizeof(postrec));
  133.   }
  134.  
  135.   /* set sub */
  136.   curlsub=si;
  137.   subchg=0;
  138.   last_msgnum=0;
  139.  
  140.   /* read in first rec, specifying # posts */
  141.   sh_lseek(sub_f,0L,SEEK_SET);
  142.   sh_read(sub_f,&p, sizeof(postrec));
  143.   nummsgs=p.owneruser;
  144.  
  145. #ifndef NOT_BBS
  146.   /* read in sub date, if don't already know it */
  147.   if (sub_dates[si]==0) {
  148.     if (nummsgs) {
  149.       sh_lseek(sub_f, ((long) nummsgs)*sizeof(postrec), SEEK_SET);
  150.       sh_read(sub_f, &p, sizeof(postrec));
  151.       sub_dates[si]=p.qscan;
  152.     } else {
  153.       sub_dates[si]=1;
  154.     }
  155.   }
  156. #endif
  157.  
  158.   /* close file */
  159.   close_sub();
  160.  
  161.   /* iscanned correctly */
  162.   return(1);
  163. }
  164.  
  165.  
  166. /****************************************************************************/
  167.  
  168. #ifndef NOT_BBS
  169.  
  170. int iscan(int b)
  171. /*
  172.  * Initializes use of a sub (usub[] value, not subboards[] value).
  173.  */
  174. {
  175.   return(iscan1(usub[b].subnum, 0));
  176. }
  177.  
  178. #endif
  179.  
  180. /****************************************************************************/
  181.  
  182. postrec *get_post(unsigned short mn)
  183. /*
  184.  * Returns info for a post.  Maintains a cache.  Does not correct anything
  185.  * if the sub has changed.
  186.  */
  187. {
  188.   postrec p;
  189.   int close_file;
  190.  
  191.   if (mn==0)
  192.     return(NULL);
  193.  
  194.   if (subchg==1) {
  195.     /* sub has changed (detected in read_status); invalidate cache */
  196.     believe_cache=0;
  197.  
  198.     /* kludge: subch==2 leaves subch indicating change, but the '2' value */
  199.     /* indicates, to this routine, that it has been handled at this level */
  200.     subchg=2;
  201.   }
  202.  
  203.   /* see if we need new cache info */
  204.   if ((!believe_cache) ||
  205.       (mn<cache_start) ||
  206.       (mn>=(cache_start+MAX_TO_CACHE))) {
  207.  
  208.     if (sub_f < 0) {
  209.       /* open the sub data file, if necessary */
  210.       if (open_sub(0)<0)
  211.         return(NULL);
  212.  
  213.       close_file = 1;
  214.     } else {
  215.       close_file = 0;
  216.     }
  217.  
  218.     /* re-read # msgs, if needed */
  219.     if (subchg==2) {
  220.       sh_lseek(sub_f, 0L, SEEK_SET);
  221.       sh_read(sub_f, &p, sizeof(postrec));
  222.       nummsgs=p.owneruser;
  223.  
  224.       /* another kludge: subch==3 indicates we have re-read # msgs also */
  225.       /* only used so we don't do this every time through */
  226.       subchg=3;
  227.  
  228.       /* adjust msgnum, if it is no longer valid */
  229.       if (mn>nummsgs)
  230.         mn=nummsgs;
  231.     }
  232.  
  233.     /* select new starting point of cache */
  234.     if (mn >= last_msgnum) {
  235.       /* going forward */
  236.  
  237.       if (nummsgs<=MAX_TO_CACHE)
  238.         cache_start=1;
  239.  
  240.       else if (mn>(nummsgs-MAX_TO_CACHE))
  241.         cache_start=nummsgs-MAX_TO_CACHE+1;
  242.  
  243.       else
  244.         cache_start = mn;
  245.  
  246.     } else {
  247.       /* going backward */
  248.       if (mn>MAX_TO_CACHE)
  249.         cache_start = mn-MAX_TO_CACHE+1;
  250.       else
  251.         cache_start = 1;
  252.     }
  253.  
  254.     if (cache_start<1)
  255.       cache_start=1;
  256.  
  257.     /* read in some sub info */
  258.     sh_lseek(sub_f, ((long) cache_start)*sizeof(postrec), SEEK_SET);
  259.     sh_read(sub_f, cache, MAX_TO_CACHE*sizeof(postrec));
  260.  
  261.     /* now, close the file, if necessary */
  262.     if (close_file) {
  263.       close_sub();
  264.     }
  265.  
  266.     /* cache is now valid */
  267.     believe_cache = 1;
  268.   }
  269.  
  270.   /* error if msg # invalid */
  271.   if ((mn<1) || (mn>nummsgs))
  272.     return(NULL);
  273.  
  274.   last_msgnum=mn;
  275.  
  276.   return(cache+(mn-cache_start));
  277. }
  278.  
  279. /****************************************************************************/
  280.  
  281. #define BUFSIZE 32000
  282.  
  283. void delete(int mn)
  284. {
  285.   postrec *p1, p;
  286.   int close_file=0;
  287.   unsigned int nb;
  288.   char *buf;
  289.   long len, l, cp;
  290.  
  291.   /* open file, if needed */
  292.   if (sub_f <= 0) {
  293.     open_sub(1);
  294.     close_file=1;
  295.   }
  296.  
  297.   /* see if anything changed */
  298.   read_status();
  299.  
  300.   if (sub_f >= 0) {
  301.     if ((mn>0) && (mn<=nummsgs)) {
  302.       buf=(char *)malloca(BUFSIZE);
  303.       if (buf) {
  304.         p1=get_post(mn);
  305.         remove_link(&(p1->msg),(subboards[curlsub].filename));
  306.  
  307.         cp=((long)mn+1)*sizeof(postrec);
  308.         len=((long)(nummsgs+1))*sizeof(postrec);
  309.  
  310.         do {
  311.           l=len-cp;
  312.           if (l<BUFSIZE)
  313.             nb=(int)l;
  314.           else
  315.             nb=BUFSIZE;
  316.           if (nb) {
  317.             sh_lseek(sub_f, cp, SEEK_SET);
  318.             sh_read(sub_f, buf, nb);
  319.             sh_lseek(sub_f, cp-sizeof(postrec), SEEK_SET);
  320.             sh_write(sub_f, buf, nb);
  321.             cp += nb;
  322.           }
  323.         } while (nb==BUFSIZE);
  324.  
  325.         /* update # msgs */
  326.         sh_lseek(sub_f, 0L, SEEK_SET);
  327.         sh_read(sub_f, &p, sizeof(postrec));
  328.         p.owneruser--;
  329.         nummsgs=p.owneruser;
  330.         sh_lseek(sub_f, 0L, SEEK_SET);
  331.         sh_write(sub_f, &p, sizeof(postrec));
  332.  
  333.         /* cache is now invalid */
  334.         believe_cache = 0;
  335.  
  336.         bbsfree(buf);
  337.       }
  338.     }
  339.   }
  340.  
  341.   /* close file, if needed */
  342.   if (close_file)
  343.     close_sub();
  344.  
  345. }
  346.  
  347.  
  348. /****************************************************************************/
  349.  
  350. void write_post(int mn, postrec *pp)
  351. {
  352.   postrec *p1;
  353.  
  354.   if (sub_f>=0) {
  355.     sh_lseek(sub_f, ((long) mn)*sizeof(postrec), SEEK_SET);
  356.     sh_write(sub_f, pp, sizeof(postrec));
  357.     if (believe_cache) {
  358.       if ((mn>=cache_start) && (mn<(cache_start+MAX_TO_CACHE))) {
  359.         p1=cache+(mn-cache_start);
  360.         if (p1!=pp) {
  361.           *p1=*pp;
  362.         }
  363.       }
  364.     }
  365.   }
  366. }
  367.  
  368.  
  369. /****************************************************************************/
  370.  
  371. void add_post(postrec *pp)
  372. {
  373.   postrec p;
  374.   int close_file=0;
  375.  
  376.   /* open the sub, if necessary  */
  377.  
  378.   if (sub_f <= 0) {
  379.     open_sub(1);
  380.     close_file=1;
  381.   }
  382.  
  383.   if (sub_f>=0) {
  384.  
  385.     /* get updated info */
  386.     read_status();
  387.     sh_lseek(sub_f, 0L, SEEK_SET);
  388.     sh_read(sub_f, &p, sizeof(postrec));
  389.  
  390.     /* one more post */
  391.     p.owneruser++;
  392.     nummsgs=p.owneruser;
  393.     sh_lseek(sub_f, 0L, SEEK_SET);
  394.     sh_write(sub_f, &p, sizeof(postrec));
  395.  
  396.     /* add the new post */
  397.     sh_lseek(sub_f, ((long)nummsgs)*sizeof(postrec), SEEK_SET);
  398.     sh_write(sub_f, pp, sizeof(postrec));
  399.  
  400.     /* we've modified the sub */
  401.     believe_cache=0;
  402.     subchg=0;
  403. #ifndef NOT_BBS
  404.     sub_dates[curlsub]=pp->qscan;
  405. #endif
  406.   }
  407.  
  408.   if (close_file)
  409.     close_sub();
  410.  
  411. }
  412.  
  413. /****************************************************************************/
  414.  
  415. #ifndef NOT_BBS
  416.  
  417. static int postsame(postrec *p1, postrec *p2)
  418. {
  419.   if (p1 && p2 &&
  420.       (p1->daten==p2->daten) &&
  421.       (p1->qscan==p2->qscan) &&
  422.       (p1->ownersys==p2->ownersys) &&
  423.       (p1->owneruser==p2->owneruser) &&
  424.       (strcmp(p1->title, p2->title)==0))
  425.     return(1);
  426.   else
  427.     return(0);
  428. }
  429.  
  430. void resynch(int subnum, int *msgnum, postrec *pp)
  431. {
  432.   postrec p, *pp1;
  433.   int i;
  434.  
  435.   /* don't care about this param now */
  436.   i=subnum;
  437.  
  438.   if (pp)
  439.     p=*pp;
  440.   else {
  441.     pp1=get_post(*msgnum);
  442.     if (!pp1)
  443.       return;
  444.     p=*pp1;
  445.   }
  446.  
  447.   read_status();
  448.  
  449.   if (subchg || pp) {
  450.  
  451.     pp1=get_post(*msgnum);
  452.     if (postsame(pp1,&p)) {
  453.       return;
  454.     } else if (!pp1 || (p.qscan<pp1->qscan)) {
  455.       if (*msgnum>nummsgs)
  456.         *msgnum=nummsgs+1;
  457.       for (i=*msgnum-1; i>0; i--) {
  458.         pp1=get_post(i);
  459.         if (postsame(&p, pp1) || (p.qscan>=pp1->qscan)) {
  460.           *msgnum=i;
  461.           return;
  462.         }
  463.       }
  464.       *msgnum=0;
  465.     } else {
  466.       for (i=*msgnum+1; i<=nummsgs; i++) {
  467.         pp1=get_post(i);
  468.         if (postsame(&p, pp1) || (p.qscan<=pp1->qscan)) {
  469.           *msgnum=i;
  470.           return;
  471.         }
  472.       }
  473.       *msgnum=nummsgs;
  474.     }
  475.   }
  476. }
  477.  
  478. #endif
  479.