/*
* $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>