home *** CD-ROM | disk | FTP | other *** search
/ The Arcade BBS / arcadebbs.zip / arcadebbs / bbstools / MODS / 1AD_001.ZIP / 1ADINI.C < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-16  |  24.3 KB  |  1,061 lines

  1. #include <ctype.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <io.h>
  6.  
  7. #include "1adini.h"
  8.  
  9. extern FILE *log;
  10.  
  11. int get_ini_value(char *fname, char *area, char *indent, char *value, int max_value)
  12. {
  13.   ini_inforec ini_info;
  14.  
  15.   if(!open_ini_file(fname, &ini_info))
  16.     return -1;    /* Wasn't able to retrieve or create fname.ini */
  17.  
  18.   read_ini_string(&ini_info, area, indent, value, max_value);
  19.  
  20.   if(ini_info.changes_made)
  21.     write_ini_file(&ini_info);   // value had to be added, so write it to disk
  22.  
  23.   free_ini_info(&ini_info);
  24.   return 1;       /* Successful read */
  25. }
  26.  
  27. int put_ini_value(char *fname, char *area, char *indent, char *value)
  28. {
  29.   ini_inforec ini_info;
  30.  
  31.   if(!open_ini_file(fname, &ini_info))
  32.     return -1;    /* Wasn't able to retrieve or create fname.ini */
  33.  
  34.   set_ini_string(&ini_info, area, indent, value);
  35.   write_ini_file(&ini_info);   // set_ini_string only sets the memory, it must
  36.                                // be written to disk
  37.  
  38.   free_ini_info(&ini_info);
  39.   return 1;       /* Successful read */
  40. }
  41.  
  42. int get_ini_number(char *fname, char *area, char *indent, int default_value)
  43. {
  44.   ini_inforec ini_info;
  45.   long x;
  46.  
  47.   if(!open_ini_file(fname, &ini_info))
  48.     return -1;    /* Wasn't able to retrieve or create fname.ini */
  49.  
  50.   x = read_ini_number(&ini_info, area, indent, default_value);
  51.  
  52.   if(ini_info.changes_made)
  53.     write_ini_file(&ini_info);   // value had to be added, so write it to disk
  54.  
  55.   free_ini_info(&ini_info);
  56.   return x;       /* Successful read */
  57. }
  58.  
  59. int put_ini_number(char *fname, char *area, char *indent, long value)
  60. {
  61.   ini_inforec ini_info;
  62.  
  63.   if(!open_ini_file(fname, &ini_info))
  64.     return -1;    /* Wasn't able to retrieve or create fname.ini */
  65.  
  66.   set_ini_number(&ini_info, area, indent, value);
  67.   write_ini_file(&ini_info);   // set_ini_string only sets the memory, it must
  68.                                // be written to disk
  69.  
  70.   free_ini_info(&ini_info);
  71.   return 1;       /* Successful read */
  72. }
  73.  
  74.  
  75. int get_ini_boolean(char *fname, char *area, char *indent, char *value)
  76. {
  77.   char s[51];
  78.  
  79.   strcpy(s, value);
  80.   get_ini_value(fname, area, indent, s, 50);
  81.  
  82.   strupr(s);
  83.  
  84.   if(strcmp(s, "YES")==0 || strcmp(s, "TRUE")==0 || strcmp(s, "1")==0)
  85.     return 1;
  86.  
  87.   if(strcmp(s, "NO")==0 || strcmp(s, "FALSE")==0 || strcmp(s, "0")==0)
  88.     return 0;
  89.  
  90.   return -1;
  91. }
  92.  
  93. int read_ini_boolean(ini_inforec *ini_info, char *area, char *indent, char *value)
  94. {
  95.   char s[51];
  96.  
  97.   strcpy(s, value);
  98.   read_ini_string(ini_info, area, indent, s, 50);
  99.  
  100.   strupr(s);
  101.  
  102.   if(strcmp(s, "YES")==0 || strcmp(s, "TRUE")==0 || strcmp(s, "1")==0)
  103.     return 1;
  104.  
  105.   if(strcmp(s, "NO")==0 || strcmp(s, "FALSE")==0 || strcmp(s, "0")==0)
  106.     return 0;
  107.  
  108.   return -1;
  109. }
  110.  
  111.  
  112. /* ------------------------------------------------------------------------ */
  113. /* read a string in area, if area doesn't exist, create it...  if indent    */
  114. /* doesn't exist, create it                                                 */
  115.  
  116. int read_ini_string(ini_inforec *ini_info, char *area, char *indent, char *value, int max_value)
  117. {
  118.   return(ll_read_ini_string(ini_info, area, indent, value, max_value, 1, 0));
  119. }
  120.  
  121. /* ------------------------------------------------------------------------ */
  122. /* Look for string in area, returns 0 if not there, does NOT create it      */
  123. int look_ini_string(ini_inforec *ini_info, char *area, char *indent, char *value, int max_value)
  124. {
  125.   return(ll_read_ini_string(ini_info, area, indent, value, max_value, 0, 0));
  126. }
  127.  
  128. /* ------------------------------------------------------------------------ */
  129. /* For duplicatate indents, searchs for the "which'th" indent and returns   */
  130. /* that value, unexistant ones are not created                              */
  131. int look_ini_string_dup(ini_inforec *ini_info, char *area, char *indent, char *value, int max_value, int which)
  132. {
  133.   return(ll_read_ini_string(ini_info, area, indent, value, max_value, 0, which));
  134. }
  135.  
  136.  
  137.  
  138. /* ------------------------------------------------------------------------ */
  139. /* just like read_ini string, creates missing parts if needed (including    */
  140. /* ini file                                                                 */
  141. long read_ini_number(ini_inforec *ini_info, char *area, char *indent, long value)
  142. {
  143.   return(ll_read_ini_number(ini_info, area, indent, value, 1, 0));
  144. }
  145.  
  146. long look_ini_number(ini_inforec *ini_info, char *area, char *indent, long value)
  147. {
  148.   return(ll_read_ini_number(ini_info, area, indent, value, 0, 0));
  149. }
  150.  
  151. long look_ini_number_dup(ini_inforec *ini_info, char *area, char *indent, long value, int which)
  152. {
  153.   return(ll_read_ini_number(ini_info, area, indent, value, 0, which));
  154. }
  155.  
  156.  
  157.  
  158. void set_ini_number(ini_inforec *ini_info, char *area, char *indent, long value)
  159. {
  160.   set_ini_number_dup(ini_info, area, indent, value, 0);
  161. }
  162.  
  163. void set_ini_string(ini_inforec *ini_info, char *area, char *indent, char *value)
  164. {
  165.   set_ini_string_dup(ini_info, area, indent, value, 0);
  166. }
  167.  
  168.  
  169.  
  170.  
  171.  
  172.  
  173. void free_ini_info(ini_inforec *ini_info)
  174. {
  175.   if(ini_info->ini && ini_info->open)
  176.     free(ini_info->ini);
  177.  
  178.   ini_info->open = 0;
  179.   return;
  180. }
  181.  
  182.  
  183.  
  184. int write_ini_file(ini_inforec *ini_info)
  185. {
  186.   FILE *fp;
  187.  
  188.   if(!ini_info->changes_made)
  189.     return 2;
  190.  
  191.   fp = fopen(ini_info->fname, "w+t");
  192.   if(!fp)
  193.     return 0;               /*  Couldn't create ini file */
  194.  
  195.   fseek(fp, 0, SEEK_SET);
  196.   fwrite((void *)ini_info->ini, 1, ini_info->fsize, fp);
  197.  
  198.   fclose(fp);
  199.   return 1;
  200. }
  201.  
  202. char *open_ini_file(char *fname, ini_inforec *ini_info)
  203. {
  204.   FILE *fp;
  205.  
  206.   memset((void *)ini_info, 0, sizeof(ini_inforec));
  207.   strcpy(ini_info->fname, fname);
  208.  
  209.   fp = fopen(fname, "rt" );
  210.  
  211.   if(!fp)                        /* if it doesn't exist, create it */
  212.   {
  213.     fp = fopen(fname, "w+t");
  214.     if(!fp)
  215.       return NULL;               /*  Couldn't create ini file */
  216.   }
  217.  
  218.   ini_info->fsize=filesize(fp);
  219.  
  220.   if(ini_info->fsize < 60000L)   /* Make 60,000 our file size */
  221.     ini_info->ini = (char *) malloc(ini_info->fsize + EXTRA_INI_SPACE);
  222.  
  223.   if(!ini_info->ini)
  224.   {
  225.     fclose(fp);
  226.     return NULL;
  227.   }
  228.  
  229.   fseek(fp, 0, SEEK_SET);
  230.   ini_info->fsize = fread((void *)ini_info->ini, 1, ini_info->fsize, fp);
  231.   ini_info->ini[ini_info->fsize]=0;
  232.  
  233.   ini_info->allocated=ini_info->fsize + EXTRA_INI_SPACE;
  234.   ini_info->open = 1;                // turn closed flag off
  235.  
  236.   fclose(fp);
  237.   return(ini_info->ini);
  238. }
  239.  
  240. char * increase_ini_allocation(ini_inforec *ini_info)
  241. {
  242.   ini_info->allocated += EXTRA_INI_SPACE;
  243.  
  244.   if(ini_info->allocated > 0xffff)
  245.     return NULL;
  246.  
  247.   ini_info->ini = (char *)realloc(ini_info->ini, ini_info->allocated);
  248.  
  249.   return(ini_info->ini);
  250. }
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259. char * get_ini_line(char *buff, int max_len, long *pos, char *ini)
  260. {
  261.   int c, buff_pos=0;
  262.   char *temp;
  263.  
  264.   if(!ini[*pos])     // If at end of buffer, return NULL
  265.     return NULL;
  266.  
  267.   while(1)
  268.   {
  269.     c = ini[*pos];
  270.  
  271.     if(c == 0 || c == '\n')
  272.     {
  273.       buff[buff_pos] = 0;
  274.       if(c)    // Only increment if we are on a newline
  275.         ++*pos;
  276.  
  277.       temp=strchr(buff, ';');
  278.       if(temp)
  279.         temp[0]=0;      // Null out all after ; (comment)
  280.  
  281.       return(buff);
  282.     }
  283.  
  284.     buff[buff_pos] = c;
  285.  
  286.     ++buff_pos;
  287.     ++*pos;
  288.  
  289.     if(buff_pos >= max_len)
  290.     {
  291.       buff[buff_pos] = 0;
  292.  
  293.       temp=strchr(buff, ';');
  294.       if(temp)
  295.         temp[0]=0;      // Null out all after ; (comment)
  296.  
  297.       return(buff);
  298.     }
  299.   }
  300. }
  301.  
  302.  
  303.  
  304. void break_up_ini(char *buff, char *w1, char *w2)
  305. {
  306.   int pos=0, spos;
  307.   int c;
  308.  
  309.   strip_string(buff);
  310.  
  311.   while(1)
  312.   {
  313.     c = buff[pos];
  314.  
  315.     if(c == '=' || c == 0)
  316.     {
  317.       buff[pos]=0;
  318.       if(c)
  319.         ++pos;
  320.       break;
  321.     }
  322.     ++pos;
  323.   }
  324.   strcpy(w1, buff);
  325.  
  326.   spos=pos;
  327.  
  328.   while(1)
  329.   {
  330.     c = buff[pos];
  331.  
  332.     if(c == 0)
  333.     {
  334.       buff[pos] = 0;
  335.       break;
  336.     }
  337.  
  338.     ++pos;
  339.   }
  340.  
  341.   strcpy(w2, buff+spos);
  342.  
  343.   strip_string(w1);
  344.   strip_string(w2);
  345. }
  346.  
  347.  
  348. long find_ini_area(char *ini, char *area)
  349. {
  350.   char buff[255], *tmp;
  351.   long pos=0;
  352.  
  353.   if(!area[0])       /* If we don't specify an area, start at top */
  354.     return 0;
  355.  
  356.   while(1)
  357.   {
  358.     tmp = get_ini_line(buff, 255, &pos, ini);
  359.  
  360.     if(!tmp)
  361.       return(pos);
  362.  
  363.     strip_string(buff);
  364.  
  365.     if(buff[0] != '[')
  366.       continue;
  367.  
  368.     tmp=strchr(buff, ']');
  369.  
  370.     if(!tmp)
  371.       continue;
  372.  
  373.     tmp[0]=0;
  374.  
  375.     if(strcmpi(buff+1, area) == 0)
  376.       return(pos);
  377.  
  378.   }
  379. }
  380.  
  381. long count_ini_areas(ini_inforec *ini, char *area)
  382. {
  383.   char buff[255], *tmp;
  384.   long pos=0;
  385.   int x = strlen(area), matches=0;
  386.  
  387.  
  388.   while(1)
  389.   {
  390.     tmp = get_ini_line(buff, 255, &pos, ini->ini);
  391.  
  392.     if(!tmp)
  393.       return(matches);
  394.  
  395.     strip_string(buff);
  396.  
  397.     if(buff[0] != '[')
  398.       continue;
  399.  
  400.     tmp=strchr(buff, ']');
  401.  
  402.     if(!tmp)
  403.       return(pos);
  404.  
  405.     tmp[0]=0;
  406.  
  407.     if(x)
  408.     {
  409.       if(strncmpi(buff+1, area, x) == 0)
  410.         ++matches;
  411.     }
  412.     else
  413.       ++matches;
  414.   }
  415. }
  416.  
  417.  
  418.  
  419. /* ------------------------------------------------------------------------- */
  420. /*  read_ini_area                                                            */
  421. /*                                                                           */
  422. /*  Memory allocated by this function must be 'free_2d' to release the memory*/
  423. /*  that it allocates.                                                       */
  424. /*                                                                           */
  425. /*  ie                                                                       */
  426. /*                                                                           */
  427. /*  char **tmp;                                                              */
  428. /*  tmp = read_ini_areas(&ini_info, "USER"));                                */
  429. /*  ...                                                                      */
  430. /*  free_2d(tmp);                                                            */
  431. /*                                                                           */
  432. /*  area is a sorta a wildcard, if it is specified, it will read in all areas*/
  433. /*  that match the area specified, up to the size of the area specified, so  */
  434. /*  if you want to count 'USER 1', 'USER 2', 'USER 3', etc..., you would     */
  435. /*  users = read_ini_areas(&ini, "USER ");                                   */
  436. /* ------------------------------------------------------------------------- */
  437.  
  438. #define MAX_INI_AREA_SIZE 50
  439. char ** read_ini_areas(ini_inforec *ini, char *area)
  440. {
  441.   char buff[255], *tmp;
  442.   char **areas;
  443.   long pos=0;
  444.   int x = strlen(area), matches=0;
  445.   int amount;
  446.  
  447.  
  448.   amount = count_ini_areas(ini, area) + 1;
  449.   areas = alloc_2d(amount, MAX_INI_AREA_SIZE + 1, sizeof(char));
  450.  
  451.  
  452.   while(1)
  453.   {
  454.     tmp = get_ini_line(buff, 255, &pos, ini->ini);
  455.  
  456.     if(!tmp)
  457.     {
  458.       areas[matches]=NULL;
  459.       return(areas);
  460.     }
  461.  
  462.     strip_string(buff);
  463.  
  464.     if(buff[0] != '[')
  465.       continue;
  466.  
  467.     tmp=strchr(buff, ']');
  468.  
  469.     if(!tmp)
  470.     {
  471.       areas[matches]=NULL;
  472.       return(areas);
  473.     }
  474.  
  475.     tmp[0]=0;
  476.  
  477.     if(x)
  478.     {
  479.       if(strncmpi(buff+1, area, x) == 0)
  480.       {
  481.         strncpy(areas[matches], buff+1, MAX_INI_AREA_SIZE);
  482.         areas[matches][MAX_INI_AREA_SIZE] = 0;
  483.         ++matches;
  484.       }
  485.     }
  486.     else
  487.     {
  488.       strncpy(areas[matches], buff+1, MAX_INI_AREA_SIZE);
  489.       areas[matches][MAX_INI_AREA_SIZE] = 0;
  490.       ++matches;
  491.     }
  492.   }
  493. }
  494.  
  495. long area_exist(ini_inforec *ini, char *area)
  496. {
  497.   char buff[255], *tmp;
  498.   long pos=0;
  499.  
  500.   if(!area[0])     /* If no area was specified, of course it was found */
  501.     return 1;
  502.  
  503.   while(1)
  504.   {
  505.     tmp = get_ini_line(buff, 255, &pos, ini->ini);
  506.  
  507.     if(!tmp)
  508.       return 0;                      /* DID NOT find area */
  509.  
  510.     strip_string(buff);
  511.  
  512.     if(buff[0] != '[')
  513.       continue;
  514.  
  515.     tmp=strchr(buff, ']');
  516.  
  517.     if(!tmp)
  518.       continue;
  519.  
  520.     tmp[0]=0;
  521.  
  522.     if(strcmpi(buff+1, area) == 0)
  523.       return 1;                     /* Found area */
  524.  
  525.   }
  526. }
  527.  
  528.  
  529.  
  530. int count_ini_indents(ini_inforec *ini_info, char *area, char *indent)
  531. {
  532.   char *tmp, buff[255], w1[128], w2[128];
  533.   long area_start, pos;
  534.   int amount = 0, size = strlen(indent);
  535.  
  536.  
  537.   area_start = find_ini_area(ini_info->ini, area);
  538.  
  539.  
  540.   if(area_start >= ini_info->fsize)
  541.     return 0;                        /* No matches, the area doesn't exist */
  542.  
  543.  
  544.   pos = area_start;
  545.   while(1)
  546.   {
  547.     tmp = get_ini_line(buff, 255, &pos, ini_info->ini);
  548.  
  549.     if(!tmp)          // No more lines
  550.       return amount;
  551.  
  552.     strip_string(tmp);
  553.  
  554.     if(buff[0]=='[')  // Star of a new area
  555.       return amount;
  556.  
  557.  
  558.     break_up_ini(buff, w1, w2);
  559.     if(strncmpi(w1, indent, size) == 0)    /* Found a match */
  560.       ++amount;
  561.   }
  562. }
  563.  
  564.  
  565. /* ------------------------------------------------------------------------- */
  566. /*  read_ini_indents                                                         */
  567. /*                                                                           */
  568. /*  Memory allocated by this function must be 'free_2d' to release the memory*/
  569. /*  that it allocates.                                                       */
  570. /*                                                                           */
  571. /*  ie                                                                       */
  572. /*                                                                           */
  573. /*  char **tmp;                                                              */
  574. /*  tmp = read_ini_areas(&ini_info, "USER", "LOAD"));                        */
  575. /*  ...                                                                      */
  576. /*  free_2d(tmp);                                                            */
  577. /*                                                                           */
  578. /*  Indent is sort of wildcard, 'Load' will find any thing with load at the  */
  579. /*  start of it, 'Load 1', 'Load 2' etc...                                   */
  580. /* ------------------------------------------------------------------------- */
  581.  
  582. #define MAX_INI_INDENT_SIZE 80
  583. char ** read_ini_indents(ini_inforec *ini_info, char *area, char *indent)
  584. {
  585.   char buff[255], *tmp;
  586.   char **indents, w1[128], w2[128];
  587.   long pos=0;
  588.   int size = strlen(indent), matches=0, amount;
  589.   unsigned area_start;
  590.  
  591.  
  592.   amount = count_ini_indents(ini_info, area, indent) + 1;
  593.   indents = alloc_2d(amount, MAX_INI_INDENT_SIZE + 1, sizeof(char));
  594.  
  595.   area_start = find_ini_area(ini_info->ini, area);
  596.  
  597.  
  598.   if(area_start >= ini_info->fsize)
  599.     return 0;                        /* No matches, the area doesn't exist */
  600.  
  601.  
  602.   pos = area_start;
  603.   while(1)
  604.   {
  605.     tmp = get_ini_line(buff, 255, &pos, ini_info->ini);
  606.  
  607.     if(!tmp)          // No more lines
  608.     {
  609.       indents[matches]=NULL;
  610.       return(indents);
  611.     }
  612.     strip_string(tmp);
  613.  
  614.     if(buff[0]=='[')  // Star of a new area
  615.     {
  616.       indents[matches]=NULL;
  617.       return(indents);
  618.     }
  619.  
  620.     break_up_ini(buff, w1, w2);
  621.     if(strncmpi(w1, indent, size) == 0)    /* Found a match */
  622.     {
  623.       strncpy(indents[matches], w2, MAX_INI_AREA_SIZE);
  624.       indents[matches][MAX_INI_AREA_SIZE] = 0;
  625.       ++matches;
  626.     }
  627.   }
  628.  
  629. }
  630.  
  631.  
  632.  
  633. long ll_read_ini_number(ini_inforec *ini_info, char *area, char *indent, long value, int should_update, int which)
  634. {
  635.   char *tmp, buff[255], w1[128], w2[128];
  636.   long area_start, pos;
  637.   int amount, this_which = 0;
  638.  
  639.  
  640.   area_start = find_ini_area(ini_info->ini, area);
  641.  
  642.  
  643.   if(area_start >= ini_info->fsize)
  644.   {
  645.  
  646.     if(should_update)
  647.     {
  648.       if(area[0])
  649.       {
  650.         amount = sprintf(buff, "\n[%s]\n", area);
  651.  
  652.         if(ini_info->fsize + amount >= ini_info->allocated)
  653.           if(!increase_ini_allocation(ini_info))
  654.             return value;
  655.  
  656.         strcat(ini_info->ini, buff);
  657.         ini_info->fsize += amount;
  658.       }
  659.  
  660.       amount = sprintf(buff, "%s = %ld\n", indent, value);
  661.  
  662.       if(ini_info->fsize + amount >= ini_info->allocated)
  663.         if(!increase_ini_allocation(ini_info))
  664.           return value;
  665.  
  666.       strcat(ini_info->ini, buff);
  667.       ini_info->fsize += amount;
  668.  
  669.  
  670.       ini_info->changes_made = 1;
  671.     }
  672.     return(value);
  673.   }
  674.  
  675.  
  676.  
  677.   pos = area_start;
  678.   while(1)
  679.   {
  680.     tmp = get_ini_line(buff, 255, &pos, ini_info->ini);
  681.  
  682.     if(!tmp)          // No more lines
  683.     {
  684.       if(should_update)
  685.         set_ini_number(ini_info, area, indent, value);
  686.       return value;
  687.     }
  688.  
  689.     strip_string(tmp);
  690.  
  691.  
  692.     if(buff[0]=='[')  // Star of a new area
  693.     {
  694.       if(should_update)
  695.         set_ini_number(ini_info, area, indent, value);
  696.       return value;
  697.     }
  698.  
  699.     break_up_ini(buff, w1, w2);
  700.  
  701.     if(strcmpi(w1, indent) == 0)
  702.     {
  703.       if(this_which == which)
  704.         return(atol(w2));
  705.       else
  706.         ++this_which;
  707.     }
  708.   }
  709. }
  710.  
  711.       
  712.  
  713.  
  714. int ll_read_ini_string(ini_inforec *ini_info, char *area, char *indent, char *value, int max_value, int should_update, int which)
  715. {
  716.   char *tmp, buff[255], w1[128], w2[128];
  717.   long area_start, pos;
  718.   int amount, this_which = 0;
  719.  
  720.  
  721.   area_start = find_ini_area(ini_info->ini, area);
  722.  
  723.  
  724.   if(area_start >= ini_info->fsize)
  725.   {
  726.  
  727.     if(should_update)
  728.     {
  729.       if(area[0])
  730.       {
  731.         amount = sprintf(buff, "\n[%s]\n", area);
  732.  
  733.         if(ini_info->fsize + amount >= ini_info->allocated)
  734.           if(!increase_ini_allocation(ini_info))
  735.             return 0;
  736.  
  737.         strcat(ini_info->ini, buff);
  738.         ini_info->fsize += amount;
  739.       }
  740.  
  741.       amount = sprintf(buff, "%s = %s\n", indent, value);
  742.  
  743.       if(ini_info->fsize + amount >= ini_info->allocated)
  744.         if(!increase_ini_allocation(ini_info))
  745.           return 0;
  746.  
  747.       strcat(ini_info->ini, buff);
  748.       ini_info->fsize += amount;
  749.  
  750.       ini_info->changes_made = 1;
  751.       return 1;           /* Value was added, area was created */
  752.     }
  753.     else
  754.       return 0;
  755.   }
  756.  
  757.  
  758.  
  759.   pos = area_start;
  760.   while(1)
  761.   {
  762.     tmp = get_ini_line(buff, 255, &pos, ini_info->ini);
  763.  
  764.     if(!tmp)          // No more lines
  765.     {
  766.       if(should_update)
  767.       {
  768.         set_ini_string(ini_info, area, indent, value);
  769.         return 2;
  770.       }
  771.       else
  772.         return 0;
  773.     }
  774.  
  775.     strip_string(tmp);
  776.  
  777.     if(buff[0]=='[')  // Star of a new area
  778.     {
  779.       if(should_update)
  780.       {
  781.         set_ini_string(ini_info, area, indent, value);
  782.         return 2;
  783.       }
  784.       else
  785.         return 0;
  786.     }
  787.  
  788.     break_up_ini(buff, w1, w2);
  789.  
  790.  
  791.     /* Check to see if indents match */
  792.     if(strcmpi(w1, indent) == 0)
  793.     {
  794.       // which is for duplicate indents, only return it if this is the one
  795.       // the user specified
  796.       if(this_which == which)
  797.       {
  798.         if(w2[0])
  799.         {
  800.           strncpy(value, w2, max_value);
  801.           value[max_value]=0;
  802.         }
  803.         return 3;
  804.       }
  805.       else
  806.       {
  807.         // otherwise, increment our 'this_which'
  808.         ++this_which;
  809.       }
  810.     }
  811.   }
  812. }
  813.  
  814.  
  815. void set_ini_string_dup(ini_inforec *ini_info, char *area, char *indent, char *value, int which)
  816. {
  817.   char buff[255], *tmp, w1[128], w2[128];
  818.   long area_start, pos, save_pos;
  819.   int amount, this_which=0;
  820.  
  821.  
  822.   area_start = find_ini_area(ini_info->ini, area);
  823.  
  824.   if(area_start >= ini_info->fsize)
  825.   {
  826.  
  827.     if(area[0])
  828.     {
  829.       amount = sprintf(buff, "\n[%s]\n", area);
  830.  
  831.       if(ini_info->fsize + amount >= ini_info->allocated)
  832.         if(!increase_ini_allocation(ini_info))
  833.           return;
  834.  
  835.       strcat(ini_info->ini, buff);
  836.       ini_info->fsize+= amount;
  837.     }
  838.  
  839.     amount = sprintf(buff, "%s = %s\n", indent, value);
  840.  
  841.     if(ini_info->fsize + amount >= ini_info->allocated)
  842.       if(!increase_ini_allocation(ini_info))
  843.         return;
  844.  
  845.     strcat(ini_info->ini, buff);
  846.     ini_info->fsize+= amount;
  847.  
  848.     ini_info->changes_made = 1;
  849.     return;
  850.   }
  851.  
  852.  
  853.   pos = area_start;
  854.   while(1)
  855.   {
  856.     save_pos = pos;
  857.     tmp = get_ini_line(buff, 255, &pos, ini_info->ini);
  858.  
  859.     if(!tmp)
  860.       break;
  861.  
  862.     strip_string(buff);
  863.  
  864.     if(buff[0]=='[')  // Star of a new area, so break
  865.     {
  866.       save_pos = area_start;    // Put value right after [area], comment out this line to put at end
  867.       break;
  868.     }
  869.     break_up_ini(buff, w1, w2);
  870.  
  871.     if(strcmpi(w1, indent) == 0)
  872.     {
  873.       if(this_which == which)
  874.       {
  875.         if(!w2[0])
  876.           strcpy(w2, value);
  877.  
  878.         memmove(ini_info->ini + save_pos, ini_info->ini + pos, ini_info->fsize - pos+1);
  879.         ini_info->fsize = ini_info->fsize - (pos - save_pos);
  880.         break;
  881.       }
  882.       else
  883.         ++this_which;
  884.     }
  885.   }
  886.  
  887.   amount = sprintf(buff, "%s = %s\n", indent, value);
  888.  
  889.   if(ini_info->fsize + amount >= ini_info->allocated)
  890.     if(!increase_ini_allocation(ini_info))
  891.       return;
  892.  
  893.   memmove(ini_info->ini+amount+save_pos, ini_info->ini+save_pos,
  894.                                ini_info->fsize+amount-save_pos+1);
  895.   strncpy(ini_info->ini+save_pos, buff, amount);
  896.   ini_info->fsize += amount;
  897.  
  898.   ini_info->changes_made = 1;
  899.   return;         // Value was updated
  900. }
  901.  
  902.  
  903. void set_ini_number_dup(ini_inforec *ini_info, char *area, char *indent, long value, int which)
  904. {
  905.   char buff[255], *tmp, w1[128], w2[128];
  906.   long area_start, pos, save_pos;
  907.   int amount, this_which = 0;
  908.  
  909.  
  910.   area_start = find_ini_area(ini_info->ini, area);
  911.  
  912.  
  913.   if(area_start >= ini_info->fsize)
  914.   {
  915.  
  916.     if(area[0])
  917.     {
  918.       amount = sprintf(buff, "\n[%s]\n", area);
  919.  
  920.       if(ini_info->fsize + amount >= ini_info->allocated)
  921.         if(!increase_ini_allocation(ini_info))
  922.           return;
  923.  
  924.       strcat(ini_info->ini, buff);
  925.       ini_info->fsize+= amount;
  926.     }
  927.  
  928.     amount = sprintf(buff, "%s = %ld\n", indent, value);
  929.  
  930.     if(ini_info->fsize + amount >= ini_info->allocated)
  931.       if(!increase_ini_allocation(ini_info))
  932.         return;
  933.  
  934.     strcat(ini_info->ini, buff);
  935.     ini_info->fsize+= amount;
  936.  
  937.     ini_info->changes_made = 1;
  938.     return;
  939.   }
  940.  
  941.  
  942.   pos = area_start;
  943.   while(1)
  944.   {
  945.     save_pos = pos;
  946.     tmp = get_ini_line(buff, 255, &pos, ini_info->ini);
  947.  
  948.     if(!tmp)
  949.       break;
  950.  
  951.     strip_string(buff);
  952.  
  953.     if(buff[0]=='[')  // Star of a new area, so break
  954.     {
  955.       save_pos = area_start;    // Put value right after [area], comment out this line to put at end
  956.       break;
  957.     }
  958.     break_up_ini(buff, w1, w2);
  959.  
  960.     if(strcmpi(w1, indent) == 0)
  961.     {
  962.       if(this_which == which)
  963.       {
  964.         memmove(ini_info->ini + save_pos, ini_info->ini + pos, ini_info->fsize - pos+1);
  965.         ini_info->fsize = ini_info->fsize - (pos - save_pos);
  966.         break;
  967.       }
  968.       else
  969.         ++this_which;
  970.     }
  971.   }
  972.  
  973.   amount = sprintf(buff, "%s = %ld\n", indent, value);
  974.  
  975.   if(ini_info->fsize + amount >= ini_info->allocated)
  976.     if(!increase_ini_allocation(ini_info))
  977.       return;
  978.  
  979.   memmove(ini_info->ini+amount+save_pos, ini_info->ini+save_pos,
  980.                                ini_info->fsize+amount-save_pos+1);
  981.   strncpy(ini_info->ini+save_pos, buff, amount);
  982.   ini_info->fsize += amount;
  983.  
  984.   ini_info->changes_made = 1;
  985.   return;
  986. }
  987.  
  988.  
  989. char **alloc_2d(int row, int col, unsigned size)
  990. {
  991.    int i;
  992.    char **prow, *pdata;
  993.  
  994.    pdata = (char *) calloc(row * col, size);
  995.    if (pdata == (char *) NULL)
  996.    {
  997.       fprintf(log, "No heap space for data\n");
  998.       printf("Memory Error in alloc2d!\n");
  999.       return(NULL);
  1000.    }
  1001.    prow  = (char **) malloc(row * sizeof (char *));
  1002.  
  1003.    if (prow == (char **) NULL)
  1004.    {
  1005.       fprintf(log, "No heap space for row pointers\n");
  1006.       printf("Memory Error (2) in alloc2d!\n");
  1007.       free(pdata);
  1008.       return(NULL);
  1009.    }
  1010.  
  1011.    for (i = 0; i < row; i++)
  1012.    {
  1013.      prow[i] = pdata;             /* store pointers to rows */
  1014.      pdata += size * col;         /* move to next row */
  1015.    }
  1016.    return prow;                   /* pointer to 2D array */
  1017. }
  1018.  
  1019. void free_2d(char **pa)
  1020. {
  1021.    free(*pa);                    /* free the data */
  1022.    free(pa);                     /* free pointer to row pointers */
  1023. }
  1024.  
  1025. long filesize(FILE *stream)
  1026. {
  1027.   long curpos, length;
  1028.   
  1029.   curpos=ftell(stream);
  1030.   
  1031.   fseek(stream, 0L, SEEK_END);
  1032.   length=ftell(stream);
  1033.   
  1034.   fseek(stream, curpos, SEEK_SET);
  1035.   
  1036.   return length;
  1037. }
  1038.  
  1039. char * strip_string(char *string)
  1040. {
  1041.   int x=0, y;
  1042.   while(isspace(string[x]) && string[x])
  1043.     ++x;
  1044.     
  1045.   y=strlen(string);
  1046.   memmove(string, string+x, y-x+1);
  1047.   string[y-x+1]=0;
  1048.   
  1049.   y=strlen(string);
  1050.   --y;
  1051.   
  1052.   while(isspace(string[y]) && y >= 0)
  1053.     --y;
  1054.     
  1055.   string[y+1]=0;
  1056.   
  1057.   
  1058.   return(string);
  1059. }
  1060.  
  1061.