Annotation of freem/src/fmadm.c, revision 1.23
1.1 snw 1: /*
1.23 ! snw 2: * $Id: fmadm.c,v 1.22 2025/04/01 23:21:45 snw Exp $
1.1 snw 3: * FreeM Administration Tool
4: *
5: *
1.6 snw 6: * Author: Serena Willis <snw@coherent-logic.com>
1.1 snw 7: * Copyright (C) 1998 MUG Deutschland
1.7 snw 8: * Copyright (C) 2020, 2023, 2025 Coherent Logic Development LLC
1.1 snw 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: *
1.8 snw 26: * $Log: fmadm.c,v $
1.23 ! snw 27: * Revision 1.22 2025/04/01 23:21:45 snw
! 28: * fmadm commands for stopping, starting, and restarting environments now functional
! 29: *
1.22 snw 30: * Revision 1.21 2025/04/01 20:11:46 snw
31: * Further work on fmadm
32: *
1.21 snw 33: * Revision 1.20 2025/04/01 16:37:12 snw
34: * Configure DEFAULT environment the same as others, and set permissions/ownership directly in fmadm configure. Add env.conf file as a centralized configuration listing all environments.
35: *
1.20 snw 36: * Revision 1.19 2025/04/01 14:32:11 snw
37: * Begin work on environment and namespace reorg
38: *
1.19 snw 39: * Revision 1.18 2025/03/31 16:33:56 snw
40: * Work on fmadm edit global
41: *
1.18 snw 42: * Revision 1.17 2025/03/30 01:36:58 snw
43: * Make it easier to bring back fma_gedit, fix double-free in global handler, limit $CHAR to 7-bit ASCII
44: *
1.17 snw 45: * Revision 1.16 2025/03/24 20:59:58 snw
46: * Try using DosCopy API instead of built-in cp function on OS/2
47: *
1.16 snw 48: * Revision 1.15 2025/03/24 20:58:05 snw
49: * Try using DosCopy API instead of built-in cp function on OS/2
50: *
1.15 snw 51: * Revision 1.14 2025/03/24 20:57:06 snw
52: * Try using DosCopy API instead of built-in cp function on OS/2
53: *
1.14 snw 54: * Revision 1.13 2025/03/24 20:15:09 snw
55: * Set file permissions on freemd.exe on OS/2 in fmadm configure
56: *
1.13 snw 57: * Revision 1.12 2025/03/24 20:13:34 snw
58: * Set file permissions on freemd.exe on OS/2 in fmadm configure
59: *
1.12 snw 60: * Revision 1.11 2025/03/24 19:25:48 snw
61: * Make fmadm configure copy freem.exe to freemd.exe for daemon operation on OS/2 systems
62: *
1.11 snw 63: * Revision 1.10 2025/03/24 19:22:16 snw
64: * Make fmadm configure copy freem.exe to freemd.exe for daemon operation on OS/2 systems
65: *
1.10 snw 66: * Revision 1.9 2025/03/24 19:19:42 snw
67: * Make fmadm configure copy freem.exe to freemd.exe for daemon operation on OS/2 systems
68: *
1.9 snw 69: * Revision 1.8 2025/03/22 18:43:54 snw
70: * Make STRLEN 255 chars and add BIGSTR macro for larger buffers
71: *
1.8 snw 72: * Revision 1.7 2025/03/09 19:14:25 snw
73: * First phase of REUSE compliance and header reformat
74: *
1.7 snw 75: *
76: * SPDX-FileCopyrightText: (C) 2025 Coherent Logic Development LLC
77: * SPDX-License-Identifier: AGPL-3.0-or-later
1.1 snw 78: **/
79:
80: #include <sys/types.h>
81: #include <sys/stat.h>
1.19 snw 82: #include <pwd.h>
83: #include <grp.h>
1.1 snw 84: #include <stddef.h>
85: #include <stdio.h>
86: #include <string.h>
87: #include <dirent.h>
88: #include <stdlib.h>
89: #include <unistd.h>
90: #include <errno.h>
1.4 snw 91: #include <ctype.h>
1.1 snw 92: #include "config.h"
93: #include "transact.h"
94: #include "namespace.h"
95: #include "fs.h"
96:
1.14 snw 97: #if defined(__OS2__)
98: # include <os2.h>
99: #endif
100:
1.1 snw 101: #ifdef HAVE_LIBREADLINE
102: # if defined(HAVE_READLINE_READLINE_H)
103: # include <readline/readline.h>
104: # elif defined(HAVE_READLINE_H)
105: # include <readline.h>
106: # else /* !defined(HAVE_READLINE_H) */
107: extern char *readline ();
108: # endif /* !defined(HAVE_READLINE_H) */
109: /*char *cmdline = NULL;*/
110: #else /* !defined(HAVE_READLINE_READLINE_H) */
111: /* no readline */
112: #endif /* HAVE_LIBREADLINE */
113:
114: #ifdef HAVE_READLINE_HISTORY
115: # if defined(HAVE_READLINE_HISTORY_H)
116: # include <readline/history.h>
117: # elif defined(HAVE_HISTORY_H)
118: # include <history.h>
119: # else /* !defined(HAVE_HISTORY_H) */
120: extern void add_history ();
121: extern int write_history ();
122: extern int read_history ();
123: # endif /* defined(HAVE_READLINE_HISTORY_H) */
124: /* no history */
125: #endif /* HAVE_READLINE_HISTORY */
126:
127:
128: #include "fmadm.h"
129: #include "errmsg.h"
130: #include "iniconf.h"
131: #include "init.h"
132: #include "version.h"
133: #include "shmmgr.h"
134: #include "jobtab.h"
135: #include "locktab.h"
136:
137: /* namespace configuration */
138: char fma_environment[STRLEN];
139: char fma_namespace[STRLEN];
1.8 snw 140: char fma_routine_path[PATHLEN];
141: char fma_global_path[PATHLEN];
142: char fma_journal_path[PATHLEN];
143: char fma_pct_global_path[PATHLEN];
144: char fma_pct_routine_path[PATHLEN];
1.1 snw 145: char fma_journal_cut_threshold[STRLEN];
1.8 snw 146: char fma_locktab[PATHLEN];
1.1 snw 147: short fma_base_opt = 1;
148: short fma_min_args = 2;
149: short fma_explicit_namespace = FALSE;
150: short fma_explicit_environment = FALSE;
151:
152: /* miscellaneous global state */
153: char obj_str[STRLEN];
154:
155: extern char config_file[4096];
1.20 snw 156: extern char env_config_file[4096];
157: extern char env_user[255];
158: extern char env_group[255];
1.1 snw 159:
160: int fm_shell(void);
161: void fm_checkperms(void);
162: void fm_reconfigure(void);
163: void fm_configure(void);
1.21 snw 164: int fm_daemonctl (short action, short object, int optc, char **options);
1.1 snw 165: void fm_write (FILE *file, char *buf);
166: int fma_jobs_remove (int optc, char **opts);
1.20 snw 167: void set_permissions(char *path, char *user, char *grp, int mode);
1.21 snw 168: extern int read_profile_string(char *file, char *section, char *key, char *value);
1.1 snw 169:
170: int main (int argc, char **argv)
171: {
172: char action[STRLEN];
173:
174: short act = -1;
175: short obj = -1;
176:
177: char **opts;
178: int optc = argc - 3;
179:
180: int i = 0;
181: int j = 1;
182: int base_arg = 4;
183: int k = 0;
184:
185: short got_action = FALSE;
186: short got_object = FALSE;
187:
188:
189: /* snprintf (config_file, 4096, "%s/freem.conf", SYSCONFDIR); */
190:
191: base_arg = 1;
192:
193: /* enforce action in argv[1] */
194: if (argc > 1) {
195: if (argv[1][0] == '-') {
196: fprintf (stderr, "fmadm: first argument, if given, must be an action, not a flag\n");
197: fmadm_usage ();
198: exit (1);
199: }
200: }
201:
202: for (i = base_arg; i < argc; i++) {
203: if (i == 1 && isalpha (argv[i][0])) {
204: got_action = TRUE;
205: strncpy (action, argv[i], STRLEN - 1);
206: base_arg++;
207: }
208: if (i == 2 && isalpha (argv[i][0])) {
209: got_object = TRUE;
210: strncpy (obj_str, argv[i], STRLEN - 1);
211: base_arg++;
212: }
213: if (argv[i][0] == '-') {
214:
215: switch (argv[i][1]) {
1.20 snw 216:
217: case 'u':
218: if (argv[i][2] != '=') {
219: fprintf (stderr, "fmadm: missing equals sign in flag -%c\n", argv[i][1]);
220: fmadm_usage ();
221: exit (1);
222: }
223:
224: k = 0;
225:
226: for (j = 3; j < strlen (argv[i]); j++) {
227: env_user[k++] = argv[i][j];
228: }
229:
230: fma_explicit_environment = TRUE;
231: base_arg++;
232:
233: break;
234:
235: case 'g':
236: if (argv[i][2] != '=') {
237: fprintf (stderr, "fmadm: missing equals sign in flag -%c\n", argv[i][1]);
238: fmadm_usage ();
239: exit (1);
240: }
241:
242: k = 0;
243:
244: for (j = 3; j < strlen (argv[i]); j++) {
245: env_group[k++] = argv[i][j];
246: }
247:
248: fma_explicit_environment = TRUE;
249: base_arg++;
250:
251: break;
252:
1.1 snw 253:
254: case 'e':
255: if (argv[i][2] != '=') {
256: fprintf (stderr, "fmadm: missing equals sign in flag -%c\n", argv[i][1]);
257: fmadm_usage ();
258: exit (1);
259: }
260:
261: k = 0;
262:
263: for (j = 3; j < strlen (argv[i]); j++) {
264: fma_environment[k++] = argv[i][j];
265: }
1.21 snw 266:
267: if (strcmp (fma_environment, "all") == 0 ) {
268: fprintf (stderr, "fmadm: 'all' is an invalid environment name\n");
269: exit (1);
270: }
1.1 snw 271:
272: fma_explicit_environment = TRUE;
273: base_arg++;
274:
275: break;
276:
277: case 'n':
278: if (argv[i][2] != '=') {
279: fprintf (stderr, "fmadm: missing equals sign in flag -%c\n", argv[i][1]);
280: fmadm_usage ();
281: exit (1);
282: }
283:
284: k = 0;
285:
286: for (j = 3; j < strlen (argv[i]); j++) {
287: fma_namespace[k++] = argv[i][j];
288: }
289:
290: fma_explicit_namespace = TRUE;
291: base_arg++;
292:
293: break;
294:
295: }
296: }
297: }
1.20 snw 298:
1.21 snw 299: if (obj != OBJ_DAEMON) {
300: if (strlen (env_user) == 0) {
301: snprintf (env_user, 6, "freem");
302: }
303:
304: if (strlen (env_group) == 0) {
305: snprintf (env_group, 6, "freem");
306: }
1.20 snw 307:
1.1 snw 308:
1.21 snw 309: if (!fma_explicit_environment) snprintf (fma_environment, 4096, "DEFAULT");
310: if (!fma_explicit_namespace) snprintf (fma_namespace, 4096, "SYSTEM");
311:
312: snprintf (config_file, 4096, "%s/freem/%s/freem.conf", SYSCONFDIR, fma_environment);
313: }
1.1 snw 314:
1.20 snw 315: snprintf (env_config_file, 4096, "%s/freem/env.conf", SYSCONFDIR);
316:
1.1 snw 317: /*
318: printf ("action = '%s' object = '%s' environment = '%s' namespace = '%s' config_file = '%s' base_arg = '%d' next argument = '%s'\n", action, obj_str, fma_environment, fma_namespace, config_file, base_arg, argv[base_arg]);
319: exit(1);
320: */
321:
1.21 snw 322: /* override for fmadm configure and daemon stuff */
1.1 snw 323: if (got_action) {
324: if (strcmp (argv[1], "configure") == 0) {
325: fm_configure ();
326: exit (0);
327: }
328: else if (strcmp (argv[1], "reconfigure") == 0) {
329: fm_reconfigure ();
330: exit (0);
331: }
1.21 snw 332: else if (strcmp (argv[1], "start") == 0 && strcmp (argv[2], "environment") == 0) {
333: act = ACT_START;
334: obj = OBJ_DAEMON;
335: goto act_switch;
336: }
337: else if (strcmp (argv[1], "stop") == 0 && strcmp (argv[2], "environment") == 0) {
338: act = ACT_STOP;
339: obj = OBJ_DAEMON;
340: goto act_switch;
341: }
342: else if (strcmp (argv[1], "restart") == 0 && strcmp (argv[2], "environment") == 0) {
343: act = ACT_RESTART;
344: obj = OBJ_DAEMON;
345: goto act_switch;
1.23 ! snw 346: }
! 347: else if (strcmp (argv[1], "status") == 0 && strcmp (argv[2], "environment") == 0) {
! 348: act = ACT_STATUS;
! 349: obj = OBJ_DAEMON;
! 350: goto act_switch;
1.21 snw 351: }
1.23 ! snw 352:
1.1 snw 353: }
354:
355: pid = getpid ();
356:
357: shm_init (16777216);
358: tp_init ();
359: jobtab_init ();
360: job_init (TRUE);
361:
362: fm_sig_init ();
1.21 snw 363:
1.1 snw 364: /* go to fmadm shell if no arguments passed */
365: if (!got_action && !got_object) return fm_shell ();
366:
367: if (argc > 1 && strcmp (argv[1], "checkperms") == 0) {
368: fm_checkperms ();
369: exit (0);
370: }
371:
372: set_namespace (fma_namespace, FALSE);
373:
374: /* allocate opts array */
375:
376: /* first dimension */
377: if ((opts = (char **) malloc (FMA_MAXARGS * sizeof (char *))) == NULL) {
378: fprintf (stderr, "fmadm [FATAL]: could not acquire memory\n");
379: return 1;
380: }
381:
382: /* second dimension */
383: for (i = 0; i < FMA_MAXARGS; i++) {
384: if ((opts[i] = (char *) malloc (STRLEN * sizeof (char *))) == NULL) {
385: fprintf (stderr, "fmadm [FATAL]: could not acquire memory\n");
386: return 1;
387: }
388: }
389:
390: /* copy argv[base_arg] through argv[argc - 1] to opts[1] through opts[argc - 3] */
391:
392: strncpy (opts[0], argv[0], STRLEN - 1); /* preserve argv[0] */
393:
394: j = 1;
395: for (i = base_arg; i < argc; i++) {
396: if (i > FMA_MAXARGS) return fmadm_usage(); /* bail if we're going to overrun the array */
397: strncpy (opts[j++], argv[i], STRLEN - 1);
398: }
399:
400: if (strncmp (action, "list", STRLEN - 1) == 0) act = ACT_LIST;
401: else if (strncmp (action, "examine", STRLEN - 1) == 0) act = ACT_EXAMINE;
402: else if (strncmp (action, "verify", STRLEN - 1) == 0) act = ACT_VERIFY;
403: else if (strncmp (action, "compact", STRLEN - 1) == 0) act = ACT_COMPACT;
404: else if (strncmp (action, "repair", STRLEN - 1) == 0) act = ACT_REPAIR;
405: else if (strncmp (action, "create", STRLEN - 1) == 0) act = ACT_CREATE;
406: else if (strncmp (action, "remove", STRLEN - 1) == 0) act = ACT_REMOVE;
407: else if (strncmp (action, "import", STRLEN - 1) == 0) act = ACT_IMPORT;
408: else if (strncmp (action, "export", STRLEN - 1) == 0) act = ACT_EXPORT;
409: else if (strncmp (action, "backup", STRLEN - 1) == 0) act = ACT_BACKUP;
410: else if (strncmp (action, "restore", STRLEN - 1) == 0) act = ACT_RESTORE;
411: else if (strncmp (action, "migrate", STRLEN - 1) == 0) act = ACT_MIGRATE;
1.21 snw 412: else if (strncmp (action, "edit", STRLEN - 1) == 0) act = ACT_EDIT;
413: else if (strncmp (action, "start", STRLEN - 1) == 0) act = ACT_START;
414: else if (strncmp (action, "stop", STRLEN - 1) == 0) act = ACT_STOP;
415: else if (strncmp (action, "restart", STRLEN - 1) == 0) act = ACT_RESTART;
1.1 snw 416: else return fmadm_usage();
417:
418: if (strncmp (obj_str, "lock", STRLEN - 1) == 0) obj = OBJ_LOCK;
419: else if (strncmp (obj_str, "zallocate", STRLEN - 1) == 0) obj = OBJ_ZALLOC;
420: else if (strncmp (obj_str, "journal", STRLEN - 1) == 0) obj = OBJ_JOURNAL;
421: else if (strncmp (obj_str, "namespace", STRLEN - 1) == 0) obj = OBJ_NAMESPACE;
422: else if (strncmp (obj_str, "global", STRLEN - 1) == 0) obj = OBJ_GLOBAL;
423: else if (strncmp (obj_str, "routine", STRLEN - 1) == 0) obj = OBJ_ROUTINE;
424: else if (strncmp (obj_str, "job", STRLEN - 1) == 0) obj = OBJ_JOB;
1.21 snw 425: else if (strncmp (obj_str, "environment", STRLEN - 1) == 0) obj = OBJ_DAEMON;
1.1 snw 426: else return fmadm_usage();
427:
1.21 snw 428: if (act > ACT_EDIT) goto act_switch;
429:
1.1 snw 430: if (get_conf (fma_namespace, "routines_path", fma_routine_path) == FALSE) {
431: fprintf (stderr, "fmadm: cannot determine routine path for namespace %s\n", fma_namespace);
432: return 1;
433: }
434:
435: if (get_conf (fma_namespace, "globals_path", fma_global_path) == FALSE) {
436: fprintf (stderr, "fmadm: cannot determine global path for namespace %s\n", fma_namespace);
437: return 1;
438: }
439:
440: if (get_conf ("SYSTEM", "globals_path", fma_pct_global_path) == FALSE) {
441: fprintf (stderr, "fmadm: cannot determine %% global path for namespace %s\n", "SYSTEM");
442: return 1;
443: }
444:
445: if (get_conf ("SYSTEM", "routines_path", fma_pct_routine_path) == FALSE) {
446: fprintf (stderr, "fmadm: cannot determine %% routine path for namespace %s\n", "SYSTEM");
447: return 1;
448: }
449:
450: if (get_conf ("SYSTEM", "journal_file", fma_journal_path) == FALSE) {
451: strcpy (fma_journal_path, "");
452: }
453:
454: if (get_conf ("SYSTEM", "journal_cut_threshold", fma_journal_cut_threshold) == FALSE) {
455: strcpy (fma_journal_cut_threshold, "1073741824");
456: }
457:
458: strcpy (gloplib, fma_pct_global_path);
459: stcnv_c2m (gloplib);
460:
461: strcpy (glopath, fma_global_path);
462: stcnv_c2m (glopath);
463:
464:
1.21 snw 465: act_switch:
1.1 snw 466: switch (act) {
467:
468:
469: case ACT_LIST:
470: fmadm_exit (fm_list (obj, optc, opts));
471:
472:
473: case ACT_EXAMINE:
474: fmadm_exit (fm_examine (obj, optc, opts));
475:
476:
477: case ACT_VERIFY:
478: fmadm_exit (fm_verify (obj, optc, opts));
479:
480:
481: case ACT_COMPACT:
482: fmadm_exit (fm_compact (obj, optc, opts));
483:
484:
485: case ACT_REPAIR:
486: fmadm_exit (fm_repair (obj, optc, opts));
487:
488:
489: case ACT_CREATE:
490: fmadm_exit (fm_create (obj, optc, opts));
491:
492:
493: case ACT_REMOVE:
494: fmadm_exit (fm_remove (obj, optc, opts));
495:
496:
497: case ACT_IMPORT:
498: fmadm_exit (fm_import (obj, optc, opts));
499:
500:
501: case ACT_EXPORT:
502: fmadm_exit (fm_export (obj, optc, opts));
503:
504:
505: case ACT_BACKUP:
506: fmadm_exit (fm_backup (obj, optc, opts));
507:
508:
509: case ACT_RESTORE:
510: fmadm_exit (fm_restore (obj, optc, opts));
511:
512:
513: case ACT_MIGRATE:
514: fmadm_exit (fm_migrate (obj, optc, opts));
515:
516:
517: case ACT_EDIT:
518: fmadm_exit (fm_edit (obj, optc, opts));
519:
1.21 snw 520: case ACT_START:
521: case ACT_STOP:
522: case ACT_RESTART:
1.23 ! snw 523: case ACT_STATUS:
1.21 snw 524: fmadm_exit (fm_daemonctl (act, obj, optc, opts));
1.1 snw 525:
526: default:
527: return fmadm_usage();
528: }
529:
530: return 0; /* should never be reached */
531:
532: } /* main() */
533:
534: int fm_shell (void)
535: {
536:
537: #if defined(HAVE_LIBREADLINE) && !defined(_AIX)
538: int cmd;
539: int i;
540: int j;
541: int obj;
542: int optc;
543: int argc;
544: char **args;
545: char **opts;
546: char *fmarl_buf;
547: char *fma_prompt = (char *) malloc (STRLEN * sizeof (char));
548: char *cmdt = (char *) malloc (65535 * sizeof (char));
549: char *result = (char *) malloc (65535 * sizeof (char));
550:
551: /*
552: strcpy (fma_namespace, "SYSTEM");
553: set_namespace (fma_namespace, FALSE);
554: */
555:
556: snprintf (fma_prompt, STRLEN - 1, "fmadm [%s]> ", fma_namespace);
557:
558: if (get_conf (fma_namespace, "routines_path", fma_routine_path) == FALSE) {
559: fprintf (stderr, "fmadm: cannot determine routine path for namespace %s\n", fma_namespace);
560: return 1;
561: }
562:
563: if (get_conf (fma_namespace, "globals_path", fma_global_path) == FALSE) {
564: fprintf (stderr, "fmadm: cannot determine global path for namespace %s\n", fma_namespace);
565: return 1;
566: }
567:
568: if (get_conf ("SYSTEM", "globals_path", fma_pct_global_path) == FALSE) {
569: fprintf (stderr, "fmadm: cannot determine %% global path for namespace %s\n", "SYSTEM");
570: return 1;
571: }
572:
573: if (get_conf ("SYSTEM", "routines_path", fma_pct_routine_path) == FALSE) {
574: fprintf (stderr, "fmadm: cannot determine %% routine path for namespace %s\n", "SYSTEM");
575: return 1;
576: }
577:
578: if (get_conf ("SYSTEM", "journal_file", fma_journal_path) == FALSE) {
579: strcpy (fma_journal_path, "");
580: }
581:
582: if (get_conf ("SYSTEM", "journal_cut_threshold", fma_journal_cut_threshold) == FALSE) {
583: strcpy (fma_journal_cut_threshold, "1073741824");
584: }
585:
586: strcpy (gloplib, fma_pct_global_path);
587: stcnv_c2m (gloplib);
588:
589: strcpy (glopath, fma_global_path);
590: stcnv_c2m (glopath);
591:
592: /* allocate args array */
593:
594: /* first dimension */
595: if ((args = (char **) malloc (FMA_MAXARGS * sizeof (char *))) == NULL) {
596: fprintf (stderr, "fmadm [FATAL]: could not acquire memory\n");
597: return 1;
598: }
599:
600: /* second dimension */
601: for (i = 0; i < FMA_MAXARGS; i++) {
602: if ((args[i] = (char *) malloc (STRLEN * sizeof (char *))) == NULL) {
603: fprintf (stderr, "fmadm [FATAL]: could not acquire memory\n");
604: return 1;
605: }
606: }
607:
608: /* allocate opts array */
609:
610: /* first dimension */
611: if ((opts = (char **) malloc (FMA_MAXARGS * sizeof (char *))) == NULL) {
612: fprintf (stderr, "fmadm [FATAL]: could not acquire memory\n");
613: return 1;
614: }
615:
616: /* second dimension */
617: for (i = 0; i < FMA_MAXARGS; i++) {
618: if ((opts[i] = (char *) malloc (STRLEN * sizeof (char *))) == NULL) {
619: fprintf (stderr, "fmadm [FATAL]: could not acquire memory\n");
620: return 1;
621: }
622: }
623:
624:
625: for (;;) {
626:
627: fmarl_buf = readline (fma_prompt);
628:
629: if (fmarl_buf == (char *) NULL) continue;
630:
631: cmdt = strtok (fmarl_buf, " ");
632:
1.2 snw 633: if (cmdt == (char *) NULL) continue;
634:
1.1 snw 635: for (i = 0; i < strlen (cmdt); i++) cmdt[i] = cmdt[i] | 0140;
636:
637: if (strcmp (cmdt, "exit") == 0) cmd = FMAC_EXIT;
638: else if (strcmp (cmdt, "quit") == 0) cmd = FMAC_EXIT;
639: else if (strcmp (cmdt, "select") == 0) cmd = FMAC_SELECT;
640: else if (strcmp (cmdt, "list") == 0) cmd = FMAC_LIST;
641: else if (strcmp (cmdt, "examine") == 0) cmd = FMAC_EXAMINE;
642: else if (strcmp (cmdt, "verify") == 0) cmd = FMAC_VERIFY;
643: else if (strcmp (cmdt, "compact") == 0) cmd = FMAC_COMPACT;
644: else if (strcmp (cmdt, "repair") == 0) cmd = FMAC_REPAIR;
645: else if (strcmp (cmdt, "create") == 0) cmd = FMAC_CREATE;
646: else if (strcmp (cmdt, "import") == 0) cmd = FMAC_IMPORT;
647: else if (strcmp (cmdt, "export") == 0) cmd = FMAC_EXPORT;
648: else if (strcmp (cmdt, "backup") == 0) cmd = FMAC_BACKUP;
649: else if (strcmp (cmdt, "restore") == 0) cmd = FMAC_RESTORE;
650: else if (strcmp (cmdt, "migrate") == 0) cmd = FMAC_MIGRATE;
651: else if (strcmp (cmdt, "edit") == 0) cmd = FMAC_EDIT;
652: else if (strcmp (cmdt, "set") == 0) cmd = FMAC_SET;
653: else if (strcmp (cmdt, "show") == 0) cmd = FMAC_SHOW;
654: else if (strcmp (cmdt, "remove") == 0) cmd = FMAC_REMOVE;
655: else cmd = FMAC_INVALID;
656:
657: i = 0;
658: while ((result = strtok (NULL, " ")) != NULL) {
659: // printf ("%d = %s\n", i, result);
660: strcpy (args[i++], result);
661: }
662:
663: argc = i;
664: j = 0;
665:
666: for (i = 1; i < argc; i++) {
667: strncpy (opts[j++], args[i], STRLEN - 1);
668: }
669:
670: optc = argc - 1;
671:
672: if (i > 0) {
673:
674: strcpy (obj_str, args[0]);
675:
676: if (strncmp (obj_str, "lock", STRLEN - 1) == 0) obj = OBJ_LOCK;
677: else if (strncmp (obj_str, "zallocate", STRLEN - 1) == 0) obj = OBJ_ZALLOC;
678: else if (strncmp (obj_str, "journal", STRLEN - 1) == 0) obj = OBJ_JOURNAL;
679: else if (strncmp (obj_str, "namespace", STRLEN - 1) == 0) obj = OBJ_NAMESPACE;
680: else if (strncmp (obj_str, "global", STRLEN - 1) == 0) obj = OBJ_GLOBAL;
681: else if (strncmp (obj_str, "routine", STRLEN - 1) == 0) obj = OBJ_ROUTINE;
682: else if (strncmp (obj_str, "job", STRLEN - 1) == 0) obj = OBJ_JOB;
683:
684: }
685:
686: switch (cmd) {
687:
688:
689: case FMAC_SELECT:
690:
691:
692: break;
693:
694:
695: case FMAC_LIST:
696: fm_list (obj, optc, opts);
697: break;
698:
699:
700: case FMAC_EXAMINE:
701: fm_examine (obj, optc, opts);
702: break;
703:
704:
705: case FMAC_VERIFY:
706: fm_verify (obj, optc, opts);
707: break;
708:
709:
710: case FMAC_COMPACT:
711: fm_compact (obj, optc, opts);
712: break;
713:
714:
715: case FMAC_REPAIR:
716: fm_repair (obj, optc, opts);
717: break;
718:
719:
720: case FMAC_CREATE:
721: fm_create (obj, optc, opts);
722: break;
723:
724:
725: case FMAC_REMOVE:
726: fm_remove (obj, optc, opts);
727: break;
728:
729:
730: case FMAC_IMPORT:
731: fm_import (obj, optc, opts);
732: break;
733:
734:
735: case FMAC_EXPORT:
736: fm_export (obj, optc, opts);
737: break;
738:
739:
740: case FMAC_BACKUP:
741: fm_backup (obj, optc, opts);
742: break;
743:
744:
745: case FMAC_RESTORE:
746: fm_restore (obj, optc, opts);
747: break;
748:
749:
750: case FMAC_MIGRATE:
751: fm_migrate (obj, optc, opts);
752: break;
753:
754:
755: case FMAC_EDIT:
756: fm_edit (obj, optc, opts);
757: break;
758:
759:
760: case FMAC_SET:
761:
762: if (i < 2) {
763: printf ("fmadm: syntax error\n");
764: break;
765: }
766:
767: if (strcmp (args[0], "namespace") == 0) {
768: strcpy (fma_namespace, args[1]);
769:
770: if (get_conf (fma_namespace, "routines_path", fma_routine_path) == FALSE) {
771: fprintf (stderr, "fmadm: cannot determine routine path for namespace %s\n", fma_namespace);
772: return 1;
773: }
774:
775: if (get_conf (fma_namespace, "globals_path", fma_global_path) == FALSE) {
776: fprintf (stderr, "fmadm: cannot determine global path for namespace %s\n", fma_namespace);
777: return 1;
778: }
779:
780: if (get_conf ("SYSTEM", "globals_path", fma_pct_global_path) == FALSE) {
781: fprintf (stderr, "fmadm: cannot determine %% global path for namespace %s\n", "SYSTEM");
782: return 1;
783: }
784:
785: if (get_conf ("SYSTEM", "routines_path", fma_pct_routine_path) == FALSE) {
786: fprintf (stderr, "fmadm: cannot determine %% routine path for namespace %s\n", "SYSTEM");
787: return 1;
788: }
789:
790: if (get_conf ("SYSTEM", "journal_file", fma_journal_path) == FALSE) {
791: strcpy (fma_journal_path, "");
792: }
793:
794: if (get_conf ("SYSTEM", "journal_cut_threshold", fma_journal_cut_threshold) == FALSE) {
795: strcpy (fma_journal_cut_threshold, "1073741824");
796: }
797:
798: strcpy (gloplib, fma_pct_global_path);
799: stcnv_c2m (gloplib);
800:
801: strcpy (glopath, fma_global_path);
802: stcnv_c2m (glopath);
803:
804: snprintf (fma_prompt, STRLEN - 1, "fmadm [%s]> ", fma_namespace);
805:
806: }
807: else if (strcmp (args[0], "maintenance") == 0) {
808: if (strcmp (args[1], "on") == 0) {
809: shm_config->hdr->maintenance_mode = 1;
810: break;
811: }
812: else if (strcmp (args[1], "off") == 0) {
813: shm_config->hdr->maintenance_mode = 0;
814: break;
815: }
816: else {
817: printf ("fmadm: syntax error\n");
818: }
819:
820: printf ("fmadm: syntax error\n");
821:
822: }
823: else {
824: printf ("fmadm: syntax error\n");
825: break;
826: }
827:
828: break;
829:
830:
831: case FMAC_SHOW:
832: printf ("Namespace: %s\n", fma_namespace);
833: printf ("Routine Path: %s\n", fma_routine_path);
834: printf ("%%-Routine Path: %s\n", fma_pct_routine_path);
835: printf ("Global Path: %s\n", fma_global_path);
836: printf ("%%-Global Path: %s\n", fma_pct_global_path);
837: printf ("Journal File: %s\n", fma_journal_path);
1.5 snw 838: printf ("Journal Cut Threshold: %s bytes\n", fma_journal_cut_threshold);
1.1 snw 839: break;
840:
841: case FMAC_EXIT:
842: fmadm_exit (0);
843: break;
844:
845:
846: default:
847: printf ("fmadm: '%s' is not a valid fmadm command\n", cmdt);
848: break;
849:
850: }
851: }
852:
853: #endif
854:
855: }
856:
857: void fmadm_exit (int retval)
858: {
859: locktab_unlock_all ();
860: job_remove (pid);
861:
862: shm_exit ();
863:
864: exit (retval);
865: }
866:
867: int fmadm_usage (void)
868: {
869:
870: fprintf (stdout, "\nusage: fmadm <action> <object> [-e=<environment] [-n=<namespace>] [OPTIONS]\n");
871: fprintf (stdout, " fmadm configure\n");
872: fprintf (stdout, " fmadm reconfigure\n");
873: /* fprintf (stdout, " fmadm checkperms\n\n"); */
874:
875: fprintf (stdout, " <action> can be one of:\n");
876: fprintf (stdout, " list, examine, verify, compact, repair, create, remove,\n");
1.21 snw 877: fprintf (stdout, " import, export, backup, restore, migrate, edit, start,\n");
878: fprintf (stdout, " stop, restart\n\n");
1.1 snw 879:
880: fprintf (stdout, " <object> can be one of:\n");
1.21 snw 881: fprintf (stdout, " lock, zallocate, journal, namespace, global, routine, job,\n");
882: fprintf (stdout, " environment\n\n");
1.1 snw 883:
884: fprintf (stdout, " Not all actions are valid for all objects. Please see the FreeM manual\n");
885: fprintf (stdout, " for details on fmadm usage and options.\n\n");
886:
887: return 1;
888:
889: } /* fmadm_usage() */
890:
891: int fm_list (short object, int optc, char **options)
892: {
893:
894: switch (object) {
895:
896: case OBJ_LOCK:
897: return fma_locks_list (optc, options);
898:
899: case OBJ_ROUTINE:
900: return fma_routines_list (optc, options);
901:
902: case OBJ_GLOBAL:
903: return fma_globals_list (optc, options);
904:
905: case OBJ_JOB:
906: return fma_jobs_list (optc, options);
907:
908: default:
909: fprintf (stderr, "fmadm: 'list' is an invalid action for '%s'\n", obj_str);
910: return 1;
911:
912: }
913:
914:
915: } /* fm_list() */
916:
917: int fm_examine (short object, int optc, char **options)
918: {
919:
920: switch (object) {
921:
922: case OBJ_ROUTINE:
923: return fma_routines_examine (optc, options);
924:
925: case OBJ_GLOBAL:
926: return fma_globals_examine (optc, options);
927:
928: case OBJ_JOB:
929: return fma_jobs_examine (optc, options);
930:
931: case OBJ_JOURNAL:
932: return fma_journals_examine (optc, options);
933:
934: default:
935: fprintf (stderr, "fmadm: 'examine' is an invalid action for '%s'\n", obj_str);
936: return 1;
937:
938: }
939:
940: } /* fm_examine() */
941:
942: int fm_verify (short object, int optc, char **options)
943: {
944:
945: switch (object) {
946:
947: case OBJ_GLOBAL:
948: return fma_globals_verify (optc, options);
949:
950: default:
951: fprintf (stderr, "fmadm: 'examine' is an invalid action for '%s'\n", obj_str);
952: return 1;
953:
954: }
955:
956: } /* fm_verify() */
957:
958: int fm_compact (short object, int optc, char **options)
959: {
960:
961: switch (object) {
962:
963: default:
964: fprintf (stderr, "fmadm: 'compact' is an invalid action for '%s'\n", obj_str);
965: return 1;
966:
967: }
968:
969: } /* fm_compact() */
970:
971: int fm_repair (short object, int optc, char **options)
972: {
973:
974: switch (object) {
975:
976: default:
977: fprintf (stderr, "fmadm: 'repair' is an invalid action for '%s'\n", obj_str);
978: return 1;
979:
980: }
981:
982: } /* fm_repair() */
983:
984: int fm_create (short object, int optc, char **options)
985: {
986:
987: switch (object) {
988:
989: default:
990: fprintf (stderr, "fmadm: 'create' is an invalid action for '%s'\n", obj_str);
991: return 1;
992:
993: }
994: } /* fm_create() */
995:
996: int fm_remove (short object, int optc, char **options)
997: {
998:
999: switch (object) {
1000:
1001: case OBJ_JOB:
1002: return fma_jobs_remove (optc, options);
1003:
1004: case OBJ_LOCK:
1005: return fma_locks_remove (optc, options);
1006:
1007: case OBJ_ROUTINE:
1008: return fma_routines_remove (optc, options);
1009:
1010: case OBJ_GLOBAL:
1011: return fma_globals_remove (optc, options);
1012:
1013: default:
1014: fprintf (stderr, "fmadm: 'remove' is an invalid action for '%s'\n", obj_str);
1015: return 1;
1016:
1017: }
1018:
1019: } /* fm_remove() */
1020:
1021: int fm_import (short object, int optc, char **options)
1022: {
1023:
1024: switch (object) {
1025:
1026: case OBJ_ROUTINE:
1027: return fma_routines_import (optc, options);
1028:
1029: default:
1030: fprintf (stderr, "fmadm: 'import' is an invalid action for '%s'\n", obj_str);
1031: return 1;
1032:
1033: }
1034:
1035: } /* fm_import() */
1036:
1037: int fm_export (short object, int optc, char **options)
1038: {
1039:
1040: switch (object) {
1041:
1042: case OBJ_ROUTINE:
1043: return fma_routines_export (optc, options);
1044:
1045: default:
1046: fprintf (stderr, "fmadm: 'export' is an invalid action for '%s'\n", obj_str);
1047: return 1;
1048:
1049: }
1050:
1051: } /* fm_export() */
1052:
1053: int fm_backup (short object, int optc, char **options)
1054: {
1055:
1056: switch (object) {
1057:
1058: case OBJ_ROUTINE:
1059: return fma_routines_backup (optc, options);
1060:
1061: default:
1062: fprintf (stderr, "fmadm: 'backup' is an invalid action for '%s'\n", obj_str);
1063: return 1;
1064:
1065: }
1066:
1067: } /* fm_backup() */
1068:
1069: int fm_restore (short object, int optc, char **options)
1070: {
1071:
1072: switch (object) {
1073:
1074: case OBJ_JOURNAL:
1075: return fma_journals_restore (optc, options);
1076:
1077: default:
1078: fprintf (stderr, "fmadm: 'restore' is an invalid action for '%s'\n", obj_str);
1079: return 1;
1080:
1081: }
1082:
1083: } /* fm_restore() */
1084:
1085: int fm_migrate (short object, int optc, char **options)
1086: {
1087:
1088: switch (object) {
1089:
1090: default:
1091: fprintf (stderr, "fmadm: 'migrate' is an invalid action for '%s'\n", obj_str);
1092: return 1;
1093:
1094: }
1095:
1096: } /* fm_migrate() */
1097:
1098: int fm_edit (short object, int optc, char **options)
1099: {
1100:
1101: switch (object) {
1102:
1103: case OBJ_ROUTINE:
1104: return fma_routines_edit (optc, options);
1105:
1.18 snw 1106: case OBJ_GLOBAL:
1.1 snw 1107: return fma_globals_edit (optc, options);
1.18 snw 1108:
1.1 snw 1109: default:
1110: fprintf (stderr, "fmadm: 'edit' is an invalid action for '%s'\n", obj_str);
1111: return 1;
1112:
1113: }
1114:
1115: } /* fm_edit() */
1116:
1.22 snw 1117: long fm_get_pid (char *env)
1118: {
1119: char pid_file[4096];
1120: char tmp_pid[255];
1121: long res;
1122:
1123: FILE *fp;
1124:
1125: snprintf (pid_file, 4095, "%s/freem/run/%s.pid", LOCALSTATEDIR, env);
1126:
1127: if ((fp = fopen (pid_file, "r")) != NULL) {
1128: if (fgets (tmp_pid, 255, fp)) {
1129: fclose (fp);
1130: return atol (tmp_pid);
1131: }
1132: else {
1133: fclose (fp);
1134: return -1;
1135: }
1136: }
1137: else {
1138: return -1;
1139: }
1140: }
1141:
1.21 snw 1142: int fm_daemonctl (short action, short object, int optc, char **options)
1143: {
1144: FILE *ef;
1145: char *envlist;
1146: char env[255];
1147: char line[255];
1148: char tmps[255];
1149: char *cur_env;
1150: char cmd[4096];
1.23 ! snw 1151: char verb[40];
1.21 snw 1152: char e_user[255];
1153: char e_grp[255];
1154: char e_ena[10];
1155: char basecmd[255];
1156: char *savptr;
1157: int result;
1.22 snw 1158: long epid;
1.21 snw 1159:
1160: #if !defined(__OS2__)
1161: snprintf (basecmd, 254, "%s/bin/freem", PREFIX);
1162: #else
1163: snprintf (basecmd, 254, "%s/bin/freemd.exe", PREFIX);
1164: #endif
1165:
1166: switch (action) {
1167: case ACT_START:
1168: sprintf (verb, "starting");
1169: break;
1170: case ACT_STOP:
1171: sprintf (verb, "stopping");
1172: break;
1173: case ACT_RESTART:
1174: sprintf (verb, "restarting");
1175: break;
1.23 ! snw 1176: case ACT_STATUS:
! 1177: sprintf (verb, "checking status of");
! 1178: break;
1.21 snw 1179: }
1180:
1181: if (optc) {
1182: /* environment list specified as command-line argument */
1.23 ! snw 1183: envlist = (char *) malloc (sizeof (char) * BIGSTR);
! 1184: NULLPTRCHK(envlist,"fm_daemonctl");
! 1185:
! 1186: strcpy (envlist, options[0]);
1.21 snw 1187: }
1188: else {
1189: /* no environment specified; do 'action' for all environments */
1190: envlist = (char *) malloc (sizeof (char) * BIGSTR);
1191: NULLPTRCHK(envlist,"fm_daemonctl");
1192:
1193: ef = fopen (env_config_file, "r");
1194:
1195: while (fgets (line, 254, ef)) {
1196: if (line[0] == '[') {
1197: strncpy (env, &(line[1]), 255);
1198: env[strlen (env) - 2] = '\0';
1199: snprintf (tmps, 255, "%s,", env);
1200: strncat (envlist, tmps, BIGSTR - 1);
1201: }
1202: }
1203: envlist[strlen (envlist) - 1] = '\0';
1204:
1205: fclose (ef);
1206: }
1207:
1208: savptr = envlist;
1209: cur_env = strtok_r (envlist, ",", &savptr);
1210: do {
1211: result = read_profile_string (env_config_file, cur_env, "enabled", e_ena);
1212: if (result == FALSE || strcmp (e_ena, "true") == 0) {
1213:
1214: result = read_profile_string (env_config_file, cur_env, "user", e_user);
1215: if (result == FALSE) {
1216: strcpy (e_user, "freem");
1217: }
1218: result = read_profile_string (env_config_file, cur_env, "group", e_grp);
1219: if (result == FALSE) {
1220: strcpy (e_grp, "freem");
1221: }
1.22 snw 1222:
1.21 snw 1223: printf ("fmadm: %s environment %s\n", verb, cur_env);
1224:
1225: switch (action) {
1226: case ACT_START:
1227: #if !defined(__OS2__)
1228: snprintf (cmd, 4095, "%s -d -e %s -u %s -g %s", basecmd, cur_env, e_user, e_grp);
1229: #else
1230: sprintf (cmd, 4095, "%s -d -k -e %s -u %s -g %s", basecmd, cur_env, e_user, e_grp);
1.22 snw 1231: #endif
1232: system (cmd);
1.21 snw 1233: break;
1234: case ACT_STOP:
1.22 snw 1235: epid = fm_get_pid (cur_env);
1236: if (epid > -1) {
1237: fprintf (stderr, "fmadm: stopping environment daemon pid %d\n", epid);
1238: kill (epid, SIGINT);
1239: kill (epid, SIGTERM);
1240: }
1241: else {
1242: fprintf (stderr, "fmadm: could not obtain environment daemon pid\n");
1243: }
1244:
1245: break;
1.21 snw 1246: case ACT_RESTART:
1.22 snw 1247: epid = fm_get_pid (cur_env);
1248: if (epid > -1) {
1249: fprintf (stderr, "fmadm: stopping environment daemon pid %d\n", epid);
1250: kill (epid, SIGINT);
1251: kill (epid, SIGTERM);
1252: }
1253: else {
1254: fprintf (stderr, "fmadm: could not obtain environment daemon pid\n");
1255: }
1256: fprintf (stderr, "fmadm: waiting 2 seconds\n");
1257: sleep (2);
1258: fprintf (stderr, "fmadm: starting environment %s\n", cur_env);
1259: #if !defined(__OS2__)
1260: snprintf (cmd, 4095, "%s -d -e %s -u %s -g %s", basecmd, cur_env, e_user, e_grp);
1261: #else
1262: sprintf (cmd, 4095, "%s -d -k -e %s -u %s -g %s", basecmd, cur_env, e_user, e_grp);
1263: #endif
1264: system (cmd);
1265:
1266:
1.21 snw 1267: break;
1.23 ! snw 1268: case ACT_STATUS:
! 1269: epid = fm_get_pid (cur_env);
! 1270: if (epid > -1) {
! 1271: fprintf (stderr, " - %s environment daemon running as pid %d\n", cur_env, epid);
! 1272: }
! 1273: else {
! 1274: fprintf (stderr, " - %s environment daemon does not appear to be running\n", cur_env);
! 1275: }
1.22 snw 1276: }
1.21 snw 1277: }
1278: else {
1279: printf ("fmadm: %s environment is disabled; skipping\n", cur_env);
1280: }
1281: } while ((cur_env = strtok_r (NULL, ",", &savptr)) != NULL);
1282:
1283: free (envlist);
1284: exit (0);
1285:
1286: } /* fm_daemonctl() */
1287:
1.1 snw 1288: void fm_checkperms(void)
1289: {
1290:
1291: } /* fm_checkperms() */
1292:
1293:
1294: void fm_reconfigure(void)
1295: {
1296: char config_backup[4096];
1297: char vers[4096];
1298:
1299: int retval;
1300:
1301: if (geteuid () != 0) {
1302: fprintf (stderr, "fmadm: not superuser\n");
1303: exit (1);
1304: }
1305:
1306: snprintf (config_backup, 4095, "%s.orig", config_file);
1307:
1308: fprintf (stderr, "fmadm: reconfiguring FreeM with system defaults for %s...\n", FREEM_VERSION_CSTR);
1309: fprintf (stderr, "fmadm: backing up %s to %s...\t", config_file, config_backup);
1310:
1311: retval = rename (config_file, config_backup);
1312:
1313: if (retval == 0) {
1.18 snw 1314: fprintf (stderr, "[OK]\n");
1.1 snw 1315:
1316: fm_configure ();
1317:
1318: fprintf (stderr, "\n\nYou may wish to edit %s if site-specific changes were made to the original FreeM configuration.\n", config_file);
1319: exit (0);
1320: }
1321: else {
1322: fprintf (stderr, "[FAIL (%s)]\n", strerror (errno));
1323: exit (1);
1324: }
1325:
1326: } /* fm_reconfigure() */
1327:
1328:
1329: void fm_configure (void)
1330: {
1.21 snw 1331: char rundir[4096];
1.19 snw 1332: char varbase[4096];
1.1 snw 1333: char sysrtn[4096];
1334: char sysgbl[4096];
1335: char usrrtn[4096];
1336: char usrgbl[4096];
1337:
1338: char locktab[4096];
1339: char zalloctab[4096];
1.23 ! snw 1340: char jnldir[4096];
1.1 snw 1341: char jnlfile[4096];
1342: char jnlmode[4];
1343: char jnlhostid[4096];
1344: char jnlcut[4096];
1345: char hostid[4096];
1346:
1347: char confbase[4096];
1348: char envbase[4096];
1349:
1350: char nsbase[4096];
1351:
1352: char buf[4096];
1353: FILE *fp;
1354:
1355: struct stat etcstat;
1356: int stat_result;
1.19 snw 1357:
1358: DIR *dir;
1359: struct dirent *ent;
1360: char src_dir[4096];
1361: char dest_dir[4096];
1362:
1.20 snw 1363: char *username = env_user;
1364: char *groupname = env_group;
1365:
1366: #if !defined(__OS2__)
1.19 snw 1367: struct group *d_grp;
1368: struct passwd *d_user;
1369: gid_t d_gid;
1.20 snw 1370: uid_t d_uid;
1.19 snw 1371:
1.20 snw 1372: if ((d_grp = getgrnam (groupname)) == NULL) {
1373: fprintf (stderr, "fmadm: '%s' group must exist before configuring\n", groupname);
1374: exit (1);
1375: }
1376: d_gid = d_grp->gr_gid;
1377:
1378: if ((d_user = getpwnam (username)) == NULL) {
1379: fprintf (stderr, "fmadm: '%s' user must exist before configuring\n", username);
1380: exit (1);
1381: }
1382: d_uid = d_user->pw_uid;
1383: #endif
1.23 ! snw 1384:
1.19 snw 1385: snprintf (varbase, 4095, "%s/freem", LOCALSTATEDIR);
1.21 snw 1386: snprintf (rundir, 4095, "%s/freem/run", LOCALSTATEDIR);
1.1 snw 1387: snprintf (sysrtn, 4095, "%s/freem/%s/SYSTEM/routines", LOCALSTATEDIR, fma_environment);
1388: snprintf (sysgbl, 4095, "%s/freem/%s/SYSTEM/globals", LOCALSTATEDIR, fma_environment);
1389: snprintf (usrrtn, 4095, "%s/freem/%s/USER/routines", LOCALSTATEDIR, fma_environment);
1390: snprintf (usrgbl, 4095, "%s/freem/%s/USER/globals", LOCALSTATEDIR, fma_environment);
1391: snprintf (locktab, 4095, "/tmp/locktab");
1392: snprintf (zalloctab, 4095, "/tmp/zalloctab");
1.23 ! snw 1393: snprintf (jnldir, 4095, "%s/freem/%s/journals", LOCALSTATEDIR, fma_environment);
! 1394: snprintf (jnlfile, 4095, "%s/freem_journal_%s.dat", jnldir, fma_environment);
1.1 snw 1395: snprintf (jnlmode, 3, "on");
1396: snprintf (jnlhostid, 4095, "DEFAULT");
1397: snprintf (jnlcut, 4095, "4294967000");
1398:
1399: if (geteuid () != 0) {
1400: fprintf (stderr, "fmadm: not superuser\n");
1401: exit (1);
1402: }
1403:
1404: if (file_exists (config_file)) {
1.18 snw 1405: fprintf (stderr, "fmadm: '%s' already exists; running fmadm reconfigure instead\n", config_file);
1406: fm_reconfigure ();
1407: return;
1.1 snw 1408: }
1409:
1410: gethostname (hostid, 4095);
1411: uuid_v4 (buf);
1412:
1413: snprintf (jnlhostid, 4095, "%s:%s", hostid, buf);
1414: snprintf (confbase, 4095, "%s/freem", SYSCONFDIR);
1415: snprintf (envbase, 4095, "%s/freem/%s", SYSCONFDIR, fma_environment);
1416: snprintf (nsbase, 4095, "%s/freem/%s", LOCALSTATEDIR, fma_environment);
1417:
1.9 snw 1418: #if defined(__OS2__)
1419: {
1420: char srcfile[PATHLEN];
1.11 snw 1421: char dstfile[PATHLEN];
1422:
1.9 snw 1423: snprintf (srcfile, PATHLEN, "%s/bin/freem.exe", PREFIX);
1424: snprintf (dstfile, PATHLEN, "%s/bin/freemd.exe", PREFIX);
1.11 snw 1425:
1426: unlink (dstfile);
1.9 snw 1427:
1.10 snw 1428: fprintf (stderr, "fmadm: running on OS/2; will copy %s to %s\n", srcfile, dstfile);
1.12 snw 1429:
1.16 snw 1430: if (DosCopy (srcfile, dstfile, 1) != 0) {
1.9 snw 1431: fprintf (stderr, "fmadm: fatal error copying %s to %s\n", srcfile, dstfile);
1432: exit (1);
1433: }
1.13 snw 1434:
1435: chmod (dstfile, 0755);
1.9 snw 1436: }
1437: #else
1438: fprintf (stderr, "fmadm: not running on OS/2\n");
1439: #endif
1440:
1.1 snw 1441: printf ("\nFreeM Initial Configuration\n");
1442: printf ("---------------------------\n\n");
1443:
1444: printf ("This utility will create the initial configuration file for ");
1.20 snw 1445: printf ("FreeM environment '%s' (owned by %s:%s) in '%s'.\n\n", fma_environment, username, groupname, config_file);
1.9 snw 1446:
1.1 snw 1447: /* check for existence of needed directories */
1448: if (stat (SYSCONFDIR, &etcstat) == -1) {
1.23 ! snw 1449: fprintf (stderr, "fmadm: creating %s [SYSCONFDIR]\n", SYSCONFDIR);
1.19 snw 1450: mkdir (SYSCONFDIR, 0775);
1.20 snw 1451: set_permissions (SYSCONFDIR, username, groupname, 0775);
1.1 snw 1452: }
1453:
1454: if (stat (confbase, &etcstat) == -1) {
1.23 ! snw 1455: fprintf (stderr, "fmadm: creating %s [confbase]\n", confbase);
1.19 snw 1456: mkdir (confbase, 0775);
1.20 snw 1457: set_permissions (confbase, username, groupname, 0775);
1.1 snw 1458: }
1459:
1.19 snw 1460: if (stat (varbase, &etcstat) == -1) {
1.23 ! snw 1461: fprintf (stderr, "fmadm: creating %s [varbase]\n", varbase);
1.19 snw 1462: mkdir (varbase, 0775);
1.20 snw 1463: set_permissions (varbase, username, groupname, 0775);
1.19 snw 1464: }
1.21 snw 1465:
1.23 ! snw 1466: if (stat (envbase, &etcstat) == -1) {
! 1467: fprintf (stderr, "fmadm: creating %s [envbase]\n", envbase);
! 1468: mkdir (envbase, 0775);
! 1469: set_permissions (envbase, username, groupname, 0775);
! 1470: }
! 1471:
1.21 snw 1472: if (stat (rundir, &etcstat) == -1) {
1.23 ! snw 1473: fprintf (stderr, "fmadm: creating %s [rundir]\n", rundir);
1.21 snw 1474: mkdir (rundir, 0777);
1475: chmod (rundir, 0777);
1476: }
1477:
1.1 snw 1478: if (stat (nsbase, &etcstat) == -1) {
1.23 ! snw 1479: fprintf (stderr, "fmadm: creating %s [nsbase]\n", nsbase);
1.19 snw 1480: mkdir (nsbase, 0775);
1.20 snw 1481: set_permissions (nsbase, username, groupname, 0775);
1.1 snw 1482: }
1483:
1.23 ! snw 1484: if (stat (jnldir, &etcstat) == -1) {
! 1485: fprintf (stderr, "fmadm: creating %s [jnldir]\n", jnldir);
! 1486: mkdir (jnldir, 0775);
! 1487: set_permissions (jnldir, username, groupname, 0775);
! 1488: }
! 1489:
! 1490:
1.19 snw 1491: snprintf (src_dir, 4095, "%s/freem/mlib", DATADIR);
1492: snprintf (dest_dir, 4095, "%s/freem/%s/SYSTEM/routines", LOCALSTATEDIR, fma_environment);
1493:
1494: fprintf (stderr, "fmadm: populating new environment '%s'\n", fma_environment);
1495:
1496: snprintf (buf, 4095, "%s/freem/%s/SYSTEM", LOCALSTATEDIR, fma_environment);
1497: mkdir (buf, 0775);
1.20 snw 1498: set_permissions (buf, username, groupname, 0775);
1.19 snw 1499:
1500: snprintf (buf, 4095, "%s/freem/%s/USER", LOCALSTATEDIR, fma_environment);
1501: mkdir (buf, 0775);
1.20 snw 1502: set_permissions (buf, username, groupname, 0775);
1.19 snw 1503:
1504: snprintf (buf, 4095, "%s/freem/%s/SYSTEM/routines", LOCALSTATEDIR, fma_environment);
1505: mkdir (buf, 0775);
1.20 snw 1506: set_permissions (buf, username, groupname, 0775);
1.19 snw 1507:
1508: snprintf (buf, 4095, "%s/freem/%s/USER/globals", LOCALSTATEDIR, fma_environment);
1509: mkdir (buf, 0775);
1.20 snw 1510: set_permissions (buf, username, groupname, 0775);
1.19 snw 1511:
1512: snprintf (buf, 4095, "%s/freem/%s/SYSTEM/globals", LOCALSTATEDIR, fma_environment);
1513: mkdir (buf, 0775);
1.20 snw 1514: set_permissions (buf, username, groupname, 0775);
1.19 snw 1515:
1516: snprintf (buf, 4095, "%s/freem/%s/USER/routines", LOCALSTATEDIR, fma_environment);
1517: mkdir (buf, 0775);
1.20 snw 1518: set_permissions (buf, username, groupname, 0775);
1.19 snw 1519:
1520: fprintf (stderr, "fmadm: copying routines from '%s' to '%s'...\n", src_dir, dest_dir);
1.1 snw 1521:
1.19 snw 1522: if ((dir = opendir (src_dir)) == NULL) {
1523: fprintf (stderr, "\nfmadm: could not open source directory %s\n", src_dir);
1524: exit (1);
1525: }
1526:
1527: while ((ent = readdir (dir)) != NULL) {
1528: char infile[4096];
1529: char outfile[4096];
1.1 snw 1530:
1.19 snw 1531: if ((strcmp (ent->d_name, ".") != 0) && (strcmp (ent->d_name, "..") != 0)) {
1532:
1533: fprintf (stderr, "\t%s\n", ent->d_name);
1534:
1535: snprintf (infile, 4095, "%s/%s", src_dir, ent->d_name);
1536: snprintf (outfile, 4095, "%s/%s", dest_dir, ent->d_name);
1.1 snw 1537:
1.19 snw 1538: #if !defined(__OS2__)
1539: if (cp (outfile, infile) != 0) {
1540: fprintf (stderr, "fmadm: failure copying %s to %s\n", infile, outfile);
1541: }
1.20 snw 1542: set_permissions (outfile, username, groupname, 0755);
1.19 snw 1543: #else
1544: if (DosCopy (infile, outfile, 1) != 0) {
1545: fprintf (stderr, "fmadm: failure copying %s to %s\n", infile, outfile);
1.1 snw 1546: }
1.19 snw 1547: #endif
1.1 snw 1548:
1549: }
1550:
1551: }
1.20 snw 1552:
1553: fp = fopen (env_config_file, "a+");
1554:
1555: fprintf (stderr, "Creating %s... ", env_config_file);
1556:
1557: snprintf (buf, 4095, "[%s]", fma_environment);
1558: fm_write (fp, buf);
1559:
1560: snprintf (buf, 4095, "user=%s", env_user);
1561: fm_write (fp, buf);
1562:
1563: snprintf (buf, 4095, "group=%s", env_group);
1564: fm_write (fp, buf);
1.21 snw 1565:
1566: snprintf (buf, 4095, "enabled=true");
1567: fm_write (fp, buf);
1.20 snw 1568:
1569: snprintf (buf, 4095, "env_path=%s/freem/%s", LOCALSTATEDIR, fma_environment);
1570: fm_write (fp, buf);
1571:
1572: fclose (fp);
1573: fprintf (stderr, "[OK]\n");
1.1 snw 1574:
1575: fp = fopen (config_file, "a+");
1576:
1.20 snw 1577: fprintf (stderr, "Creating %s... ", config_file);
1.1 snw 1578:
1579: snprintf (buf, 4095, "[SYSTEM]");
1580: fm_write (fp, buf);
1581:
1582: snprintf (buf, 4095, "root=%s/freem/%s/SYSTEM", LOCALSTATEDIR, fma_environment);
1583: fm_write (fp, buf);
1584:
1585: snprintf (buf, 4095, "routines_path=%s", sysrtn);
1586: fm_write (fp, buf);
1587:
1588: snprintf (buf, 4095, "globals_path=%s", sysgbl);
1589: fm_write (fp, buf);
1590:
1591: snprintf (buf, 4095, "journal_file=%s", jnlfile);
1592: fm_write (fp, buf);
1593:
1594: snprintf (buf, 4095, "journal_mode=%s", jnlmode);
1595: fm_write (fp, buf);
1596:
1597: snprintf (buf, 4095, "journal_host_id=%s", jnlhostid);
1598: fm_write (fp, buf);
1599:
1600: snprintf (buf, 4095, "journal_cut_threshold=%s", jnlcut);
1601: fm_write (fp, buf);
1602:
1603: snprintf (buf, 4095, "zdate_format=%%x");
1604: fm_write (fp, buf);
1605:
1606: snprintf (buf, 4095, "ztime_format=%%X");
1607: fm_write (fp, buf);
1608:
1609: snprintf (buf, 4095, "\n[USER]");
1610: fm_write (fp, buf);
1611:
1612: snprintf (buf, 4095, "root=%s/freem/%s/USER", LOCALSTATEDIR, fma_environment);
1613: fm_write (fp, buf);
1614:
1615: snprintf (buf, 4095, "routines_path=%s", usrrtn);
1616: fm_write (fp, buf);
1617:
1618: snprintf (buf, 4095, "globals_path=%s", usrgbl);
1619: fm_write (fp, buf);
1.20 snw 1620:
1.1 snw 1621: fclose (fp);
1.20 snw 1622: set_permissions (config_file, username, groupname, 0755);
1623: fprintf (stderr, "[OK]\n");
1.1 snw 1624:
1625: printf ("FreeM initial configuration is complete.\n\n");
1626:
1627: printf (" USER globals: %s\n", usrgbl);
1628: printf (" USER routines: %s\n", usrrtn);
1629: printf (" SYSTEM globals: %s\n", sysgbl);
1630: printf (" SYSTEM routines: %s\n", sysrtn);
1631: printf (" After-image journal: %s [%s]\n", jnlfile, jnlmode);
1632: printf (" Journal cut threshold: %s bytes\n", jnlcut);
1633: printf (" Distributed journaling host ID: %s\n", jnlhostid);
1634:
1635:
1636: } /* fm_configure */
1637:
1.20 snw 1638: void set_permissions(char *path, char *user, char *grp, int mode)
1639: {
1640:
1641: #if !defined(__OS2__)
1642: struct group *d_grp;
1643: struct passwd *d_user;
1644: gid_t d_gid;
1645: uid_t d_uid;
1646: #endif
1647:
1648:
1649: #if !defined(__OS2__)
1650: if ((d_grp = getgrnam (grp)) == NULL) {
1651: fprintf (stderr, "fmadm: '%s' group must exist before configuring\n", grp);
1652: exit (1);
1653: }
1654: d_gid = d_grp->gr_gid;
1655:
1656: if ((d_user = getpwnam (user)) == NULL) {
1657: fprintf (stderr, "fmadm: '%s' user must exist before configuring\n", user);
1658: exit (1);
1659: }
1660: d_uid = d_user->pw_uid;
1661:
1662: if (chown (path, d_uid, d_gid) != 0) {
1663: fprintf (stderr, "fmadm: error setting ownership on %s\n", path);
1664: exit (1);
1665: }
1666: #endif
1667:
1668: if (chmod (path, mode) != 0) {
1669: fprintf (stderr, "fmadm: error setting permissions on %s to %d\n", path, mode);
1670: exit (1);
1671: }
1672:
1673: }
1674:
1.1 snw 1675: void fm_write (FILE *file, char *buf)
1676: {
1677: fprintf (file, "%s\n", buf);
1678: }
1679:
1680: void fm_sig_attach (int sig, void *handler)
1681: {
1682: struct sigaction act;
1683:
1684: act.sa_handler = handler;
1685: sigaction (sig, &act, NULL);
1686:
1687: }
1688:
1689: void fm_sig_init (void)
1690: {
1691: sig_attach (SIGINT, &fm_on_sigint);
1692: sig_attach (SIGTERM, &fm_on_sigterm);
1693: }
1694:
1695: void fm_on_sigint (void)
1696: {
1697: fprintf (stderr, "\nfmadm: caught SIGINT\n");
1698: fmadm_exit (0);
1699: }
1700:
1701: void fm_on_sigterm (void)
1702: {
1703: fprintf (stderr, "\nfmadm: caught SIGTERM\n");
1704: fmadm_exit (0);
1705: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>