diff --git a/include/ntux/ntux.h b/include/ntux/ntux.h index ff7d504..6063304 100644 --- a/include/ntux/ntux.h +++ b/include/ntux/ntux.h @@ -54,6 +54,7 @@ enum ntux_cmd { NTUX_CMD_STAT, NTUX_CMD_SPAWN, NTUX_CMD_STRACE, + NTUX_CMD_CAP, }; struct ntux_source_version { diff --git a/src/driver/ntux_driver_ctx.c b/src/driver/ntux_driver_ctx.c index f06d085..cc5142b 100644 --- a/src/driver/ntux_driver_ctx.c +++ b/src/driver/ntux_driver_ctx.c @@ -29,6 +29,21 @@ static const nt_tty_affiliation tty_affiliation /* ntapi accessor table */ const ntapi_vtbl * ntux_ntapi; +/* ntux command names */ +static const char * const ntux_cmd_name[NTUX_CMD_CAP] = { + [NTUX_CMD_STAT] = "stat", + [NTUX_CMD_SPAWN] = "spawn", + [NTUX_CMD_STRACE] = "strace", +}; + +/* ntux command options */ +static const struct argv_option * ntux_cmd_options[NTUX_CMD_CAP] = { + [NTUX_CMD_DEFAULT] = ntux_default_options, + [NTUX_CMD_STAT] = ntux_default_options, + [NTUX_CMD_SPAWN] = ntux_spawn_options, + [NTUX_CMD_STRACE] = ntux_strace_options, +}; + /* package info */ static const struct ntux_source_version ntux_src_version = { NTUX_TAG_VER_MAJOR, @@ -64,9 +79,22 @@ static int ntux_driver_usage( const char * program, const char * arg, const struct argv_option ** optv, - struct argv_meta * meta) + struct argv_meta * meta, + enum ntux_cmd cmd) { - char header[512]; + char header[512]; + char * cmdarg[2]; + const char * cmdname; + + if (cmd == NTUX_CMD_DEFAULT) { + cmdarg[0] = ""; + cmdarg[1] = ""; + cmdname = ""; + } else { + cmdarg[0] = " (--cmd="; + cmdarg[1] = ")"; + cmdname = ntux_cmd_name[cmd]; + } snprintf(header,sizeof(header), "Usage: %s [options] ...\n" @@ -76,8 +104,8 @@ static int ntux_driver_usage( " for commands that spawn other programs (e.g. spawn, strace),\n" " the first non-option argument must specify the name of the\n" " program to be executed.\n\n" - "Options:\n", - program,program); + "Options%s%s%s:\n", + program,program,cmdarg[0],cmdname,cmdarg[1]); argv_usage(stdout,header,optv,arg); argv_free(meta); @@ -140,7 +168,7 @@ static int ntux_cctx_update( if (flags & NTUX_DRIVER_VERBOSITY_USAGE) return ntux_driver_usage( program,entry->arg, - optv,0); + optv,0,cctx->cmd); case TAG_VERSION: cctx->drvflags |= NTUX_DRIVER_VERSION; @@ -150,7 +178,7 @@ static int ntux_cctx_update( if (*nunits) return ntux_driver_usage( program,entry->arg, - optv,0); + optv,0,cctx->cmd); if (!strcmp(entry->arg,"stat")) cctx->cmd = NTUX_CMD_STAT; @@ -185,6 +213,32 @@ static int ntux_get_driver_ctx_fail(struct argv_meta * meta) return -1; } +static int ntux_cmd_from_program(const char * program) +{ + const char * dot; + const char * hyphen; + const char * mark; + + dot = strrchr(program,'.'); + hyphen = strrchr(program,'-'); + + if (hyphen > dot) + mark = ++hyphen; + else if (dot > hyphen) + mark = ++dot; + else + mark = program; + + if (!strcmp(mark,"stat")) + return NTUX_CMD_STAT; + else if (!strcmp(mark,"spawn")) + return NTUX_CMD_SPAWN; + else if (!strcmp(mark,"strace")) + return NTUX_CMD_STRACE; + + return NTUX_CMD_DEFAULT; +} + int ntux_get_driver_ctx( char ** argv, char ** envp, @@ -212,16 +266,17 @@ int ntux_get_driver_ctx( memset(&cctx,0,sizeof(cctx)); - cctx.drvflags = flags; - program = argv_program_name(argv[0]); nunits = 0; execargv = 0; + program = argv_program_name(argv[0]); + cctx.cmd = ntux_cmd_from_program(program); + cctx.drvflags = flags; /* missing arguments? */ - argv_optv_init(ntux_default_options,optv); + argv_optv_init(ntux_cmd_options[cctx.cmd],optv); if (!argv[1] && (flags & NTUX_DRIVER_VERBOSITY_USAGE)) - return ntux_driver_usage(program,0,optv,0); + return ntux_driver_usage(program,0,optv,0,cctx.cmd); /* initial argv scan: ... --cmd=xxx ... */ for (parg=argv, cmdargv=0; *parg && !cmdargv; parg++) { @@ -271,7 +326,7 @@ int ntux_get_driver_ctx( } if (!ctx.unitidx && (flags & NTUX_DRIVER_VERBOSITY_USAGE)) - ntux_driver_usage(program,0,optv,0); + ntux_driver_usage(program,0,optv,0,cctx.cmd); if (!ctx.unitidx) return NTUX_ERROR; @@ -300,7 +355,7 @@ int ntux_get_driver_ctx( /* finalize */ if (nunits && !cctx.cmd) - return ntux_driver_usage(program,0,optv,meta); + return ntux_driver_usage(program,0,optv,meta,NTUX_CMD_DEFAULT); if (!(ictx = ntux_driver_ctx_alloc(meta,&cctx,nunits))) return ntux_get_driver_ctx_fail(meta);