home *** CD-ROM | disk | FTP | other *** search
/ The Arcade BBS / arcadebbs.zip / arcadebbs / bbstools / MODS / COMMON40.ZIP / COMMON.C next >
Encoding:
C/C++ Source or Header  |  1995-06-20  |  27.0 KB  |  1,197 lines

  1. #include "vars.h"
  2. #pragma hdrstop
  3.  
  4. #include <stdarg.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <errno.h>
  9. #include <ctype.h>
  10. #include <conio.h>
  11. #include <dos.h>
  12. #include <dir.h>
  13. #include <io.h>
  14. #include <fcntl.h>
  15. #include <conio.h>
  16. #include <sys/stat.h>
  17.  
  18.  
  19.  
  20. int outchr_color(int c)
  21. {
  22.   int x;
  23.  
  24.   g_flags |= g_flag_pipe_colors;
  25.   x = outchr(c);
  26.   g_flags &= ~g_flag_pipe_colors;
  27.   return(x);
  28. }
  29.  
  30. char **alloc_2d(int row, int col, unsigned size)
  31. {
  32.    int i;
  33.    char **prow, *pdata;
  34.  
  35.    pdata = (char *) farcalloc(row * col, size);
  36.    if (pdata == (char *) NULL) {
  37.       sysoplog("2Dalloc Err");
  38.       pl("Mem Error!");
  39.       hangup=1;
  40.       return(NULL);
  41.    }
  42.    prow  = (char **) malloca(row * sizeof (char *));
  43.    if (prow == (char **) NULL) {
  44.       sysoplog("2Dalloc Err\n");
  45.       pl("Mem Error!");
  46.       hangup=1;
  47.       bbsfree(pdata);
  48.       return(NULL);
  49.    }
  50.  
  51.    for (i = 0; i < row; i++) {
  52.      prow[i] = pdata;             /* store pointers to rows */
  53.      pdata += size * col;         /* move to next row */
  54.    }
  55.    return prow;                   /* pointer to 2D array */
  56. }
  57.  
  58. void free_2d(char **pa)
  59. {
  60.   if(pa)
  61.   {
  62.     bbsfree(*pa);                    /* free the data */
  63.     bbsfree(pa);                     /* free pointer to row pointers */
  64.   }
  65. }
  66.  
  67.  
  68. unsigned side_menu(int *menu_pos, int redraw, char *menu_items[], int xpos, int ypos, struct side_menu_colors *smc)
  69. {
  70.   static int positions[20], amount=1;
  71.   int x;
  72.   unsigned event;
  73.  
  74.   tleft(1);
  75.   
  76.   if(redraw)
  77.   {
  78.     amount=1;
  79.     positions[0]=xpos;
  80.     while(menu_items[amount] && menu_items[amount][0] && !hangup )
  81.     {
  82.       positions[amount]=positions[amount-1]+strlen(menu_items[amount-1])+2;
  83.       ++amount;
  84.     }
  85.     
  86.     x=0;
  87.     setc(smc->normal_menu_item);
  88.  
  89.     while(menu_items[x] && menu_items[x][0] && !hangup)
  90.     {
  91.       GOTO_XY(positions[x], ypos);
  92.       
  93.       if(*menu_pos==x)
  94.       {
  95.         setc(smc->current_highlight);
  96.         outchr(menu_items[x][0]);
  97.         setc(smc->current_menu_item);
  98.         outstr(menu_items[x]+1);
  99.       }
  100.       else
  101.       {
  102.         setc(smc->normal_highlight);
  103.         outchr(menu_items[x][0]);
  104.         setc(smc->normal_menu_item);
  105.         outstr(menu_items[x]+1);
  106.       }
  107.       ++x;
  108.     }
  109.   }
  110.   
  111.   
  112.   
  113.   setc(smc->normal_menu_item);
  114.  
  115.   while(!hangup)
  116.   {
  117.     event=get_kb_event();
  118.  
  119.       
  120.     if(event<128)
  121.     {
  122.       int x=0;
  123.       while(menu_items[x] && menu_items[x][0] && !hangup)
  124.       {
  125.         if(event==toupper(menu_items[x][0]) || event==tolower(menu_items[x][0]))
  126.         {
  127.           GOTO_XY(positions[*menu_pos], ypos);
  128.           setc(smc->normal_highlight);
  129.           outchr(menu_items[*menu_pos][0]);
  130.           setc(smc->normal_menu_item);
  131.           outstr(menu_items[*menu_pos]+1);
  132.  
  133.           *menu_pos=x;
  134.           
  135.           setc(smc->current_highlight);
  136.           GOTO_XY(positions[*menu_pos], ypos);
  137.           outchr(menu_items[*menu_pos][0]);
  138.           setc(smc->current_menu_item);
  139.           outstr(menu_items[*menu_pos]+1);
  140.           
  141.           if(modem_speed>2400 || !using_modem)
  142.             GOTO_XY(positions[*menu_pos], ypos);
  143.           
  144.           return(EXECUTE);
  145.         }
  146.         ++x;
  147.       }
  148.       return(event);     /* added to return a value that isn't a hot key */
  149.     }
  150.     else
  151.     {
  152.       switch(event)
  153.       {
  154.         case COMMAND_LEFT:
  155.           GOTO_XY(positions[*menu_pos], ypos);
  156.           setc(smc->normal_highlight);
  157.           outchr(menu_items[*menu_pos][0]);
  158.           setc(smc->normal_menu_item);
  159.           outstr(menu_items[*menu_pos]+1);
  160.  
  161.           if(!*menu_pos)
  162.             *menu_pos=amount-1;
  163.           else
  164.             --*menu_pos;
  165.             
  166.             setc(smc->current_highlight);
  167.             GOTO_XY(positions[*menu_pos], ypos);
  168.             outchr(menu_items[*menu_pos][0]);
  169.             setc(smc->current_menu_item);
  170.             outstr(menu_items[*menu_pos]+1);
  171.  
  172.           if(modem_speed>2400 || !using_modem)
  173.             GOTO_XY(positions[*menu_pos], ypos);
  174.           
  175.           break;
  176.           
  177.         case COMMAND_RIGHT:
  178.           GOTO_XY(positions[*menu_pos], ypos);
  179.             setc(smc->normal_highlight);
  180.             outchr(menu_items[*menu_pos][0]);
  181.             setc(smc->normal_menu_item);
  182.             outstr(menu_items[*menu_pos]+1);
  183.           if(*menu_pos==amount-1)
  184.             *menu_pos=0;
  185.           else
  186.             ++*menu_pos;
  187.             
  188.             setc(smc->current_highlight);
  189.             GOTO_XY(positions[*menu_pos], ypos);
  190.             outchr(menu_items[*menu_pos][0]);
  191.             setc(smc->current_menu_item);
  192.             outstr(menu_items[*menu_pos]+1);
  193.             
  194.           if(modem_speed>2400 || !using_modem)
  195.             GOTO_XY(positions[*menu_pos], ypos);
  196.  
  197.           
  198.           break;
  199.           
  200.         default:
  201.           return(event);
  202.           
  203.       }
  204.     }
  205.   } // While !hangup   
  206.   return(0);      
  207. }          
  208.  
  209.  
  210.  
  211.  
  212. void show_common_mods(void)
  213. {
  214.   existprint("COMMON.LST");
  215. }
  216.  
  217.  
  218.  
  219. #ifdef TEST_VM
  220. void test_vm(void)
  221. {
  222.   inputeditrec input1, input2;
  223.   showtextrec text1, text2;
  224.  
  225.   varimenurec *menu=NULL, newmenu;
  226.   varimenuinfo info={YELLOW+(BLUE<<4), RED+(BLUE<<4), BLACK+(CYAN<<4), RED+(CYAN<<4), DARKGRAY+(BLUE<<4),
  227.                      COMMON_FULL, 0, 0, 0, 0, 0};
  228.   int done=0;
  229.  
  230.   enum TEST_STUFF
  231.   {
  232.     LOGON,
  233.     CHAT,
  234.     EMAIL,
  235.     GOODBYE
  236.   };
  237.  
  238.  
  239.   build_showtextrec(&text1, 5, 5, 17, "Logon", JUSTIFY_CENTER, '■');
  240.   fillvarimenurec(&newmenu, &text1, SHOW_TEXT_TYPE, 0, LOGON, COMMON_ACTIVE);
  241.   menu=addvarimenu(menu, &newmenu);
  242.  
  243.   build_showtextrec(&text2, 5, 7, 17, "GoodBye", JUSTIFY_CENTER, '∙');
  244.   fillvarimenurec(&newmenu, &text2, SHOW_TEXT_TYPE, 0, GOODBYE, COMMON_ACTIVE);
  245.   menu=addvarimenu(menu, &newmenu);
  246.  
  247.   build_inputrec(&input1, 30, 5, 9, 17, 1, IE_MIXED);
  248.   fillvarimenurec(&newmenu, &input1, INPUT_EDIT_TYPE, 0, CHAT, COMMON_ACTIVE);
  249.   menu=addvarimenu(menu, &newmenu);
  250.  
  251.  
  252.   build_inputrec(&input2, 30, 5, 11, 17, 1, IE_PROPPER);
  253.   fillvarimenurec(&newmenu, &input2, INPUT_EDIT_TYPE, 0, EMAIL, COMMON_ACTIVE);
  254.   menu=addvarimenu(menu, &newmenu);
  255.  
  256.  
  257.   // Print out ansi or prep screen in other way
  258.   CLS();
  259.  
  260.   while(!done && !hangup)
  261.   {
  262.     varimenu(menu, &info);
  263.  
  264.     switch(info.event)
  265.     {
  266.       case EXECUTE:
  267.         switch(info.returnvalue)
  268.         {
  269.           case GOODBYE:
  270.           case GET_OUT:
  271.             done=1;
  272.             break;
  273.           default:
  274.             info.redraw=COMMON_NONE;
  275.             break;
  276.         }
  277.         break;
  278.  
  279.       case GET_OUT:
  280.         done=1;
  281.         break;
  282.  
  283.       default:
  284.         info.redraw=COMMON_NONE;
  285.         break;
  286.     }
  287.  
  288.   }
  289.  
  290.   killvarimenu(menu);
  291.   CLS();
  292. }
  293. #endif   // end ifdef test_var
  294.  
  295.  
  296.  
  297.  
  298. // Waits for 'seconds' seconds, does not exit on comhit
  299. void wait_sec(double seconds)
  300. {
  301.   time_t time1;
  302.   time_t time2;
  303.  
  304.   time(&time1);
  305.   time(&time2);
  306.  
  307.   if( seconds == 1 )
  308.     ++seconds;
  309.  
  310.   while(difftime(time2,time1) < seconds && !hangup)
  311.     time(&time2);
  312. }
  313.  
  314.  
  315. long filesize(FILE *stream)
  316. {
  317.   long curpos, length;
  318.   
  319.   curpos=ftell(stream);
  320.   
  321.   fseek(stream, 0L, SEEK_END);
  322.   length=ftell(stream);
  323.   
  324.   fseek(stream, curpos, SEEK_SET);
  325.   
  326.   return length;
  327. }
  328.  
  329.  
  330.  
  331. int fset_rec(FILE *stream, unsigned rec, unsigned rec_size)
  332. {
  333.   int error;
  334.   
  335.   error = fseek(stream, (long) ((rec)*((long)rec_size)), SEEK_SET);
  336.  
  337. #if 0
  338.   if(error)
  339.     ; // Could not set rec
  340. #endif
  341.  
  342.   return(!error);
  343. }
  344.  
  345. int set_rec(int filenum, unsigned rec, unsigned rec_size)
  346. {
  347.   int error;
  348.   
  349.   error = sh_lseek(filenum, (long) ((rec)*((long)rec_size)), SEEK_SET);
  350.  
  351. #if 0
  352.   if(error)
  353.     ; // Could not set rec
  354. #endif
  355.  
  356.   return(!error);
  357. }
  358.  
  359.  
  360.  
  361.  
  362.  
  363. /*
  364.   ASYLUM INI function - COMMON
  365. */
  366.  
  367.  
  368.  
  369. /* ----------------------------------------------------------------------
  370.  
  371.   What was changed?
  372.  
  373.  
  374.  
  375. The flags explained:
  376.   IF_NONE - Open up the ini file in read/write mode
  377.  
  378.   IF_STC  - When doing a write, it will look for the identifier hidden
  379.             behind a comment, and replace that commented out line with
  380.             the value you are specifing
  381.  
  382.   IF_STCR - When doing a read, it will remove the first comment to see if
  383.             the identifier exists behind a comment.  Not meant to be used
  384.             all the time, since the person might actually want the item
  385.             commented out.
  386.  
  387.   IF_OREAD - Opens ini file in read only mode.  No changes will be saved
  388.  
  389.   IF_WINR - When doing a read, if the identifier doesn't exist, it will
  390.             do a write with the contents of what you have in the buffer,
  391.             it is up to you to put a good value here.
  392.  
  393.  
  394.  
  395.  
  396. ------------------------------------------------------------------------- */
  397.  
  398.  
  399.  
  400.  
  401.  
  402. char bool_strings[AMOUNT_BOOLS][2][8] = {{ "YES",  "NO" },
  403.                                          { "TRUE", "FALSE"},
  404.                                          { "ON",   "OFF"},
  405.                                          { "1",    "0"}};
  406. static int which_bool;
  407.  
  408.  
  409.  
  410.  
  411.  
  412. ini_record * open_ini(char *fname, unsigned long flags)
  413. {
  414.   ini_record *ini;
  415.  
  416.  
  417.   ini=(ini_record *)MALLOC(sizeof(ini_record));
  418.   if(!ini)
  419.     return NULL;
  420.  
  421.   memset((void *) ini, 0, sizeof(ini_record));
  422.  
  423.  
  424.   fix_ini_name(fname);
  425.  
  426.   strcpy(ini->fname, fname);
  427.   ini->fp = FOPEN(fname, "rt");       /* if it doesn't exist, no error      */
  428.  
  429.   ini->flags = flags;
  430.   return ini;
  431. }
  432.  
  433. void close_ini(ini_record *ini)
  434. {
  435.   /* if there is no ini allocated, then there is nothing */
  436.   /* to free up and close                                */
  437.   if(!ini)
  438.     return;
  439.  
  440.   release_ini_section(ini);     /* free the data rows       */
  441.  
  442.   if(ini->patt_idents)
  443.     FREE(ini->patt_idents);
  444.  
  445.   if(ini->fp)
  446.     FCLOSE(ini->fp);
  447.  
  448.   FREE(ini);                    /* free the whole structure */
  449. }
  450.  
  451. char *ini_read_string(ini_record *ini, char *area, char *ident, char *buff)
  452. {
  453.   char line[MAX_LINE_WIDTH];
  454.   char *data, *comment;
  455.   int x;
  456.  
  457.   strip_string(area);
  458.   strip_string(ident);
  459.  
  460.   read_ini_area(ini, area);    /* read area in, if needed */
  461.  
  462.  
  463.   x = does_ident_exist(ini, area, ident);  /* x points to the line in the   */
  464.   if(x)                                    /* ini rows that the line exists */
  465.   {                                        /* or 0 for not exist, but is 1  */
  466.     --x;                                   /* relative, so make 0 relative  */
  467.     strcpy(line, ini->ini_rows[x]);
  468.  
  469.     if(ini->flags & INI_FLAGS_SEE_THROUGH_ON_READ)
  470.     {
  471.       strip_string(line);       /* if first char is a comment */
  472.       if(line[0] == ';')        /* then turn it into a space  */
  473.         line[0]=' ';
  474.     }
  475.  
  476.     comment=strchr(line, ';');
  477.     if(comment)
  478.       comment[0] = 0;
  479.  
  480.     data=strchr(line, '=');
  481.     if(data)
  482.     {
  483.       data[0] = 0;
  484.       ++data;
  485.     }
  486.  
  487.     strip_string(line);
  488.  
  489.     if(!data)
  490.       buff[0] = 0;
  491.     else
  492.       strcpy(buff, strip_string(data));
  493.  
  494.     return buff;
  495.   }
  496.   else    /* see if the option to add it if it doesn't exist is on */
  497.   {
  498.     if(ini->flags & INI_FLAGS_WRITE_IF_NO_READ)
  499.     {
  500.       if(ini_write_string(ini, area, ident, buff))
  501.         return buff;
  502.       else
  503.       {
  504.         buff[0]=0;
  505.         return NULL;
  506.       }
  507.     }
  508.   }
  509.  
  510.  
  511.   buff[0] = 0;
  512.   return NULL;
  513. }
  514.  
  515. long ini_read_number(ini_record *ini, char *area, char *ident)
  516. {
  517.   char line[MAX_LINE_WIDTH];
  518.  
  519.   line[0]=0;    /* just in case we have write on fail, don't write junk */
  520.   if(ini_read_string(ini, area, ident, line))
  521.     return(atol(line));
  522.  
  523.   return 0;
  524. }
  525.  
  526. int ini_read_boolean(ini_record *ini, char *area, char *ident)
  527. {
  528.   char line[MAX_LINE_WIDTH];
  529.   ini_read_string(ini, area, ident, line);
  530.  
  531.   line[0] = toupper(line[0]);
  532.  
  533.   switch(line[0])
  534.   {
  535.     case 'Y':        /* yes  */
  536.     case 'T':        /* true */
  537.     case '1':        /* 1    */
  538.       return 1;
  539.  
  540.     case 'O':        /* maybe on */
  541.       if(strcmpi(line, "ON") == 0)
  542.         return 1;
  543.  
  544.     default:         /* if it isn't on, it must be off */
  545.       return 0;
  546.   }
  547. }
  548.  
  549. int ini_write_boolean(ini_record *ini, char *area, char *ident, int value)
  550. {
  551.   char temp[21];
  552.  
  553.   sprintf(temp, "%ld", value);
  554.   return(ini_write_string(ini, area, ident, bool_strings[which_bool][value ? 1 : 0]));
  555. }
  556.  
  557.  
  558. void set_boolean_value(int value)
  559. {
  560.   which_bool = value;
  561. }
  562.  
  563. int get_boolean_value(void)
  564. {
  565.   return which_bool;
  566. }
  567.  
  568.  
  569.  
  570.  
  571. int ini_write_string(ini_record *ini, char *area, char *ident, char *value)
  572. {
  573.   char line[MAX_LINE_WIDTH], new_line[MAX_LINE_WIDTH];
  574.   char *comment, *data;
  575.   int x = 0, junk;
  576.  
  577.   strip_string(area);
  578.   strip_string(ident);
  579.  
  580.   read_ini_area(ini, area);     /* if needed, read in ini area */
  581.  
  582.   /* first see if identifier already exists, and mod it if so */
  583.   x = 0;
  584.   while(x < ini->amount_rows)
  585.   {
  586.     strcpy(line, ini->ini_rows[x]);
  587.     strip_string(line);
  588.  
  589.     if(ini->flags & INI_FLAGS_SEE_THROUGH_COMMENTS)
  590.     {
  591.       if(line[0] == ';')
  592.         line[0] = ' ';
  593.     }
  594.  
  595.  
  596.     comment=strchr(line, ';');
  597.     if(comment)
  598.       { comment[0] = 0; ++comment; }
  599.  
  600.  
  601.     data=strchr(line, '=');
  602.     if(data)
  603.     {
  604.       data[0] = 0;
  605.       ++data;
  606.     }
  607.  
  608.     strip_string(line);
  609.     if(strcmpi(line, ident) == 0)
  610.     {
  611.       sprintf(new_line, "%" INI_COL_WIDTH "s = %s", ident, value);
  612.  
  613.       /*
  614.          -----------------------------------------
  615.          If there was a comment, then pad our line
  616.          out to the size we have specified in the
  617.          #define INI_COMMENT_POS, then append the
  618.          comment to the end of our line
  619.          -----------------------------------------
  620.       */
  621.  
  622.       if(comment && comment[0])         // first see if there was a comment
  623.       {
  624.         junk = strlen(new_line);        // now find out how long our string is
  625.         while(junk < INI_COMMENT_POS-1) // if we are less than the size we
  626.         {                               // have defined, then pad it with
  627.           new_line[junk] = ' ';         // spaces to the size we have defined
  628.           ++junk;
  629.         }
  630.         new_line[junk]=0;               // append a null
  631.         strcat(new_line, "; ");         // and concatenate our comment letter
  632.         strip_string(comment);
  633.         strcat(new_line, comment);      // and finally the comment
  634.       }
  635.  
  636.  
  637.       strip_string(new_line);           // remove any random spaces
  638.       return(replace_in_ini_lines(ini, new_line, x));
  639.  
  640.     }
  641.     ++x;
  642.   }
  643.   sprintf(new_line, "%" INI_COL_WIDTH "s = %s", ident, value);
  644.   return(addto_ini_lines(ini, new_line, 1));
  645. }
  646.  
  647. int ini_write_number(ini_record *ini, char *area, char *ident, long value)
  648. {
  649.   char temp[21];
  650.  
  651.   sprintf(temp, "%ld", value);
  652.   return(ini_write_string(ini, area, ident, temp));
  653. }
  654.  
  655.  
  656. int ini_remove_ident(ini_record *ini, char *area, char *ident)
  657. {
  658.   int x;
  659.  
  660.   strip_string(area);
  661.   strip_string(ident);
  662.  
  663.  
  664.   read_ini_area(ini, area);    /* if needed, read in ini area */
  665.  
  666.   x = does_ident_exist(ini, area, ident);
  667.  
  668.   if(x)
  669.   {
  670.     --x;                      /* make x zero relative */
  671.     return(remove_from_ini_lines(ini, x));
  672.   }
  673.   return 0;                   /* nothing removed      */
  674. }
  675.  
  676. void ini_remove_area(ini_record *ini, char *area)
  677. {
  678.   strip_string(area);
  679.  
  680.   release_ini_section(ini);    /* write and release any current changes */
  681.   strcpy(ini->area, area);     /* next time the disk is flushed, this   */
  682.   ini->modified = 1;           /* area of nothing will be written to    */
  683.                                /* disk, effectivly removing the old     */
  684.                                /* section                               */
  685. }
  686.  
  687.  
  688.  
  689.  
  690. /* sees if an identifer exists in a given section, if it does, it will   */
  691. /* return a pointer to it + 1, ie, if it returns 1, then it is the first */
  692. /* identifer in the ini->ini_rows position (ini_rows[0])                 */
  693. int does_ident_exist(ini_record *ini, char *area, char *ident)
  694. {
  695.   char line[MAX_LINE_WIDTH];
  696.   char *data;
  697.   int x = 0;
  698.  
  699.   strip_string(area);
  700.   strip_string(ident);
  701.  
  702.   read_ini_area(ini, area);        /* if needed, read in ini area  */
  703.  
  704.   x = 0;
  705.   while(x < ini->amount_rows)
  706.   {
  707.     strcpy(line, ini->ini_rows[x]);
  708.  
  709.  
  710.     if(ini->flags & INI_FLAGS_SEE_THROUGH_ON_READ)
  711.     {
  712.       strip_string(line);    /* if the first char is a comment */
  713.       if(line[0] == ';')     /* then turn comment into a space */
  714.         line[0]=' ';
  715.     }
  716.  
  717.  
  718.     data=strchr(line, '=');
  719.     if(data)
  720.       data[0] = 0;
  721.  
  722.     strip_string(line);
  723.  
  724.  
  725.     if(strcmpi(line, ident) == 0)
  726.       return x+1;                  /* return 1 relative position to ident */
  727.  
  728.     ++x;
  729.   }
  730.   return 0;           /* identifer doesn't exist */
  731. }
  732.  
  733. int does_ini_area_exist(ini_record *ini, char *area)
  734. {
  735.   char line[MAX_LINE_WIDTH], fix_area[101];
  736.   int x;
  737.  
  738.   strip_string(area);
  739.  
  740.   if(strcmpi(area, ini->area)==0) /* if we have it in memory... */
  741.     return 1;                     /* then it does exist         */
  742.  
  743.   if(!ini->fp)       /* if the file doesn't yet exist, it doesn't exist */
  744.     return 0;
  745.  
  746.   strip_string(area);
  747.   if(area[0]=='[')
  748.     strcpy(fix_area, area);
  749.   else
  750.     sprintf(fix_area, "[%s]", area);
  751.  
  752.   x = strlen(fix_area);
  753.  
  754.   fseek(ini->fp, 0, SEEK_SET);
  755.   while(1)
  756.   {
  757.     if(!fgets(line, MAX_LINE_WIDTH, ini->fp))
  758.       return 0;                        /* section doesn't exist */
  759.  
  760.     strip_string(line);
  761.  
  762.     if(strncmpi(fix_area, line, x) == 0)
  763.       return 1;
  764.   }
  765. }
  766.  
  767. int get_ident_positions(ini_record *ini, char *area, char *ipattern)
  768. {
  769.   int amount;
  770.  
  771.   read_ini_area(ini, area);
  772.  
  773.   if(ini->patt_idents)
  774.   {
  775.     FREE(ini->patt_idents);
  776.     ini->patt_idents = NULL;
  777.   }
  778.  
  779.   amount = get_ident_patterns(ini, area, ipattern, 0);
  780.  
  781.   ini->patt_idents = (int *) MALLOC(amount * (sizeof(int)));
  782.   if(!ini->patt_idents)
  783.     { ini->amount_patt_idents = 0; return 0; }
  784.  
  785.  
  786.   get_ident_patterns(ini, area, ipattern, 1);
  787.  
  788.   return(amount);
  789. }
  790.  
  791. int get_ident_patterns(ini_record *ini, char *area, char *ipattern, int getem)
  792. {
  793.   char line[MAX_LINE_WIDTH];
  794.   int amount=0, pos = 0, len = strlen(ipattern);
  795.  
  796.   read_ini_area(ini, area);
  797.  
  798.   while(pos < ini->amount_rows)
  799.   {
  800.     strcpy(line, ini->ini_rows[pos]);
  801.  
  802.     strip_string(line);
  803.     if(strncmpi(line, ipattern, len) == 0)
  804.     {
  805.       if(getem)                          /* memory has to be allocated */
  806.         ini->patt_idents[amount] = pos;  /* before this can be done    */
  807.       ++amount;
  808.     }
  809.  
  810.     ++pos;
  811.   }
  812.   ini->amount_patt_idents = amount;
  813.   return amount;
  814. }
  815.  
  816.  
  817.  
  818. char *fix_ini_name(char *fname)
  819. {
  820.   char *tmp;
  821.  
  822.   strupr(fname);
  823.   strip_string(fname);
  824.  
  825.   tmp = strchr(fname, '.');
  826.   if(tmp)                          /* if extension exists      */
  827.     return fname;                  /* then no change is needed */
  828.  
  829.   fname[8]=0;
  830.   strcat(fname, ".INI");
  831.   return(fname);
  832. }
  833.  
  834.  
  835. int ini_write_changes(ini_record *ini)
  836. {
  837.   FILE *new_file;
  838.   char tmp_fname[13], line[MAX_LINE_WIDTH], fixed_area[MAX_LINE_WIDTH];
  839.   char new_name[130], *s;
  840.   int area_width, i=0;
  841.   
  842.   if (!ini->modified)                  /* it it wasn't modified, then */
  843.     return 2;                          /* there is no need to write   */
  844.   
  845.   if (ini->flags & INI_FLAGS_READ_ONLY)/* if in read only mode then */
  846.     return 3;                          /* we obviously can't write  */
  847.   
  848.   
  849.   tmpnam(tmp_fname);
  850.   new_file=FOPEN(tmp_fname, "wt");
  851.   if (!new_file)                       /* couldn't open file for writting */
  852.     return 0;
  853.   
  854.   
  855.   /*
  856.       ------------------------------------------------------------
  857.     if the file didn't exist, then we can't read from it, flush it,
  858.     seek in it, or anything else, so jump right to the write part
  859.       ------------------------------------------------------------
  860.   */
  861.   if (!ini->fp)
  862.     goto WRITE_AREA;
  863.   
  864.  
  865.   fflush(ini->fp);
  866.   
  867.   strip_string(ini->area);
  868.   if(ini->area[0] == '[')
  869.     strcpy(fixed_area, ini->area);
  870.   else
  871.     sprintf(fixed_area, "[%s]", ini->area);
  872.   area_width=strlen(fixed_area);
  873.   
  874.   fseek(ini->fp, 0, SEEK_SET);         /* jump to start of file */
  875.   while (ini->fp)
  876.   {
  877.     if (fgets(line, MAX_LINE_WIDTH, ini->fp)==NULL)
  878.       break;
  879.     
  880.     strip_string(line);
  881.     
  882.     if (ini->modified && strncmpi(fixed_area, line, area_width)==0)
  883.     {
  884.       int x;
  885.       x=0;
  886.       
  887.       while (1)
  888.       /* bypass this area so we can write updated memory */
  889.       {
  890.         if (fgets(line, MAX_LINE_WIDTH, ini->fp)==NULL)
  891.           break;
  892.         strip_string(line);
  893.         if (line[0]=='[') {             /* start of a new area */
  894.           i=1;       // so it will write the line after the area,
  895.           break;     // and not skipping it.
  896.         }
  897.       }
  898.       
  899. WRITE_AREA:
  900.       fprintf(new_file, "%s\n", fixed_area);
  901.       x=0;
  902.       while (x<ini->amount_rows)
  903.       {
  904.         if (ini->ini_rows[x])  /* if it hasn't been free'd, the write it */
  905.           fprintf(new_file, "%s\n", ini->ini_rows[x]);
  906.         x++;
  907.       }
  908.       ini->modified=0;  /* once written, then it isn't modified anymore */
  909.  
  910.       if (i==1)
  911.       {
  912.         i=0; /* Write the extra line forgot by the previous routine */
  913.         /* (the one that was just read, but was a new area)         */
  914.         fprintf(new_file, "\n%s\n", line);
  915.       }
  916.     }
  917.     else
  918.       fprintf(new_file, "%s\n", line);
  919.   }
  920.   if (ini->modified)
  921.     goto WRITE_AREA;
  922.   
  923.   /* no need to check new_file against NULL here, it is checked above */
  924.   FCLOSE(new_file);
  925.   
  926.   if (ini->fp)
  927.   {
  928.     FCLOSE(ini->fp);
  929.     ini->fp=NULL;
  930.   }
  931.   
  932.   
  933.   strcpy(new_name, ini->fname);        /* rename our ini file to a .BAK */
  934.   s=strchr(new_name, '.');             /* so that we will have a name   */
  935.   if (s)                               /* for our tmpfile               */
  936.     strcpy(s, ".BAK");
  937.   else
  938.     strcat(new_name, ".BAK");
  939.   
  940.   unlink(new_name);                    /* make room for out backup      */
  941.   rename(ini->fname, new_name);
  942.   
  943.   copyfile(tmp_fname, ini->fname, 0);
  944.   unlink(tmp_fname);
  945.   
  946.   
  947.   ini->fp=FOPEN(ini->fname, "rt");
  948.   
  949.   return 1;
  950. }
  951.  
  952.  
  953. void release_ini_section(ini_record *ini)
  954. {
  955.   int x = 0;
  956.  
  957.   ini_write_changes(ini);
  958.  
  959.   x = 0;
  960.   while(x < ini->amount_rows)
  961.   {
  962.     if(ini->ini_rows[x])
  963.       FREE(ini->ini_rows[x]);
  964.  
  965.     ini->ini_rows[x] = NULL;
  966.  
  967.     ++x;
  968.   }
  969.  
  970.   if(ini->ini_rows)
  971.     FREE(ini->ini_rows);
  972.  
  973.   ini->area[0] = 0;
  974.   ini->ini_rows = NULL;
  975.   ini->amount_rows = 0;
  976.   ini->rows_allocated = 0;
  977. }
  978.  
  979.  
  980.  
  981.  
  982.  
  983.  
  984.  
  985. int read_ini_area(ini_record *ini, char *area)
  986. {
  987.   char line[MAX_LINE_WIDTH];
  988.  
  989.   strip_string(area);
  990.  
  991.  
  992.   if(strcmpi(area, ini->area) == 0)   /* already read in */
  993.     return 2;
  994.  
  995.   release_ini_section(ini);
  996.  
  997.   if(!ini->fp)                     /* if the file doesn't exist then */
  998.   {                                /* consider it read               */
  999.     strcpy(ini->area, area);       /* add it as area read            */
  1000.     return 1;
  1001.   }
  1002.  
  1003.   /* if area does exist, the function leaves the disk pointer at the */
  1004.   /* part of that area, so just start reading in the area from the   */
  1005.   /* current disk pointer                                            */
  1006.   if(does_ini_area_exist(ini, area))
  1007.   {
  1008.     strcpy(ini->area, area);       /* add it as area read            */
  1009.     while(1)
  1010.     {
  1011.       if(!fgets(line, MAX_LINE_WIDTH, ini->fp))
  1012.       {
  1013.         ini_pack_lines(ini);       /* remove trailing blank lines    */
  1014.         return 1;
  1015.       }
  1016.  
  1017.       strip_string(line);
  1018.       if(line[0] == '[')
  1019.       {
  1020.         ini_pack_lines(ini);       /* remove trailing blank lines    */
  1021.         return 1;                  /* done, starting a new section   */
  1022.       }
  1023.  
  1024.       addto_ini_lines(ini, line, 0);
  1025.     }
  1026.   }
  1027.   else   /* don't actually need this else statement, but... */
  1028.   {
  1029.     strcpy(ini->area, area);    /* add the area if it doesn't exist */
  1030.     ini->modified=1;            /* and set the modified flag        */
  1031.   }
  1032.  
  1033.   return 0;                     /* nothing there to read */
  1034. }
  1035.  
  1036.  
  1037.  
  1038.  
  1039. int addto_ini_lines(ini_record *ini, char *line, int modify)
  1040. {
  1041.   char **tmp;
  1042.  
  1043.   if(ini->amount_rows == 0xffff)    /* max rows is 0xffff (65535) */
  1044.     return 0;                       /* line not added             */
  1045.  
  1046.   if(ini->amount_rows >= ini->rows_allocated)
  1047.   {
  1048.     tmp = (char **)REALLOC(ini->ini_rows, (ini->rows_allocated+100) * sizeof(char *));
  1049.  
  1050.     if(!tmp)
  1051.       return 0;                /* couldn't allocate 100 more rows     */
  1052.  
  1053.     ini->ini_rows = tmp;       /* point our pointer to our new memory */
  1054.     ini->rows_allocated += 100; /* added 100 rows of allocation space  */
  1055.   }
  1056.  
  1057.   ini->ini_rows[ini->amount_rows] = (char *)MALLOC(strlen(line)+1);
  1058.   if(!ini->ini_rows[ini->amount_rows])
  1059.     return 0;
  1060.  
  1061.  
  1062.   strcpy(ini->ini_rows[ini->amount_rows++], line);
  1063.   if(modify)
  1064.     ini->modified = 1;
  1065.   return 1;
  1066. }
  1067.  
  1068. void ini_pack_lines(ini_record *ini)
  1069. {
  1070.   int x = ini->amount_rows-1;
  1071.  
  1072.   while(x > -1)
  1073.   {
  1074.     if(ini->ini_rows[x])
  1075.     {
  1076.       strip_string(ini->ini_rows[x]);
  1077.  
  1078.       if(ini->ini_rows[x][0] != 0)
  1079.         break;
  1080.  
  1081.       FREE(ini->ini_rows[x]);
  1082.       ini->ini_rows[x]=NULL;
  1083.     }
  1084.  
  1085.     --x;
  1086.   }
  1087.  
  1088.   if(ini->ini_rows[x][0] || x == -1)
  1089.     ++x;
  1090.  
  1091.   ini->amount_rows = x;
  1092. }
  1093.  
  1094.  
  1095.  
  1096. int replace_in_ini_lines(ini_record *ini, char *line, int x)
  1097. {
  1098.   char *tmp;
  1099.  
  1100.   tmp = (char *)REALLOC(ini->ini_rows[x], strlen(line)+1);
  1101.   if(!tmp)
  1102.     return 0;
  1103.  
  1104.   ini->ini_rows[x] = tmp;    /* point our realloced memory to the ini rows */
  1105.   strcpy(ini->ini_rows[x], line);
  1106.   ini->modified = 1;
  1107.   return 1;
  1108. }
  1109.  
  1110. int remove_from_ini_lines(ini_record *ini, int x)
  1111. {
  1112.   if(x >= ini->amount_rows)
  1113.     return 0;                /* out of range, nothing removed       */
  1114.  
  1115.   if(ini->ini_rows[x])
  1116.     FREE(ini->ini_rows[x]);  /* just free it and set it to          */
  1117.   ini->ini_rows[x] = NULL;   /* NULL, don't worry about removing it */
  1118.  
  1119.   ini->modified = 1;
  1120.   return 1;                  /* identifer properly removed          */
  1121. }
  1122.  
  1123.  
  1124.  
  1125. int amount_areas_names(ini_record *ini)
  1126. {
  1127.   int found = 0;
  1128.   char line[MAX_LINE_WIDTH];
  1129.  
  1130.   release_ini_section(ini);
  1131.  
  1132.   if(!ini->fp)
  1133.     return NULL;
  1134.  
  1135.  
  1136.   fseek(ini->fp, 0, SEEK_SET);
  1137.   while(1)
  1138.   {
  1139.     if(!fgets(line, MAX_LINE_WIDTH, ini->fp))
  1140.       return found;
  1141.  
  1142.     strip_string(line);
  1143.  
  1144.     if(line[0] == '[')
  1145.       ++found;
  1146.   }
  1147. }
  1148.  
  1149. /*
  1150.   Reads all areas names into buffer which must be allocated as such:
  1151.  
  1152.   char *buffer[MAX_LINE_WIDTH];
  1153.   amount = amount_ini_areas(ini);
  1154.   buffer = (buffer *[]) MALLOC(amount * MAX_LINE_WIDTH);
  1155.   read_ini_areas(ini, buffer, amount);
  1156.   ...
  1157.   FREE(buffer);
  1158.  
  1159.  
  1160.   It reads a max of 'max' areas and returns the actual amount of areas
  1161.   that were read
  1162. */
  1163.  
  1164. int get_area_names(ini_record *ini, char (*buffer)[MAX_LINE_WIDTH], int max)
  1165. {
  1166.   int found = 0;
  1167.   char line[MAX_LINE_WIDTH];
  1168.  
  1169.   release_ini_section(ini);
  1170.  
  1171.   if(!ini->fp)
  1172.     return NULL;
  1173.  
  1174.  
  1175.   fseek(ini->fp, 0, SEEK_SET);
  1176.   while(1)
  1177.   {
  1178.     if(!fgets(line, MAX_LINE_WIDTH, ini->fp))
  1179.       return found;
  1180.  
  1181.     strip_string(line);
  1182.  
  1183.     if(line[0] == '[')
  1184.     {
  1185.       if(found < max)
  1186.         strcpy(buffer[found], line);
  1187.       else
  1188.         return 0;  /* more areas than we specified the max was */
  1189.  
  1190.       ++found;
  1191.     }
  1192.   }
  1193. }
  1194.  
  1195.  
  1196.  
  1197.