home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / WWIV2.ZIP / STRINGS.C < prev    next >
C/C++ Source or Header  |  1993-01-03  |  8KB  |  366 lines

  1. /*****************************************************************************
  2.  
  3.                 WWIV Version 4
  4.                     Copyright (C) 1988-1993 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. #include <stdio.h>
  17. #include <string.h>
  18. #include <alloc.h>
  19. #include <io.h>
  20. #include <fcntl.h>
  21. #include <sys\stat.h>
  22. #include <mem.h>
  23. #include <stdlib.h>
  24.  
  25.  
  26. #define CACHE_LEN 4096
  27. #define WRITE_SUPPORT
  28. #define MAX_STRFILES 7
  29.  
  30. typedef struct {
  31.   int str_f;
  32.   long str_l;
  33.   long str_o;
  34.   long str_num;
  35.   int allowwrite;
  36.   char fn[81];
  37. } strfile_t;
  38.  
  39. static char str_buf[256];
  40.               
  41. #ifdef CACHE_LEN
  42.  
  43. typedef struct {
  44.   int num;
  45.   int nxt;
  46. } strhdr;
  47.  
  48. static char *str_cache;
  49. static int str_first;
  50. static long str_total, str_hits;
  51.  
  52. #endif
  53.  
  54. static strfile_t fileinfo[MAX_STRFILES];
  55.  
  56.  
  57. /****************************************************************************/
  58.  
  59. static void close_strfile(strfile_t *sfi)
  60. {
  61.   if (sfi->str_f>0) {
  62.     close(sfi->str_f);
  63.     sfi->str_f=0;
  64.   }
  65. }
  66.  
  67. /****************************************************************************/
  68.  
  69. static int open_strfile(strfile_t *sfi)
  70. {
  71.   unsigned int i;
  72.   char ch;
  73.  
  74.   if (sfi->str_f)
  75.     return(sfi->str_f);
  76.  
  77.   if (sfi->fn[0]==0)
  78.     return(0);
  79.  
  80. #ifdef WRITE_SUPPORT
  81.   if (sfi->allowwrite)
  82.     sfi->str_f = open(sfi->fn, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE);
  83.   else
  84.     sfi->str_f = open(sfi->fn, O_RDONLY|O_BINARY);
  85. #else
  86.   sfi->str_f = open(sfi->fn, O_RDWR|O_BINARY);
  87. #endif
  88.   if (sfi->str_f<0)
  89.     sfi->str_f=0;
  90.   else {
  91.     if (sfi->str_l==0) {
  92.  
  93. #ifdef WRITE_SUPPORT
  94.       if ((filelength(sfi->str_f)==0) && (sfi->allowwrite)) {
  95.         i=0xffff;
  96.         write(sfi->str_f,&i,2);
  97.         ch=100;
  98.         write(sfi->str_f,&ch,1);
  99.         lseek(sfi->str_f, 0, SEEK_SET);
  100.       }
  101. #endif
  102.  
  103.       i=0;
  104.       read(sfi->str_f,&i,2);
  105.       if (i!=0xffff) {
  106.         sfi->str_l=161;
  107.         sfi->str_o=0;
  108.       } else {
  109.         read(sfi->str_f,&ch,1);
  110.         sfi->str_l=ch;
  111.         sfi->str_o=3;
  112.       }
  113.     }
  114.     if (sfi->str_l)
  115.       sfi->str_num=(filelength(sfi->str_f) - sfi->str_o) / sfi->str_l;
  116.   }
  117.  
  118.   return(sfi->str_f);
  119. }
  120.  
  121. /****************************************************************************/
  122.  
  123. int set_strings_fn(int filen, char *dir, char *fn, int allowwrite)
  124. {
  125.   strfile_t *sfi;
  126. #ifdef CACHE_LEN
  127.   strhdr *sp;
  128. #endif
  129.  
  130.   if ((filen>=MAX_STRFILES) || (filen<0))
  131.     return(-1);
  132.  
  133. #ifndef WRITE_SUPPORT
  134.   if (allowwrite)
  135.     return(-1);
  136. #endif
  137.  
  138.   sfi=&(fileinfo[filen]);
  139.  
  140.   close_strfile(sfi);
  141.  
  142.   memset(sfi, 0, sizeof(strfile_t));
  143.   sfi->allowwrite = allowwrite;
  144.  
  145.   if (dir && dir[0]) {
  146.     strcpy(sfi->fn,dir);
  147.     if (sfi->fn[strlen(sfi->fn)-1]!='\\')
  148.       strcat(sfi->fn,"\\");
  149.   } else
  150.     sfi->fn[0]=0;
  151.   strcat(sfi->fn,fn);
  152.  
  153.   if (open_strfile(sfi)==0) {
  154.     memset(sfi, 0, sizeof(strfile_t));
  155.     return(-1);
  156.   }
  157.  
  158.   if (filen==0) {
  159.  
  160. #ifdef CACHE_LEN
  161.     if (!str_cache)
  162.       str_cache=(char *)farmalloc(CACHE_LEN);
  163.  
  164.     if (str_cache) {
  165.       sp=(strhdr *)str_cache;
  166.       sp->num=sp->nxt=-1;
  167.       str_first=0;
  168.       str_total=0;
  169.       str_hits=0;
  170.     }
  171. #endif
  172.   } else {
  173.     close_strfile(sfi);
  174.   }
  175.  
  176.   return(0);
  177. }
  178.  
  179. /****************************************************************************/
  180.  
  181. #ifdef WRITE_SUPPORT
  182. void put_string(int filen, int n, char *s)
  183. {
  184.   long l;
  185.   strfile_t *sfi;
  186. #ifdef CACHE_LEN
  187.   strhdr *sp;
  188. #endif
  189.  
  190.   if ((filen>=MAX_STRFILES) || (filen<0))
  191.     return;
  192.  
  193.   sfi=&(fileinfo[filen]);
  194.  
  195.   n--;
  196.  
  197.   if ((n<0) || (!open_strfile(sfi)))
  198.     return;
  199.  
  200.   memset(str_buf, 0, sizeof(str_buf));
  201.  
  202.   while (sfi->str_num<n) {
  203.     l = (((long)sfi->str_num) * sfi->str_l) + sfi->str_o;
  204.     lseek(sfi->str_f, l, SEEK_SET);
  205.     write(sfi->str_f, str_buf, sfi->str_l);
  206.     sfi->str_num++;
  207.   }
  208.  
  209.   l = (((long)n) * sfi->str_l) + sfi->str_o;
  210.   lseek(sfi->str_f, l, SEEK_SET);
  211.   strncpy(str_buf, s, sfi->str_l-1);
  212.   write(sfi->str_f, str_buf, sfi->str_l);
  213.  
  214.   if (sfi->str_num<=n)
  215.     sfi->str_num=n+1;
  216.  
  217. #ifdef CACHE_LEN
  218.   if (str_cache) {
  219.     sp=(strhdr *)str_cache;
  220.     sp->num=sp->nxt=-1;
  221.   }
  222. #endif
  223.  
  224.   if (filen)
  225.     close_strfile(sfi);
  226.  
  227. }
  228. #endif
  229.  
  230.  
  231. /****************************************************************************/
  232.  
  233. int cachestat(void)
  234. {
  235. #ifdef CACHE_LEN
  236.   if (!str_total)
  237.     return(0);
  238.  
  239.   return((int) ((str_hits*100)/str_total));
  240. #else
  241.   return(0);
  242. #endif
  243. }
  244.  
  245. /****************************************************************************/
  246.  
  247. char *get_stringx(int filen, int n)
  248. {
  249.   char *ss;
  250.   strfile_t *sfi;
  251. #ifdef CACHE_LEN
  252.   int cur_idx, next_idx, last_idx;
  253.   strhdr *sp, *sp1;
  254. #endif
  255.  
  256.   n--;
  257.  
  258.   if ((filen>=MAX_STRFILES) || (filen<0))
  259.     return("");
  260.  
  261.   sfi=&(fileinfo[filen]);
  262.  
  263.   if ((n<0) || (!open_strfile(sfi)))
  264.     return("");
  265.  
  266.   if (n>=sfi->str_num)
  267.     return("");
  268.  
  269. #ifdef CACHE_LEN
  270.   if (str_cache && (filen==0)) {
  271.     str_total++;
  272.  
  273.     for (last_idx=cur_idx=str_first, sp=(strhdr *) (str_cache+cur_idx);
  274.          sp->num!=-1;
  275.          last_idx=cur_idx, cur_idx=sp->nxt, sp=(strhdr *) (str_cache+cur_idx)) {
  276.       if (sp->num==n) {
  277.         str_hits++;
  278.         return(str_cache+cur_idx+sizeof(strhdr));
  279.       }
  280.     }
  281.   }
  282. #endif
  283.  
  284.   lseek(sfi->str_f,(((long)n) * sfi->str_l) + sfi->str_o, SEEK_SET);
  285.   read(sfi->str_f, str_buf, sfi->str_l);
  286.   ss=str_buf;
  287.  
  288. #ifdef CACHE_LEN
  289.   if (str_cache && (filen==0)) {
  290.     next_idx=cur_idx+sizeof(strhdr)+strlen(str_buf)+1;
  291.     if (next_idx+sizeof(strhdr)>CACHE_LEN) {
  292.       sp1=(strhdr *) (str_cache+last_idx);
  293.       sp1->nxt=0;
  294.       sp=(strhdr *) str_cache;
  295.       next_idx -= cur_idx;
  296.       while ((str_first>cur_idx) || (str_first<next_idx+sizeof(strhdr))) {
  297.         sp1=(strhdr *) (str_cache+str_first);
  298.         str_first=sp1->nxt;
  299.       }
  300.       cur_idx=0;
  301.     } else {
  302.       while ((str_first>cur_idx) && (next_idx+sizeof(strhdr)>str_first)) {
  303.         sp1=(strhdr *) (str_cache+str_first);
  304.         str_first=sp1->nxt;
  305.       }
  306.     }
  307.     sp->num=n;
  308.     sp->nxt=next_idx;
  309.     ss=str_cache+cur_idx+sizeof(strhdr);
  310.     strcpy(ss, str_buf);
  311.     sp=(strhdr *)(str_cache+next_idx);
  312.     sp->num=sp->nxt=-1;
  313.   }
  314. #endif
  315.  
  316.   if (filen)
  317.     close_strfile(sfi);
  318.  
  319.   return(ss);
  320. }
  321.  
  322. /****************************************************************************/
  323.  
  324. char *get_string(int n)
  325. {
  326.   return(get_stringx(0,n));
  327. }
  328.  
  329. /****************************************************************************/
  330.  
  331. int num_strings(int filen)
  332. {
  333.   if ((filen>=MAX_STRFILES) || (filen<0))
  334.     return(0);
  335.  
  336.   return(fileinfo[filen].str_num);
  337. }
  338.  
  339. /****************************************************************************/
  340.  
  341. char *getrandomstring(int filen)
  342. {
  343.   strfile_t *sfi;
  344.  
  345.   if ((filen>=MAX_STRFILES) || (filen<0))
  346.     return("");
  347.  
  348.   sfi=&(fileinfo[filen]);
  349.  
  350.   if (!open_strfile(sfi))
  351.     return("");
  352.   else
  353.     return(get_stringx(filen,1+random((int) ((filelength(sfi->str_f)-sfi->str_o)/sfi->str_l))));
  354. }
  355.  
  356. /****************************************************************************/
  357.  
  358. void close_strfiles(void)
  359. {
  360.   int i;
  361.  
  362.   for (i=0; i<MAX_STRFILES; i++) {
  363.     close_strfile(&(fileinfo[i]));
  364.   }
  365. }
  366.