-
Notifications
You must be signed in to change notification settings - Fork 584
/
Copy pathnsh_session.c
252 lines (212 loc) · 6.75 KB
/
nsh_session.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
/****************************************************************************
* apps/nshlib/nsh_session.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <termios.h>
#ifdef CONFIG_NSH_CLE
# include "system/cle.h"
#else
# include "system/readline.h"
#endif
#include "nsh.h"
#include "nsh_console.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nsh_session
*
* Description:
* This is the common session login on any NSH session. This function
* returns when an error reading from the input stream occurs, presumably
* signaling the end of the session.
*
* This function:
* - Performs the login sequence if so configured
* - Executes the NSH login script
* - Presents a greeting
* - Then provides a prompt then gets and processes the command line.
* - This continues until an error occurs, then the session returns.
*
* Input Parameters:
* pstate - Abstracts the underlying session.
*
* Returned Values:
* EXIT_SUCCESS or EXIT_FAILURE is returned.
*
****************************************************************************/
int nsh_session(FAR struct console_stdio_s *pstate,
int login, int argc, FAR char *argv[])
{
FAR struct nsh_vtbl_s *vtbl;
int ret = EXIT_FAILURE;
DEBUGASSERT(pstate);
vtbl = &pstate->cn_vtbl;
#ifdef CONFIG_NSH_CONSOLE_LOGIN
if (login == NSH_LOGIN_LOCAL)
{
/* Login User and Password Check */
if (nsh_login(pstate) != OK)
{
nsh_exit(vtbl, 1);
return -1; /* nsh_exit does not return */
}
}
else
#endif /* CONFIG_NSH_CONSOLE_LOGIN */
#ifdef CONFIG_NSH_TELNET_LOGIN
if (login == NSH_LOGIN_TELNET)
{
/* Login User and Password Check */
if (nsh_telnetlogin(pstate) != OK)
{
nsh_exit(vtbl, 1);
return -1; /* nsh_exit does not return */
}
}
#endif /* CONFIG_NSH_TELNET_LOGIN */
if (login != NSH_LOGIN_NONE)
{
/* Present a greeting and possibly a Message of the Day (MOTD) */
write(OUTFD(pstate), g_nshgreeting, strlen(g_nshgreeting));
#ifdef CONFIG_NSH_MOTD
# ifdef CONFIG_NSH_PLATFORM_MOTD
/* Output the platform message of the day */
platform_motd(vtbl->iobuffer, IOBUFFERSIZE);
dprintf(OUTFD(pstate), "%s\n", vtbl->iobuffer);
# else
/* Output the fixed message of the day */
dprintf(OUTFD(pstate), "%s\n", g_nshmotd);
# endif
#endif
/* Execute the login script */
#ifdef CONFIG_NSH_ROMFSRC
nsh_loginscript(vtbl);
#endif
}
/* Process the command line option */
if (argc > 1)
{
if (strcmp(argv[1], "-h") == 0)
{
nsh_output(vtbl, "Usage: %s [<script-path>|-c <command>]\n",
argv[0]);
return EXIT_SUCCESS;
}
else if (strcmp(argv[1], "-c") == 0)
{
/* Process the inline command */
if (argc > 2)
{
return nsh_parse(vtbl, argv[2]);
}
else
{
nsh_error(vtbl, g_fmtargrequired, argv[0]);
return EXIT_FAILURE;
}
}
else if (argv[1][0] == '-')
{
/* Unknown option */
nsh_error(vtbl, g_fmtsyntax, argv[0]);
return EXIT_FAILURE;
}
else
{
#ifndef CONFIG_NSH_DISABLESCRIPT
/* Execute the shell script */
return nsh_script(vtbl, argv[0], argv[1], true);
#else
return EXIT_FAILURE;
#endif
}
}
#ifdef CONFIG_NSH_DISABLE_ECHOBACK
/* Disable echoback */
if (isatty(INFD(pstate)))
{
struct termios cfg;
if (tcgetattr(INFD(pstate), &cfg) == 0)
{
cfg.c_lflag &= ~ECHO;
tcsetattr(INFD(pstate), TCSANOW, &cfg);
}
}
#endif
/* Then enter the command line parsing loop */
for (; ; )
{
/* For the case of debugging the USB console...
* dump collected USB trace data
*/
#ifdef CONFIG_NSH_USBDEV_TRACE
nsh_usbtrace();
#endif
/* Get the next line of input. readline() returns EOF
* on end-of-file or any read failure.
*/
#ifdef CONFIG_NSH_CLE
/* cle() normally returns the number of characters read, but will
* return a negated errno value on end of file or if an error
* occurs. Either will cause the session to terminate.
*/
ret = cle_fd(pstate->cn_line, nsh_prompt(), LINE_MAX,
INFD(pstate), OUTFD(pstate));
if (ret < 0)
{
dprintf(ERRFD(pstate), g_fmtcmdfailed, "nsh_session",
"cle", NSH_ERRNO_OF(-ret));
continue;
}
#else
/* Display the prompt string */
write(OUTFD(pstate), nsh_prompt(), strlen(nsh_prompt()));
/* readline() normally returns the number of characters read, but
* will return EOF on end of file or if an error occurs. EOF
* will cause the session to terminate.
*/
ret = readline_fd(pstate->cn_line, LINE_MAX,
INFD(pstate), OUTFD(pstate));
if (ret == EOF)
{
/* NOTE: readline() does not set the errno variable, but
* perhaps we will be lucky and it will still be valid.
*/
dprintf(ERRFD(pstate), g_fmtcmdfailed, "nsh_session",
"readline", NSH_ERRNO);
ret = EXIT_SUCCESS;
break;
}
#endif
/* Parse process the command */
nsh_parse(vtbl, pstate->cn_line);
nsh_update_prompt();
}
return ret;
}