File:  [Coherent Logic Development] / freem / src / fmadm.c
Revision 1.8: download - view: text, annotated - select for diffs
Sat Mar 22 18:43:54 2025 UTC (6 months, 2 weeks ago) by snw
Branches: MAIN
CVS tags: v0-62-2, HEAD
Make STRLEN 255 chars and add BIGSTR macro for larger buffers

    1: /*
    2:  *   $Id: fmadm.c,v 1.8 2025/03/22 18:43:54 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.8  2025/03/22 18:43:54  snw
   28:  *   Make STRLEN 255 chars and add BIGSTR macro for larger buffers
   29:  *
   30:  *   Revision 1.7  2025/03/09 19:14:25  snw
   31:  *   First phase of REUSE compliance and header reformat
   32:  *
   33:  *
   34:  * SPDX-FileCopyrightText:  (C) 2025 Coherent Logic Development LLC
   35:  * SPDX-License-Identifier: AGPL-3.0-or-later 
   36:  **/
   37: 
   38: #include <sys/types.h>
   39: #include <sys/stat.h>
   40: #include <stddef.h>
   41: #include <stdio.h>
   42: #include <string.h>
   43: #include <dirent.h>
   44: #include <stdlib.h>
   45: #include <unistd.h>
   46: #include <errno.h>
   47: #include <ctype.h>
   48: #include "config.h"
   49: #include "transact.h"
   50: #include "namespace.h"
   51: #include "fs.h"
   52: 
   53: #ifdef HAVE_LIBREADLINE
   54: #  if defined(HAVE_READLINE_READLINE_H)
   55: #    include <readline/readline.h>
   56: #  elif defined(HAVE_READLINE_H)
   57: #    include <readline.h>
   58: #  else /* !defined(HAVE_READLINE_H) */
   59: extern char *readline ();
   60: #  endif /* !defined(HAVE_READLINE_H) */
   61: /*char *cmdline = NULL;*/
   62: #else /* !defined(HAVE_READLINE_READLINE_H) */
   63:   /* no readline */
   64: #endif /* HAVE_LIBREADLINE */
   65: 
   66: #ifdef HAVE_READLINE_HISTORY
   67: #  if defined(HAVE_READLINE_HISTORY_H)
   68: #    include <readline/history.h>
   69: #  elif defined(HAVE_HISTORY_H)
   70: #    include <history.h>
   71: #  else /* !defined(HAVE_HISTORY_H) */
   72: extern void add_history ();
   73: extern int write_history ();
   74: extern int read_history ();
   75: #  endif /* defined(HAVE_READLINE_HISTORY_H) */
   76:   /* no history */
   77: #endif /* HAVE_READLINE_HISTORY */
   78: 
   79: 
   80: #include "fmadm.h"
   81: #include "errmsg.h"
   82: #include "iniconf.h"
   83: #include "init.h"
   84: #include "version.h"
   85: #include "shmmgr.h"
   86: #include "jobtab.h"
   87: #include "locktab.h"
   88: 
   89: /* namespace configuration */
   90: char fma_environment[STRLEN];
   91: char fma_namespace[STRLEN];
   92: char fma_routine_path[PATHLEN];
   93: char fma_global_path[PATHLEN];
   94: char fma_journal_path[PATHLEN];
   95: char fma_pct_global_path[PATHLEN];
   96: char fma_pct_routine_path[PATHLEN];
   97: char fma_journal_cut_threshold[STRLEN];
   98: char fma_locktab[PATHLEN];
   99: short fma_base_opt = 1;
  100: short fma_min_args = 2;
  101: short fma_explicit_namespace = FALSE;
  102: short fma_explicit_environment = FALSE;
  103: 
  104: /* miscellaneous global state */
  105: char obj_str[STRLEN];
  106: 
  107: extern char config_file[4096];
  108: 
  109: int fm_shell(void);
  110: void fm_checkperms(void);
  111: void fm_reconfigure(void);
  112: void fm_configure(void);
  113: void fm_write (FILE *file, char *buf);
  114: int fma_jobs_remove (int optc, char **opts);
  115: 
  116: int main (int argc, char **argv)
  117: {
  118:     char action[STRLEN];    
  119: 
  120:     short act = -1;
  121:     short obj = -1;
  122: 
  123:     char **opts;
  124:     int optc = argc - 3;
  125: 
  126:     int i = 0;
  127:     int j = 1;
  128:     int base_arg = 4;
  129:     int k = 0;
  130: 
  131:     short got_action = FALSE;
  132:     short got_object = FALSE;
  133: 
  134: 
  135:     /* snprintf (config_file, 4096, "%s/freem.conf", SYSCONFDIR); */
  136: 
  137:     base_arg = 1;
  138: 
  139:     /* enforce action in argv[1] */
  140:     if (argc > 1) {
  141:         if (argv[1][0] == '-') {
  142:             fprintf (stderr, "fmadm:  first argument, if given, must be an action, not a flag\n");
  143:             fmadm_usage ();
  144:             exit (1);
  145:         }
  146:     }
  147:     
  148:     for (i = base_arg; i < argc; i++) {
  149:         if (i == 1 && isalpha (argv[i][0])) {
  150:             got_action = TRUE;
  151:             strncpy (action, argv[i], STRLEN - 1);
  152:             base_arg++;
  153:         }
  154:         if (i == 2 && isalpha (argv[i][0])) {
  155:             got_object = TRUE;
  156:             strncpy (obj_str, argv[i], STRLEN - 1);
  157:             base_arg++;
  158:         }
  159:         if (argv[i][0] == '-') {
  160:                         
  161:             switch (argv[i][1]) {
  162:                 
  163:                 case 'e':
  164:                     if (argv[i][2] != '=') {
  165:                         fprintf (stderr, "fmadm:  missing equals sign in flag -%c\n", argv[i][1]);
  166:                         fmadm_usage ();
  167:                         exit (1);
  168:                     }
  169: 
  170:                     k = 0;
  171:                     
  172:                     for (j = 3; j < strlen (argv[i]); j++) {
  173:                         fma_environment[k++] = argv[i][j];
  174:                     }
  175:                     
  176:                     fma_explicit_environment = TRUE;
  177:                     base_arg++;
  178:                     
  179:                     break;
  180:                     
  181:                 case 'n':
  182:                     if (argv[i][2] != '=') {
  183:                         fprintf (stderr, "fmadm:  missing equals sign in flag -%c\n", argv[i][1]);
  184:                         fmadm_usage ();
  185:                         exit (1);
  186:                     }
  187: 
  188:                     k = 0;
  189:                     
  190:                     for (j = 3; j < strlen (argv[i]); j++) {
  191:                         fma_namespace[k++] = argv[i][j];
  192:                     }
  193:                     
  194:                     fma_explicit_namespace = TRUE;
  195:                     base_arg++;
  196:                     
  197:                     break;                                                
  198: 
  199:             }
  200:         }
  201:     }
  202: 
  203:     if (!fma_explicit_environment) snprintf (fma_environment, 4096, "DEFAULT");
  204:     if (!fma_explicit_namespace) snprintf (fma_namespace, 4096, "SYSTEM");
  205:     
  206:     snprintf (config_file, 4096, "%s/freem/%s/freem.conf", SYSCONFDIR, fma_environment);
  207: 
  208:     /*
  209:     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]);
  210:     exit(1);
  211:     */
  212:     
  213:     /* override for fmadm configure */
  214:     if (got_action) {
  215:         if (strcmp (argv[1], "configure") == 0) {
  216:             fm_configure ();
  217:             exit (0);
  218:         }
  219:         else if (strcmp (argv[1], "reconfigure") == 0) {
  220:             fm_reconfigure ();
  221:             exit (0);
  222:         }
  223:     }
  224: 
  225:     pid = getpid ();
  226:     
  227:     shm_init (16777216);
  228:     tp_init ();
  229:     jobtab_init ();
  230:     job_init (TRUE);
  231: 
  232:     fm_sig_init ();
  233:     
  234:     /* go to fmadm shell if no arguments passed */
  235:     if (!got_action && !got_object) return fm_shell ();    
  236:     
  237:     if (argc > 1 && strcmp (argv[1], "checkperms") == 0) {
  238: 	fm_checkperms ();
  239: 	exit (0);
  240:     }
  241: 
  242: #if 0
  243:     /* how many args do we have? */
  244:     switch (argc) {
  245:         
  246:         case 3: /* action, object */
  247:             strncpy (action, argv[1], STRLEN - 1);
  248:             strncpy (obj_str, argv[2], STRLEN - 1);
  249:             strncpy (fma_namespace, "SYSTEM", STRLEN - 1);
  250: 
  251:             optc = argc - 2;
  252:             
  253:             fma_explicit_namespace = FALSE;
  254:             fma_min_args = 1;
  255:             base_arg = 3;
  256:             
  257:             break;
  258: 
  259:         case 4: /* action, object, namespace */
  260: 
  261:             strncpy (action, argv[1], STRLEN - 1);
  262:             strncpy (obj_str, argv[2], STRLEN - 1);
  263: 
  264:             if (validate_namespace (argv[3]) == TRUE) {
  265:                 strncpy (fma_namespace, argv[3], STRLEN - 1);
  266:                 fma_min_args = 2;
  267:                 fma_explicit_namespace = TRUE;
  268:                 base_arg = 4;
  269:                 optc = argc - 3;
  270:             }
  271:             else {
  272:                 strncpy (fma_namespace, "SYSTEM", 10);
  273:                 fma_min_args = 1;
  274:                 fma_explicit_namespace = FALSE;
  275:                 base_arg = 3;
  276:                 optc = argc - 2;
  277:             }
  278: 
  279:             break;
  280: 
  281:         default:
  282:             if (argc < 4) fmadm_usage();
  283: 
  284:             /* we don't know what any but the first two args actually mean */
  285:             strncpy (action, argv[1], STRLEN - 1);
  286:             strncpy (obj_str, argv[2], STRLEN - 1);
  287: 
  288:             if (validate_namespace (argv[3]) == TRUE) {
  289:                 strncpy (fma_namespace, argv[3], STRLEN - 1);
  290:                 fma_min_args = 2;
  291:                 fma_explicit_namespace = TRUE;
  292:                 base_arg = 4;
  293:                 optc = argc - 3;
  294:             }
  295:             else {
  296:                 strncpy (fma_namespace, "SYSTEM", 10);
  297:                 fma_min_args = 1;
  298:                 fma_explicit_namespace = FALSE;
  299:                 base_arg = 3;
  300:                 optc = argc - 2;
  301:             }
  302: 
  303: 
  304:     }
  305: #endif
  306:     
  307:     set_namespace (fma_namespace, FALSE);
  308:     
  309:     /* allocate opts array */
  310:     
  311:     /* first dimension */
  312:     if ((opts = (char **) malloc (FMA_MAXARGS * sizeof (char *))) == NULL) {	
  313:         fprintf (stderr, "fmadm [FATAL]:  could not acquire memory\n");
  314:         return 1;
  315:     } 
  316: 
  317:     /* second dimension */
  318:     for (i = 0; i < FMA_MAXARGS; i++) {
  319:         if ((opts[i] = (char *) malloc (STRLEN * sizeof (char *))) == NULL) {
  320:             fprintf (stderr, "fmadm [FATAL]:  could not acquire memory\n");
  321:             return 1;
  322:         } 
  323:     }
  324: 
  325:     /* copy argv[base_arg] through argv[argc - 1] to opts[1] through opts[argc - 3] */
  326:     
  327:     strncpy (opts[0], argv[0], STRLEN - 1); /* preserve argv[0] */
  328: 
  329:     j = 1;
  330:     for (i = base_arg; i < argc; i++) {
  331:         if (i > FMA_MAXARGS) return fmadm_usage(); /* bail if we're going to overrun the array */
  332:         strncpy (opts[j++], argv[i], STRLEN - 1);
  333:     }
  334:     
  335:     if (strncmp (action, "list", STRLEN - 1) == 0) act = ACT_LIST;
  336:     else if (strncmp (action, "examine", STRLEN - 1) == 0) act = ACT_EXAMINE;
  337:     else if (strncmp (action, "verify", STRLEN - 1) == 0) act = ACT_VERIFY;
  338:     else if (strncmp (action, "compact", STRLEN - 1) == 0) act = ACT_COMPACT;
  339:     else if (strncmp (action, "repair", STRLEN - 1) == 0) act = ACT_REPAIR;
  340:     else if (strncmp (action, "create", STRLEN - 1) == 0) act = ACT_CREATE;
  341:     else if (strncmp (action, "remove", STRLEN - 1) == 0) act = ACT_REMOVE;
  342:     else if (strncmp (action, "import", STRLEN - 1) == 0) act = ACT_IMPORT;
  343:     else if (strncmp (action, "export", STRLEN - 1) == 0) act = ACT_EXPORT;
  344:     else if (strncmp (action, "backup", STRLEN - 1) == 0) act = ACT_BACKUP;
  345:     else if (strncmp (action, "restore", STRLEN - 1) == 0) act = ACT_RESTORE;
  346:     else if (strncmp (action, "migrate", STRLEN - 1) == 0) act = ACT_MIGRATE;
  347:     else if (strncmp (action, "edit", STRLEN -1) == 0) act = ACT_EDIT;
  348:     else return fmadm_usage();
  349: 
  350:     if (strncmp (obj_str, "lock", STRLEN - 1) == 0) obj = OBJ_LOCK;
  351:     else if (strncmp (obj_str, "zallocate", STRLEN - 1) == 0) obj = OBJ_ZALLOC;
  352:     else if (strncmp (obj_str, "journal", STRLEN - 1) == 0) obj = OBJ_JOURNAL;
  353:     else if (strncmp (obj_str, "namespace", STRLEN - 1) == 0) obj = OBJ_NAMESPACE;
  354:     else if (strncmp (obj_str, "global", STRLEN - 1) == 0) obj = OBJ_GLOBAL;
  355:     else if (strncmp (obj_str, "routine", STRLEN - 1) == 0) obj = OBJ_ROUTINE;
  356:     else if (strncmp (obj_str, "job", STRLEN - 1) == 0) obj = OBJ_JOB;
  357:     else return fmadm_usage();
  358: 
  359:     if (get_conf (fma_namespace, "routines_path", fma_routine_path) == FALSE) {
  360:         fprintf (stderr, "fmadm:  cannot determine routine path for namespace %s\n", fma_namespace);
  361:         return 1;
  362:     }   
  363: 
  364:     if (get_conf (fma_namespace, "globals_path", fma_global_path) == FALSE) {
  365:         fprintf (stderr, "fmadm:  cannot determine global path for namespace %s\n", fma_namespace);
  366:         return 1;
  367:     }   
  368: 
  369:     if (get_conf ("SYSTEM", "globals_path", fma_pct_global_path) == FALSE) {
  370:         fprintf (stderr, "fmadm:  cannot determine %% global path for namespace %s\n", "SYSTEM");
  371:         return 1;
  372:     }
  373: 
  374:     if (get_conf ("SYSTEM", "routines_path", fma_pct_routine_path) == FALSE) {
  375:         fprintf (stderr, "fmadm:  cannot determine %% routine path for namespace %s\n", "SYSTEM");
  376:         return 1;
  377:     }
  378: 
  379:     if (get_conf ("SYSTEM", "journal_file", fma_journal_path) == FALSE) {
  380:         strcpy (fma_journal_path, "");
  381:     }
  382: 
  383:     if (get_conf ("SYSTEM", "journal_cut_threshold", fma_journal_cut_threshold) == FALSE) {
  384:         strcpy (fma_journal_cut_threshold, "1073741824");
  385:     }
  386:     
  387:     strcpy (gloplib, fma_pct_global_path);
  388:     stcnv_c2m (gloplib);
  389: 
  390:     strcpy (glopath, fma_global_path);
  391:     stcnv_c2m (glopath);
  392: 
  393: 
  394:     switch (act) {
  395: 
  396:         
  397:         case ACT_LIST:
  398:             fmadm_exit (fm_list (obj, optc, opts));
  399: 
  400: 
  401:         case ACT_EXAMINE:
  402:             fmadm_exit (fm_examine (obj, optc, opts));
  403: 
  404: 
  405:         case ACT_VERIFY:
  406:             fmadm_exit (fm_verify (obj, optc, opts));
  407: 
  408: 
  409:         case ACT_COMPACT:
  410:             fmadm_exit (fm_compact (obj, optc, opts));
  411: 
  412: 
  413:         case ACT_REPAIR:
  414:             fmadm_exit (fm_repair (obj, optc, opts));
  415: 
  416: 
  417:         case ACT_CREATE:
  418:             fmadm_exit (fm_create (obj, optc, opts));
  419: 
  420: 
  421:         case ACT_REMOVE:
  422:             fmadm_exit (fm_remove (obj, optc, opts));
  423: 
  424: 
  425:         case ACT_IMPORT:
  426:             fmadm_exit (fm_import (obj, optc, opts));
  427: 
  428: 
  429:         case ACT_EXPORT:
  430:             fmadm_exit (fm_export (obj, optc, opts));
  431: 
  432: 
  433:         case ACT_BACKUP:
  434:             fmadm_exit (fm_backup (obj, optc, opts));
  435: 
  436: 
  437:         case ACT_RESTORE:
  438:             fmadm_exit (fm_restore (obj, optc, opts));
  439: 
  440: 
  441:         case ACT_MIGRATE:
  442:             fmadm_exit (fm_migrate (obj, optc, opts));
  443: 
  444: 
  445:         case ACT_EDIT:
  446:             fmadm_exit (fm_edit (obj, optc, opts));
  447: 
  448: 
  449:         default:
  450:             return fmadm_usage();
  451:     }
  452: 
  453:     return 0;   /* should never be reached */
  454: 
  455: } /* main() */
  456: 
  457: int fm_shell (void)
  458: {
  459:     
  460: #if defined(HAVE_LIBREADLINE) && !defined(_AIX)
  461:     int cmd;
  462:     int i;
  463:     int j;
  464:     int obj;
  465:     int optc;
  466:     int argc;
  467:     char **args;
  468:     char **opts;    
  469:     char *fmarl_buf;
  470:     char *fma_prompt = (char *) malloc (STRLEN * sizeof (char));
  471:     char *cmdt = (char *) malloc (65535 * sizeof (char));
  472:     char *result = (char *) malloc (65535 * sizeof (char));
  473: 
  474:     /*
  475:     strcpy (fma_namespace, "SYSTEM");
  476:     set_namespace (fma_namespace, FALSE);
  477:     */
  478:     
  479:     snprintf (fma_prompt, STRLEN - 1, "fmadm [%s]> ", fma_namespace);
  480:     
  481:     if (get_conf (fma_namespace, "routines_path", fma_routine_path) == FALSE) {
  482:         fprintf (stderr, "fmadm:  cannot determine routine path for namespace %s\n", fma_namespace);
  483:         return 1;
  484:     }   
  485: 
  486:     if (get_conf (fma_namespace, "globals_path", fma_global_path) == FALSE) {
  487:         fprintf (stderr, "fmadm:  cannot determine global path for namespace %s\n", fma_namespace);
  488:         return 1;
  489:     }   
  490: 
  491:     if (get_conf ("SYSTEM", "globals_path", fma_pct_global_path) == FALSE) {
  492:         fprintf (stderr, "fmadm:  cannot determine %% global path for namespace %s\n", "SYSTEM");
  493:         return 1;
  494:     }
  495: 
  496:     if (get_conf ("SYSTEM", "routines_path", fma_pct_routine_path) == FALSE) {
  497:         fprintf (stderr, "fmadm:  cannot determine %% routine path for namespace %s\n", "SYSTEM");
  498:         return 1;
  499:     }
  500: 
  501:     if (get_conf ("SYSTEM", "journal_file", fma_journal_path) == FALSE) {
  502:         strcpy (fma_journal_path, "");
  503:     }
  504: 
  505:     if (get_conf ("SYSTEM", "journal_cut_threshold", fma_journal_cut_threshold) == FALSE) {
  506:         strcpy (fma_journal_cut_threshold, "1073741824");
  507:     }
  508:     
  509:     strcpy (gloplib, fma_pct_global_path);
  510:     stcnv_c2m (gloplib);
  511: 
  512:     strcpy (glopath, fma_global_path);
  513:     stcnv_c2m (glopath);
  514:     
  515:     /* allocate args array */
  516:     
  517:     /* first dimension */
  518:     if ((args = (char **) malloc (FMA_MAXARGS * sizeof (char *))) == NULL) {	
  519:         fprintf (stderr, "fmadm [FATAL]:  could not acquire memory\n");
  520:         return 1;
  521:     } 
  522: 
  523:     /* second dimension */
  524:     for (i = 0; i < FMA_MAXARGS; i++) {
  525:         if ((args[i] = (char *) malloc (STRLEN * sizeof (char *))) == NULL) {
  526:             fprintf (stderr, "fmadm [FATAL]:  could not acquire memory\n");
  527:             return 1;
  528:         } 
  529:     }
  530: 
  531:     /* allocate opts array */
  532:     
  533:     /* first dimension */
  534:     if ((opts = (char **) malloc (FMA_MAXARGS * sizeof (char *))) == NULL) {	
  535:         fprintf (stderr, "fmadm [FATAL]:  could not acquire memory\n");
  536:         return 1;
  537:     } 
  538: 
  539:     /* second dimension */
  540:     for (i = 0; i < FMA_MAXARGS; i++) {
  541:         if ((opts[i] = (char *) malloc (STRLEN * sizeof (char *))) == NULL) {
  542:             fprintf (stderr, "fmadm [FATAL]:  could not acquire memory\n");
  543:             return 1;
  544:         } 
  545:     }
  546: 
  547:     
  548:     for (;;) {
  549: 
  550:         fmarl_buf = readline (fma_prompt);
  551: 
  552:         if (fmarl_buf == (char *) NULL) continue;
  553:         
  554:         cmdt = strtok (fmarl_buf, " ");
  555: 
  556:         if (cmdt == (char *) NULL) continue;
  557:         
  558:         for (i = 0; i < strlen (cmdt); i++) cmdt[i] = cmdt[i] | 0140;        
  559:         
  560:         if (strcmp (cmdt, "exit") == 0) cmd = FMAC_EXIT;
  561:         else if (strcmp (cmdt, "quit") == 0) cmd = FMAC_EXIT;
  562:         else if (strcmp (cmdt, "select") == 0) cmd = FMAC_SELECT;
  563:         else if (strcmp (cmdt, "list") == 0) cmd = FMAC_LIST;
  564:         else if (strcmp (cmdt, "examine") == 0) cmd = FMAC_EXAMINE;
  565:         else if (strcmp (cmdt, "verify") == 0) cmd = FMAC_VERIFY;
  566:         else if (strcmp (cmdt, "compact") == 0) cmd = FMAC_COMPACT;
  567:         else if (strcmp (cmdt, "repair") == 0) cmd = FMAC_REPAIR;
  568:         else if (strcmp (cmdt, "create") == 0) cmd = FMAC_CREATE;
  569:         else if (strcmp (cmdt, "import") == 0) cmd = FMAC_IMPORT;
  570:         else if (strcmp (cmdt, "export") == 0) cmd = FMAC_EXPORT;
  571:         else if (strcmp (cmdt, "backup") == 0) cmd = FMAC_BACKUP;
  572:         else if (strcmp (cmdt, "restore") == 0) cmd = FMAC_RESTORE;
  573:         else if (strcmp (cmdt, "migrate") == 0) cmd = FMAC_MIGRATE;
  574:         else if (strcmp (cmdt, "edit") == 0) cmd = FMAC_EDIT;
  575:         else if (strcmp (cmdt, "set") == 0) cmd = FMAC_SET;
  576:         else if (strcmp (cmdt, "show") == 0) cmd = FMAC_SHOW;
  577:         else if (strcmp (cmdt, "remove") == 0) cmd = FMAC_REMOVE;
  578:         else cmd = FMAC_INVALID;            
  579: 
  580:         i = 0;
  581:         while ((result = strtok (NULL, " ")) != NULL) {
  582:             //    printf ("%d = %s\n", i, result);
  583:             strcpy (args[i++], result);
  584:         }
  585: 
  586:         argc = i;
  587:         j = 0;
  588:         
  589:         for (i = 1; i < argc; i++) {
  590:             strncpy (opts[j++], args[i], STRLEN - 1);
  591:         }
  592: 
  593:         optc = argc - 1;
  594:         
  595:         if (i > 0) {
  596:             
  597:             strcpy (obj_str, args[0]);
  598:         
  599:             if (strncmp (obj_str, "lock", STRLEN - 1) == 0) obj = OBJ_LOCK;
  600:             else if (strncmp (obj_str, "zallocate", STRLEN - 1) == 0) obj = OBJ_ZALLOC;
  601:             else if (strncmp (obj_str, "journal", STRLEN - 1) == 0) obj = OBJ_JOURNAL;
  602:             else if (strncmp (obj_str, "namespace", STRLEN - 1) == 0) obj = OBJ_NAMESPACE;
  603:             else if (strncmp (obj_str, "global", STRLEN - 1) == 0) obj = OBJ_GLOBAL;
  604:             else if (strncmp (obj_str, "routine", STRLEN - 1) == 0) obj = OBJ_ROUTINE;
  605:             else if (strncmp (obj_str, "job", STRLEN - 1) == 0) obj = OBJ_JOB;
  606: 
  607:         }
  608:         
  609:         switch (cmd) {
  610: 
  611:             
  612:             case FMAC_SELECT:
  613:                 
  614:                 
  615:                 break;
  616: 
  617:                 
  618:             case FMAC_LIST:
  619:                 fm_list (obj, optc, opts);
  620:                 break;
  621: 
  622:                 
  623:             case FMAC_EXAMINE:
  624:                 fm_examine (obj, optc, opts);
  625:                 break;
  626: 
  627: 
  628:             case FMAC_VERIFY:
  629:                 fm_verify (obj, optc, opts);
  630:                 break;
  631: 
  632: 
  633:             case FMAC_COMPACT:
  634:                 fm_compact (obj, optc, opts);
  635:                 break;
  636: 
  637: 
  638:             case FMAC_REPAIR:
  639:                 fm_repair (obj, optc, opts);
  640:                 break;
  641: 
  642: 
  643:             case FMAC_CREATE:
  644:                 fm_create (obj, optc, opts);
  645:                 break;
  646: 
  647: 
  648:             case FMAC_REMOVE:
  649:                 fm_remove (obj, optc, opts);
  650:                 break;
  651: 
  652: 
  653:             case FMAC_IMPORT:
  654:                 fm_import (obj, optc, opts);
  655:                 break;
  656: 
  657: 
  658:             case FMAC_EXPORT:
  659:                 fm_export (obj, optc, opts);
  660:                 break;
  661: 
  662: 
  663:             case FMAC_BACKUP:
  664:                 fm_backup (obj, optc, opts);
  665:                 break;
  666: 
  667: 
  668:             case FMAC_RESTORE:
  669:                 fm_restore (obj, optc, opts);
  670:                 break;
  671: 
  672: 
  673:             case FMAC_MIGRATE:
  674:                 fm_migrate (obj, optc, opts);
  675:                 break;
  676: 
  677: 
  678:             case FMAC_EDIT:
  679:                 fm_edit (obj, optc, opts);
  680:                 break;
  681: 
  682: 
  683:             case FMAC_SET:
  684: 
  685:                 if (i < 2) {
  686:                     printf ("fmadm:  syntax error\n");
  687:                     break;
  688:                 }
  689:                 
  690:                 if (strcmp (args[0], "namespace") == 0) {
  691:                     strcpy (fma_namespace, args[1]);
  692: 
  693:                     if (get_conf (fma_namespace, "routines_path", fma_routine_path) == FALSE) {
  694:                         fprintf (stderr, "fmadm:  cannot determine routine path for namespace %s\n", fma_namespace);
  695:                         return 1;
  696:                     }   
  697:                     
  698:                     if (get_conf (fma_namespace, "globals_path", fma_global_path) == FALSE) {
  699:                         fprintf (stderr, "fmadm:  cannot determine global path for namespace %s\n", fma_namespace);
  700:                         return 1;
  701:                     }   
  702:                     
  703:                     if (get_conf ("SYSTEM", "globals_path", fma_pct_global_path) == FALSE) {
  704:                         fprintf (stderr, "fmadm:  cannot determine %% global path for namespace %s\n", "SYSTEM");
  705:                         return 1;
  706:                     }
  707:                     
  708:                     if (get_conf ("SYSTEM", "routines_path", fma_pct_routine_path) == FALSE) {
  709:                         fprintf (stderr, "fmadm:  cannot determine %% routine path for namespace %s\n", "SYSTEM");
  710:                         return 1;
  711:                     }
  712:                     
  713:                     if (get_conf ("SYSTEM", "journal_file", fma_journal_path) == FALSE) {
  714:                         strcpy (fma_journal_path, "");
  715:                     }
  716:                     
  717:                     if (get_conf ("SYSTEM", "journal_cut_threshold", fma_journal_cut_threshold) == FALSE) {
  718:                         strcpy (fma_journal_cut_threshold, "1073741824");
  719:                     }
  720:                     
  721:                     strcpy (gloplib, fma_pct_global_path);
  722:                     stcnv_c2m (gloplib);
  723:                     
  724:                     strcpy (glopath, fma_global_path);
  725:                     stcnv_c2m (glopath);
  726: 
  727:                     snprintf (fma_prompt, STRLEN - 1, "fmadm [%s]> ", fma_namespace);
  728:                     
  729:                 }
  730:                 else if (strcmp (args[0], "maintenance") == 0) {
  731:                     if (strcmp (args[1], "on") == 0) {
  732:                         shm_config->hdr->maintenance_mode = 1;
  733:                         break;
  734:                     }
  735:                     else if (strcmp (args[1], "off") == 0) {
  736:                         shm_config->hdr->maintenance_mode = 0;
  737:                         break;
  738:                     }
  739:                     else {
  740:                         printf ("fmadm:  syntax error\n");
  741:                     }
  742: 
  743:                     printf ("fmadm:  syntax error\n");
  744:                         
  745:                 }
  746:                 else {
  747:                     printf ("fmadm:  syntax error\n");
  748:                     break;
  749:                 }
  750:                 
  751:                 break;
  752: 
  753:                 
  754:             case FMAC_SHOW:
  755:                 printf ("Namespace:                  %s\n", fma_namespace);
  756:                 printf ("Routine Path:               %s\n", fma_routine_path);
  757:                 printf ("%%-Routine Path:             %s\n", fma_pct_routine_path);
  758:                 printf ("Global Path:                %s\n", fma_global_path);
  759:                 printf ("%%-Global Path:              %s\n", fma_pct_global_path);
  760:                 printf ("Journal File:               %s\n", fma_journal_path);
  761:                 printf ("Journal Cut Threshold:      %s bytes\n", fma_journal_cut_threshold);
  762:                 break;
  763: 
  764:             case FMAC_EXIT:
  765:                 fmadm_exit (0);
  766:                 break;
  767: 
  768: 
  769:             default:
  770:                 printf ("fmadm:  '%s' is not a valid fmadm command\n", cmdt);
  771:                 break;
  772: 
  773:         }
  774:     }
  775: 
  776: #endif
  777:     
  778: }
  779: 
  780: void fmadm_exit (int retval)
  781: {
  782:     locktab_unlock_all ();
  783:     job_remove (pid);
  784:     
  785:     shm_exit ();
  786: 
  787:     exit (retval);
  788: }
  789: 
  790: int fmadm_usage (void)
  791: {
  792: 
  793:     fprintf (stdout, "\nusage:  fmadm <action> <object> [-e=<environment] [-n=<namespace>] [OPTIONS]\n");
  794:     fprintf (stdout, "        fmadm configure\n");
  795:     fprintf (stdout, "        fmadm reconfigure\n");
  796:     /* fprintf (stdout, "        fmadm checkperms\n\n"); */
  797:     
  798:     fprintf (stdout, "        <action> can be one of:\n");
  799:     fprintf (stdout, "            list, examine, verify, compact, repair, create, remove,\n");
  800:     fprintf (stdout, "            import, export, backup, restore, migrate, edit\n\n");
  801: 
  802:     fprintf (stdout, "        <object> can be one of:\n");
  803:     fprintf (stdout, "            lock, zallocate, journal, namespace, global, routine, job\n\n");
  804: 
  805:     fprintf (stdout, "    Not all actions are valid for all objects. Please see the FreeM manual\n");
  806:     fprintf (stdout, "    for details on fmadm usage and options.\n\n");
  807:     
  808:     return 1;
  809: 
  810: } /* fmadm_usage() */
  811: 
  812: int fm_list (short object, int optc, char **options)
  813: {
  814: 
  815:     switch (object) {
  816: 
  817:         case OBJ_LOCK:
  818:             return fma_locks_list (optc, options);
  819: 
  820:         case OBJ_ROUTINE:
  821:             return fma_routines_list (optc, options);
  822: 
  823:         case OBJ_GLOBAL:
  824:             return fma_globals_list (optc, options);
  825: 
  826:         case OBJ_JOB:
  827:             return fma_jobs_list (optc, options);
  828: 
  829:         default:
  830:             fprintf (stderr, "fmadm:  'list' is an invalid action for '%s'\n", obj_str);
  831:             return 1;
  832: 
  833:     }
  834: 
  835: 
  836: } /* fm_list() */
  837: 
  838: int fm_examine (short object, int optc, char **options)
  839: {
  840: 
  841:     switch (object) {
  842: 
  843:         case OBJ_ROUTINE:
  844:             return fma_routines_examine (optc, options);
  845: 
  846:         case OBJ_GLOBAL:
  847:             return fma_globals_examine (optc, options);
  848: 
  849:         case OBJ_JOB:
  850:             return fma_jobs_examine (optc, options);
  851: 
  852:         case OBJ_JOURNAL:
  853:             return fma_journals_examine (optc, options);
  854:             
  855:         default:
  856:             fprintf (stderr, "fmadm:  'examine' is an invalid action for '%s'\n", obj_str);
  857:             return 1;
  858: 
  859:     }
  860: 
  861: } /* fm_examine() */
  862: 
  863: int fm_verify (short object, int optc, char **options)
  864: {
  865: 
  866:     switch (object) {
  867: 
  868:         case OBJ_GLOBAL:
  869:             return fma_globals_verify (optc, options);
  870:         
  871:         default:
  872:             fprintf (stderr, "fmadm:  'examine' is an invalid action for '%s'\n", obj_str);
  873:             return 1;
  874: 
  875:     }
  876: 
  877: } /* fm_verify() */ 
  878: 
  879: int fm_compact (short object, int optc, char **options)
  880: {
  881: 
  882:     switch (object) {
  883: 
  884:         default:
  885:             fprintf (stderr, "fmadm:  'compact' is an invalid action for '%s'\n", obj_str);
  886:             return 1;
  887: 
  888:     }
  889: 
  890: } /* fm_compact() */
  891: 
  892: int fm_repair (short object, int optc, char **options)
  893: {
  894: 
  895:     switch (object) {
  896: 
  897:         default:
  898:             fprintf (stderr, "fmadm:  'repair' is an invalid action for '%s'\n", obj_str);
  899:             return 1;
  900: 
  901:     }
  902: 
  903: } /* fm_repair() */
  904: 
  905: int fm_create (short object, int optc, char **options)
  906: {
  907: 
  908:     switch (object) {
  909: 
  910:         default:
  911:             fprintf (stderr, "fmadm:  'create' is an invalid action for '%s'\n", obj_str);
  912:             return 1;
  913: 
  914:     }
  915: } /* fm_create() */
  916: 
  917: int fm_remove (short object, int optc, char **options)
  918: {
  919: 
  920:     switch (object) {
  921: 
  922:         case OBJ_JOB:
  923:             return fma_jobs_remove (optc, options);
  924:         
  925:         case OBJ_LOCK:
  926:             return fma_locks_remove (optc, options);
  927: 
  928:         case OBJ_ROUTINE:
  929:             return fma_routines_remove (optc, options);
  930: 
  931:         case OBJ_GLOBAL:
  932:             return fma_globals_remove (optc, options);
  933: 
  934:         default:
  935:             fprintf (stderr, "fmadm:  'remove' is an invalid action for '%s'\n", obj_str);
  936:             return 1;
  937: 
  938:     }
  939: 
  940: } /* fm_remove() */
  941: 
  942: int fm_import (short object, int optc, char **options)
  943: {
  944: 
  945:     switch (object) {
  946: 
  947:         case OBJ_ROUTINE: 
  948:             return fma_routines_import (optc, options);
  949: 
  950:         default:
  951:             fprintf (stderr, "fmadm:  'import' is an invalid action for '%s'\n", obj_str);
  952:             return 1;
  953: 
  954:     }
  955: 
  956: } /* fm_import() */
  957: 
  958: int fm_export (short object, int optc, char **options)
  959: {
  960: 
  961:     switch (object) {
  962: 
  963:         case OBJ_ROUTINE: 
  964:             return fma_routines_export (optc, options);
  965: 
  966:         default:
  967:             fprintf (stderr, "fmadm:  'export' is an invalid action for '%s'\n", obj_str);
  968:             return 1;
  969: 
  970:     }
  971: 
  972: } /* fm_export() */
  973: 
  974: int fm_backup (short object, int optc, char **options)
  975: {
  976: 
  977:     switch (object) {
  978: 
  979:         case OBJ_ROUTINE: 
  980:             return fma_routines_backup (optc, options);
  981: 
  982:         default:
  983:             fprintf (stderr, "fmadm:  'backup' is an invalid action for '%s'\n", obj_str);
  984:             return 1;
  985: 
  986:     }
  987: 
  988: } /* fm_backup() */
  989: 
  990: int fm_restore (short object, int optc, char **options)
  991: {
  992: 
  993:     switch (object) {
  994: 
  995:         case OBJ_JOURNAL:
  996:             return fma_journals_restore (optc, options);
  997:         
  998:         default:
  999:             fprintf (stderr, "fmadm:  'restore' is an invalid action for '%s'\n", obj_str);
 1000:             return 1;
 1001: 
 1002:     }
 1003: 
 1004: } /* fm_restore() */
 1005: 
 1006: int fm_migrate (short object, int optc, char **options)
 1007: {
 1008: 
 1009:     switch (object) {
 1010: 
 1011:         default:
 1012:             fprintf (stderr, "fmadm:  'migrate' is an invalid action for '%s'\n", obj_str);
 1013:             return 1;
 1014: 
 1015:     }
 1016: 
 1017: } /* fm_migrate() */
 1018: 
 1019: int fm_edit (short object, int optc, char **options)
 1020: {
 1021: 
 1022:     switch (object) {
 1023: 
 1024:         case OBJ_ROUTINE:
 1025:             return fma_routines_edit (optc, options);
 1026: 
 1027:         /*
 1028:         case OBJ_GLOBAL:
 1029:             return fma_globals_edit (optc, options);
 1030:         */
 1031:             
 1032:         default:
 1033:             fprintf (stderr, "fmadm:  'edit' is an invalid action for '%s'\n", obj_str);
 1034:             return 1;
 1035: 
 1036:     }
 1037: 
 1038: } /* fm_edit() */
 1039: 
 1040: void fm_checkperms(void)
 1041: {
 1042: 
 1043: } /* fm_checkperms() */
 1044: 
 1045: 
 1046: void fm_reconfigure(void)
 1047: {
 1048:     char config_backup[4096];
 1049:     char vers[4096];
 1050:     
 1051:     int retval;   
 1052:     
 1053:     if (geteuid () != 0) {
 1054:         fprintf (stderr, "fmadm:  not superuser\n");
 1055:         exit (1);
 1056:     }
 1057:     
 1058:     snprintf (config_backup, 4095, "%s.orig", config_file);
 1059: 
 1060:     fprintf (stderr, "fmadm:  reconfiguring FreeM with system defaults for %s...\n", FREEM_VERSION_CSTR);
 1061:     fprintf (stderr, "fmadm:  backing up %s to %s...\t", config_file, config_backup);    
 1062: 
 1063:     retval = rename (config_file, config_backup);
 1064: 
 1065:     if (retval == 0) {
 1066: 	fprintf (stderr, "[OK]\n\n");
 1067: 	
 1068: 	fm_configure ();
 1069: 
 1070: 	fprintf (stderr, "\n\nYou may wish to edit %s if site-specific changes were made to the original FreeM configuration.\n", config_file);
 1071: 	exit (0);
 1072:     }
 1073:     else {
 1074: 	fprintf (stderr, "[FAIL (%s)]\n", strerror (errno));
 1075: 	exit (1);
 1076:     }
 1077:     
 1078: } /* fm_reconfigure() */
 1079: 
 1080: 
 1081: void fm_configure (void)
 1082: {
 1083: 
 1084:     char sysrtn[4096];
 1085:     char sysgbl[4096];
 1086:     char usrrtn[4096];
 1087:     char usrgbl[4096];
 1088: 
 1089:     char locktab[4096];
 1090:     char zalloctab[4096];
 1091:     char jnlfile[4096];
 1092:     char jnlmode[4];
 1093:     char jnlhostid[4096];    
 1094:     char jnlcut[4096];
 1095:     char hostid[4096];
 1096: 
 1097:     char confbase[4096];
 1098:     char envbase[4096];
 1099: 
 1100:     char nsbase[4096];
 1101:     
 1102:     char buf[4096];
 1103:     FILE *fp;
 1104: 
 1105:     struct stat etcstat;
 1106:     int stat_result;
 1107:     
 1108:     snprintf (sysrtn, 4095, "%s/freem/%s/SYSTEM/routines", LOCALSTATEDIR, fma_environment);
 1109:     snprintf (sysgbl, 4095, "%s/freem/%s/SYSTEM/globals", LOCALSTATEDIR, fma_environment);
 1110:     snprintf (usrrtn, 4095, "%s/freem/%s/USER/routines", LOCALSTATEDIR, fma_environment);
 1111:     snprintf (usrgbl, 4095, "%s/freem/%s/USER/globals", LOCALSTATEDIR, fma_environment);
 1112:     snprintf (locktab, 4095, "/tmp/locktab");
 1113:     snprintf (zalloctab, 4095, "/tmp/zalloctab");
 1114:     snprintf (jnlfile, 4095, "/tmp/freem_journal_%s.dat", fma_environment);
 1115:     snprintf (jnlmode, 3, "on");
 1116:     snprintf (jnlhostid, 4095, "DEFAULT");
 1117:     snprintf (jnlcut, 4095, "4294967000");
 1118:     
 1119:     if (geteuid () != 0) {
 1120:         fprintf (stderr, "fmadm:  not superuser\n");
 1121:         exit (1);
 1122:     }
 1123:     
 1124:     if (file_exists (config_file)) {
 1125:         fprintf (stderr, "fmadm:  '%s' already exists.\n\n", config_file);
 1126:         fprintf (stderr, "'fmadm configure' may only be used on a fresh installation of FreeM.\n");
 1127:         exit (1);
 1128:     }
 1129: 
 1130: 
 1131:     gethostname (hostid, 4095);
 1132:     uuid_v4 (buf);
 1133: 
 1134:     snprintf (jnlhostid, 4095, "%s:%s", hostid, buf);
 1135: 
 1136:     snprintf (confbase, 4095, "%s/freem", SYSCONFDIR);
 1137:     snprintf (envbase, 4095, "%s/freem/%s", SYSCONFDIR, fma_environment); 
 1138:     snprintf (nsbase, 4095, "%s/freem/%s", LOCALSTATEDIR, fma_environment);
 1139: 
 1140:     printf ("\nFreeM Initial Configuration\n");
 1141:     printf ("---------------------------\n\n");
 1142: 
 1143:     printf ("This utility will create the initial configuration file for ");
 1144:     printf ("FreeM environment '%s' in %s.\n\n", fma_environment, config_file);    
 1145: 
 1146:     
 1147:     /* check for existence of needed directories */
 1148:     if (stat (SYSCONFDIR, &etcstat) == -1) {
 1149: 	fprintf (stderr, "fmadm:  creating %s\n", SYSCONFDIR);
 1150: 	mkdir (SYSCONFDIR, 0755);
 1151:     }
 1152: 
 1153:     if (stat (confbase, &etcstat) == -1) {
 1154:         fprintf (stderr, "fmadm:  creating %s\n", confbase);
 1155:         mkdir (confbase, 0755);
 1156:     }
 1157: 
 1158:     if (stat (envbase, &etcstat) == -1) {
 1159:         fprintf (stderr, "fmadm:  creating %s\n", envbase);
 1160:         mkdir (envbase, 0755);
 1161:     }
 1162: 
 1163:     if (stat (nsbase, &etcstat) == -1) {
 1164:         fprintf (stderr, "fmadm:  creating %s\n", nsbase);
 1165:         mkdir (nsbase, 0755);
 1166:     }
 1167: 
 1168:    
 1169: 
 1170:     if (strcmp (fma_environment, "DEFAULT") != 0) {
 1171: 
 1172:         DIR *dir;
 1173:         struct dirent *ent;
 1174:         char src_dir[4096];
 1175:         char dest_dir[4096];
 1176: 
 1177:         snprintf (src_dir, 4095, "%s/freem/DEFAULT/SYSTEM/routines", LOCALSTATEDIR);
 1178:         snprintf (dest_dir, 4095, "%s/freem/%s/SYSTEM/routines", LOCALSTATEDIR, fma_environment);
 1179:         
 1180:         fprintf (stderr, "fmadm:  populating new environment '%s'\n", fma_environment);
 1181:         
 1182:         snprintf (buf, 4095, "%s/freem/%s/SYSTEM", LOCALSTATEDIR, fma_environment);
 1183:         mkdir (buf, 0755);
 1184: 
 1185:         snprintf (buf, 4095, "%s/freem/%s/USER", LOCALSTATEDIR, fma_environment);
 1186:         mkdir (buf, 0755);
 1187: 
 1188:         snprintf (buf, 4095, "%s/freem/%s/SYSTEM/routines", LOCALSTATEDIR, fma_environment);
 1189:         mkdir (buf, 0755);
 1190: 
 1191:         snprintf (buf, 4095, "%s/freem/%s/USER/globals", LOCALSTATEDIR, fma_environment);
 1192:         mkdir (buf, 0755);
 1193: 
 1194:         snprintf (buf, 4095, "%s/freem/%s/SYSTEM/globals", LOCALSTATEDIR, fma_environment);
 1195:         mkdir (buf, 0755);
 1196: 
 1197:         snprintf (buf, 4095, "%s/freem/%s/USER/routines", LOCALSTATEDIR, fma_environment);
 1198:         mkdir (buf, 0755);
 1199: 
 1200:         fprintf (stderr, "fmadm:  copying routines from '%s' to '%s'...\n", src_dir, dest_dir);
 1201: 
 1202:         if ((dir = opendir (src_dir)) == NULL) {
 1203:             fprintf (stderr, "\nfmadm:  could not open source directory %s\n", src_dir);
 1204:             exit (1);
 1205:         }
 1206: 
 1207:         while ((ent = readdir (dir)) != NULL) {
 1208:             char infile[4096];
 1209:             char outfile[4096];
 1210:            
 1211:             if ((strcmp (ent->d_name, ".") != 0) && (strcmp (ent->d_name, "..") != 0)) {
 1212: 
 1213:                 fprintf (stderr, "\t%s\n", ent->d_name);
 1214:                 
 1215:                 snprintf (infile, 4095, "%s/%s", src_dir, ent->d_name);
 1216:                 snprintf (outfile, 4095, "%s/%s", dest_dir, ent->d_name);
 1217: 
 1218:                 if (cp (outfile, infile) != 0) {
 1219:                     fprintf (stderr, "fmadm:  failure copying %s to %s\n", infile, outfile);
 1220:                 }
 1221: 
 1222:             }
 1223:             
 1224:         }
 1225:             
 1226:         
 1227:     }
 1228:     
 1229:    
 1230:     fp = fopen (config_file, "a+");
 1231:     
 1232: 
 1233:     printf ("Creating %s... ", config_file); 
 1234:     
 1235:     snprintf (buf, 4095, "[SYSTEM]");
 1236:     fm_write (fp, buf);
 1237: 
 1238:     snprintf (buf, 4095, "root=%s/freem/%s/SYSTEM", LOCALSTATEDIR, fma_environment);
 1239:     fm_write (fp, buf);
 1240: 
 1241:     snprintf (buf, 4095, "routines_path=%s", sysrtn);
 1242:     fm_write (fp, buf);
 1243: 
 1244:     snprintf (buf, 4095, "globals_path=%s", sysgbl);
 1245:     fm_write (fp, buf);
 1246: 
 1247:     snprintf (buf, 4095, "journal_file=%s", jnlfile);
 1248:     fm_write (fp, buf);
 1249: 
 1250:     snprintf (buf, 4095, "journal_mode=%s", jnlmode);
 1251:     fm_write (fp, buf);
 1252: 
 1253:     snprintf (buf, 4095, "journal_host_id=%s", jnlhostid);
 1254:     fm_write (fp, buf);
 1255: 
 1256:     snprintf (buf, 4095, "journal_cut_threshold=%s", jnlcut);
 1257:     fm_write (fp, buf);
 1258: 
 1259:     snprintf (buf, 4095, "zdate_format=%%x");
 1260:     fm_write (fp, buf);
 1261: 
 1262:     snprintf (buf, 4095, "ztime_format=%%X");
 1263:     fm_write (fp, buf);
 1264:     
 1265:     snprintf (buf, 4095, "\n[USER]");
 1266:     fm_write (fp, buf);
 1267: 
 1268:     snprintf (buf, 4095, "root=%s/freem/%s/USER", LOCALSTATEDIR, fma_environment);
 1269:     fm_write (fp, buf);
 1270: 
 1271:     snprintf (buf, 4095, "routines_path=%s", usrrtn);
 1272:     fm_write (fp, buf);
 1273: 
 1274:     snprintf (buf, 4095, "globals_path=%s", usrgbl);
 1275:     fm_write (fp, buf);
 1276:     
 1277:     
 1278:     fclose (fp);
 1279: 
 1280:     printf ("[OK]\n\n");
 1281: 
 1282: /*
 1283:     printf ("Setting USER namespace permissions... ");
 1284: 
 1285:     snprintf (buf, 4095, "%s/freem/USER/globals", LOCALSTATEDIR);
 1286:     chmod (buf, 0777);
 1287: 
 1288:     snprintf (buf, 4095, "%s/freem/USER/routines", LOCALSTATEDIR);
 1289:     chmod (buf, 0777);
 1290: 
 1291:     printf ("[OK]\n");
 1292:     printf ("Setting SYSTEM namespace permissions... ");
 1293:     
 1294:     snprintf (buf, 4095, "%s/freem/SYSTEM/globals", LOCALSTATEDIR);
 1295:     chmod (buf, 0755);
 1296: 
 1297:     snprintf (buf, 4095, "%s/freem/SYSTEM/routines", LOCALSTATEDIR);
 1298:     chmod (buf, 0755);
 1299: 
 1300:     printf ("[OK]\n\n\n");
 1301: */
 1302:     printf ("FreeM initial configuration is complete.\n\n");
 1303: 
 1304:     printf (" USER globals:                   %s\n", usrgbl);
 1305:     printf (" USER routines:                  %s\n", usrrtn);
 1306:     printf (" SYSTEM globals:                 %s\n", sysgbl);
 1307:     printf (" SYSTEM routines:                %s\n", sysrtn);
 1308:     printf (" After-image journal:            %s [%s]\n", jnlfile, jnlmode);
 1309:     printf (" Journal cut threshold:          %s bytes\n", jnlcut);
 1310:     printf (" Distributed journaling host ID: %s\n", jnlhostid);
 1311: 
 1312:     
 1313: } /* fm_configure */
 1314: 
 1315: void fm_write (FILE *file, char *buf)
 1316: {
 1317:     fprintf (file, "%s\n", buf);
 1318: }
 1319: 
 1320: void fm_sig_attach (int sig, void *handler)
 1321: {
 1322:     struct sigaction act;
 1323: 
 1324:     act.sa_handler = handler;
 1325:     sigaction (sig, &act, NULL);
 1326:     
 1327: }
 1328: 
 1329: void fm_sig_init (void)
 1330: {
 1331:     sig_attach (SIGINT, &fm_on_sigint);
 1332:     sig_attach (SIGTERM, &fm_on_sigterm);
 1333: }
 1334: 
 1335: void fm_on_sigint (void)
 1336: {
 1337:     fprintf (stderr, "\nfmadm:  caught SIGINT\n");
 1338:     fmadm_exit (0);
 1339: }
 1340: 
 1341: void fm_on_sigterm (void)
 1342: {
 1343:     fprintf (stderr, "\nfmadm:  caught SIGTERM\n");
 1344:     fmadm_exit (0);
 1345: }

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