File:  [Coherent Logic Development] / freem / src / fmadm.c
Revision 1.30: download - view: text, annotated - select for diffs
Thu Apr 3 20:48:14 2025 UTC (6 months, 1 week ago) by snw
Branches: MAIN
CVS tags: v0-63-1-rc1, v0-63-0, HEAD
Improve daemon error diagnostics and bump to 0.63.0-rc3

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

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