File:  [Coherent Logic Development] / freem / src / fmadm.c
Revision 1.37: download - view: text, annotated - select for diffs
Mon Apr 14 19:20:20 2025 UTC (5 months, 4 weeks ago) by snw
Branches: MAIN
CVS tags: HEAD
Create LOCALSTATEDIR during fmadm configure if needed

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

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