version 1.12, 2025/04/02 02:16:27
|
version 1.19, 2025/04/10 01:24:38
|
Line 24
|
Line 24
|
* along with FreeM. If not, see <https://www.gnu.org/licenses/>. |
* along with FreeM. If not, see <https://www.gnu.org/licenses/>. |
* |
* |
* $Log$ |
* $Log$ |
|
* Revision 1.19 2025/04/10 01:24:38 snw |
|
* Remove C++ style comments |
|
* |
|
* Revision 1.18 2025/04/09 19:52:02 snw |
|
* Eliminate as many warnings as possible while building with -Wall |
|
* |
|
* Revision 1.17 2025/04/04 21:28:16 snw |
|
* Remove custom_user and custom_group vars from freem and shed privileges per environment catalog settings |
|
* |
|
* 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 |
* Revision 1.12 2025/04/02 02:16:27 snw |
* Add fmadm status environment command and move journals to a better location |
* Add fmadm status environment command and move journals to a better location |
* |
* |
Line 56
|
Line 77
|
* SPDX-License-Identifier: AGPL-3.0-or-later |
* SPDX-License-Identifier: AGPL-3.0-or-later |
**/ |
**/ |
|
|
|
#define _GNU_SOURCE |
#include <stdlib.h> |
#include <stdlib.h> |
#include <stddef.h> |
#include <stddef.h> |
#include "mpsdef.h" |
#include "mpsdef.h" |
Line 112 int main (int argc, char **argv, char **
|
Line 134 int main (int argc, char **argv, char **
|
|
|
int option_index = 0; |
int option_index = 0; |
|
|
|
char fm_initialized = FALSE; |
|
|
char dx_mcode[512]; |
char dx_mcode[512]; |
char startup_routine[256]; |
char startup_routine[256]; |
short routine_mode; |
short routine_mode; |
Line 126 int main (int argc, char **argv, char **
|
Line 150 int main (int argc, char **argv, char **
|
gid_t d_gid; |
gid_t d_gid; |
uid_t d_uid; |
uid_t d_uid; |
|
|
short custom_user = FALSE; |
|
short custom_group = FALSE; |
|
|
|
#if defined(HAVE_GETOPT_LONG) |
#if defined(HAVE_GETOPT_LONG) |
struct option long_options[] = { |
struct option long_options[] = { |
{"help", no_argument, 0, 'h'}, |
{"help", no_argument, 0, 'h'}, |
Line 157 int main (int argc, char **argv, char **
|
Line 178 int main (int argc, char **argv, char **
|
|
|
char *symname = (char *) calloc(STRLEN, sizeof(char)); |
char *symname = (char *) calloc(STRLEN, sizeof(char)); |
char *symval = (char *) calloc(STRLEN, sizeof(char)); |
char *symval = (char *) calloc(STRLEN, sizeof(char)); |
|
|
int namelen; |
|
int vallen; |
|
|
|
char cli_rtn_path[PATH_MAX] = {0}; |
char cli_rtn_path[PATH_MAX] = {0}; |
char *cli_rtn_file; |
char *cli_rtn_file; |
char cli_rtn_name[256]; |
char cli_rtn_name[256]; |
|
|
|
char env_ena[25]; |
|
|
routine_mode = FALSE; |
routine_mode = FALSE; |
strcpy (m_dialect, "FREEM"); |
strcpy (m_dialect, "FREEM"); |
|
|
Line 194 int main (int argc, char **argv, char **
|
Line 214 int main (int argc, char **argv, char **
|
|
|
while (1) { |
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 == -1) break; |
if (c == '?') freem_usage (); |
if (c == '?') freem_usage (); |
Line 217 int main (int argc, char **argv, char **
|
Line 237 int main (int argc, char **argv, char **
|
break; |
break; |
|
|
case 'e': /* specify FreeM environment */ |
case 'e': /* specify FreeM environment */ |
strncpy (shm_env, optarg, 255); |
strncpy (shm_env, optarg, sizeof (shm_env) - 1); |
break; |
break; |
|
|
case 'R': |
case 'R': |
Line 307 int main (int argc, char **argv, char **
|
Line 327 int main (int argc, char **argv, char **
|
|
|
case 'S': /* --shmsize */ |
case 'S': /* --shmsize */ |
shm_init_size = atol (optarg); |
shm_init_size = atol (optarg); |
break; |
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; |
|
|
|
|
|
} |
} |
|
|
Line 330 int main (int argc, char **argv, char **
|
Line 339 int main (int argc, char **argv, char **
|
extern char *optarg; |
extern char *optarg; |
extern int optind, optopt; |
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 (); |
if (c == '?') freem_usage (); |
|
|
Line 353 int main (int argc, char **argv, char **
|
Line 362 int main (int argc, char **argv, char **
|
break; |
break; |
|
|
case 'e': /* specify FreeM environment */ |
case 'e': /* specify FreeM environment */ |
strncpy (shm_env, optarg, 255); |
strncpy (shm_env, optarg, sizeof (shm_env) - 1); |
break; |
break; |
|
|
case 'R': |
case 'R': |
Line 438 int main (int argc, char **argv, char **
|
Line 447 int main (int argc, char **argv, char **
|
shm_init_size = atol (optarg); |
shm_init_size = atol (optarg); |
break; |
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; |
|
|
|
|
|
} |
} |
} |
} |
} |
} |
Line 462 int main (int argc, char **argv, char **
|
Line 460 int main (int argc, char **argv, char **
|
#endif |
#endif |
|
|
snprintf (config_file, 4096, "%s/freem/%s/freem.conf", SYSCONFDIR, shm_env); |
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) { |
if (!file_exists (config_file)) { |
d_grp = getgrnam (d_groupname); |
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) { |
if (read_profile_string (env_config_file, shm_env, "user", d_username) == FALSE) { |
fprintf (stderr, "freem: invalid group '%s'\n", d_groupname); |
fprintf (stderr, "freem: could not determine owning user for environment %s\n", shm_env); |
exit (1); |
exit (1); |
} |
} |
|
|
d_gid = d_grp->gr_gid; |
|
} |
|
|
|
if (custom_user) { |
if (read_profile_string (env_config_file, shm_env, "group", d_groupname) == FALSE) { |
d_user = getpwnam (d_username); |
fprintf (stderr, "freem: could not determine owning group for environment %s\n", shm_env); |
|
exit (1); |
|
} |
|
|
if (d_user == NULL) { |
if (read_profile_string (env_config_file, shm_env, "enabled", env_ena) == FALSE) { |
fprintf (stderr, "freem: invalid user '%s'\n", d_username); |
fprintf (stderr, "freem: could not discover enabled state for environment %s\n", shm_env); |
exit (1); |
exit (1); |
} |
} |
|
|
d_uid = d_user->pw_uid; |
if (strcmp (env_ena, "true") != 0) { |
} |
fprintf (stderr, "freem: environment %s is administratively disabled\n", shm_env); |
else { |
exit (1); |
d_uid = 0; |
} |
} |
|
|
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)) { |
if ((nofork == TRUE) && (run_daemon == FALSE)) { |
Line 547 int main (int argc, char **argv, char **
|
Line 576 int main (int argc, char **argv, char **
|
if (geteuid () == 0) { |
if (geteuid () == 0) { |
/* shed privileges */ |
/* shed privileges */ |
|
|
if (custom_group) { |
|
fprintf (stderr, "freem: switching to group %s\n", d_groupname); |
fprintf (stderr, "freem: switching to group %s\n", d_groupname); |
m_log (1, "switching groups"); |
m_log (1, "switching groups"); |
|
|
if (setgid (d_gid) == -1) { |
if (setgid (d_gid) == -1) { |
fprintf (stderr, "freem: failure switching GID\n"); |
fprintf (stderr, "freem: failure switching GID\n"); |
m_log (1, "failure switching GIDs"); |
m_log (1, "failure switching GIDs"); |
exit (1); |
exit (1); |
} |
|
} |
} |
|
|
|
|
|
|
if (custom_user) { |
if (d_uid != geteuid ()) { |
fprintf (stderr, "freem: switching to username %s\n", d_username); |
fprintf (stderr, "freem: switching to username %s\n", d_username); |
m_log (1, "switching users"); |
m_log (1, "switching users"); |
|
|
Line 595 int main (int argc, char **argv, char **
|
Line 624 int main (int argc, char **argv, char **
|
errsav = errno; |
errsav = errno; |
|
|
if (pid_fd < 0) { |
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, "freem: could not open PID file"); |
m_log (1, strerror (errsav)); |
m_log (1, strerror (errsav)); |
exit (1); |
exit (1); |
Line 602 int main (int argc, char **argv, char **
|
Line 632 int main (int argc, char **argv, char **
|
|
|
if (lockf (pid_fd, F_TLOCK, 0) < 0) { |
if (lockf (pid_fd, F_TLOCK, 0) < 0) { |
errsav = errno; |
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, "freem: could not lock PID file - perhaps already running?"); |
m_log (1, strerror (errsav)); |
m_log (1, strerror (errsav)); |
exit (1); |
exit (1); |
Line 639 int main (int argc, char **argv, char **
|
Line 670 int main (int argc, char **argv, char **
|
skip_init = 1; |
skip_init = 1; |
|
|
/* initialize FreeM environment */ |
/* initialize FreeM environment */ |
strncpy (nsnbuf, nsname, 255); |
strncpy (nsnbuf, nsname, sizeof (nsnbuf)); |
if (init (nsnbuf) == FALSE) { |
if (init (nsnbuf) == FALSE) { |
|
|
set_io (UNIX); |
if (fm_initialized) set_io (UNIX); |
fprintf (stderr, "\nError initializing FreeM.\n"); |
fprintf (stderr, "\nError initializing FreeM.\n"); |
|
|
exit (1); |
exit (1); |
|
|
} |
} |
|
else { |
|
fm_initialized = TRUE; |
|
} |
|
|
|
|
direct_mode = FALSE; |
direct_mode = FALSE; |
Line 674 int main (int argc, char **argv, char **
|
Line 708 int main (int argc, char **argv, char **
|
/* isolate the path from the routine file */ |
/* isolate the path from the routine file */ |
strncpy (cli_rtn_path, argv[optind], strrchr (argv[optind], '/') - argv[optind]); |
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? */ |
/* do we have a file extension? */ |
Line 714 int main (int argc, char **argv, char **
|
Line 744 int main (int argc, char **argv, char **
|
|
|
} |
} |
|
|
|
|
if (!file_exists (config_file)) { |
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"); |
fprintf (stderr, "\nFreeM has not been configured. Please run 'fmadm configure'.\n\n\n\n"); |
|
|
exit (2); |
exit (2); |
Line 726 int main (int argc, char **argv, char **
|
Line 757 int main (int argc, char **argv, char **
|
|
|
if (!skip_init) { |
if (!skip_init) { |
/* initialize FreeM environment */ |
/* initialize FreeM environment */ |
strncpy (nsnbuf, nsname, 255); |
strncpy (nsnbuf, nsname, sizeof (nsnbuf)); |
if (init (nsnbuf) == FALSE) { |
if (init (nsnbuf) == FALSE) { |
|
|
set_io (UNIX); |
set_io (UNIX); |
fprintf (stderr, "\nError initializing FreeM.\n"); |
fprintf (stderr, "\nError initializing FreeM.\n"); |
|
|
exit (1); |
exit (1); |
|
|
} |
} |
|
else { |
|
fm_initialized = TRUE; |
|
} |
} |
} |
|
|
if (first_process == TRUE) { |
if (first_process == TRUE) { |
Line 834 int main (int argc, char **argv, char **
|
Line 866 int main (int argc, char **argv, char **
|
|
|
|
|
#if !defined(_AIX) |
#if !defined(_AIX) |
if(import_env == TRUE) { |
if (import_env == TRUE) { |
|
|
int i_maxlen = 255; |
int i_maxlen = 255; |
|
|
for(env = envp; *env != 0; env++) { |
for (env = envp; *env != 0; env++) { |
|
varname = strtok (*env, "="); |
namelen = 0; |
varval = strtok (NULL, "="); |
vallen = 0; |
|
|
|
varname = strtok(*env, "="); |
|
varval = strtok(NULL, "="); |
|
|
|
if(varval != NULL) { |
|
namelen = strlen (varname); |
|
vallen = strlen (varval); |
|
|
|
|
if (varval != NULL) { |
snprintf (symname, i_maxlen, "ENV.%s\201\201", varname); |
snprintf (symname, i_maxlen, "ENV.%s\201\201", varname); |
strncpy (symval, varval, i_maxlen); |
strncpy (symval, varval, i_maxlen - 1); |
|
|
stcnv_c2m (symval); |
stcnv_c2m (symval); |
|
|