1: /*
2: * $Id: namespace.c,v 1.6 2025/04/13 04:22:43 snw Exp $
3: * Namespace support
4: *
5: *
6: * Author: Serena Willis <snw@coherent-logic.com>
7: * Copyright (C) 1998 MUG Deutschland
8: * Copyright (C) 2020, 2025 Coherent Logic Development LLC
9: *
10: *
11: * This file is part of FreeM.
12: *
13: * FreeM is free software: you can redistribute it and/or modify
14: * it under the terms of the GNU Affero Public License as published by
15: * the Free Software Foundation, either version 3 of the License, or
16: * (at your option) any later version.
17: *
18: * FreeM is distributed in the hope that it will be useful,
19: * but WITHOUT ANY WARRANTY; without even the implied warranty of
20: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21: * GNU Affero Public License for more details.
22: *
23: * You should have received a copy of the GNU Affero Public License
24: * along with FreeM. If not, see <https://www.gnu.org/licenses/>.
25: *
26: * $Log: namespace.c,v $
27: * Revision 1.6 2025/04/13 04:22:43 snw
28: * Fix snprintf calls
29: *
30: * Revision 1.5 2025/04/09 19:52:02 snw
31: * Eliminate as many warnings as possible while building with -Wall
32: *
33: * Revision 1.4 2025/04/02 03:02:42 snw
34: * Stop requiring users to pass -e to fmadm when -u or -g are passed
35: *
36: * Revision 1.3 2025/03/09 19:50:47 snw
37: * Second phase of REUSE compliance and header reformat
38: *
39: *
40: * SPDX-FileCopyrightText: (C) 2025 Coherent Logic Development LLC
41: * SPDX-License-Identifier: AGPL-3.0-or-later
42: **/
43:
44: #include <stddef.h>
45: #include <stdio.h>
46: #include <string.h>
47: #include <unistd.h>
48: #include <stdlib.h>
49:
50: #include "mpsdef.h"
51: #include "iniconf.h"
52: #include "journal.h"
53: #include "init.h"
54: #include "namespace.h"
55:
56: #include <limits.h>
57:
58: #if !defined(PATH_MAX) && defined(_SCO_DS)
59: # define PATH_MAX 4096
60: #endif
61:
62: #if !defined(PATH_MAX) && defined(__gnu_hurd__)
63: # define PATH_MAX 1024
64: #endif
65:
66: #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
67: # include <sys/syslimits.h>
68: #endif
69:
70: #define LOCK 'l'
71:
72: void ns_error(char *ns, char *e)
73: {
74: char msg_buf[256];
75:
76: snprintf(msg_buf, sizeof (msg_buf) - 1, "error switching to namespace '%s': %s (possibly a configuration error?)\r\n\201", ns, e);
77: write_m(msg_buf);
78:
79: return;
80: }
81:
82: void set_namespace(char *ns, int verbose)
83: {
84: register int i;
85:
86: char tmps[256];
87:
88: char notif[256];
89: char ns_m[256];
90: char ns_buf[PATH_MAX];
91:
92: char jour_file[PATH_MAX];
93:
94: unsigned long cut_threshold = 1073741824; /* default journal cut threshold of 1GiB */
95:
96: strncpy (ns_m, ns, 256 - 1);
97: stcnv_c2m (ns_m);
98:
99:
100: /* get the root directory of the namespace */
101: get_conf (ns, "root", nsroot);
102:
103: if(!file_exists (config_file)) {
104: snprintf (tmps, sizeof (tmps) - 1, "configuration file '%s' does not exist.\n", config_file);
105: ns_error (ns, tmps);
106:
107: cleanup ();
108:
109: exit (1);
110: }
111:
112:
113: /* turn off all the old so-called "journal" implementation */
114: ug_buf[HOME][0] = EOL;
115: jour_flag = 0;
116:
117: /* the real journal file */
118: jour_file[0] = NUL;
119:
120:
121: /* only read journal config for SYSTEM namespace, as journaling
122: is across all namespaces */
123:
124: /* clear private buffer */
125: for(i = 0; i < 256; i++) ns_buf[i] = NUL;
126:
127: if(get_conf("SYSTEM", "journal_file", ns_buf) == TRUE) {
128: strncpy (jour_file, ns_buf, PATH_MAX);
129: }
130:
131: if(get_conf("SYSTEM", "journal_host_id", ns_buf) == TRUE) {
132: strncpy (jour_hostid, ns_buf, 255);
133: }
134: else {
135: strncpy (jour_hostid, "DEFAULT", 255);
136: }
137:
138: if(get_conf("SYSTEM", "journal_cut_threshold", ns_buf) == TRUE) {
139: cut_threshold = (unsigned long) strtol (ns_buf, NULL, 0);
140: }
141:
142: /* clear private buffer */
143: for(i = 0; i < 256; i++) ns_buf[i] = NUL;
144:
145: if(get_conf("SYSTEM", "journal_mode", ns_buf) == TRUE) {
146:
147: if(strcmp(ns_buf, "off") == 0) {
148: /* journaling is disabled */
149: }
150: else if(strcmp(ns_buf, "on") == 0) {
151:
152: if (jour_file[0] == NUL) {
153: ns_error ("SYSTEM", "journal file undefined while trying to set journal mode");
154: goto jour_end;
155: }
156:
157: jnl_init (jour_file, jour_hostid, cut_threshold, 0);
158:
159: }
160: else {
161: snprintf (tmps, sizeof (tmps) - 1, "invalid journal_mode '%s'", ns_buf);
162: ns_error ("SYSTEM", tmps);
163:
164: goto jour_end;
165: }
166:
167: }
168:
169:
170: jour_end:
171:
172:
173: /* clear private buffer */
174: for(i = 0; i < 256; i++) ns_buf[i] = NUL;
175:
176: /* set up percent routines -- always in SYSTEM */
177: if(get_conf("SYSTEM", "routines_path", ns_buf) != TRUE) {
178: ns_error("SYSTEM", "could not get routines_path");
179: }
180: else {
181: stcnv_c2m(ns_buf);
182: stcpy(rou0plib, ns_buf); /* Set DO-GOTO-JOB % routine access path */
183: stcpy(rou1plib, ns_buf); /* Set ZLOAD-ZSAVE % routine access path */
184:
185: /* clear %-routine buffer */
186: for (i = 0; i < NO_OF_RBUF; i++) {
187:
188: if (pgms[i][0] == '%') {
189:
190: if (rouptr != (buff + (i * PSIZE0))) {
191: pgms[i][0] = EOL;
192: ages[i] = 0L;
193: }
194:
195: path[i][0] = EOL;
196: }
197:
198: }
199: }
200:
201: /* clear private buffer */
202: for(i = 0; i < 256; i++) ns_buf[i] = NUL;
203:
204: /* set up percent globals -- always in SYSTEM */
205: if(get_conf("SYSTEM", "globals_path", ns_buf) != TRUE) {
206: ns_error("SYSTEM", "could not get globals_path");
207: }
208: else {
209: stcnv_c2m(ns_buf);
210: stcpy(gloplib, ns_buf); /* Set % globals path */
211:
212: /* close % globals */
213: for (i = 0; i < NO_GLOBLS; i++) {
214:
215: if (oldfil[i][0] == '%') {
216:
217: close (olddes[i]);
218:
219: usage[i] = 0;
220: olddes[i] = 0;
221: oldfil[i][0] = NUL;
222: }
223:
224: }
225: }
226:
227:
228: /* set up global engines */
229: /* SYSTEM */
230: for(i = 0; i < 256; i++) ns_buf[i] = NUL;
231:
232: if(get_conf("SYSTEM", "global_engine", ns_buf) == TRUE) {
233: global_set_engine ('s', ns_buf);
234: }
235: else {
236: global_set_engine ('s', "BUILTIN");
237: }
238:
239: /* primary namespace */
240: for(i = 0; i < 256; i++) ns_buf[i] = NUL;
241:
242: if(get_conf(ns, "global_engine", ns_buf) == TRUE) {
243: global_set_engine ('u', ns_buf);
244: }
245: else {
246: global_set_engine ('u', "BUILTIN");
247: }
248:
249: /* set up local engine */
250: for(i = 0; i < 256; i++) ns_buf[i] = NUL;
251:
252: if(get_conf (ns, "local_engine", ns_buf) == TRUE) {
253: snprintf (loc_engine, sizeof (loc_engine), "%s", ns_buf);
254: }
255: else {
256: sprintf (loc_engine, "BUILTIN");
257: }
258:
259:
260: /* clear private buffer */
261: for(i = 0; i < 256; i++) ns_buf[i] = NUL;
262:
263: /* set up regular routines */
264: if(get_conf(ns, "routines_path", ns_buf) != TRUE) {
265: if (verbose) {
266: ns_error(ns, "could not get routines_path");
267: }
268: else {
269: merr_raise (M26);
270: return;
271: }
272: }
273: else {
274: stcnv_c2m(ns_buf);
275: stcpy(rou0path, ns_buf); /* Set DO-GOTO-JOB routine access path */
276: stcpy(rou1path, ns_buf); /* Set ZLOAD-ZSAVE routine access path */
277:
278: /* clear routine buffer */
279: for (i = 0; i < NO_OF_RBUF; i++) {
280:
281: if (pgms[i][0] != '%') {
282:
283: if (rouptr != (buff + (i * PSIZE0))) {
284: pgms[i][0] = EOL;
285: ages[i] = 0L;
286: }
287:
288: path[i][0] = EOL;
289: }
290:
291: }
292: }
293:
294: /* clear private buffer */
295: for(i = 0; i < 256; i++) ns_buf[i] = NUL;
296:
297: /* set up regular globals */
298: if (get_conf (ns, "globals_path", ns_buf) != TRUE) {
299: if (verbose) {
300: ns_error (ns, "could not get globals_path");
301: }
302: else {
303: merr_raise (M26);
304: return;
305: }
306: }
307: else {
308: stcnv_c2m (ns_buf);
309: stcpy (glopath, ns_buf); /* Set globals path */
310:
311: /* close regular globals
312: for (i = 0; i < NO_GLOBLS; i++) {
313:
314: if (oldfil[i][0] != '%') {
315:
316: close (olddes[i]);
317:
318: usage[i] = 0;
319: olddes[i] = 0;
320: oldfil[i][0] = NUL;
321: }
322:
323: }
324: */
325: }
326:
327: strcpy (nsname, ns);
328:
329: if (verbose == TRUE) {
330: snprintf (notif, sizeof (notif) - 1, "Namespace set to '%s'\r\n\201", ns);
331: write_m (notif);
332: }
333:
334: }
335:
336: short validate_namespace (char *nsn_v)
337: {
338: char scratch[256];
339:
340: if (get_conf (nsn_v, "routines_path", scratch) == FALSE) return FALSE;
341: if (get_conf (nsn_v, "globals_path", scratch) == FALSE) return FALSE;
342:
343: return TRUE;
344:
345: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>