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

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

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