File:  [Coherent Logic Development] / freem / src / namespace.c
Revision 1.3: download - view: text, annotated - select for diffs
Sun Mar 9 19:50:47 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
Second phase of REUSE compliance and header reformat

/*
 *   $Id: namespace.c,v 1.3 2025/03/09 19:50:47 snw Exp $
 *    Namespace support
 *
 *  
 *   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: namespace.c,v $
 *   Revision 1.3  2025/03/09 19:50:47  snw
 *   Second phase of REUSE compliance and header reformat
 *
 *
 * SPDX-FileCopyrightText:  (C) 2025 Coherent Logic Development LLC
 * SPDX-License-Identifier: AGPL-3.0-or-later
 **/

#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

#include "mpsdef.h"
#include "iniconf.h"
#include "journal.h"
#include "init.h"
#include "namespace.h"

#include <limits.h>

#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(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
# include <sys/syslimits.h>
#endif

#define LOCK        'l'
#define ZDEALLOCATE 'D'

void ns_error(char *ns, char *e)
{
    char msg_buf[256];

    snprintf(msg_buf, 256, "error switching to namespace '%s': %s (possibly a configuration error?)\r\n\201", ns, e);
    write_m(msg_buf);

    return;
}

void set_namespace(char *ns, int verbose)
{
    register int i;
    
    char tmps[256];

    char notif[256];
    char ns_m[256];
    char ns_buf[PATH_MAX];

    char jour_file[PATH_MAX];

    unsigned long cut_threshold = 1073741824; /* default journal cut threshold of 1GiB */
        
    strncpy (ns_m, ns, 256 - 1);
    stcnv_c2m (ns_m);

 
    /* get the root directory of the namespace */
    get_conf (ns, "root", nsroot);

    if(!file_exists (config_file)) {
        snprintf (tmps, 256, "configuration file '%s' does not exist.\n", config_file);
        ns_error (ns, tmps);

        cleanup ();

        exit (1);
    }


    /* turn off all the old so-called "journal" implementation */
    ug_buf[HOME][0] = EOL;
    jour_flag = 0;
    jourfile[0] = NUL;

    /* the real journal file */
    jour_file[0] = NUL;


    /* only read journal config for SYSTEM namespace, as journaling
       is across all namespaces */
   
    /* clear private buffer */
    for(i = 0; i < 256; i++) ns_buf[i] = NUL;

    if(get_conf("SYSTEM", "journal_file", ns_buf) == TRUE) {
        strncpy (jour_file, ns_buf, PATH_MAX);
    }

    if(get_conf("SYSTEM", "journal_host_id", ns_buf) == TRUE) {
        strncpy (jour_hostid, ns_buf, 255);
    }
    else {
        strncpy (jour_hostid, "DEFAULT", 255);
    }

    if(get_conf("SYSTEM", "journal_cut_threshold", ns_buf) == TRUE) {
        cut_threshold = (unsigned long) strtol (ns_buf, NULL, 0);
    }

    /* clear private buffer */
    for(i = 0; i < 256; i++) ns_buf[i] = NUL;

    if(get_conf("SYSTEM", "journal_mode", ns_buf) == TRUE) {

        if(strcmp(ns_buf, "off") == 0) {            
            /* journaling is disabled */    
        }
        else if(strcmp(ns_buf, "on") == 0) {
            
            if (jour_file[0] == NUL) {
                ns_error ("SYSTEM", "journal file undefined while trying to set journal mode");
                goto jour_end;
            }

            jnl_init (jour_file, jour_hostid, cut_threshold, 0);

        }
        else {
            snprintf (tmps, 256, "invalid journal_mode '%s'", ns_buf);
            ns_error ("SYSTEM", tmps);

            goto jour_end;
        }

    }
    

jour_end:


    /* clear private buffer */
    for(i = 0; i < 256; i++) ns_buf[i] = NUL;

    /* set up percent routines -- always in SYSTEM */
    if(get_conf("SYSTEM", "routines_path", ns_buf) != TRUE) {
        ns_error("SYSTEM", "could not get routines_path"); 
    }
    else {   
        stcnv_c2m(ns_buf);
        stcpy(rou0plib, ns_buf); /* Set DO-GOTO-JOB % routine access path */
        stcpy(rou1plib, ns_buf); /* Set ZLOAD-ZSAVE % routine access path */

        /* clear %-routine buffer */
        for (i = 0; i < NO_OF_RBUF; i++) { 
            
            if (pgms[i][0] == '%') {
                
                if (rouptr != (buff + (i * PSIZE0))) { 
                    pgms[i][0] = EOL;
                    ages[i] = 0L;
                }
            
                path[i][0] = EOL;
            }   

        }
    } 

    /* clear private buffer */
    for(i = 0; i < 256; i++) ns_buf[i] = NUL;

    /* set up percent globals -- always in SYSTEM */
    if(get_conf("SYSTEM", "globals_path", ns_buf) != TRUE) {
        ns_error("SYSTEM", "could not get globals_path");
    }
    else {
        stcnv_c2m(ns_buf);
        stcpy(gloplib, ns_buf); /* Set % globals path */

        /* close % globals */
        for (i = 0; i < NO_GLOBLS; i++) {
         
            if (oldfil[i][0] == '%') {
                
                close (olddes[i]);
                
                usage[i] = 0;
                olddes[i] = 0;
                oldfil[i][0] = NUL;
            }
        
        }
    }


    /* set up global engines */
    /* SYSTEM */
    for(i = 0; i < 256; i++) ns_buf[i] = NUL;

    if(get_conf("SYSTEM", "global_engine", ns_buf) == TRUE) {
        global_set_engine ('s', ns_buf);
    }
    else {
        global_set_engine ('s', "BUILTIN");
    }

    /* primary namespace */
    for(i = 0; i < 256; i++) ns_buf[i] = NUL;

    if(get_conf(ns, "global_engine", ns_buf) == TRUE) {
        global_set_engine ('u', ns_buf);
    }
    else {
        global_set_engine ('u', "BUILTIN");
    }
    
    /* set up local engine */
    for(i = 0; i < 256; i++) ns_buf[i] = NUL;

    if(get_conf(ns, "local_engine", ns_buf) == TRUE) {
        sprintf(loc_engine, "%s", ns_buf);
    }
    else {
        sprintf(loc_engine, "BUILTIN");
    }

    
    /* clear private buffer */
    for(i = 0; i < 256; i++) ns_buf[i] = NUL;
    
    /* set up regular routines */
    if(get_conf(ns, "routines_path", ns_buf) != TRUE) {
        if (verbose) {
            ns_error(ns, "could not get routines_path");
        }
        else {
            merr_raise (M26);
            return;
        }
    }
    else {
        stcnv_c2m(ns_buf);
        stcpy(rou0path, ns_buf); /* Set DO-GOTO-JOB routine access path */
        stcpy(rou1path, ns_buf); /* Set ZLOAD-ZSAVE routine access path */

        /* clear routine buffer */
        for (i = 0; i < NO_OF_RBUF; i++) { 
            
            if (pgms[i][0] != '%') {
                
                if (rouptr != (buff + (i * PSIZE0))) { 
                    pgms[i][0] = EOL;
                    ages[i] = 0L;
                }
            
                path[i][0] = EOL;
            }   

        }
    }

    /* clear private buffer */
    for(i = 0; i < 256; i++) ns_buf[i] = NUL;

    /* set up regular globals */
    if (get_conf (ns, "globals_path", ns_buf) != TRUE) {
        if (verbose) {
            ns_error (ns, "could not get globals_path");
        }
        else {
            merr_raise (M26);
            return;
        }
    }
    else {
        stcnv_c2m (ns_buf);
        stcpy (glopath, ns_buf); /* Set globals path */ 

        /* close regular globals 
        for (i = 0; i < NO_GLOBLS; i++) {
         
            if (oldfil[i][0] != '%') {
                
                close (olddes[i]);
                
                usage[i] = 0;
                olddes[i] = 0;
                oldfil[i][0] = NUL;
            }
        
        }
        */
    }

    strcpy (nsname, ns);

    if (verbose == TRUE) {
        snprintf (notif, 256, "Namespace set to '%s'\r\n\201", ns);
        write_m (notif);
    }

}

short validate_namespace (char *nsn_v)
{
    char scratch[256];

    if (get_conf (nsn_v, "routines_path", scratch) == FALSE) return FALSE;
    if (get_conf (nsn_v, "globals_path", scratch) == FALSE) return FALSE;

    return TRUE;
    
}

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