1 // SPDX-License-Identifier: GPL-2.0-only or License-Ref-kk-custom
2 /*
3 * Copyright (C) 2020 Kernkonzept GmbH.
4 * Author(s): Adam Lackorzynski <adam.lackorzynski@kernkonzept.com>
5 * Sarah Hoffmann <sarah.hoffmann@kernkonzept.com>
6 *
7 * This file is distributed under the terms of the GNU General Public
8 * License, version 2. Please see the COPYING-GPL-2 file for details.
9 */
10
11 /**
12 *
13 * A command line prompt using ned's server interface.
14 *
15 * Usage: ned-prompt [<prompt>]
16 *
17 * The capability to the ned server is expected under the name srv.
18 * Optionally a different prompt than 'Cmd>' may be set via the command
19 * line.
20 */
21
22 #include <cstdio>
23 #include <cstdlib>
24
25 #include <readline/history.h>
26 #include <readline/readline.h>
27
28 #include <l4/ned/cmd_control>
29 #include <l4/re/env>
30 #include <l4/re/error_helper>
31
32 /**
33 * Add a line to the readline history.
34 *
35 * This function mimicks the 'ignoreboth' HISTCONTROL setting.
36 */
add_to_history(char * line)37 static void add_to_history(char *line)
38 {
39 if (line[0] == ' ')
40 return;
41
42 HIST_ENTRY **hist_list = history_list();
43 if (hist_list)
44 {
45 HIST_ENTRY *hist = hist_list[history_length - 1];
46 if (hist && strcmp(line, hist->line) == 0)
47 return;
48 }
49
50 add_history(line);
51 }
52
run_cmds(char const * prompt)53 static void run_cmds(char const* prompt)
54 {
55 char fullprompt[64];
56
57 snprintf(fullprompt, sizeof(fullprompt), "%s ", prompt);
58
59 using L4Re::Ned::Cmd_control;
60 auto srv = L4Re::chkcap(L4Re::Env::env()->get_cap<Cmd_control>("svr"),
61 "Searching ned command capability 'svr'");
62
63 for (;;)
64 {
65 char *cmd;
66 do
67 {
68 cmd = readline(fullprompt);
69 }
70 while (!cmd);
71
72 if (*cmd)
73 {
74 char buffer[L4_UTCB_GENERIC_DATA_SIZE * sizeof(l4_umword_t)];
75 L4::Ipc::String<> c(cmd);
76 L4::Ipc::String<char> result(sizeof(buffer), buffer);
77 int e = srv->execute(c, &result);
78 if (e < 0)
79 printf("Error calling ned: %d\n", e);
80 else if (result.length != 3 || strncmp("nil", result.data, 3) != 0)
81 printf("%.*s\n", (int)result.length, result.data);
82 add_to_history(cmd);
83 }
84
85 free(cmd);
86 }
87 }
88
main(int argc,char * argv[])89 int main(int argc, char *argv[])
90 {
91 printf("Welcome to ned prompt.\n");
92 try
93 {
94 run_cmds(argc < 2 ? "Cmd>" : argv[1]);
95 }
96 catch (L4::Runtime_error &e)
97 {
98 printf("%s: %s\n", e.str(), e.extra_str());
99 return 1;
100 }
101
102 return 0;
103 }
104