Annotation of freem/src/fmadm.c, revision 1.34

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

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