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 (3 weeks, 2 days 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

/*
 *   $Id: iniconf.c,v 1.3 2025/03/09 19:14:25 snw Exp $
 *    Function implementations for reading
 *    FreeM configuration files
 *
 *  
 *   Author: Serena Willis <snw@coherent-logic.com>
 *    Copyright (C) 1998 MUG Deutschland
 *    Copyright (C) 2020, 2025 Coherent Logic Development LLC
 *
 *
 *   This file is part of FreeM.
 *
 *   FreeM is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   FreeM is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero Public License for more details.
 *
 *   You should have received a copy of the GNU Affero Public License
 *   along with FreeM.  If not, see <https://www.gnu.org/licenses/>.
 *
 *   $Log: iniconf.c,v $
 *   Revision 1.3  2025/03/09 19:14:25  snw
 *   First phase of REUSE compliance and header reformat
 *
 *
 * SPDX-FileCopyrightText:  (C) 2025 Coherent Logic Development LLC
 * SPDX-License-Identifier: AGPL-3.0-or-later
 **/

#define FALSE 0
#define TRUE 1
#include <stddef.h>
#include "iniconf.h"
#include "libfill.h"
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <string.h>
#include <limits.h>
#include "mpsdef.h"

extern char config_file[4096];

#if !defined(PATH_MAX) && defined(_SCO_DS)
# define PATH_MAX 4096
#endif

#if !defined(PATH_MAX) && defined(__gnu_hurd__)
# define PATH_MAX 1024
#endif

#if !defined(PATH_MAX) && defined(_AIX)
# define PATH_MAX 1024
#endif

#if defined(__NetBSD__) || defined(__FreeBSD__)
# include <sys/syslimits.h>
#endif

ini_keyvalue *ini_head;

/* prototypes for internal-use-only functions */
int read_profile_string(char *file, char *section, char *key, char *value);

int get_conf(char *section, char *key, char *value)
{
    char *etcfile;
    char *dotfile;
    char *homedir;

    int exists_in_etc = FALSE;
    int exists_in_dotfile = FALSE;
    int dotexists;
    int etcexists;

    char *etc_value;
    char *dot_value;
    
    etc_value = (char *) malloc(CONF_BUFSIZE);
    NULLPTRCHK(etc_value,"get_conf");
    dot_value = (char *) malloc(CONF_BUFSIZE);
    NULLPTRCHK(dot_value,"get_conf");
    
    etcfile = config_file;


#if !defined(__AMIGA) && !defined(_SCO_DS) && !defined(_AIX)
    uid_t uid = geteuid();
    struct passwd *pw = getpwuid(uid);

    if (pw == NULL) {
        free (etc_value);
        free (dot_value);

        return (FALSE);
    }

    homedir = (char *) calloc(strlen(pw->pw_dir) + 1, sizeof(char));
    NULLPTRCHK(homedir,"get_conf");
    
    (void) strcpy(homedir, pw->pw_dir);

    dotfile = calloc(PATH_MAX, sizeof(char));
    NULLPTRCHK(dotfile,"get_conf");
    
    (void) strcat(dotfile, homedir);
    (void) strcat(dotfile, "/.freemrc");

    etcexists = file_exists(etcfile);
    dotexists = file_exists(dotfile);
#else

#if defined(__AMIGA)
    strcpy (etcfile, "./freem.conf");
    etcexists = TRUE;
    dotexists = FALSE;
#else
    strcpy (etcfile, SYSCONFDIR"/freem.conf");
    
    etcexists = TRUE;
    dotexists = FALSE;
#endif

#endif

    if (etcexists == TRUE) {
        exists_in_etc = read_profile_string(etcfile, section, key, etc_value);
    }
    else {
        exists_in_etc = FALSE;
    }

    if (dotexists == TRUE) {
        exists_in_dotfile = read_profile_string(dotfile, section, key, dot_value);
    }
    else {
        exists_in_dotfile = FALSE;
    }

    if (exists_in_dotfile) {
        strcpy (value, dot_value);

        free (etc_value);
        free (dot_value);
#if !defined(__AMIGA) && !defined(_SCO_DS) && !defined(_AIX)
        free (homedir);
        free (dotfile);
#endif
        
        return (TRUE);
    }

    if (exists_in_etc) {
        strcpy(value, etc_value);

        free (etc_value);
        free (dot_value);
#if !defined(__AMIGA) && !defined(_SCO_DS) && !defined(_AIX)        
        free (homedir);
        free (dotfile);
#endif        

        return (TRUE);
    }

    free (etc_value);
    free (dot_value);
#if !defined(__AMIGA) && !defined(_SCO_DS) && !defined(_AIX)    
    free (homedir);
    free (dotfile);
#endif

    return (FALSE); /* didn't exist anywhere */
}

int read_profile_string(char *file, char *section, char *key, char *value)
{

    register int i;

    FILE *fp;
    
    char *curkey;
    char *curval;
    char *fullsec;
    char *cursec;
    char *line;
    int lnum = 0;
    
    fullsec = (char *) malloc(CONF_BUFSIZE);
    NULLPTRCHK(fullsec,"read_profile_string");

    cursec = (char *) malloc(CONF_BUFSIZE);
    NULLPTRCHK(cursec,"read_profile_string");
    
    line = (char *) malloc(CONF_BUFSIZE);
    NULLPTRCHK(line,"read_profile_string");




    snprintf(fullsec, CONF_BUFSIZE, "[%s]%c", section, '\0');

    strcpy(cursec, "[]");


    fp = fopen(file, "r");

    while(fgets(line, CONF_BUFSIZE, fp) != NULL) {
        ++lnum;

        if(line[0] == '[') {
            strcpy(cursec, line);

            for(i = 0; i < CONF_BUFSIZE; i++) {
                if(cursec[i] == ']') {
                    cursec[i + 1] = '\0';
                    break;
                }
            }
        }
        else {
            if ((line[0] != '[') && (strchr(line, '=') != NULL)) {
                curkey = strtok(line, "=");
                curval = strtok(NULL, "=");  
                curval = strtok(curval, "\n");
       

                if((strcmp(curkey, key) == 0) && (strcmp(cursec, fullsec) == 0)) {                                                
                    strcpy(value, curval);
                    (void) fclose(fp);

                    free (fullsec);
                    free (curkey);
                    free (cursec);
                    
                    return(TRUE);
                }
            }
        }        

    }

    if (fp != NULL) {
        (void) fclose(fp);
    }

    /* if we've gotten here, the section and/or key was not found */
    sprintf (value, "\0");

    free (fullsec);
    free (curkey);
    free (cursec);

    return(FALSE);

}

int file_exists(char *filename)
{
    FILE *fp;

    if ((fp = fopen(filename, "r")) != NULL) {
        (void) fclose(fp);
        
        return(TRUE);
    }
    else {
        return(FALSE);
    } 
}

void write_profile_string(char *file, char *section, char *key, char *value)
{
    ini_keyvalue *ini_head;
    
}

ini_keyvalue *ini_insert(ini_section *s, char *section, char *key, char *value)
{
    ini_section *t;
    
    for (t = s; t != NULL; t = t->next) {

	if (strcmp (t->name, section) == 0) {

	    /* this section already exists. update. */
	    return ini_kv_insert (s, key, value);
	    
	}

    }

    /* section does not exist. insert. */
    t = (ini_section *) malloc (sizeof (ini_section));
    NULLPTRCHK(t,"ini_insert");
    
    t->name = (char *) malloc ((strlen (section) + 1) * sizeof (char));
    NULLPTRCHK(t->name,"ini_insert");
    
    strcpy (t->name, section);

    t->next = s;
    s = t;

    return ini_kv_insert (s, key, value);

}

ini_keyvalue *ini_kv_insert(ini_section *s, char *key, char *value)
{
    ini_keyvalue *t;

    for (t = s->head; t != NULL; t = t->next) {

	if (strcmp (t->key, key) == 0) {

	    /* this is an update */
	    free (t->value);
	    t->value = (char *) malloc ((strlen (value) + 1) * sizeof (char));
	    NULLPTRCHK(t->value,"ini_kv_insert");
	    
	    strcpy (t->value, value);

	    return t;

	}

    }

    /* this is an insert */
    t = (ini_keyvalue *) malloc (sizeof (ini_keyvalue));
    NULLPTRCHK(t,"ini_kv_insert");
    
    t->key = (char *) malloc ((strlen (key) + 1) * sizeof (char));
    NULLPTRCHK(t->key,"ini_kv_insert");
    
    t->value = (char *) malloc ((strlen (value) + 1) * sizeof (char));
    NULLPTRCHK(t->value,"ini_kv_insert");
    
    strcpy (t->key, key);
    strcpy (t->value, value);

    t->next = s->head;
    s->head = t;

    return t;
    
}

void ini_section_delete(ini_section *head, char *name)
{
    ini_section *t = head;
    ini_section *p = NULL;

    if ((t != (ini_section *) NULL) && (strcmp (t->name, name) == 0)) {
	head = t->next;

	free (t->name);
	free (t);
	return;
    }

    while ((t != NULL) && (strcmp (t->name, name) != 0)) {
	p = t;
	t = t->next;
    }

    if (t == NULL) return;
    
    free (t->name);
    free (t);

    return;	
}

void ini_key_delete(ini_section *head, char *key)
{

}

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