--- freem/src/fmadm.c 2025/04/02 04:50:49 1.25 +++ freem/src/fmadm.c 2025/04/15 18:19:40 1.40 @@ -1,5 +1,5 @@ /* - * $Id: fmadm.c,v 1.25 2025/04/02 04:50:49 snw Exp $ + * $Id: fmadm.c,v 1.40 2025/04/15 18:19:40 snw Exp $ * FreeM Administration Tool * * @@ -24,6 +24,51 @@ * along with FreeM. If not, see . * * $Log: fmadm.c,v $ + * Revision 1.40 2025/04/15 18:19:40 snw + * Further attempts to fix FreeBSD + * + * Revision 1.39 2025/04/15 16:49:36 snw + * Make use of logprintf throughout codebase + * + * Revision 1.38 2025/04/15 02:24:43 snw + * Improve FreeM logging capabilities + * + * Revision 1.37 2025/04/14 19:20:20 snw + * Create LOCALSTATEDIR during fmadm configure if needed + * + * Revision 1.36 2025/04/13 15:12:21 snw + * Fix transaction checkpoints on OS/2 [CLOSES #34] + * + * Revision 1.35 2025/04/13 04:22:43 snw + * Fix snprintf calls + * + * Revision 1.34 2025/04/10 15:31:25 snw + * Attempt to fix DosCopy calls for OS/2 + * + * Revision 1.33 2025/04/10 01:24:38 snw + * Remove C++ style comments + * + * Revision 1.32 2025/04/09 19:52:02 snw + * Eliminate as many warnings as possible while building with -Wall + * + * Revision 1.31 2025/04/04 19:43:18 snw + * Switch to using environment catalog to determine user and group for environment, and remove -u and -g flags from freem + * + * Revision 1.30 2025/04/03 20:48:14 snw + * Improve daemon error diagnostics and bump to 0.63.0-rc3 + * + * Revision 1.29 2025/04/03 01:41:02 snw + * New features frozen; prepare 0.63.0-rc1 + * + * Revision 1.28 2025/04/02 19:59:38 snw + * Automatically modify env.conf from fmadm reconfigure + * + * Revision 1.27 2025/04/02 15:36:25 snw + * Do extensive result checking for environment stop/start/restart in fmadm + * + * Revision 1.26 2025/04/02 14:37:57 snw + * Improve environment control parts of fmadm + * * Revision 1.25 2025/04/02 04:50:49 snw * Allow vendor routines to be upgraded * @@ -98,14 +143,14 @@ #include #include #include +#if defined(__OS2__) +# include +#endif #include "config.h" #include "transact.h" #include "namespace.h" #include "fs.h" - -#if defined(__OS2__) -# include -#endif +#include "log.h" #ifdef HAVE_LIBREADLINE # if defined(HAVE_READLINE_READLINE_H) @@ -165,6 +210,8 @@ extern char config_file[4096]; extern char env_config_file[4096]; extern char env_user[255]; extern char env_group[255]; +extern char env_enabled[10]; +extern char shm_env[255]; int fm_shell(void); void fm_checkperms(void); @@ -174,6 +221,7 @@ int fm_daemonctl (short action, short ob void fm_write (FILE *file, char *buf); int fma_jobs_remove (int optc, char **opts); void set_permissions(char *path, char *user, char *grp, int mode); +int fm_environment_running (char *env); extern int read_profile_string(char *file, char *section, char *key, char *value); int main (int argc, char **argv) @@ -194,6 +242,7 @@ int main (int argc, char **argv) short got_action = FALSE; short got_object = FALSE; + strcpy (env_enabled, "true"); /* snprintf (config_file, 4096, "%s/freem.conf", SYSCONFDIR); */ @@ -280,6 +329,31 @@ int main (int argc, char **argv) base_arg++; break; + + case 'E': + if (argv[i][2] != '=') { + fprintf (stderr, "fmadm: missing equals sign in flag -%c\n", argv[i][1]); + fmadm_usage (); + exit (1); + } + + k = 0; + + for (j = 3; j < strlen (argv[i]); j++) { + env_enabled[k++] = argv[i][j]; + } + env_enabled[k] = '\0'; + + if ((strcmp (env_enabled, "true") != 0) && (strcmp (env_enabled, "false") != 0)) { + fprintf (stderr, "fmadm: -E (environment enabled) option must be either 'true' or 'false'\n"); + fmadm_usage (); + exit (1); + } + + base_arg++; + + break; + case 'n': if (argv[i][2] != '=') { @@ -305,26 +379,28 @@ int main (int argc, char **argv) if (obj != OBJ_DAEMON) { if (strlen (env_user) == 0) { - snprintf (env_user, 6, "freem"); + snprintf (env_user, sizeof (env_user) - 1, "freem"); } if (strlen (env_group) == 0) { - snprintf (env_group, 6, "freem"); + snprintf (env_group, sizeof (env_group) - 1, "freem"); } - if (!fma_explicit_environment) snprintf (fma_environment, 4096, "DEFAULT"); - if (!fma_explicit_namespace) snprintf (fma_namespace, 4096, "SYSTEM"); + if (!fma_explicit_environment) snprintf (fma_environment, sizeof (fma_environment) - 1, "DEFAULT"); + if (!fma_explicit_namespace) snprintf (fma_namespace, sizeof (fma_namespace) - 1, "SYSTEM"); - snprintf (config_file, 4096, "%s/freem/%s/freem.conf", SYSCONFDIR, fma_environment); + snprintf (config_file, sizeof (config_file) - 1, "%s/freem/%s/freem.conf", SYSCONFDIR, fma_environment); } - snprintf (env_config_file, 4096, "%s/freem/env.conf", SYSCONFDIR); + snprintf (env_config_file, sizeof (env_config_file) - 1, "%s/freem/env.conf", SYSCONFDIR); - /* +/* 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]); exit(1); - */ +*/ + strncpy (shm_env, fma_environment, sizeof (shm_env) - 1); + init_log (); /* override for fmadm configure and daemon stuff */ if (got_action) { @@ -339,22 +415,22 @@ int main (int argc, char **argv) else if (strcmp (argv[1], "start") == 0 && strcmp (argv[2], "environment") == 0) { act = ACT_START; obj = OBJ_DAEMON; - goto act_switch; + goto process_args; } else if (strcmp (argv[1], "stop") == 0 && strcmp (argv[2], "environment") == 0) { act = ACT_STOP; obj = OBJ_DAEMON; - goto act_switch; + goto process_args; } else if (strcmp (argv[1], "restart") == 0 && strcmp (argv[2], "environment") == 0) { act = ACT_RESTART; obj = OBJ_DAEMON; - goto act_switch; + goto process_args; } else if (strcmp (argv[1], "status") == 0 && strcmp (argv[2], "environment") == 0) { act = ACT_STATUS; obj = OBJ_DAEMON; - goto act_switch; + goto process_args; } } @@ -377,7 +453,8 @@ int main (int argc, char **argv) } set_namespace (fma_namespace, FALSE); - + +process_args: /* allocate opts array */ /* first dimension */ @@ -400,7 +477,8 @@ int main (int argc, char **argv) j = 1; for (i = base_arg; i < argc; i++) { - if (i > FMA_MAXARGS) return fmadm_usage(); /* bail if we're going to overrun the array */ + if (i > FMA_MAXARGS) return fmadm_usage(); + /* bail if we're going to overrun the array */ strncpy (opts[j++], argv[i], STRLEN - 1); } @@ -420,6 +498,7 @@ int main (int argc, char **argv) else if (strncmp (action, "start", STRLEN - 1) == 0) act = ACT_START; else if (strncmp (action, "stop", STRLEN - 1) == 0) act = ACT_STOP; else if (strncmp (action, "restart", STRLEN - 1) == 0) act = ACT_RESTART; + else if (strncmp (action, "status", STRLEN - 1) == 0) act = ACT_STATUS; else return fmadm_usage(); if (strncmp (obj_str, "lock", STRLEN - 1) == 0) obj = OBJ_LOCK; @@ -554,10 +633,7 @@ int fm_shell (void) char *cmdt = (char *) malloc (65535 * sizeof (char)); char *result = (char *) malloc (65535 * sizeof (char)); - /* - strcpy (fma_namespace, "SYSTEM"); - set_namespace (fma_namespace, FALSE); - */ + obj = 0; snprintf (fma_prompt, STRLEN - 1, "fmadm [%s]> ", fma_namespace); @@ -662,7 +738,6 @@ int fm_shell (void) i = 0; while ((result = strtok (NULL, " ")) != NULL) { - // printf ("%d = %s\n", i, result); strcpy (args[i++], result); } @@ -872,15 +947,14 @@ void fmadm_exit (int retval) int fmadm_usage (void) { - fprintf (stdout, "\nusage: fmadm [-e=] [OPTIONS]\n"); + fprintf (stdout, "\nusage: fmadm [-e=] [-u=] [-g=] [-E=true|false] [OPTIONS]\n"); fprintf (stdout, " fmadm configure\n"); fprintf (stdout, " fmadm reconfigure\n"); - /* fprintf (stdout, " fmadm checkperms\n\n"); */ fprintf (stdout, " can be one of:\n"); fprintf (stdout, " list, examine, verify, compact, repair, create, remove,\n"); fprintf (stdout, " import, export, backup, restore, migrate, edit, start,\n"); - fprintf (stdout, " stop, restart\n\n"); + fprintf (stdout, " stop, restart, status\n\n"); fprintf (stdout, " can be one of:\n"); fprintf (stdout, " lock, journal, namespace, global, routine, job,\n"); @@ -1123,11 +1197,9 @@ long fm_get_pid (char *env) { char pid_file[4096]; char tmp_pid[255]; - long res; - FILE *fp; - snprintf (pid_file, 4095, "%s/freem/run/%s.pid", LOCALSTATEDIR, env); + snprintf (pid_file, sizeof (pid_file) - 1, "%s/freem/run/%s.pid", LOCALSTATEDIR, env); if ((fp = fopen (pid_file, "r")) != NULL) { if (fgets (tmp_pid, 255, fp)) { @@ -1144,6 +1216,110 @@ long fm_get_pid (char *env) } } +int fm_validate_environment (char *env) +{ + FILE *fp; + char line[255]; + char chkline[255]; + + snprintf (chkline, sizeof (chkline) - 1, "[%s]\n", env); + + if ((fp = fopen (env_config_file, "r")) == NULL) { + fprintf (stderr, "fmadm: could not open %s [%s]\n", env_config_file, strerror (errno)); + return FALSE; + } + + while (fgets (line, 254, fp)) { + if (strncmp (line, chkline, 254) == 0) { + fclose (fp); + return TRUE; + } + } + + fclose (fp); + return FALSE; +} + +int fm_start_environment (char *env) +{ + char basecmd[255]; + char cmd[4096]; + + if (fm_environment_running (env) == TRUE) { + return TRUE; + } + +#if !defined(__OS2__) + snprintf (basecmd, sizeof (basecmd) - 1, "%s/bin/freem", PREFIX); +#else + snprintf (basecmd, sizeof (basecmd) - 1, "%s/bin/freemd.exe", PREFIX); +#endif + +#if !defined(__OS2__) + snprintf (cmd, sizeof (basecmd) - 1, "%s -d -e %s", basecmd, env); +#else + sprintf (cmd, 4095, "%s -d -k -e %s", basecmd, env); +#endif + + system (cmd); + + sleep (1); + + return (fm_environment_running (env)); +} + +int fm_stop_environment (char *env) +{ + long epid; + + epid = fm_get_pid (env); + if (epid > -1) { + kill (epid, SIGINT); + sleep (5); + + if (fm_environment_running (env) == FALSE) { + return TRUE; + } + else { + kill (epid, SIGTERM); + sleep (5); + if (fm_environment_running (env) == FALSE) { + return TRUE; + } + else { + kill (epid, SIGKILL); + sleep (5); + if (fm_environment_running (env) == FALSE) { + return TRUE; + } + else { + return FALSE; + } + } + } + } + else { + return FALSE; + } +} + +int fm_environment_running (char *env) +{ + long epid; + int result; + + epid = fm_get_pid (env); + + if (epid == -1) { + return FALSE; + } + else { + result = kill (epid, 0); + + return ((result == 0) ? TRUE : FALSE); + } +} + int fm_daemonctl (short action, short object, int optc, char **options) { FILE *ef; @@ -1152,21 +1328,16 @@ int fm_daemonctl (short action, short ob char line[255]; char tmps[255]; char *cur_env; - char cmd[4096]; char verb[40]; char e_user[255]; char e_grp[255]; char e_ena[10]; - char basecmd[255]; char *savptr; int result; long epid; - -#if !defined(__OS2__) - snprintf (basecmd, 254, "%s/bin/freem", PREFIX); -#else - snprintf (basecmd, 254, "%s/bin/freemd.exe", PREFIX); -#endif + int retval; + + retval = 0; switch (action) { case ACT_START: @@ -1188,7 +1359,7 @@ int fm_daemonctl (short action, short ob envlist = (char *) malloc (sizeof (char) * BIGSTR); NULLPTRCHK(envlist,"fm_daemonctl"); - strcpy (envlist, options[0]); + strcpy (envlist, options[1]); } else { /* no environment specified; do 'action' for all environments */ @@ -1201,7 +1372,7 @@ int fm_daemonctl (short action, short ob if (line[0] == '[') { strncpy (env, &(line[1]), 255); env[strlen (env) - 2] = '\0'; - snprintf (tmps, 255, "%s,", env); + snprintf (tmps, sizeof (tmps) - 1, "%s,", env); strncat (envlist, tmps, BIGSTR - 1); } } @@ -1213,6 +1384,12 @@ int fm_daemonctl (short action, short ob savptr = envlist; cur_env = strtok_r (envlist, ",", &savptr); do { + + if (fm_validate_environment (cur_env) == FALSE) { + fprintf (stderr, "fmadm: %s is not a valid environment\n", cur_env); + continue; + } + result = read_profile_string (env_config_file, cur_env, "enabled", e_ena); if (result == FALSE || strcmp (e_ena, "true") == 0) { @@ -1225,55 +1402,62 @@ int fm_daemonctl (short action, short ob strcpy (e_grp, "freem"); } - printf ("fmadm: %s environment %s\n", verb, cur_env); + switch (action) { + case ACT_START: + case ACT_STOP: + case ACT_RESTART: + fprintf (stderr, "fmadm: %s environment %s... ", verb, cur_env); + break; + case ACT_STATUS: + fprintf (stderr, "fmadm: %s environment %s\n", verb, cur_env); + break; + } switch (action) { + case ACT_START: -#if !defined(__OS2__) - snprintf (cmd, 4095, "%s -d -e %s -u %s -g %s", basecmd, cur_env, e_user, e_grp); -#else - sprintf (cmd, 4095, "%s -d -k -e %s -u %s -g %s", basecmd, cur_env, e_user, e_grp); -#endif - system (cmd); + result = fm_start_environment (cur_env); + if (result == TRUE) { + fprintf (stderr, "[OK]\n"); + } + else { + fprintf (stderr, "[FAIL]\n"); + } break; + case ACT_STOP: - epid = fm_get_pid (cur_env); - if (epid > -1) { - fprintf (stderr, "fmadm: stopping environment daemon pid %d\n", epid); - kill (epid, SIGINT); - kill (epid, SIGTERM); + result = fm_stop_environment (cur_env); + if (result == TRUE) { + fprintf (stderr, "[OK]\n"); } else { - fprintf (stderr, "fmadm: could not obtain environment daemon pid\n"); - } - + fprintf (stderr, "[FAIL]\n"); + retval++; + } break; + case ACT_RESTART: - epid = fm_get_pid (cur_env); - if (epid > -1) { - fprintf (stderr, "fmadm: stopping environment daemon pid %d\n", epid); - kill (epid, SIGINT); - kill (epid, SIGTERM); + if (fm_stop_environment (cur_env) == TRUE) { + result = fm_start_environment (cur_env); + if (result == TRUE) { + fprintf (stderr, "[OK]\n"); + } + else { + fprintf (stderr, "[FAIL]\n"); + retval++; + } } else { - fprintf (stderr, "fmadm: could not obtain environment daemon pid\n"); - } - fprintf (stderr, "fmadm: waiting 2 seconds\n"); - sleep (2); - fprintf (stderr, "fmadm: starting environment %s\n", cur_env); -#if !defined(__OS2__) - snprintf (cmd, 4095, "%s -d -e %s -u %s -g %s", basecmd, cur_env, e_user, e_grp); -#else - sprintf (cmd, 4095, "%s -d -k -e %s -u %s -g %s", basecmd, cur_env, e_user, e_grp); -#endif - system (cmd); - + fprintf (stderr, "[FAIL]\n"); + retval++; + } break; + case ACT_STATUS: epid = fm_get_pid (cur_env); if (epid > -1) { - fprintf (stderr, " - %s environment daemon running as pid %d\n", cur_env, epid); + fprintf (stderr, " - %s environment daemon running as pid %ld\n", cur_env, epid); } else { fprintf (stderr, " - %s environment daemon does not appear to be running\n", cur_env); @@ -1286,7 +1470,7 @@ int fm_daemonctl (short action, short ob } while ((cur_env = strtok_r (NULL, ",", &savptr)) != NULL); free (envlist); - exit (0); + exit (retval); } /* fm_daemonctl() */ @@ -1299,7 +1483,6 @@ void fm_checkperms(void) void fm_reconfigure(void) { char config_backup[4096]; - char vers[4096]; int retval; @@ -1308,12 +1491,16 @@ void fm_reconfigure(void) exit (1); } - snprintf (config_backup, 4095, "%s.orig", config_file); + snprintf (config_backup, sizeof (config_backup) - 1, "%s.orig", config_file); fprintf (stderr, "fmadm: reconfiguring FreeM with system defaults for %s...\n", FREEM_VERSION_CSTR); fprintf (stderr, "fmadm: backing up %s to %s...\t", config_file, config_backup); - retval = rename (config_file, config_backup); +#if !defined(__OS2__) + retval = cp (config_backup, config_file); +#else + retval = DosCopy (config_file, config_backup, 1); +#endif if (retval == 0) { fprintf (stderr, "[OK]\n"); @@ -1330,11 +1517,28 @@ void fm_reconfigure(void) } /* fm_reconfigure() */ +void update_conf (char *file, char *section, char *key, char *new_value) +{ + char old_value[255]; + char tbuf[255]; + + snprintf (tbuf, sizeof (tbuf) - 1, "%s.%s", section, key); + + read_profile_string (file, section, key, old_value); + if (strcmp (old_value, new_value) != 0) { + modify_profile_string (file, section, key, new_value); + fprintf (stderr, "\t%-40s%-20s -> %s\n", tbuf, old_value, new_value); + } + else { + fprintf (stderr, "\t%-40s%-20s\n", tbuf, "no change"); + } +} void fm_configure (void) { char rundir[4096]; char varbase[4096]; + char vardir[4096]; char sysrtn[4096]; char sysgbl[4096]; char usrrtn[4096]; @@ -1346,7 +1550,8 @@ void fm_configure (void) char jnlhostid[4096]; char jnlcut[4096]; char hostid[4096]; - + char logdir[4096]; + char confbase[4096]; char envbase[4096]; @@ -1355,8 +1560,9 @@ void fm_configure (void) char buf[4096]; FILE *fp; + int reconfigure = FALSE; + struct stat etcstat; - int stat_result; DIR *dir; struct dirent *ent; @@ -1365,42 +1571,39 @@ void fm_configure (void) char *username = env_user; char *groupname = env_group; - + #if !defined(__OS2__) + struct group *d_grp; + struct passwd *d_user; + if (geteuid () != 0) { fprintf (stderr, "fmadm: not superuser\n"); exit (1); } - struct group *d_grp; - struct passwd *d_user; - gid_t d_gid; - uid_t d_uid; - if ((d_grp = getgrnam (groupname)) == NULL) { fprintf (stderr, "fmadm: '%s' group must exist before configuring\n", groupname); exit (1); } - d_gid = d_grp->gr_gid; - if ((d_user = getpwnam (username)) == NULL) { fprintf (stderr, "fmadm: '%s' user must exist before configuring\n", username); exit (1); } - d_uid = d_user->pw_uid; #endif - - snprintf (varbase, 4095, "%s/freem", LOCALSTATEDIR); - snprintf (rundir, 4095, "%s/freem/run", LOCALSTATEDIR); - snprintf (sysrtn, 4095, "%s/freem/%s/SYSTEM/routines", LOCALSTATEDIR, fma_environment); - snprintf (sysgbl, 4095, "%s/freem/%s/SYSTEM/globals", LOCALSTATEDIR, fma_environment); - snprintf (usrrtn, 4095, "%s/freem/%s/USER/routines", LOCALSTATEDIR, fma_environment); - snprintf (usrgbl, 4095, "%s/freem/%s/USER/globals", LOCALSTATEDIR, fma_environment); - snprintf (jnldir, 4095, "%s/freem/%s/journals", LOCALSTATEDIR, fma_environment); - snprintf (jnlfile, 4095, "%s/freem_journal_%s.dat", jnldir, fma_environment); - snprintf (jnlmode, 3, "on"); - snprintf (jnlhostid, 4095, "DEFAULT"); - snprintf (jnlcut, 4095, "4294967000"); + + snprintf (logdir, sizeof (logdir) - 1, "/var/log/freem"); + snprintf (vardir, sizeof (vardir) - 1, "%s", LOCALSTATEDIR); + snprintf (varbase, sizeof (varbase) - 1, "%s/freem", LOCALSTATEDIR); + snprintf (rundir, sizeof (rundir) - 1, "%s/freem/run", LOCALSTATEDIR); + snprintf (sysrtn, sizeof (sysrtn) - 1, "%s/freem/%s/SYSTEM/routines", LOCALSTATEDIR, fma_environment); + snprintf (sysgbl, sizeof (sysgbl) - 1, "%s/freem/%s/SYSTEM/globals", LOCALSTATEDIR, fma_environment); + snprintf (usrrtn, sizeof (usrrtn) - 1, "%s/freem/%s/USER/routines", LOCALSTATEDIR, fma_environment); + snprintf (usrgbl, sizeof (usrgbl) - 1, "%s/freem/%s/USER/globals", LOCALSTATEDIR, fma_environment); + snprintf (jnldir, sizeof (jnldir) - 1, "%s/freem/%s/journals", LOCALSTATEDIR, fma_environment); + snprintf (jnlfile, sizeof (jnlfile) - 1, "%s/freem_journal_%s.dat", jnldir, fma_environment); + snprintf (jnlmode, sizeof (jnlmode) - 1, "on"); + snprintf (jnlhostid, sizeof (jnlhostid) - 1, "DEFAULT"); + snprintf (jnlcut, sizeof (jnlcut) - 1, "4294967000"); if (geteuid () != 0) { fprintf (stderr, "fmadm: not superuser\n"); @@ -1408,26 +1611,24 @@ void fm_configure (void) } if (file_exists (config_file)) { - fprintf (stderr, "fmadm: '%s' already exists; running fmadm reconfigure instead\n", config_file); - fm_reconfigure (); - return; + reconfigure = TRUE; } - + gethostname (hostid, 4095); uuid_v4 (buf); - snprintf (jnlhostid, 4095, "%s:%s", hostid, buf); - snprintf (confbase, 4095, "%s/freem", SYSCONFDIR); - snprintf (envbase, 4095, "%s/freem/%s", SYSCONFDIR, fma_environment); - snprintf (nsbase, 4095, "%s/freem/%s", LOCALSTATEDIR, fma_environment); + snprintf (jnlhostid, sizeof (jnlhostid) - 1, "%s:%s", hostid, buf); + snprintf (confbase, sizeof (confbase) - 1, "%s/freem", SYSCONFDIR); + snprintf (envbase, sizeof (envbase) - 1, "%s/freem/%s", SYSCONFDIR, fma_environment); + snprintf (nsbase, sizeof (nsbase) - 1, "%s/freem/%s", LOCALSTATEDIR, fma_environment); #if defined(__OS2__) { char srcfile[PATHLEN]; char dstfile[PATHLEN]; - snprintf (srcfile, PATHLEN, "%s/bin/freem.exe", PREFIX); - snprintf (dstfile, PATHLEN, "%s/bin/freemd.exe", PREFIX); + snprintf (srcfile, PATHLEN - 1, "%s/bin/freem.exe", PREFIX); + snprintf (dstfile, PATHLEN - 1, "%s/bin/freemd.exe", PREFIX); unlink (dstfile); @@ -1440,17 +1641,30 @@ void fm_configure (void) chmod (dstfile, 0755); } -#else - fprintf (stderr, "fmadm: not running on OS/2\n"); #endif - - printf ("\nFreeM Initial Configuration\n"); - printf ("---------------------------\n\n"); - printf ("This utility will create the initial configuration file for "); - printf ("FreeM environment '%s' (owned by %s:%s) in '%s'.\n\n", fma_environment, username, groupname, config_file); + if (reconfigure == FALSE) { + printf ("\nFreeM Initial Environment Configuration\n"); + printf ("---------------------------------------\n\n"); + + printf ("This utility will create the initial configuration files for "); + printf ("FreeM environment '%s' (owned by %s:%s) in '%s'.\n\n", fma_environment, username, groupname, config_file); + } + else { + printf ("\nFreeM Environment Upgrade/Reconfiguration\n"); + printf ("-----------------------------------------\n\n"); + + printf ("This utility will update the configuration files for "); + printf ("FreeM environment '%s' (owned by %s:%s) in '%s'.\n\n", fma_environment, username, groupname, config_file); + } /* check for existence of needed directories */ + if (stat (logdir, &etcstat) == -1) { + fprintf (stderr, "fmadm: creating %s [logdir]\n", logdir); + mkdir (logdir, 0775); + set_permissions (logdir, username, groupname, 0775); + } + if (stat (SYSCONFDIR, &etcstat) == -1) { fprintf (stderr, "fmadm: creating %s [SYSCONFDIR]\n", SYSCONFDIR); mkdir (SYSCONFDIR, 0775); @@ -1463,6 +1677,12 @@ void fm_configure (void) set_permissions (confbase, username, groupname, 0775); } + if (stat (vardir, &etcstat) == -1) { + fprintf (stderr, "fmadm: creating %s [vardir]\n", vardir); + mkdir (vardir, 0775); + set_permissions (vardir, username, groupname, 0775); + } + if (stat (varbase, &etcstat) == -1) { fprintf (stderr, "fmadm: creating %s [varbase]\n", varbase); mkdir (varbase, 0775); @@ -1494,32 +1714,37 @@ void fm_configure (void) } - snprintf (src_dir, 4095, "%s/freem/mlib", DATADIR); - snprintf (dest_dir, 4095, "%s/freem/%s/SYSTEM/routines", LOCALSTATEDIR, fma_environment); - - fprintf (stderr, "fmadm: populating new environment '%s'\n", fma_environment); + snprintf (src_dir, sizeof (src_dir) - 1, "%s/freem/mlib", DATADIR); + snprintf (dest_dir, sizeof (dest_dir) - 1, "%s/freem/%s/SYSTEM/routines", LOCALSTATEDIR, fma_environment); + + if (reconfigure == FALSE) { + fprintf (stderr, "fmadm: populating new environment '%s'\n", fma_environment); + } + else { + fprintf (stderr, "fmadm: upgrading environment '%s'\n", fma_environment); + } - snprintf (buf, 4095, "%s/freem/%s/SYSTEM", LOCALSTATEDIR, fma_environment); + snprintf (buf, sizeof (buf) - 1, "%s/freem/%s/SYSTEM", LOCALSTATEDIR, fma_environment); mkdir (buf, 0775); set_permissions (buf, username, groupname, 0775); - snprintf (buf, 4095, "%s/freem/%s/USER", LOCALSTATEDIR, fma_environment); + snprintf (buf, sizeof (buf) - 1, "%s/freem/%s/USER", LOCALSTATEDIR, fma_environment); mkdir (buf, 0775); set_permissions (buf, username, groupname, 0775); - snprintf (buf, 4095, "%s/freem/%s/SYSTEM/routines", LOCALSTATEDIR, fma_environment); + snprintf (buf, sizeof (buf) - 1, "%s/freem/%s/SYSTEM/routines", LOCALSTATEDIR, fma_environment); mkdir (buf, 0775); set_permissions (buf, username, groupname, 0775); - snprintf (buf, 4095, "%s/freem/%s/USER/globals", LOCALSTATEDIR, fma_environment); + snprintf (buf, sizeof (buf) - 1, "%s/freem/%s/USER/globals", LOCALSTATEDIR, fma_environment); mkdir (buf, 0775); set_permissions (buf, username, groupname, 0775); - snprintf (buf, 4095, "%s/freem/%s/SYSTEM/globals", LOCALSTATEDIR, fma_environment); + snprintf (buf, sizeof (buf) - 1, "%s/freem/%s/SYSTEM/globals", LOCALSTATEDIR, fma_environment); mkdir (buf, 0775); set_permissions (buf, username, groupname, 0775); - snprintf (buf, 4095, "%s/freem/%s/USER/routines", LOCALSTATEDIR, fma_environment); + snprintf (buf, sizeof (buf) - 1, "%s/freem/%s/USER/routines", LOCALSTATEDIR, fma_environment); mkdir (buf, 0775); set_permissions (buf, username, groupname, 0775); @@ -1536,8 +1761,8 @@ void fm_configure (void) if ((strcmp (ent->d_name, ".") != 0) && (strcmp (ent->d_name, "..") != 0)) { - snprintf (infile, 4095, "%s/%s", src_dir, ent->d_name); - snprintf (outfile, 4095, "%s/%s", dest_dir, ent->d_name); + snprintf (infile, sizeof (infile) - 1, "%s/%s", src_dir, ent->d_name); + snprintf (outfile, sizeof (outfile) - 1, "%s/%s", dest_dir, ent->d_name); if (stat (outfile, &etcstat) == 0) { unlink (outfile); @@ -1562,88 +1787,144 @@ void fm_configure (void) } - fp = fopen (env_config_file, "a+"); + if (fm_validate_environment (fma_environment) == FALSE) { + fp = fopen (env_config_file, "a+"); + + fprintf (stderr, "Creating %s... ", env_config_file); + + snprintf (buf, sizeof (buf) - 1, "[%s]", fma_environment); + fm_write (fp, buf); + + snprintf (buf, sizeof (buf) - 1, "user=%s", env_user); + fm_write (fp, buf); + + snprintf (buf, sizeof (buf) - 1, "group=%s", env_group); + fm_write (fp, buf); + + snprintf (buf, sizeof (buf) - 1, "enabled=%s", env_enabled); + fm_write (fp, buf); + + snprintf (buf, sizeof (buf) - 1, "env_path=%s/freem/%s", LOCALSTATEDIR, fma_environment); + fm_write (fp, buf); - fprintf (stderr, "Creating %s... ", env_config_file); + snprintf (buf, sizeof (buf) - 1, "log_threshold_file=info"); + fm_write (fp, buf); + + snprintf (buf, sizeof (buf) - 1, "log_threshold_syslog=info"); + fm_write (fp, buf); - snprintf (buf, 4095, "[%s]", fma_environment); - fm_write (fp, buf); + snprintf (buf, sizeof (buf) - 1, "log_threshold_stderr=warning"); + fm_write (fp, buf); + + fclose (fp); + fprintf (stderr, "[OK]\n"); + } + else { + fprintf (stderr, "\nUpdating %s: \n", env_config_file); - snprintf (buf, 4095, "user=%s", env_user); - fm_write (fp, buf); - - snprintf (buf, 4095, "group=%s", env_group); - fm_write (fp, buf); + update_conf (env_config_file, fma_environment, "user", env_user); + update_conf (env_config_file, fma_environment, "group", env_group); + update_conf (env_config_file, fma_environment, "enabled", env_enabled); + update_conf (env_config_file, fma_environment, "log_threshold_file", "info"); + update_conf (env_config_file, fma_environment, "log_threshold_syslog", "info"); + update_conf (env_config_file, fma_environment, "log_threshold_stderr", "warning"); + } - snprintf (buf, 4095, "enabled=true"); - fm_write (fp, buf); - - snprintf (buf, 4095, "env_path=%s/freem/%s", LOCALSTATEDIR, fma_environment); - fm_write (fp, buf); - - fclose (fp); - fprintf (stderr, "[OK]\n"); - - fp = fopen (config_file, "a+"); - - fprintf (stderr, "Creating %s... ", config_file); + if (reconfigure == FALSE) { + fp = fopen (config_file, "a+"); + + fprintf (stderr, "Creating %s... ", config_file); + + snprintf (buf, sizeof (buf) - 1, "[SYSTEM]"); + fm_write (fp, buf); + + snprintf (buf, sizeof (buf) - 1, "root=%s/freem/%s/SYSTEM", LOCALSTATEDIR, fma_environment); + fm_write (fp, buf); + + snprintf (buf, sizeof (buf) - 1, "routines_path=%s", sysrtn); + fm_write (fp, buf); + + snprintf (buf, sizeof (buf) - 1, "globals_path=%s", sysgbl); + fm_write (fp, buf); + + snprintf (buf, sizeof (buf) - 1, "journal_file=%s", jnlfile); + fm_write (fp, buf); + + snprintf (buf, sizeof (buf) - 1, "journal_mode=%s", jnlmode); + fm_write (fp, buf); + + snprintf (buf, sizeof (buf) - 1, "journal_host_id=%s", jnlhostid); + fm_write (fp, buf); + + snprintf (buf, sizeof (buf) - 1, "journal_cut_threshold=%s", jnlcut); + fm_write (fp, buf); + + snprintf (buf, sizeof (buf) - 1, "zdate_format=%%x"); + fm_write (fp, buf); + + snprintf (buf, sizeof (buf) - 1, "ztime_format=%%X"); + fm_write (fp, buf); + + snprintf (buf, sizeof (buf) - 1, "\n[USER]"); + fm_write (fp, buf); + + snprintf (buf, sizeof (buf) - 1, "root=%s/freem/%s/USER", LOCALSTATEDIR, fma_environment); + fm_write (fp, buf); + + snprintf (buf, sizeof (buf) - 1, "routines_path=%s", usrrtn); + fm_write (fp, buf); + + snprintf (buf, sizeof (buf) - 1, "globals_path=%s", usrgbl); + fm_write (fp, buf); + + fclose (fp); + set_permissions (config_file, username, groupname, 0755); + fprintf (stderr, "[OK]\n"); - snprintf (buf, 4095, "[SYSTEM]"); - fm_write (fp, buf); - - snprintf (buf, 4095, "root=%s/freem/%s/SYSTEM", LOCALSTATEDIR, fma_environment); - fm_write (fp, buf); - - snprintf (buf, 4095, "routines_path=%s", sysrtn); - fm_write (fp, buf); - - snprintf (buf, 4095, "globals_path=%s", sysgbl); - fm_write (fp, buf); - - snprintf (buf, 4095, "journal_file=%s", jnlfile); - fm_write (fp, buf); - - snprintf (buf, 4095, "journal_mode=%s", jnlmode); - fm_write (fp, buf); + printf ("FreeM initial configuration is complete.\n\n"); + } + else { + char tmpsd[255]; + read_profile_string (config_file, "SYSTEM", "journal_host_id", tmpsd); + + /* existing configuration */ + fprintf (stderr, "\nUpdating environment configuration for %s:\n", fma_environment); - snprintf (buf, 4095, "journal_host_id=%s", jnlhostid); - fm_write (fp, buf); + snprintf (buf, sizeof (buf) - 1, "%s/freem/%s/SYSTEM", LOCALSTATEDIR, fma_environment); + update_conf (config_file, "SYSTEM", "root", buf); + update_conf (config_file, "SYSTEM", "routines_path", sysrtn); + update_conf (config_file, "SYSTEM", "globals_path", sysgbl); + update_conf (config_file, "SYSTEM", "journal_file", jnlfile); + update_conf (config_file, "SYSTEM", "journal_mode", jnlmode); + update_conf (config_file, "SYSTEM", "journal_host_id", tmpsd); + update_conf (config_file, "SYSTEM", "journal_cut_threshold", jnlcut); - snprintf (buf, 4095, "journal_cut_threshold=%s", jnlcut); - fm_write (fp, buf); + snprintf (buf, sizeof (buf) - 1, "%%x"); + update_conf (config_file, "SYSTEM", "zdate_format", buf); + + snprintf (buf, sizeof (buf) - 1, "%%X"); + update_conf (config_file, "SYSTEM", "ztime_format", buf); - snprintf (buf, 4095, "zdate_format=%%x"); - fm_write (fp, buf); + /* USER */ + snprintf (buf, sizeof (buf) - 1, "%s/freem/%s/USER", LOCALSTATEDIR, fma_environment); + update_conf (config_file, "USER", "root", buf); + update_conf (config_file, "USER", "routines_path", usrrtn); + update_conf (config_file, "USER", "globals_path", usrgbl); - snprintf (buf, 4095, "ztime_format=%%X"); - fm_write (fp, buf); + } - snprintf (buf, 4095, "\n[USER]"); - fm_write (fp, buf); - - snprintf (buf, 4095, "root=%s/freem/%s/USER", LOCALSTATEDIR, fma_environment); - fm_write (fp, buf); - - snprintf (buf, 4095, "routines_path=%s", usrrtn); - fm_write (fp, buf); - - snprintf (buf, 4095, "globals_path=%s", usrgbl); - fm_write (fp, buf); - fclose (fp); - set_permissions (config_file, username, groupname, 0755); - fprintf (stderr, "[OK]\n"); - - printf ("FreeM initial configuration is complete.\n\n"); - - printf (" USER globals: %s\n", usrgbl); - printf (" USER routines: %s\n", usrrtn); - printf (" SYSTEM globals: %s\n", sysgbl); - printf (" SYSTEM routines: %s\n", sysrtn); - printf (" After-image journal: %s [%s]\n", jnlfile, jnlmode); - printf (" Journal cut threshold: %s bytes\n", jnlcut); - printf (" Distributed journaling host ID: %s\n", jnlhostid); + printf ("\n\nUSER globals: %s\n", usrgbl); + printf ("USER routines: %s\n", usrrtn); + printf ("SYSTEM globals: %s\n", sysgbl); + printf ("SYSTEM routines: %s\n", sysrtn); + printf ("After-image journal: %s [%s]\n", jnlfile, jnlmode); + printf ("Journal cut threshold: %s bytes\n", jnlcut); + printf ("Distributed journaling host ID: %s\n", jnlhostid); + if (reconfigure == TRUE) { + fprintf (stderr, "\nIf you previously defined environments other than '%s', you should run\n'fmadm reconfigure -e=' on each of them to ensure they have\nthe latest vendor routines and correct, updated settings.\n\n", fma_environment); + } } /* fm_configure */