--- freem/src/fmadm.c 2025/03/24 19:19:42 1.9 +++ freem/src/fmadm.c 2025/04/01 16:37:12 1.20 @@ -1,5 +1,5 @@ /* - * $Id: fmadm.c,v 1.9 2025/03/24 19:19:42 snw Exp $ + * $Id: fmadm.c,v 1.20 2025/04/01 16:37:12 snw Exp $ * FreeM Administration Tool * * @@ -24,6 +24,39 @@ * along with FreeM. If not, see . * * $Log: fmadm.c,v $ + * 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. + * + * Revision 1.19 2025/04/01 14:32:11 snw + * Begin work on environment and namespace reorg + * + * Revision 1.18 2025/03/31 16:33:56 snw + * Work on fmadm edit global + * + * Revision 1.17 2025/03/30 01:36:58 snw + * Make it easier to bring back fma_gedit, fix double-free in global handler, limit $CHAR to 7-bit ASCII + * + * Revision 1.16 2025/03/24 20:59:58 snw + * Try using DosCopy API instead of built-in cp function on OS/2 + * + * Revision 1.15 2025/03/24 20:58:05 snw + * Try using DosCopy API instead of built-in cp function on OS/2 + * + * Revision 1.14 2025/03/24 20:57:06 snw + * Try using DosCopy API instead of built-in cp function on OS/2 + * + * Revision 1.13 2025/03/24 20:15:09 snw + * Set file permissions on freemd.exe on OS/2 in fmadm configure + * + * Revision 1.12 2025/03/24 20:13:34 snw + * Set file permissions on freemd.exe on OS/2 in fmadm configure + * + * Revision 1.11 2025/03/24 19:25:48 snw + * Make fmadm configure copy freem.exe to freemd.exe for daemon operation on OS/2 systems + * + * Revision 1.10 2025/03/24 19:22:16 snw + * Make fmadm configure copy freem.exe to freemd.exe for daemon operation on OS/2 systems + * * Revision 1.9 2025/03/24 19:19:42 snw * Make fmadm configure copy freem.exe to freemd.exe for daemon operation on OS/2 systems * @@ -40,6 +73,8 @@ #include #include +#include +#include #include #include #include @@ -53,6 +88,10 @@ #include "namespace.h" #include "fs.h" +#if defined(__OS2__) +# include +#endif + #ifdef HAVE_LIBREADLINE # if defined(HAVE_READLINE_READLINE_H) # include @@ -108,6 +147,9 @@ short fma_explicit_environment = FALSE; char obj_str[STRLEN]; extern char config_file[4096]; +extern char env_config_file[4096]; +extern char env_user[255]; +extern char env_group[255]; int fm_shell(void); void fm_checkperms(void); @@ -115,6 +157,8 @@ void fm_reconfigure(void); void fm_configure(void); 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 main (int argc, char **argv) { @@ -162,6 +206,43 @@ int main (int argc, char **argv) if (argv[i][0] == '-') { switch (argv[i][1]) { + + case 'u': + 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_user[k++] = argv[i][j]; + } + + fma_explicit_environment = TRUE; + base_arg++; + + break; + + case 'g': + 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_group[k++] = argv[i][j]; + } + + fma_explicit_environment = TRUE; + base_arg++; + + break; + case 'e': if (argv[i][2] != '=') { @@ -202,12 +283,24 @@ 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 (!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 (env_config_file, 4096, "%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); @@ -1027,11 +1120,9 @@ int fm_edit (short object, int optc, cha case OBJ_ROUTINE: return fma_routines_edit (optc, options); - /* case OBJ_GLOBAL: return fma_globals_edit (optc, options); - */ - + default: fprintf (stderr, "fmadm: 'edit' is an invalid action for '%s'\n", obj_str); return 1; @@ -1066,7 +1157,7 @@ void fm_reconfigure(void) retval = rename (config_file, config_backup); if (retval == 0) { - fprintf (stderr, "[OK]\n\n"); + fprintf (stderr, "[OK]\n"); fm_configure (); @@ -1083,7 +1174,7 @@ void fm_reconfigure(void) void fm_configure (void) { - + char varbase[4096]; char sysrtn[4096]; char sysgbl[4096]; char usrrtn[4096]; @@ -1107,7 +1198,36 @@ void fm_configure (void) struct stat etcstat; int stat_result; + + DIR *dir; + struct dirent *ent; + char src_dir[4096]; + char dest_dir[4096]; + + char *username = env_user; + char *groupname = env_group; + +#if !defined(__OS2__) + 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 (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); @@ -1125,17 +1245,15 @@ void fm_configure (void) } if (file_exists (config_file)) { - fprintf (stderr, "fmadm: '%s' already exists.\n\n", config_file); - fprintf (stderr, "'fmadm configure' may only be used on a fresh installation of FreeM.\n"); - exit (1); + fprintf (stderr, "fmadm: '%s' already exists; running fmadm reconfigure instead\n", config_file); + fm_reconfigure (); + return; } - 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); @@ -1143,17 +1261,21 @@ void fm_configure (void) #if defined(__OS2__) { char srcfile[PATHLEN]; - char dstfile[PATHLEN]; - + char dstfile[PATHLEN]; + snprintf (srcfile, PATHLEN, "%s/bin/freem.exe", PREFIX); snprintf (dstfile, PATHLEN, "%s/bin/freemd.exe", PREFIX); - - fprintf (stderr, "fmadm: running on OS/2; will copy %s to %s\n" srcfile, dstfile); - if (cp (dstfile, srcfile) != 0) { + unlink (dstfile); + + fprintf (stderr, "fmadm: running on OS/2; will copy %s to %s\n", srcfile, dstfile); + + if (DosCopy (srcfile, dstfile, 1) != 0) { fprintf (stderr, "fmadm: fatal error copying %s to %s\n", srcfile, dstfile); exit (1); } + + chmod (dstfile, 0755); } #else fprintf (stderr, "fmadm: not running on OS/2\n"); @@ -1163,98 +1285,123 @@ void fm_configure (void) printf ("---------------------------\n\n"); printf ("This utility will create the initial configuration file for "); - printf ("FreeM environment '%s' in %s.\n\n", fma_environment, config_file); - - - + 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 (SYSCONFDIR, &etcstat) == -1) { fprintf (stderr, "fmadm: creating %s\n", SYSCONFDIR); - mkdir (SYSCONFDIR, 0755); + mkdir (SYSCONFDIR, 0775); + set_permissions (SYSCONFDIR, username, groupname, 0775); } if (stat (confbase, &etcstat) == -1) { fprintf (stderr, "fmadm: creating %s\n", confbase); - mkdir (confbase, 0755); + mkdir (confbase, 0775); + set_permissions (confbase, username, groupname, 0775); } if (stat (envbase, &etcstat) == -1) { fprintf (stderr, "fmadm: creating %s\n", envbase); - mkdir (envbase, 0755); + mkdir (envbase, 0775); + set_permissions (envbase, username, groupname, 0775); } + if (stat (varbase, &etcstat) == -1) { + fprintf (stderr, "fmadm: creating %s\n", varbase); + mkdir (varbase, 0775); + set_permissions (varbase, username, groupname, 0775); + } + if (stat (nsbase, &etcstat) == -1) { fprintf (stderr, "fmadm: creating %s\n", nsbase); - mkdir (nsbase, 0755); + mkdir (nsbase, 0775); + set_permissions (nsbase, username, groupname, 0775); } - - - if (strcmp (fma_environment, "DEFAULT") != 0) { - - DIR *dir; - struct dirent *ent; - char src_dir[4096]; - char dest_dir[4096]; + 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 (buf, 4095, "%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); + mkdir (buf, 0775); + set_permissions (buf, username, groupname, 0775); + + snprintf (buf, 4095, "%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); + mkdir (buf, 0775); + set_permissions (buf, username, groupname, 0775); + + snprintf (buf, 4095, "%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); + mkdir (buf, 0775); + set_permissions (buf, username, groupname, 0775); + + fprintf (stderr, "fmadm: copying routines from '%s' to '%s'...\n", src_dir, dest_dir); - snprintf (src_dir, 4095, "%s/freem/DEFAULT/SYSTEM/routines", LOCALSTATEDIR); - snprintf (dest_dir, 4095, "%s/freem/%s/SYSTEM/routines", LOCALSTATEDIR, fma_environment); - - fprintf (stderr, "fmadm: populating new environment '%s'\n", fma_environment); + if ((dir = opendir (src_dir)) == NULL) { + fprintf (stderr, "\nfmadm: could not open source directory %s\n", src_dir); + exit (1); + } + + while ((ent = readdir (dir)) != NULL) { + char infile[4096]; + char outfile[4096]; - snprintf (buf, 4095, "%s/freem/%s/SYSTEM", LOCALSTATEDIR, fma_environment); - mkdir (buf, 0755); - - snprintf (buf, 4095, "%s/freem/%s/USER", LOCALSTATEDIR, fma_environment); - mkdir (buf, 0755); - - snprintf (buf, 4095, "%s/freem/%s/SYSTEM/routines", LOCALSTATEDIR, fma_environment); - mkdir (buf, 0755); - - snprintf (buf, 4095, "%s/freem/%s/USER/globals", LOCALSTATEDIR, fma_environment); - mkdir (buf, 0755); - - snprintf (buf, 4095, "%s/freem/%s/SYSTEM/globals", LOCALSTATEDIR, fma_environment); - mkdir (buf, 0755); - - snprintf (buf, 4095, "%s/freem/%s/USER/routines", LOCALSTATEDIR, fma_environment); - mkdir (buf, 0755); - - fprintf (stderr, "fmadm: copying routines from '%s' to '%s'...\n", src_dir, dest_dir); - - if ((dir = opendir (src_dir)) == NULL) { - fprintf (stderr, "\nfmadm: could not open source directory %s\n", src_dir); - exit (1); - } - - while ((ent = readdir (dir)) != NULL) { - char infile[4096]; - char outfile[4096]; - - if ((strcmp (ent->d_name, ".") != 0) && (strcmp (ent->d_name, "..") != 0)) { - - fprintf (stderr, "\t%s\n", ent->d_name); - - snprintf (infile, 4095, "%s/%s", src_dir, ent->d_name); - snprintf (outfile, 4095, "%s/%s", dest_dir, ent->d_name); - - if (cp (outfile, infile) != 0) { - fprintf (stderr, "fmadm: failure copying %s to %s\n", infile, outfile); - } + if ((strcmp (ent->d_name, ".") != 0) && (strcmp (ent->d_name, "..") != 0)) { + + fprintf (stderr, "\t%s\n", ent->d_name); + + snprintf (infile, 4095, "%s/%s", src_dir, ent->d_name); + snprintf (outfile, 4095, "%s/%s", dest_dir, ent->d_name); +#if !defined(__OS2__) + if (cp (outfile, infile) != 0) { + fprintf (stderr, "fmadm: failure copying %s to %s\n", infile, outfile); } + set_permissions (outfile, username, groupname, 0755); +#else + if (DosCopy (infile, outfile, 1) != 0) { + fprintf (stderr, "fmadm: failure copying %s to %s\n", infile, outfile); + } +#endif } - } + + fp = fopen (env_config_file, "a+"); + + fprintf (stderr, "Creating %s... ", env_config_file); + + snprintf (buf, 4095, "[%s]", fma_environment); + fm_write (fp, buf); + + snprintf (buf, 4095, "user=%s", env_user); + fm_write (fp, buf); + snprintf (buf, 4095, "group=%s", env_group); + 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+"); - - printf ("Creating %s... ", config_file); + fprintf (stderr, "Creating %s... ", config_file); snprintf (buf, 4095, "[SYSTEM]"); fm_write (fp, buf); @@ -1297,32 +1444,11 @@ void fm_configure (void) 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 ("[OK]\n\n"); - -/* - printf ("Setting USER namespace permissions... "); - - snprintf (buf, 4095, "%s/freem/USER/globals", LOCALSTATEDIR); - chmod (buf, 0777); - - snprintf (buf, 4095, "%s/freem/USER/routines", LOCALSTATEDIR); - chmod (buf, 0777); - - printf ("[OK]\n"); - printf ("Setting SYSTEM namespace permissions... "); - - snprintf (buf, 4095, "%s/freem/SYSTEM/globals", LOCALSTATEDIR); - chmod (buf, 0755); - - snprintf (buf, 4095, "%s/freem/SYSTEM/routines", LOCALSTATEDIR); - chmod (buf, 0755); - - printf ("[OK]\n\n\n"); -*/ printf ("FreeM initial configuration is complete.\n\n"); printf (" USER globals: %s\n", usrgbl); @@ -1336,6 +1462,43 @@ void fm_configure (void) } /* fm_configure */ +void set_permissions(char *path, char *user, char *grp, int mode) +{ + +#if !defined(__OS2__) + struct group *d_grp; + struct passwd *d_user; + gid_t d_gid; + uid_t d_uid; +#endif + + +#if !defined(__OS2__) + if ((d_grp = getgrnam (grp)) == NULL) { + fprintf (stderr, "fmadm: '%s' group must exist before configuring\n", grp); + exit (1); + } + d_gid = d_grp->gr_gid; + + if ((d_user = getpwnam (user)) == NULL) { + fprintf (stderr, "fmadm: '%s' user must exist before configuring\n", user); + exit (1); + } + d_uid = d_user->pw_uid; + + if (chown (path, d_uid, d_gid) != 0) { + fprintf (stderr, "fmadm: error setting ownership on %s\n", path); + exit (1); + } +#endif + + if (chmod (path, mode) != 0) { + fprintf (stderr, "fmadm: error setting permissions on %s to %d\n", path, mode); + exit (1); + } + +} + void fm_write (FILE *file, char *buf) { fprintf (file, "%s\n", buf);