--- freem/src/mumps.c 2025/04/01 23:21:45 1.11 +++ freem/src/mumps.c 2025/04/04 19:43:18 1.16 @@ -1,5 +1,5 @@ /* - * $Id: mumps.c,v 1.11 2025/04/01 23:21:45 snw Exp $ + * $Id: mumps.c,v 1.16 2025/04/04 19:43:18 snw Exp $ * main module of freem * * @@ -24,6 +24,21 @@ * along with FreeM. If not, see . * * $Log: mumps.c,v $ + * Revision 1.16 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.15 2025/04/03 20:48:14 snw + * Improve daemon error diagnostics and bump to 0.63.0-rc3 + * + * Revision 1.14 2025/04/02 04:50:49 snw + * Allow vendor routines to be upgraded + * + * Revision 1.13 2025/04/02 03:26:22 snw + * Don't corrupt the terminal if FreeM runs before fmadm configure has been run + * + * Revision 1.12 2025/04/02 02:16:27 snw + * Add fmadm status environment command and move journals to a better location + * * Revision 1.11 2025/04/01 23:21:45 snw * fmadm commands for stopping, starting, and restarting environments now functional * @@ -53,6 +68,7 @@ * SPDX-License-Identifier: AGPL-3.0-or-later **/ +#define _GNU_SOURCE #include #include #include "mpsdef.h" @@ -109,6 +125,8 @@ int main (int argc, char **argv, char ** int option_index = 0; + char fm_initialized = FALSE; + char dx_mcode[512]; char startup_routine[256]; short routine_mode; @@ -162,6 +180,8 @@ int main (int argc, char **argv, char ** char *cli_rtn_file; char cli_rtn_name[256]; + char env_ena[25]; + routine_mode = FALSE; strcpy (m_dialect, "FREEM"); @@ -191,7 +211,7 @@ int main (int argc, char **argv, char ** while (1) { - c = getopt_long (argc, argv, "hsfiqRr:n:e:vx:dkpS:u:g:", long_options, &option_index); + c = getopt_long (argc, argv, "hsfiqRr:n:e:vx:dkpS", long_options, &option_index); if (c == -1) break; if (c == '?') freem_usage (); @@ -304,18 +324,7 @@ int main (int argc, char **argv, char ** case 'S': /* --shmsize */ shm_init_size = atol (optarg); - break; - - case 'u': /* --user */ - strncpy (d_username, optarg, 40); - custom_user = TRUE; - break; - - case 'g': /* --group */ - strncpy (d_groupname, optarg, 40); - custom_group = TRUE; - break; - + break; } @@ -327,7 +336,7 @@ int main (int argc, char **argv, char ** extern char *optarg; extern int optind, optopt; - while ((c = getopt (argc, argv, "hsfiqRr:n:e:vx:dkS:u:g:")) != -1) { + while ((c = getopt (argc, argv, "hsfiqRr:n:e:vx:dkS:")) != -1) { if (c == '?') freem_usage (); @@ -435,17 +444,6 @@ int main (int argc, char **argv, char ** shm_init_size = atol (optarg); break; - case 'u': /* --user */ - strncpy (d_username, optarg, 40); - custom_user = TRUE; - break; - - case 'g': /* --group */ - strncpy (d_groupname, optarg, 40); - custom_group = TRUE; - break; - - } } } @@ -459,34 +457,66 @@ int main (int argc, char **argv, char ** #endif snprintf (config_file, 4096, "%s/freem/%s/freem.conf", SYSCONFDIR, shm_env); + snprintf (env_config_file, 4096, "%s/freem/env.conf", SYSCONFDIR); - if (run_daemon == TRUE && geteuid() == 0) { + if (!file_exists (env_config_file)) { + fprintf (stderr, "freem: environment catalog does not exist; may need to run fmadm configure\n"); + exit (1); + } - if (custom_group) { - d_grp = getgrnam (d_groupname); + if (!file_exists (config_file)) { + fprintf (stderr, "freem: configuration file for %s does not exist; may need to run fmadm configure\n", shm_env); + exit (1); + } - if (d_grp == NULL) { - fprintf (stderr, "freem: invalid group '%s'\n", d_groupname); - exit (1); - } - - d_gid = d_grp->gr_gid; - } + if (read_profile_string (env_config_file, shm_env, "user", d_username) == FALSE) { + fprintf (stderr, "freem: could not determine owning user for environment %s\n", shm_env); + exit (1); + } - if (custom_user) { - d_user = getpwnam (d_username); + if (read_profile_string (env_config_file, shm_env, "group", d_groupname) == FALSE) { + fprintf (stderr, "freem: could not determine owning group for environment %s\n", shm_env); + exit (1); + } - if (d_user == NULL) { - fprintf (stderr, "freem: invalid user '%s'\n", d_username); - exit (1); - } - - d_uid = d_user->pw_uid; - } - else { - d_uid = 0; - } + if (read_profile_string (env_config_file, shm_env, "enabled", env_ena) == FALSE) { + fprintf (stderr, "freem: could not discover enabled state for environment %s\n", shm_env); + exit (1); + } + + if (strcmp (env_ena, "true") != 0) { + fprintf (stderr, "freem: environment %s is administratively disabled\n", shm_env); + exit (1); + } + + d_grp = getgrnam (d_groupname); + if (d_grp == NULL) { + fprintf (stderr, "freem: invalid group '%s'\n", d_groupname); + exit (1); + } + d_gid = d_grp->gr_gid; + + d_user = getpwnam (d_username); + if (d_user == NULL) { + fprintf (stderr, "freem: invalid user '%s'\n", d_username); + exit (1); + } + d_uid = d_user->pw_uid; + + +#if defined(__linux__) + if (run_daemon == FALSE && group_member (d_gid) == 0) { + fprintf (stderr, "freem: you must be a member of the %s group to use environment %s\n", d_groupname, shm_env); + exit (1); + } +#endif + + if (run_daemon == TRUE) { + if (geteuid () != 0 && nofork == FALSE) { + fprintf (stderr, "freem: forking daemon must be run as root\n"); + exit (1); + } } if ((nofork == TRUE) && (run_daemon == FALSE)) { @@ -592,6 +622,7 @@ int main (int argc, char **argv, char ** errsav = errno; if (pid_fd < 0) { + fprintf (stderr, "freem: could not open PID file %s [%s]\n", pid_file_path, strerror (errsav)); m_log (1, "freem: could not open PID file"); m_log (1, strerror (errsav)); exit (1); @@ -599,6 +630,7 @@ int main (int argc, char **argv, char ** if (lockf (pid_fd, F_TLOCK, 0) < 0) { errsav = errno; + fprintf (stderr, "freem: could not lock PID file [%s]\n", strerror (errsav)); m_log (1, "freem: could not lock PID file - perhaps already running?"); m_log (1, strerror (errsav)); exit (1); @@ -639,12 +671,15 @@ int main (int argc, char **argv, char ** strncpy (nsnbuf, nsname, 255); if (init (nsnbuf) == FALSE) { - set_io (UNIX); + if (fm_initialized) set_io (UNIX); fprintf (stderr, "\nError initializing FreeM.\n"); exit (1); - } + } + else { + fm_initialized = TRUE; + } direct_mode = FALSE; @@ -671,10 +706,6 @@ int main (int argc, char **argv, char ** /* isolate the path from the routine file */ strncpy (cli_rtn_path, argv[optind], strrchr (argv[optind], '/') - argv[optind]); -/* set_io (UNIX); - printf ("cli_rtn_name = '%s' cli_rtn_path = '%s'\n", cli_rtn_name, cli_rtn_path); - set_io (MUMPS); -*/ } /* do we have a file extension? */ @@ -711,10 +742,11 @@ int main (int argc, char **argv, char ** } - + if (!file_exists (config_file)) { - set_io (UNIX); + if (fm_initialized == TRUE) set_io (UNIX); + fprintf (stderr, "\nFreeM has not been configured. Please run 'fmadm configure'.\n\n\n\n"); exit (2); @@ -724,14 +756,15 @@ int main (int argc, char **argv, char ** if (!skip_init) { /* initialize FreeM environment */ strncpy (nsnbuf, nsname, 255); - if (init (nsnbuf) == FALSE) { - + if (init (nsnbuf) == FALSE) { set_io (UNIX); fprintf (stderr, "\nError initializing FreeM.\n"); exit (1); - } + else { + fm_initialized = TRUE; + } } if (first_process == TRUE) { @@ -940,7 +973,6 @@ void freem_usage(void) fprintf (stdout, "\t-x \n\t\texecute M code on startup\n\n"); fprintf (stdout, "\t-d\n\t\trun the FreeM daemon (one and only one FreeM daemon must always be running)\n\n"); fprintf (stdout, "\t-k\n\t\trun the FreeM daemon in foreground (requires --daemon)\n\n"); - fprintf (stdout, "\t-p \n\t\tuse to record the PID of the FreeM daemon\n\n\n"); fprintf (stdout, "\t-S \n\t\tsets the size of the shared memory segment where FreeM stores the job table, lock table, and IPC table.\n"); #endif fprintf (stdout, "\t\t - Each concurrent job takes %d bytes (1 page) of shared memory\n", PG_SIZE);