summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>1996-06-21 06:05:13 +0000
committerMiles Bader <miles@gnu.org>1996-06-21 06:05:13 +0000
commitb2c16baabefa5b84faf80f7c8113043447815083 (patch)
tree0b446d56b9d4f12806dd6b4ffd6ceb7b377620de
parent923dcfffdbb1af8179106b82fb4b4ed84210f647 (diff)
(parse_opt):
Handle runtime invalid selection of 4.2 mode. Save select mode until we're done to correctly deal with external errors at runtime. (startup_parents, startup_argp, runtime_parents, runtime_argp): New variables. (main): Argp vars made global. (startup_parents): diskfs_device_startup_argp --> &diskfs_std_device_startup_argp.
-rw-r--r--ufs/main.c51
1 files changed, 44 insertions, 7 deletions
diff --git a/ufs/main.c b/ufs/main.c
index 58c6f427..ac3a34bb 100644
--- a/ufs/main.c
+++ b/ufs/main.c
@@ -73,32 +73,69 @@ parse_opt (int key, char *arg, struct argp_state *state)
{
switch (key)
{
+ enum compat_mode mode;
+
case 'C':
if (strcasecmp (arg, "gnu") == 0)
- compat_mode = COMPAT_GNU;
+ mode = COMPAT_GNU;
else if (strcmp (arg, "4.4") == 0)
- compat_mode = COMPAT_BSD44;
+ mode = COMPAT_BSD44;
else if (strcmp (arg, "4.2") == 0)
- compat_mode = COMPAT_BSD42;
+ {
+ if (sblock
+ && (sblock->fs_inodefmt == FS_44INODEFMT
+ || direct_symlink_extension))
+ {
+ argp_failure (state, 0, 0,
+ "4.2 compat mode requested on 4.4 fs");
+ return EINVAL;
+ }
+ mode = COMPAT_BSD42;
+ }
else
- argp_error (state, "%s: Unknown compatibility mode", arg);
+ {
+ argp_error (state, "%s: Unknown compatibility mode", arg);
+ return EINVAL;
+ }
+
+ state->hook = (void *)mode; /* Save it for the end. */
break;
+
+ case ARGP_KEY_INIT:
+ state->hook = (void *)compat_mode; break;
+ case ARGP_KEY_SUCCESS:
+ compat_mode = (enum compat_mode)state->hook; break;
+
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
+static const struct argp *startup_parents[] = {
+ &diskfs_std_device_startup_argp, 0
+};
+static const struct argp startup_argp = {
+ options, parse_opt, 0, 0, startup_parents
+};
+
+static const struct argp *runtime_parents[] = {
+ &diskfs_std_runtime_argp, 0
+};
+static const struct argp runtime_argp = {
+ options, parse_opt, 0, 0, runtime_parents
+};
+
+struct argp *diskfs_runtime_argp = (struct argp *)&runtime_argp;
+
int
main (int argc, char **argv)
{
error_t err;
off_t disk_size;
mach_port_t bootstrap;
- const struct argp *argp_parents[] = { diskfs_device_startup_argp, 0 };
- struct argp argp = {options, parse_opt, 0, 0, argp_parents};
- argp_parse (&argp, argc, argv, 0, 0, 0);
+ argp_parse (&startup_argp, argc, argv, 0, 0, 0);
/* This must come after the args have been parsed, as this is where the
host priv ports are set for booting. */