+static int command_unknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ const char *cmd_name = Jim_GetString(argv[0], NULL);
+ if (strcmp(cmd_name, "unknown") == 0) {
+ if (argc == 1)
+ return JIM_OK;
+ argc--;
+ argv++;
+ }
+ script_debug(interp, cmd_name, argc, argv);
+
+ struct command_context *cmd_ctx = current_command_context(interp);
+ struct command *c = cmd_ctx->commands;
+ int remaining = command_unknown_find(argc, argv, c, &c, true);
+ /* if nothing could be consumed, then it's really an unknown command */
+ if (remaining == argc) {
+ const char *cmd = Jim_GetString(argv[0], NULL);
+ LOG_ERROR("Unknown command:\n %s", cmd);
+ return JIM_OK;
+ }
+
+ bool found = true;
+ Jim_Obj *const *start;
+ unsigned count;
+ if (c->handler || c->jim_handler) {
+ /* include the command name in the list */
+ count = remaining + 1;
+ start = argv + (argc - remaining - 1);
+ } else {
+ c = command_find(cmd_ctx->commands, "usage");
+ if (NULL == c) {
+ LOG_ERROR("unknown command, but usage is missing too");
+ return JIM_ERR;
+ }
+ count = argc - remaining;
+ start = argv;
+ found = false;
+ }
+ /* pass the command through to the intended handler */
+ if (c->jim_handler) {
+ interp->cmdPrivData = c->jim_handler_data;
+ return (*c->jim_handler)(interp, count, start);
+ }
+
+ return script_command_run(interp, count, start, c, found);
+}
+
+static int jim_command_mode(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ struct command_context *cmd_ctx = current_command_context(interp);
+ enum command_mode mode;
+
+ if (argc > 1) {
+ struct command *c = cmd_ctx->commands;
+ int remaining = command_unknown_find(argc - 1, argv + 1, c, &c, true);
+ /* if nothing could be consumed, then it's an unknown command */
+ if (remaining == argc - 1) {
+ Jim_SetResultString(interp, "unknown", -1);
+ return JIM_OK;
+ }
+ mode = c->mode;
+ } else
+ mode = cmd_ctx->mode;
+
+ const char *mode_str;
+ switch (mode) {
+ case COMMAND_ANY:
+ mode_str = "any";
+ break;
+ case COMMAND_CONFIG:
+ mode_str = "config";
+ break;
+ case COMMAND_EXEC:
+ mode_str = "exec";
+ break;
+ default:
+ mode_str = "unknown";
+ break;
+ }
+ Jim_SetResultString(interp, mode_str, -1);
+ return JIM_OK;
+}
+
+static int jim_command_type(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ if (1 == argc)
+ return JIM_ERR;
+
+ struct command_context *cmd_ctx = current_command_context(interp);
+ struct command *c = cmd_ctx->commands;
+ int remaining = command_unknown_find(argc - 1, argv + 1, c, &c, true);
+ /* if nothing could be consumed, then it's an unknown command */
+ if (remaining == argc - 1) {
+ Jim_SetResultString(interp, "unknown", -1);
+ return JIM_OK;
+ }
+
+ if (c->jim_handler)
+ Jim_SetResultString(interp, "native", -1);
+ else if (c->handler)
+ Jim_SetResultString(interp, "simple", -1);
+ else
+ Jim_SetResultString(interp, "group", -1);
+
+ return JIM_OK;
+}