Subversion Repositories HelenOS

Rev

Rev 3425 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3425 Rev 4377
Line 31... Line 31...
31
 
31
 
32
#include <stdio.h>
32
#include <stdio.h>
33
#include <stdlib.h>
33
#include <stdlib.h>
34
#include <string.h>
34
#include <string.h>
35
#include <io/stream.h>
35
#include <io/stream.h>
-
 
36
#include <console.h>
-
 
37
#include <kbd/kbd.h>
-
 
38
#include <kbd/keycode.h>
-
 
39
#include <errno.h>
-
 
40
#include <bool.h>
36
 
41
 
37
#include "config.h"
42
#include "config.h"
38
#include "util.h"
43
#include "util.h"
39
#include "scli.h"
44
#include "scli.h"
40
#include "input.h"
45
#include "input.h"
41
#include "errors.h"
46
#include "errors.h"
42
#include "exec.h"
47
#include "exec.h"
43
 
48
 
44
extern volatile unsigned int cli_interactive;
-
 
45
 
-
 
46
/* Not exposed in input.h */
-
 
47
static void cli_restricted(char *);
-
 
48
static void read_line(char *, int);
49
static void read_line(char *, int);
49
 
50
 
50
/* More than a macro than anything */
-
 
51
static void cli_restricted(char *cmd)
-
 
52
{
-
 
53
    printf("%s is not available in %s mode\n", cmd,
-
 
54
        cli_interactive ? "interactive" : "non-interactive");
-
 
55
 
-
 
56
    return;
-
 
57
}
-
 
58
 
-
 
59
/* Tokenizes input from console, sees if the first word is a built-in, if so
51
/* Tokenizes input from console, sees if the first word is a built-in, if so
60
 * invokes the built-in entry point (a[0]) passing all arguments in a[] to
52
 * invokes the built-in entry point (a[0]) passing all arguments in a[] to
61
 * the handler */
53
 * the handler */
62
int tok_input(cliuser_t *usr)
54
int tok_input(cliuser_t *usr)
63
{
55
{
Line 67... Line 59...
67
    char *tmp;
59
    char *tmp;
68
 
60
 
69
    if (NULL == usr->line)
61
    if (NULL == usr->line)
70
        return CL_EFAIL;
62
        return CL_EFAIL;
71
 
63
 
72
    tmp = cli_strdup(usr->line);
64
    tmp = str_dup(usr->line);
73
 
65
 
74
    /* Break up what the user typed, space delimited */
-
 
75
 
-
 
76
    /* TODO: Protect things in quotes / ticks, expand wildcards */
-
 
77
    cmd[n] = cli_strtok(tmp, " ");
66
    cmd[n] = strtok(tmp, " ");
78
    while (cmd[n] && n < WORD_MAX) {
67
    while (cmd[n] && n < WORD_MAX) {
79
        cmd[++n] = cli_strtok(NULL, " ");
68
        cmd[++n] = strtok(NULL, " ");
80
    }
69
    }
81
 
70
 
82
    /* We have rubbish */
71
    /* We have rubbish */
83
    if (NULL == cmd[0]) {
72
    if (NULL == cmd[0]) {
84
        rc = CL_ENOENT;
73
        rc = CL_ENOENT;
85
        goto finit;
74
        goto finit;
86
    }
75
    }
87
 
76
 
88
    /* Its a builtin command */
77
    /* Its a builtin command ? */
89
    if ((i = (is_builtin(cmd[0]))) > -1) {
78
    if ((i = (is_builtin(cmd[0]))) > -1) {
90
        /* Its not available in this mode, see what try_exec() thinks */
-
 
91
        if (builtin_is_restricted(i)) {
-
 
92
                rc = try_exec(cmd[0], cmd);
-
 
93
                if (rc)
-
 
94
                    /* No external matching it could be found, tell the
-
 
95
                     * user that the command does exist, but is not
-
 
96
                     * available in this mode. */
-
 
97
                    cli_restricted(cmd[0]);
-
 
98
                goto finit;
-
 
99
        }
-
 
100
        /* Its a builtin, its available, run it */
-
 
101
        rc = run_builtin(i, cmd, usr);
79
        rc = run_builtin(i, cmd, usr);
102
        goto finit;
80
        goto finit;
103
    /* We repeat the same dance for modules */
81
    /* Its a module ? */
104
    } else if ((i = (is_module(cmd[0]))) > -1) {
82
    } else if ((i = (is_module(cmd[0]))) > -1) {
105
        if (module_is_restricted(i)) {
-
 
106
            rc = try_exec(cmd[0], cmd);
-
 
107
            if (rc)
-
 
108
                cli_restricted(cmd[0]);
-
 
109
            goto finit;
-
 
110
        }
-
 
111
        rc = run_module(i, cmd);
83
        rc = run_module(i, cmd);
112
        goto finit;
84
        goto finit;
113
    } else {
-
 
114
        /* Its not a module or builtin, restricted or otherwise.
-
 
115
         * See what try_exec() thinks of it and just pass its return
-
 
116
         * value back to the caller */
-
 
117
        rc = try_exec(cmd[0], cmd);
-
 
118
        goto finit;
-
 
119
    }
85
    }
120
 
86
 
-
 
87
    /* See what try_exec thinks of it */
-
 
88
    rc = try_exec(cmd[0], cmd);
-
 
89
 
121
finit:
90
finit:
122
    if (NULL != usr->line) {
91
    if (NULL != usr->line) {
123
        free(usr->line);
92
        free(usr->line);
124
        usr->line = (char *) NULL;
93
        usr->line = (char *) NULL;
125
    }
94
    }
Line 127... Line 96...
127
        free(tmp);
96
        free(tmp);
128
 
97
 
129
    return rc;
98
    return rc;
130
}
99
}
131
 
100
 
132
/* Borrowed from Jiri Svoboda's 'cli' uspace app */
-
 
133
static void read_line(char *buffer, int n)
101
static void read_line(char *buffer, int n)
134
{
102
{
135
    char c;
103
    kbd_event_t ev;
-
 
104
    size_t offs, otmp;
136
    int chars;
105
    wchar_t dec;
137
 
106
 
138
    chars = 0;
107
    offs = 0;
139
    while (chars < n - 1) {
108
    while (true) {
140
        c = getchar();
109
        fflush(stdout);
141
        if (c < 0)
110
        if (kbd_get_event(&ev) < 0)
142
            return;
111
            return;
143
        if (c == '\n')
112
        if (ev.type == KE_RELEASE)
-
 
113
            continue;
-
 
114
 
-
 
115
        if (ev.key == KC_ENTER || ev.key == KC_NENTER)
144
            break;
116
            break;
-
 
117
        if (ev.key == KC_BACKSPACE) {
145
        if (c == '\b') {
118
            if (offs > 0) {
-
 
119
                /*
-
 
120
                 * Back up until we reach valid start of
-
 
121
                 * character.
-
 
122
                 */
146
            if (chars > 0) {
123
                while (offs > 0) {
-
 
124
                    --offs; otmp = offs;
-
 
125
                    dec = str_decode(buffer, &otmp, n);
-
 
126
                    if (dec != U_SPECIAL)
-
 
127
                        break;
-
 
128
                }
147
                putchar('\b');
129
                putchar('\b');
148
                --chars;
-
 
149
            }
130
            }
150
            continue;
131
            continue;
151
        }
132
        }
-
 
133
        if (ev.c >= ' ') {
152
        putchar(c);
134
            //putchar(ev.c);
-
 
135
            if (chr_encode(ev.c, buffer, &offs, n - 1) == EOK)
153
        buffer[chars++] = c;
136
                console_putchar(ev.c);
-
 
137
        }
154
    }
138
    }
155
    putchar('\n');
139
    putchar('\n');
156
    buffer[chars] = '\0';
140
    buffer[offs] = '\0';
157
}
141
}
158
 
142
 
159
/* TODO:
143
/* TODO:
160
 * Implement something like editline() / readline(), if even
144
 * Implement something like editline() / readline(), if even
161
 * just for command history and making arrows work. */
145
 * just for command history and making arrows work. */
162
void get_input(cliuser_t *usr)
146
void get_input(cliuser_t *usr)
163
{
147
{
164
    char line[INPUT_MAX];
148
    char line[INPUT_MAX];
165
    size_t len = 0;
-
 
166
 
149
 
-
 
150
    console_set_style(STYLE_EMPHASIS);
167
    printf("%s", usr->prompt);
151
    printf("%s", usr->prompt);
-
 
152
    console_set_style(STYLE_NORMAL);
-
 
153
 
168
    read_line(line, INPUT_MAX);
154
    read_line(line, INPUT_MAX);
169
    len = strlen(line);
-
 
170
    /* Make sure we don't have rubbish or a C/R happy user */
155
    /* Make sure we don't have rubbish or a C/R happy user */
171
    if (len == 0 || line[0] == '\n')
156
    if (str_cmp(line, "") == 0 || str_cmp(line, "\n") == 0)
172
        return;
157
        return;
173
    usr->line = cli_strdup(line);
158
    usr->line = str_dup(line);
174
 
159
 
175
    return;
160
    return;
176
}
161
}
177
 
162