home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / UTIL / WWIVSOR / INI.C < prev    next >
C/C++ Source or Header  |  1995-04-29  |  10KB  |  417 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. #include <stdio.h>
  15. #include <string.h>
  16. #include <alloc.h>
  17. #include <stdlib.h>
  18. #include <fcntl.h>
  19. #include <io.h>
  20. #include <ctype.h>
  21.  
  22. #include "share.h"
  23. #include "ini.h"
  24.  
  25.  
  26. #ifndef bbsmalloc
  27. #ifdef __OS2__
  28. #define bbsmalloc(x) malloc(x)
  29. #define bbsfree(x) free(x)
  30. #else
  31. #define bbsmalloc(x) farmalloc(x)
  32. #define bbsfree(x) farfree(x)
  33. #endif
  34. #endif
  35.  
  36. typedef struct {
  37.   int num;
  38.   char *buf;
  39.   char **key;
  40.   char **value;
  41. } ini_info_t;
  42.  
  43. static ini_info_t ini_prim, ini_sec;
  44.  
  45.  
  46. /****************************************************************************/
  47. /*
  48.  * Trims a string on both the beginning and end
  49.  */
  50. static unsigned char *trimstr1(unsigned char *s)
  51. {
  52.   int i;
  53.   static char *whitespace=" \r\n\t";
  54.  
  55.   i=strlen(s);
  56.  
  57.   while ((i>0) && (strchr(whitespace,s[i-1])))
  58.     --i;
  59.  
  60.   while ((i>0) && (strchr(whitespace,*s))) {
  61.     memmove(s,s+1,--i);
  62.   }
  63.  
  64.   s[i]=0;
  65.   return(s);
  66. }
  67.  
  68. /****************************************************************************/
  69.  
  70. /* Allocates memory and returns pointer to location containing requested data
  71.  * within a file.
  72.  */
  73.  
  74. static unsigned char *mallocin_subsection(char *fn, long begin, long end)
  75. {
  76.   unsigned char *ss;
  77.   int f;
  78.  
  79.   ss=NULL;
  80.  
  81.   f=sh_open1(fn, O_RDONLY|O_BINARY);
  82.   if (f>0) {
  83.     ss=(unsigned char *)bbsmalloc(end-begin+2);
  84.     if (ss) {
  85.       lseek(f, begin, SEEK_SET);
  86.       read(f,ss,(end-begin+1));
  87.       ss[(end-begin+1)]=0;
  88.     }
  89.     sh_close(f);
  90.   }
  91.   return(ss);
  92. }
  93.  
  94. /****************************************************************************/
  95.  
  96. /* Returns begin and end locations for specified subsection within an INI file.
  97.  * If subsection not found then *begin and *end are both set to -1L.
  98.  */
  99.  
  100. static void find_subsection_area(unsigned char *fn, unsigned char *ssn, long *begin, long *end)
  101. {
  102.   FILE *f;
  103.   unsigned char s[255], tmphdr[81], *ss;
  104.   long pos=0L;
  105.  
  106.   *begin=*end=-1L;
  107.   sprintf(tmphdr, "[%s]", ssn);
  108.  
  109.   f=fsh_open(fn, "rt");
  110.   if (!f)
  111.     return;
  112.  
  113.   /* Get current position */
  114.   pos=0;
  115.  
  116.   while (fgets(s, sizeof(s)-1, f) != NULL) {
  117.     /* Get rid of CR/LF at end */
  118.     ss=strchr(s,'\n');
  119.     if (ss)
  120.       *ss=0;
  121.  
  122.     /* Get rid of trailing/leading spaces */
  123.     trimstr1(s);
  124.  
  125.     /* A comment or blank line? */
  126.     if ((s[0]) && (s[0]!=';')) {
  127.  
  128.       /* Is it a subsection header? */
  129.       if ((strlen(s)>2) && (s[0]=='[') && (s[strlen(s)-1]==']')) {
  130.  
  131.         /* Does it match requested subsection name (ssn)? */
  132.         if (strnicmp(&s[0],&tmphdr[0],strlen(tmphdr))==0) {
  133.           if (*begin==-1L)
  134.             *begin=ftell(f);
  135.         } else {
  136.           if (*begin!=-1L) {
  137.             if (*end==-1L) {
  138.               *end=pos-1;
  139.               break;
  140.             }
  141.           }
  142.         }
  143.       }
  144.     }
  145.  
  146.     /* Update file position pointer */
  147.     pos=ftell(f);
  148.   }
  149.  
  150.   /* Mark end as end of the file if not already found */
  151.   if ((*begin!=-1L) && (*end==-1L))
  152.     *end=ftell(f)-1;
  153.  
  154.   fsh_close(f);
  155. }
  156.  
  157. /****************************************************************************/
  158.  
  159. /* Reads a subsection from specified .INI file, the subsection being specified
  160.  * by *hdr. Returns a ptr to the subsection data if found and memory is
  161.  * available, else returns NULL.
  162.  */
  163.  
  164. static unsigned char *read_ini_file(unsigned char *fn, unsigned char *hdr)
  165. {
  166.   long beginloc=-1L, endloc=-1L;
  167.   unsigned char *ss;
  168.  
  169.   /* Init pointer vars */
  170.   ss=NULL;
  171.  
  172.   /* Header must be "valid", and file must exist */
  173.   if (strlen(hdr)<1)
  174.     return(NULL);
  175.  
  176.   /* Get area to read in */
  177.   find_subsection_area(fn, hdr, &beginloc, &endloc);
  178.  
  179.   /* Validate */
  180.   if (beginloc>=endloc)
  181.     return(NULL);
  182.  
  183.   /* Allocate pointer to hold data */
  184.   ss=mallocin_subsection(fn, beginloc, endloc);
  185.   return(ss);
  186. }
  187.  
  188. /****************************************************************************/
  189.  
  190. static void parse_ini_file(char *buf, ini_info_t *info)
  191. {
  192.   unsigned char *tempb, *ss1, *ss, *ss2;
  193.   unsigned int i1,count=0;
  194.  
  195.   memset(info, 0, sizeof(ini_info_t));
  196.   info->buf=buf;
  197.  
  198.   /* first, count # key-value pairs */
  199.   i1=strlen(buf);
  200.   tempb=(unsigned char *)bbsmalloc(i1+20);
  201.   if (!tempb)
  202.     return;
  203.  
  204.   memmove(tempb, buf, i1);
  205.   tempb[i1]=0;
  206.  
  207.   for (ss=strtok(tempb,"\r\n"); ss; ss=strtok(NULL,"\r\n")) {
  208.     trimstr1(ss);
  209.     if ((ss[0]==0) || (ss[0]==';'))
  210.       continue;
  211.  
  212.     ss1=strchr(ss,'=');
  213.     if (ss1) {
  214.       *ss1=0;
  215.       trimstr1(ss);
  216.       if (*ss)
  217.         count++;
  218.     }
  219.   }
  220.  
  221.   bbsfree(tempb);
  222.  
  223.   if (!count)
  224.     return;
  225.  
  226.   /* now, allocate space for key-value pairs */
  227.   info->key=(char **)bbsmalloc(count*sizeof(char *));
  228.   if (!info->key)
  229.     return;
  230.   info->value=(char **)bbsmalloc(count*sizeof(char *));
  231.   if (!info->value) {
  232.     bbsfree(info->key);
  233.     info->key=NULL;
  234.     return;
  235.   }
  236.  
  237.   /* go through and add in key-value pairs */
  238.   for (ss=strtok(buf,"\r\n"); ss; ss=strtok(NULL,"\r\n")) {
  239.     trimstr1(ss);
  240.     if ((ss[0]==0) || (ss[0]==';'))
  241.       continue;
  242.  
  243.     ss1=strchr(ss,'=');
  244.     if (ss1) {
  245.       *ss1=0;
  246.       trimstr1(ss);
  247.       if (*ss) {
  248.         ss1++;
  249.         ss2=ss1;
  250.         while ((ss2[0]) && (ss2[1]) && ((ss2=strchr(ss2+1,';'))!=NULL)) {
  251.           if (isspace(*(ss2-1))) {
  252.             *ss2=0;
  253.             break;
  254.           }
  255.         }
  256.         trimstr1(ss1);
  257.         info->key[info->num]=ss;
  258.         info->value[info->num]=ss1;
  259.         info->num++;
  260.       }
  261.     }
  262.   }
  263.  
  264.  
  265. }
  266. /****************************************************************************/
  267.  
  268. /*
  269.  * Frees up any allocated ini files
  270.  */
  271.  
  272. void ini_done(void)
  273. {
  274.   if (ini_prim.buf) {
  275.     bbsfree(ini_prim.buf);
  276.     if (ini_prim.key)
  277.       bbsfree(ini_prim.key);
  278.     if (ini_prim.value)
  279.       bbsfree(ini_prim.value);
  280.   }
  281.   memset(&ini_prim, 0, sizeof(ini_prim));
  282.   if (ini_sec.buf) {
  283.     bbsfree(ini_sec.buf);
  284.     if (ini_sec.key)
  285.       bbsfree(ini_sec.key);
  286.     if (ini_sec.value)
  287.       bbsfree(ini_sec.value);
  288.   }
  289.   memset(&ini_sec, 0, sizeof(ini_sec));
  290. }
  291.  
  292. /****************************************************************************/
  293.  
  294. /*
  295.  * Reads in some ini files
  296.  */
  297.  
  298. int ini_init(unsigned char *fn, unsigned char *prim, unsigned char *sec)
  299. {
  300.   unsigned char *buf;
  301.  
  302.   /* first, zap anything there currently */
  303.   ini_done();
  304.  
  305.   /* read in primary info */
  306.   buf=read_ini_file(fn, prim);
  307.  
  308.   if (buf) {
  309.     /* parse the data */
  310.     parse_ini_file(buf, &ini_prim);
  311.  
  312.     /* read in secondary file */
  313.     buf=read_ini_file(fn, sec);
  314.     if (buf)
  315.       parse_ini_file(buf, &ini_sec);
  316.  
  317.   } else {
  318.  
  319.     /* read in the secondary info, as the primary one */
  320.     buf=read_ini_file(fn, sec);
  321.     if (buf)
  322.       parse_ini_file(buf, &ini_prim);
  323.   }
  324.  
  325.   if (ini_prim.buf)
  326.     return(0);
  327.   else
  328.     return(1);
  329. }
  330.  
  331.  
  332.  
  333. /****************************************************************************/
  334.  
  335. /* Reads a specified value from INI file data (contained in *inidata). The
  336.  * name of the value to read is contained in *value_name. If such a name
  337.  * doesn't exist in this INI file subsection, then *val is NULL, else *val
  338.  * will be set to the string value of that value name. If *val has been set
  339.  * to something, then this function returns 1, else it returns 0.
  340.  */
  341.  
  342. unsigned char *ini_get(unsigned char *key, int index, unsigned char *index1)
  343. {
  344.   unsigned char key1[81],key2[81];
  345.   int i,i1;
  346.   ini_info_t *info;
  347.  
  348.   if (!ini_prim.buf || !key || !(*key))
  349.     return(NULL);
  350.  
  351.   if (index==-1)
  352.     strcpy(key1,key);
  353.   else
  354.     sprintf(key1,"%s[%d]",key,index);
  355.   if (index1)
  356.     sprintf(key2,"%s[%s]",key,index1);
  357.   else
  358.     key2[0]=0;
  359.  
  360.   /* loop through both sets of data and search them, in order */
  361.   for (i=0; i<=1; i++) {
  362.  
  363.     /* get pointer to data area to use */
  364.     if (i==0) {
  365.       info=&ini_prim;
  366.     } else if (ini_sec.buf) {
  367.       info=&ini_sec;
  368.     } else
  369.       break;
  370.  
  371.     /* search for it */
  372.     for (i1=0; i1<info->num; i1++) {
  373.       if ((stricmp(info->key[i1], key1)==0) || (stricmp(info->key[i1], key2)==0)) {
  374.         return(info->value[i1]);
  375.       }
  376.     }
  377.   }
  378.  
  379.  
  380.   /* nothing found */
  381.   return(NULL);
  382. }
  383.  
  384. /****************************************************************************/
  385.  
  386. unsigned long ini_flags(char yes_char, char *(*func)(int), ini_flags_rec *fs, int num, unsigned long flags) /**/
  387. {
  388.   int i;
  389.   char *ss,*ss1;
  390.  
  391.   yes_char=toupper(yes_char);
  392.  
  393.   for (i=0; i<num; i++) {
  394.     ss=func(fs[i].strnum);
  395.     if (ss) {
  396.       ss1=ini_get(ss, -1, NULL);
  397.       if (ss1) {
  398.         if (toupper(*ss1)==yes_char) {
  399.           if (fs[i].sense) {
  400.             flags &= ~fs[i].value;
  401.           } else {
  402.             flags |= fs[i].value;
  403.           }
  404.         } else {
  405.           if (fs[i].sense) {
  406.             flags |= fs[i].value;
  407.           } else {
  408.             flags &= ~fs[i].value;
  409.           }
  410.         }
  411.       }
  412.     }
  413.   }
  414.  
  415.   return(flags);
  416. }
  417.