Annotation of freem/src/iniconf.c, revision 1.3

1.1       snw         1: /*
1.3     ! snw         2:  *   $Id$
1.1       snw         3:  *    Function implementations for reading
                      4:  *    FreeM configuration files
                      5:  *
                      6:  *  
1.2       snw         7:  *   Author: Serena Willis <snw@coherent-logic.com>
1.1       snw         8:  *    Copyright (C) 1998 MUG Deutschland
1.3     ! snw         9:  *    Copyright (C) 2020, 2025 Coherent Logic Development LLC
1.1       snw        10:  *
                     11:  *
                     12:  *   This file is part of FreeM.
                     13:  *
                     14:  *   FreeM is free software: you can redistribute it and/or modify
                     15:  *   it under the terms of the GNU Affero Public License as published by
                     16:  *   the Free Software Foundation, either version 3 of the License, or
                     17:  *   (at your option) any later version.
                     18:  *
                     19:  *   FreeM is distributed in the hope that it will be useful,
                     20:  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
                     21:  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     22:  *   GNU Affero Public License for more details.
                     23:  *
                     24:  *   You should have received a copy of the GNU Affero Public License
                     25:  *   along with FreeM.  If not, see <https://www.gnu.org/licenses/>.
                     26:  *
1.3     ! snw        27:  *   $Log$
        !            28:  *
        !            29:  * SPDX-FileCopyrightText:  (C) 2025 Coherent Logic Development LLC
        !            30:  * SPDX-License-Identifier: AGPL-3.0-or-later
1.1       snw        31:  **/
                     32: 
                     33: #define FALSE 0
                     34: #define TRUE 1
                     35: #include <stddef.h>
                     36: #include "iniconf.h"
                     37: #include "libfill.h"
                     38: #include <stdio.h>
                     39: #include <unistd.h>
                     40: #include <sys/types.h>
                     41: #include <pwd.h>
                     42: #include <string.h>
                     43: #include <limits.h>
                     44: #include "mpsdef.h"
                     45: 
                     46: extern char config_file[4096];
                     47: 
                     48: #if !defined(PATH_MAX) && defined(_SCO_DS)
                     49: # define PATH_MAX 4096
                     50: #endif
                     51: 
                     52: #if !defined(PATH_MAX) && defined(__gnu_hurd__)
                     53: # define PATH_MAX 1024
                     54: #endif
                     55: 
                     56: #if !defined(PATH_MAX) && defined(_AIX)
                     57: # define PATH_MAX 1024
                     58: #endif
                     59: 
                     60: #if defined(__NetBSD__) || defined(__FreeBSD__)
                     61: # include <sys/syslimits.h>
                     62: #endif
                     63: 
                     64: ini_keyvalue *ini_head;
                     65: 
                     66: /* prototypes for internal-use-only functions */
                     67: int read_profile_string(char *file, char *section, char *key, char *value);
                     68: 
                     69: int get_conf(char *section, char *key, char *value)
                     70: {
                     71:     char *etcfile;
                     72:     char *dotfile;
                     73:     char *homedir;
                     74: 
                     75:     int exists_in_etc = FALSE;
                     76:     int exists_in_dotfile = FALSE;
                     77:     int dotexists;
                     78:     int etcexists;
                     79: 
                     80:     char *etc_value;
                     81:     char *dot_value;
                     82:     
                     83:     etc_value = (char *) malloc(CONF_BUFSIZE);
                     84:     NULLPTRCHK(etc_value,"get_conf");
                     85:     dot_value = (char *) malloc(CONF_BUFSIZE);
                     86:     NULLPTRCHK(dot_value,"get_conf");
                     87:     
                     88:     etcfile = config_file;
                     89: 
                     90: 
                     91: #if !defined(__AMIGA) && !defined(_SCO_DS) && !defined(_AIX)
                     92:     uid_t uid = geteuid();
                     93:     struct passwd *pw = getpwuid(uid);
                     94: 
                     95:     if (pw == NULL) {
                     96:         free (etc_value);
                     97:         free (dot_value);
                     98: 
                     99:         return (FALSE);
                    100:     }
                    101: 
                    102:     homedir = (char *) calloc(strlen(pw->pw_dir) + 1, sizeof(char));
                    103:     NULLPTRCHK(homedir,"get_conf");
                    104:     
                    105:     (void) strcpy(homedir, pw->pw_dir);
                    106: 
                    107:     dotfile = calloc(PATH_MAX, sizeof(char));
                    108:     NULLPTRCHK(dotfile,"get_conf");
                    109:     
                    110:     (void) strcat(dotfile, homedir);
                    111:     (void) strcat(dotfile, "/.freemrc");
                    112: 
                    113:     etcexists = file_exists(etcfile);
                    114:     dotexists = file_exists(dotfile);
                    115: #else
                    116: 
                    117: #if defined(__AMIGA)
                    118:     strcpy (etcfile, "./freem.conf");
                    119:     etcexists = TRUE;
                    120:     dotexists = FALSE;
                    121: #else
                    122:     strcpy (etcfile, SYSCONFDIR"/freem.conf");
                    123:     
                    124:     etcexists = TRUE;
                    125:     dotexists = FALSE;
                    126: #endif
                    127: 
                    128: #endif
                    129: 
                    130:     if (etcexists == TRUE) {
                    131:         exists_in_etc = read_profile_string(etcfile, section, key, etc_value);
                    132:     }
                    133:     else {
                    134:         exists_in_etc = FALSE;
                    135:     }
                    136: 
                    137:     if (dotexists == TRUE) {
                    138:         exists_in_dotfile = read_profile_string(dotfile, section, key, dot_value);
                    139:     }
                    140:     else {
                    141:         exists_in_dotfile = FALSE;
                    142:     }
                    143: 
                    144:     if (exists_in_dotfile) {
                    145:         strcpy (value, dot_value);
                    146: 
                    147:         free (etc_value);
                    148:         free (dot_value);
                    149: #if !defined(__AMIGA) && !defined(_SCO_DS) && !defined(_AIX)
                    150:         free (homedir);
                    151:         free (dotfile);
                    152: #endif
                    153:         
                    154:         return (TRUE);
                    155:     }
                    156: 
                    157:     if (exists_in_etc) {
                    158:         strcpy(value, etc_value);
                    159: 
                    160:         free (etc_value);
                    161:         free (dot_value);
                    162: #if !defined(__AMIGA) && !defined(_SCO_DS) && !defined(_AIX)        
                    163:         free (homedir);
                    164:         free (dotfile);
                    165: #endif        
                    166: 
                    167:         return (TRUE);
                    168:     }
                    169: 
                    170:     free (etc_value);
                    171:     free (dot_value);
                    172: #if !defined(__AMIGA) && !defined(_SCO_DS) && !defined(_AIX)    
                    173:     free (homedir);
                    174:     free (dotfile);
                    175: #endif
                    176: 
                    177:     return (FALSE); /* didn't exist anywhere */
                    178: }
                    179: 
                    180: int read_profile_string(char *file, char *section, char *key, char *value)
                    181: {
                    182: 
                    183:     register int i;
                    184: 
                    185:     FILE *fp;
                    186:     
                    187:     char *curkey;
                    188:     char *curval;
                    189:     char *fullsec;
                    190:     char *cursec;
                    191:     char *line;
                    192:     int lnum = 0;
                    193:     
                    194:     fullsec = (char *) malloc(CONF_BUFSIZE);
                    195:     NULLPTRCHK(fullsec,"read_profile_string");
                    196: 
                    197:     cursec = (char *) malloc(CONF_BUFSIZE);
                    198:     NULLPTRCHK(cursec,"read_profile_string");
                    199:     
                    200:     line = (char *) malloc(CONF_BUFSIZE);
                    201:     NULLPTRCHK(line,"read_profile_string");
                    202: 
                    203: 
                    204: 
                    205: 
                    206:     snprintf(fullsec, CONF_BUFSIZE, "[%s]%c", section, '\0');
                    207: 
                    208:     strcpy(cursec, "[]");
                    209: 
                    210: 
                    211:     fp = fopen(file, "r");
                    212: 
                    213:     while(fgets(line, CONF_BUFSIZE, fp) != NULL) {
                    214:         ++lnum;
                    215: 
                    216:         if(line[0] == '[') {
                    217:             strcpy(cursec, line);
                    218: 
                    219:             for(i = 0; i < CONF_BUFSIZE; i++) {
                    220:                 if(cursec[i] == ']') {
                    221:                     cursec[i + 1] = '\0';
                    222:                     break;
                    223:                 }
                    224:             }
                    225:         }
                    226:         else {
                    227:             if ((line[0] != '[') && (strchr(line, '=') != NULL)) {
                    228:                 curkey = strtok(line, "=");
                    229:                 curval = strtok(NULL, "=");  
                    230:                 curval = strtok(curval, "\n");
                    231:        
                    232: 
                    233:                 if((strcmp(curkey, key) == 0) && (strcmp(cursec, fullsec) == 0)) {                                                
                    234:                     strcpy(value, curval);
                    235:                     (void) fclose(fp);
                    236: 
                    237:                     free (fullsec);
                    238:                     free (curkey);
                    239:                     free (cursec);
                    240:                     
                    241:                     return(TRUE);
                    242:                 }
                    243:             }
                    244:         }        
                    245: 
                    246:     }
                    247: 
                    248:     if (fp != NULL) {
                    249:         (void) fclose(fp);
                    250:     }
                    251: 
                    252:     /* if we've gotten here, the section and/or key was not found */
                    253:     sprintf (value, "\0");
                    254: 
                    255:     free (fullsec);
                    256:     free (curkey);
                    257:     free (cursec);
                    258: 
                    259:     return(FALSE);
                    260: 
                    261: }
                    262: 
                    263: int file_exists(char *filename)
                    264: {
                    265:     FILE *fp;
                    266: 
                    267:     if ((fp = fopen(filename, "r")) != NULL) {
                    268:         (void) fclose(fp);
                    269:         
                    270:         return(TRUE);
                    271:     }
                    272:     else {
                    273:         return(FALSE);
                    274:     } 
                    275: }
                    276: 
                    277: void write_profile_string(char *file, char *section, char *key, char *value)
                    278: {
                    279:     ini_keyvalue *ini_head;
                    280:     
                    281: }
                    282: 
                    283: ini_keyvalue *ini_insert(ini_section *s, char *section, char *key, char *value)
                    284: {
                    285:     ini_section *t;
                    286:     
                    287:     for (t = s; t != NULL; t = t->next) {
                    288: 
                    289:        if (strcmp (t->name, section) == 0) {
                    290: 
                    291:            /* this section already exists. update. */
                    292:            return ini_kv_insert (s, key, value);
                    293:            
                    294:        }
                    295: 
                    296:     }
                    297: 
                    298:     /* section does not exist. insert. */
                    299:     t = (ini_section *) malloc (sizeof (ini_section));
                    300:     NULLPTRCHK(t,"ini_insert");
                    301:     
                    302:     t->name = (char *) malloc ((strlen (section) + 1) * sizeof (char));
                    303:     NULLPTRCHK(t->name,"ini_insert");
                    304:     
                    305:     strcpy (t->name, section);
                    306: 
                    307:     t->next = s;
                    308:     s = t;
                    309: 
                    310:     return ini_kv_insert (s, key, value);
                    311: 
                    312: }
                    313: 
                    314: ini_keyvalue *ini_kv_insert(ini_section *s, char *key, char *value)
                    315: {
                    316:     ini_keyvalue *t;
                    317: 
                    318:     for (t = s->head; t != NULL; t = t->next) {
                    319: 
                    320:        if (strcmp (t->key, key) == 0) {
                    321: 
                    322:            /* this is an update */
                    323:            free (t->value);
                    324:            t->value = (char *) malloc ((strlen (value) + 1) * sizeof (char));
                    325:            NULLPTRCHK(t->value,"ini_kv_insert");
                    326:            
                    327:            strcpy (t->value, value);
                    328: 
                    329:            return t;
                    330: 
                    331:        }
                    332: 
                    333:     }
                    334: 
                    335:     /* this is an insert */
                    336:     t = (ini_keyvalue *) malloc (sizeof (ini_keyvalue));
                    337:     NULLPTRCHK(t,"ini_kv_insert");
                    338:     
                    339:     t->key = (char *) malloc ((strlen (key) + 1) * sizeof (char));
                    340:     NULLPTRCHK(t->key,"ini_kv_insert");
                    341:     
                    342:     t->value = (char *) malloc ((strlen (value) + 1) * sizeof (char));
                    343:     NULLPTRCHK(t->value,"ini_kv_insert");
                    344:     
                    345:     strcpy (t->key, key);
                    346:     strcpy (t->value, value);
                    347: 
                    348:     t->next = s->head;
                    349:     s->head = t;
                    350: 
                    351:     return t;
                    352:     
                    353: }
                    354: 
                    355: void ini_section_delete(ini_section *head, char *name)
                    356: {
                    357:     ini_section *t = head;
                    358:     ini_section *p = NULL;
                    359: 
                    360:     if ((t != (ini_section *) NULL) && (strcmp (t->name, name) == 0)) {
                    361:        head = t->next;
                    362: 
                    363:        free (t->name);
                    364:        free (t);
                    365:        return;
                    366:     }
                    367: 
                    368:     while ((t != NULL) && (strcmp (t->name, name) != 0)) {
                    369:        p = t;
                    370:        t = t->next;
                    371:     }
                    372: 
                    373:     if (t == NULL) return;
                    374:     
                    375:     free (t->name);
                    376:     free (t);
                    377: 
                    378:     return;    
                    379: }
                    380: 
                    381: void ini_key_delete(ini_section *head, char *key)
                    382: {
                    383: 
                    384: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>