--- freem/src/fmadm.c 2025/04/01 16:37:12 1.20 +++ freem/src/fmadm.c 2025/04/01 20:11:46 1.21 @@ -1,5 +1,5 @@ /* - * $Id: fmadm.c,v 1.20 2025/04/01 16:37:12 snw Exp $ + * $Id: fmadm.c,v 1.21 2025/04/01 20:11:46 snw Exp $ * FreeM Administration Tool * * @@ -24,6 +24,9 @@ * along with FreeM. If not, see . * * $Log: fmadm.c,v $ + * Revision 1.21 2025/04/01 20:11:46 snw + * Further work on fmadm + * * Revision 1.20 2025/04/01 16:37:12 snw * Configure DEFAULT environment the same as others, and set permissions/ownership directly in fmadm configure. Add env.conf file as a centralized configuration listing all environments. * @@ -155,10 +158,11 @@ int fm_shell(void); void fm_checkperms(void); void fm_reconfigure(void); void fm_configure(void); +int fm_daemonctl (short action, short object, int optc, char **options); 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); - +extern int read_profile_string(char *file, char *section, char *key, char *value); int main (int argc, char **argv) { @@ -256,6 +260,11 @@ int main (int argc, char **argv) for (j = 3; j < strlen (argv[i]); j++) { fma_environment[k++] = argv[i][j]; } + + if (strcmp (fma_environment, "all") == 0 ) { + fprintf (stderr, "fmadm: 'all' is an invalid environment name\n"); + exit (1); + } fma_explicit_environment = TRUE; base_arg++; @@ -283,22 +292,23 @@ int main (int argc, char **argv) } } } - - if (strlen (env_user) == 0) { - fprintf (stderr, "fmadm: assuming user 'freem' for this environment's owner\n"); - snprintf (env_user, 6, "freem"); - } - if (strlen (env_group) == 0) { - fprintf (stderr, "fmadm: assuming group 'freem' for this environment's owner\n"); - snprintf (env_group, 6, "freem"); - } + if (obj != OBJ_DAEMON) { + if (strlen (env_user) == 0) { + snprintf (env_user, 6, "freem"); + } + + if (strlen (env_group) == 0) { + snprintf (env_group, 6, "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, 4096, "DEFAULT"); + if (!fma_explicit_namespace) snprintf (fma_namespace, 4096, "SYSTEM"); + + snprintf (config_file, 4096, "%s/freem/%s/freem.conf", SYSCONFDIR, fma_environment); + } - snprintf (config_file, 4096, "%s/freem/%s/freem.conf", SYSCONFDIR, fma_environment); snprintf (env_config_file, 4096, "%s/freem/env.conf", SYSCONFDIR); /* @@ -306,7 +316,7 @@ int main (int argc, char **argv) exit(1); */ - /* override for fmadm configure */ + /* override for fmadm configure and daemon stuff */ if (got_action) { if (strcmp (argv[1], "configure") == 0) { fm_configure (); @@ -316,6 +326,21 @@ int main (int argc, char **argv) fm_reconfigure (); exit (0); } + else if (strcmp (argv[1], "start") == 0 && strcmp (argv[2], "environment") == 0) { + act = ACT_START; + obj = OBJ_DAEMON; + goto act_switch; + } + else if (strcmp (argv[1], "stop") == 0 && strcmp (argv[2], "environment") == 0) { + act = ACT_STOP; + obj = OBJ_DAEMON; + goto act_switch; + } + else if (strcmp (argv[1], "restart") == 0 && strcmp (argv[2], "environment") == 0) { + act = ACT_RESTART; + obj = OBJ_DAEMON; + goto act_switch; + } } pid = getpid (); @@ -326,7 +351,7 @@ int main (int argc, char **argv) job_init (TRUE); fm_sig_init (); - + /* go to fmadm shell if no arguments passed */ if (!got_action && !got_object) return fm_shell (); @@ -334,71 +359,6 @@ int main (int argc, char **argv) fm_checkperms (); exit (0); } - -#if 0 - /* how many args do we have? */ - switch (argc) { - - case 3: /* action, object */ - strncpy (action, argv[1], STRLEN - 1); - strncpy (obj_str, argv[2], STRLEN - 1); - strncpy (fma_namespace, "SYSTEM", STRLEN - 1); - - optc = argc - 2; - - fma_explicit_namespace = FALSE; - fma_min_args = 1; - base_arg = 3; - - break; - - case 4: /* action, object, namespace */ - - strncpy (action, argv[1], STRLEN - 1); - strncpy (obj_str, argv[2], STRLEN - 1); - - if (validate_namespace (argv[3]) == TRUE) { - strncpy (fma_namespace, argv[3], STRLEN - 1); - fma_min_args = 2; - fma_explicit_namespace = TRUE; - base_arg = 4; - optc = argc - 3; - } - else { - strncpy (fma_namespace, "SYSTEM", 10); - fma_min_args = 1; - fma_explicit_namespace = FALSE; - base_arg = 3; - optc = argc - 2; - } - - break; - - default: - if (argc < 4) fmadm_usage(); - - /* we don't know what any but the first two args actually mean */ - strncpy (action, argv[1], STRLEN - 1); - strncpy (obj_str, argv[2], STRLEN - 1); - - if (validate_namespace (argv[3]) == TRUE) { - strncpy (fma_namespace, argv[3], STRLEN - 1); - fma_min_args = 2; - fma_explicit_namespace = TRUE; - base_arg = 4; - optc = argc - 3; - } - else { - strncpy (fma_namespace, "SYSTEM", 10); - fma_min_args = 1; - fma_explicit_namespace = FALSE; - base_arg = 3; - optc = argc - 2; - } - - - } -#endif set_namespace (fma_namespace, FALSE); @@ -440,7 +400,10 @@ int main (int argc, char **argv) else if (strncmp (action, "backup", STRLEN - 1) == 0) act = ACT_BACKUP; else if (strncmp (action, "restore", STRLEN - 1) == 0) act = ACT_RESTORE; else if (strncmp (action, "migrate", STRLEN - 1) == 0) act = ACT_MIGRATE; - else if (strncmp (action, "edit", STRLEN -1) == 0) act = ACT_EDIT; + else if (strncmp (action, "edit", STRLEN - 1) == 0) act = ACT_EDIT; + 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 return fmadm_usage(); if (strncmp (obj_str, "lock", STRLEN - 1) == 0) obj = OBJ_LOCK; @@ -450,8 +413,11 @@ int main (int argc, char **argv) else if (strncmp (obj_str, "global", STRLEN - 1) == 0) obj = OBJ_GLOBAL; else if (strncmp (obj_str, "routine", STRLEN - 1) == 0) obj = OBJ_ROUTINE; else if (strncmp (obj_str, "job", STRLEN - 1) == 0) obj = OBJ_JOB; + else if (strncmp (obj_str, "environment", STRLEN - 1) == 0) obj = OBJ_DAEMON; else return fmadm_usage(); + if (act > ACT_EDIT) goto act_switch; + if (get_conf (fma_namespace, "routines_path", fma_routine_path) == FALSE) { fprintf (stderr, "fmadm: cannot determine routine path for namespace %s\n", fma_namespace); return 1; @@ -487,6 +453,7 @@ int main (int argc, char **argv) stcnv_c2m (glopath); +act_switch: switch (act) { @@ -541,6 +508,10 @@ int main (int argc, char **argv) case ACT_EDIT: fmadm_exit (fm_edit (obj, optc, opts)); + case ACT_START: + case ACT_STOP: + case ACT_RESTART: + fmadm_exit (fm_daemonctl (act, obj, optc, opts)); default: return fmadm_usage(); @@ -893,10 +864,12 @@ int fmadm_usage (void) 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\n\n"); + fprintf (stdout, " import, export, backup, restore, migrate, edit, start,\n"); + fprintf (stdout, " stop, restart\n\n"); fprintf (stdout, " can be one of:\n"); - fprintf (stdout, " lock, zallocate, journal, namespace, global, routine, job\n\n"); + fprintf (stdout, " lock, zallocate, journal, namespace, global, routine, job,\n"); + fprintf (stdout, " environment\n\n"); fprintf (stdout, " Not all actions are valid for all objects. Please see the FreeM manual\n"); fprintf (stdout, " for details on fmadm usage and options.\n\n"); @@ -1131,6 +1104,108 @@ int fm_edit (short object, int optc, cha } /* fm_edit() */ +int fm_daemonctl (short action, short object, int optc, char **options) +{ + FILE *ef; + char *envlist; + char env[255]; + char line[255]; + char tmps[255]; + char *cur_env; + char cmd[4096]; + char verb[20]; + char e_user[255]; + char e_grp[255]; + char e_ena[10]; + char basecmd[255]; + char *savptr; + int result; + +#if !defined(__OS2__) + snprintf (basecmd, 254, "%s/bin/freem", PREFIX); +#else + snprintf (basecmd, 254, "%s/bin/freemd.exe", PREFIX); +#endif + + switch (action) { + case ACT_START: + sprintf (verb, "starting"); + break; + case ACT_STOP: + sprintf (verb, "stopping"); + break; + case ACT_RESTART: + sprintf (verb, "restarting"); + break; + } + + if (optc) { + /* environment list specified as command-line argument */ + envlist = options[0]; + } + else { + /* no environment specified; do 'action' for all environments */ + envlist = (char *) malloc (sizeof (char) * BIGSTR); + NULLPTRCHK(envlist,"fm_daemonctl"); + + ef = fopen (env_config_file, "r"); + + while (fgets (line, 254, ef)) { + if (line[0] == '[') { + strncpy (env, &(line[1]), 255); + env[strlen (env) - 2] = '\0'; + snprintf (tmps, 255, "%s,", env); + strncat (envlist, tmps, BIGSTR - 1); + } + } + envlist[strlen (envlist) - 1] = '\0'; + + fclose (ef); + } + + savptr = envlist; + cur_env = strtok_r (envlist, ",", &savptr); + do { + result = read_profile_string (env_config_file, cur_env, "enabled", e_ena); + if (result == FALSE || strcmp (e_ena, "true") == 0) { + + result = read_profile_string (env_config_file, cur_env, "user", e_user); + if (result == FALSE) { + strcpy (e_user, "freem"); + } + result = read_profile_string (env_config_file, cur_env, "group", e_grp); + if (result == FALSE) { + strcpy (e_grp, "freem"); + } + + printf ("fmadm: %s environment %s\n", verb, cur_env); + + 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 + break; + case ACT_STOP: + case ACT_RESTART: + printf ("fmadm: stop and restart not yet implemented\n"); + break; + } + + system (cmd); + } + else { + printf ("fmadm: %s environment is disabled; skipping\n", cur_env); + } + } while ((cur_env = strtok_r (NULL, ",", &savptr)) != NULL); + + free (envlist); + exit (0); + +} /* fm_daemonctl() */ + void fm_checkperms(void) { @@ -1174,6 +1249,7 @@ void fm_reconfigure(void) void fm_configure (void) { + char rundir[4096]; char varbase[4096]; char sysrtn[4096]; char sysgbl[4096]; @@ -1228,6 +1304,7 @@ void fm_configure (void) 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); @@ -1311,7 +1388,13 @@ void fm_configure (void) mkdir (varbase, 0775); set_permissions (varbase, username, groupname, 0775); } - + + if (stat (rundir, &etcstat) == -1) { + fprintf (stderr, "fmadm: creating %s\n", rundir); + mkdir (rundir, 0777); + chmod (rundir, 0777); + } + if (stat (nsbase, &etcstat) == -1) { fprintf (stderr, "fmadm: creating %s\n", nsbase); mkdir (nsbase, 0775); @@ -1392,6 +1475,9 @@ void fm_configure (void) snprintf (buf, 4095, "group=%s", env_group); fm_write (fp, buf); + + snprintf (buf, 4095, "enabled=true"); + fm_write (fp, buf); snprintf (buf, 4095, "env_path=%s/freem/%s", LOCALSTATEDIR, fma_environment); fm_write (fp, buf);