1: /*************************************************************************
2: * (C) 2010 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
3: * by Michael Pounov <misho@openbsd-bg.org>
4: *
5: * $Author: misho $
6: * $Id: cli.c,v 1.1.2.1 2010/03/09 12:44:40 misho Exp $
7: *
8: *************************************************************************/
9: #include "global.h"
10:
11:
12: static int cmd_exit(void *cmds, FILE *out, char ** __restrict args)
13: {
14: return 1;
15: }
16:
17: static int cmd_help(void *cmds, FILE *out, char ** __restrict args)
18: {
19: register int i;
20: ioCommands_t *commands = cmds;
21:
22: if (!cmds)
23: return -1;
24:
25: if (!args) {
26: fprintf(out, "\n");
27: for (i = 0; commands[i].cmd_name; i++)
28: fprintf(out, "%s\t\t%s\n", commands[i].cmd_name, commands[i].cmd_doc);
29: } else {
30: if (!args[1])
31: fprintf(out, "Help screen::\n");
32: else
33: if (!strncmp(args[1], "---", 3))
34: return 0;
35:
36: for (i = 0; commands[i].cmd_name; i++) {
37: if (args[1] && strcmp(args[1], commands[i].cmd_name))
38: continue;
39:
40: fprintf(out, "%s%s\t\t%s\n", args[1] ? "Syntax::\n\t" : "", commands[i].cmd_name,
41: args[1] ? commands[i].cmd_help : commands[i].cmd_doc);
42: }
43: }
44:
45: return 0;
46: }
47:
48: static int cmd_unsupported(void *cmds, FILE *out, char ** __restrict args)
49: {
50: fprintf(out, "Command %s not supported in this version ...\n", args[0]);
51: return 0;
52: }
53:
54: // ------------------------------------------------------------
55:
56: #pragma GCC visibility push(hidden)
57:
58: ioCommands_t io_stdCmds[] = {
59: { "test", cmd_unsupported, "Test - Don`t use default command structure!", "test <cr>", NULL },
60: { "-------", NULL, "---------------------", NULL, NULL },
61: { "help", cmd_help, "Help screen", "help [command] <cr>", NULL },
62: { "exit", cmd_exit, "Exit from console", "exit <cr>", NULL },
63: { NULL, NULL, NULL, NULL }
64: };
65:
66: #pragma GCC visibility pop
67:
68: // ------------------------------------------------------------
69:
70: /*
71: * ioCLIInit() Initialize CLI features
72: * @cmdList = Commands list
73: * @out = Output handle
74: * @cmdComplete = Completion function
75: * @cmdEntry = Compentry function
76: * return: none
77: */
78: void ioCLIInit(ioCommands_t *cmdList, FILE *out, io_Completion_t *cmdComplete, io_CompEntry_t *cmdEntry)
79: {
80: ioCommands_t *cmds = cmdList ? cmdList : io_stdCmds;
81:
82: inline int inline_help()
83: {
84: cmd_help(cmds, out, NULL);
85: rl_on_new_line();
86: return 0;
87: }
88:
89: rl_bind_key('?', inline_help);
90: // command completon
91: rl_attempted_completion_function = cmdComplete;
92: rl_completion_entry_function = cmdEntry;
93: }
94:
95: /*
96: * ioCLIExec() Execute CLI main loop
97: * @cmdList = Commands list
98: * @out = Output handle
99: * @csPrompt = Prompt text
100: * return: -1 error, 0 = exit w/^+D, 1 done.
101: */
102: int ioCLIExec(ioCommands_t *cmdList, FILE *out, const char *csPrompt)
103: {
104: char *line, *s, *t, **app, *items[20];
105: int ret = 0;
106: register int i;
107: ioCommands_t *cmd = NULL;
108:
109: if (!cmdList)
110: return -1;
111:
112: do {
113: line = readline(csPrompt);
114: if (!line) { // ^+d
115: fprintf(out, "\n");
116: fflush(out);
117: break;
118: }
119: // clear whitespaces
120: for (s = line; isspace(*s); s++);
121: if (*s) {
122: for (t = s + strlen(s) - 1; t > s && isspace(*t); t--);
123: *++t = 0;
124: }
125:
126: if (*s) {
127: add_history(s);
128:
129: memset(items, 0, sizeof(char*) * 20);
130: for (app = items; app < items + 19 && (*app = strsep(&s, " \t")); *app ? app++ : app);
131:
132: /*
133: for (i = 0; i < 20; i++)
134: printf("i=%d %s\n", i, items[i]);
135: */
136:
137: // exec_cmd ...
138: for (cmd = NULL, i = 0; cmdList[i].cmd_name; i++)
139: if (*items[0] && !strncmp(cmdList[i].cmd_name, items[0], strlen(items[0]))) {
140: cmd = &cmdList[i];
141: break;
142: }
143: if (!cmd) {
144: fprintf(out, "Command '%s' not found!\n", items[0]);
145: ret = -1;
146: } else
147: ret = cmd->cmd_func(cmdList, out, items);
148: }
149:
150: free(line);
151: } while (ret < 1);
152:
153: return ret;
154: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>