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