File:  [Coherent Logic Development] / freem / src / iniconf.c
Revision 1.3: download - view: text, annotated - select for diffs
Sun Mar 9 19:14:25 2025 UTC (12 months, 3 weeks ago) by snw
Branches: MAIN
CVS tags: v0-62-3, v0-62-2, v0-62-1, v0-62-0, HEAD
First phase of REUSE compliance and header reformat

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

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