This source file includes following definitions.
- getcmd
- read_conf
- docmd
- whatcmd
- readline
- nextword
- print_help
- Xhelp
- Xmachine
- Xecho
- Xstty
- Xtime
- Xls
- ls
- Xnop
- Xboot
- qualify
- Xreboot
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 #include <sys/param.h>
30 #include <sys/reboot.h>
31
32 #ifdef REGRESS
33 #include <sys/stat.h>
34 #include <errno.h>
35 #else
36 #include <libsa.h>
37 #include <lib/libkern/funcs.h>
38 #endif
39
40 #include "cmd.h"
41
42 #define CTRL(c) ((c)&0x1f)
43
44 static int Xboot(void);
45 static int Xecho(void);
46 static int Xhelp(void);
47 static int Xls(void);
48 static int Xnop(void);
49 static int Xreboot(void);
50 static int Xstty(void);
51 static int Xtime(void);
52 #ifdef MACHINE_CMD
53 static int Xmachine(void);
54 extern const struct cmd_table MACHINE_CMD[];
55 #endif
56 extern int Xset(void);
57 extern int Xenv(void);
58
59 #ifdef CHECK_SKIP_CONF
60 extern int CHECK_SKIP_CONF(void);
61 #endif
62
63 extern const struct cmd_table cmd_set[];
64 const struct cmd_table cmd_table[] = {
65 {"#", CMDT_CMD, Xnop},
66 {"boot", CMDT_CMD, Xboot},
67 {"echo", CMDT_CMD, Xecho},
68 {"env", CMDT_CMD, Xenv},
69 {"help", CMDT_CMD, Xhelp},
70 {"ls", CMDT_CMD, Xls},
71 #ifdef MACHINE_CMD
72 {"machine",CMDT_MDC, Xmachine},
73 #endif
74 {"reboot", CMDT_CMD, Xreboot},
75 {"set", CMDT_SET, Xset},
76 {"stty", CMDT_CMD, Xstty},
77 {"time", CMDT_CMD, Xtime},
78 {NULL, 0},
79 };
80
81 static void ls(char *, struct stat *);
82 static int readline(char *, size_t, int);
83 char *nextword(char *);
84 static char *whatcmd(const struct cmd_table **ct, char *);
85 static char *qualify(char *);
86
87 char cmd_buf[CMD_BUFF_SIZE];
88
89 int
90 getcmd(void)
91 {
92 cmd.cmd = NULL;
93
94 if (!readline(cmd_buf, sizeof(cmd_buf), cmd.timeout))
95 cmd.cmd = cmd_table;
96
97 return docmd();
98 }
99
100 int
101 read_conf(void)
102 {
103 #ifndef INSECURE
104 struct stat sb;
105 #endif
106 int fd, rc = 0;
107
108 #ifdef CHECK_SKIP_CONF
109 if (CHECK_SKIP_CONF()) {
110 printf("boot.conf processing skipped at operator request\n");
111 return -1;
112 }
113 #endif
114
115 if ((fd = open(qualify(cmd.conf), 0)) < 0) {
116 if (errno != ENOENT && errno != ENXIO) {
117 printf("open(%s): %s\n", cmd.path, strerror(errno));
118 return 0;
119 }
120 return -1;
121 }
122
123 #ifndef INSECURE
124 (void) fstat(fd, &sb);
125 if (sb.st_uid || (sb.st_mode & 2)) {
126 printf("non-secure %s, will not proceed\n", cmd.path);
127 close(fd);
128 return -1;
129 }
130 #endif
131
132 do {
133 char *p = cmd_buf;
134
135 cmd.cmd = NULL;
136
137 do {
138 rc = read(fd, p, 1);
139 } while (rc > 0 && *p++ != '\n' &&
140 (p-cmd_buf) < sizeof(cmd_buf));
141
142 if (rc < 0) {
143 printf("%s: %s\n", cmd.path, strerror(errno));
144 break;
145 }
146
147 if (rc == 0) {
148 if (p != cmd_buf) {
149 *p = '\0';
150 rc = docmd();
151 break;
152 }
153 } else {
154 p--;
155
156 if (*p != '\n') {
157 printf("%s: line too long\n", cmd.path);
158
159
160 rc = -1;
161 }
162
163 *p = '\0';
164 }
165
166 } while (rc > 0 && !(rc = docmd()));
167
168 close(fd);
169 return rc;
170 }
171
172 int
173 docmd(void)
174 {
175 char *p = NULL;
176 const struct cmd_table *ct = cmd_table, *cs;
177
178 cmd.argc = 1;
179 if (cmd.cmd == NULL) {
180
181
182 for (p = cmd_buf; *p == ' ' || *p == '\t'; p++)
183 ;
184 if (*p == '#' || *p == '\0') {
185 #ifdef DEBUG
186 printf("rem\n");
187 #endif
188 return 0;
189 }
190 ct = cmd_table;
191 cs = NULL;
192 cmd.argv[cmd.argc] = p;
193 p = whatcmd(&ct, p);
194 if (ct == NULL) {
195 cmd.argc++;
196 ct = cmd_table;
197 } else if (ct->cmd_type == CMDT_SET && p != NULL) {
198 cs = cmd_set;
199 #ifdef MACHINE_CMD
200 } else if (ct->cmd_type == CMDT_MDC && p != NULL) {
201 cs = MACHINE_CMD;
202 #endif
203 }
204
205 if (cs != NULL) {
206 p = whatcmd(&cs, p);
207 if (cs == NULL) {
208 printf("%s: syntax error\n", ct->cmd_name);
209 return 0;
210 }
211 ct = cs;
212 }
213 cmd.cmd = ct;
214 }
215
216 cmd.argv[0] = ct->cmd_name;
217 while (p && cmd.argc+1 < sizeof(cmd.argv) / sizeof(cmd.argv[0])) {
218 cmd.argv[cmd.argc++] = p;
219 p = nextword(p);
220 }
221 cmd.argv[cmd.argc] = NULL;
222
223 #ifdef REGRESS
224 printf("%s %s\n", cmd.argv[0],
225 (cmd.argv[1] == NULL) ? "(null)" : cmd.argv[1]);
226 #else
227 return (*cmd.cmd->cmd_exec)();
228 #endif
229 }
230
231 static char *
232 whatcmd(const struct cmd_table **ct, char *p)
233 {
234 char *q;
235 int l;
236
237 q = nextword(p);
238
239 for (l = 0; p[l]; l++)
240 ;
241
242 while ((*ct)->cmd_name != NULL && strncmp(p, (*ct)->cmd_name, l))
243 (*ct)++;
244
245 if ((*ct)->cmd_name == NULL)
246 *ct = NULL;
247
248 return q;
249 }
250
251 static int
252 readline(char *buf, size_t n, int to)
253 {
254 #ifdef DEBUG
255 extern int debug;
256 #endif
257 char *p = buf, ch;
258
259
260 if (to > 0) {
261 u_long i = 0;
262 time_t tt = getsecs() + to;
263 #ifdef DEBUG
264 if (debug > 2)
265 printf ("readline: timeout(%d) at %u\n", to, tt);
266 #endif
267
268
269 while (!cnischar())
270 if (!(i++ % 1000) && (getsecs() >= tt))
271 break;
272
273 if (!cnischar()) {
274 strlcpy(buf, "boot", 5);
275 putchar('\n');
276 return strlen(buf);
277 }
278 } else
279 while (!cnischar())
280 ;
281
282
283 cmd.timeout = 0;
284
285 while (1) {
286 switch ((ch = getchar())) {
287 case CTRL('u'):
288 while (p > buf) {
289 putchar('\177');
290 p--;
291 }
292 continue;
293 case '\n':
294 case '\r':
295 p[1] = *p = '\0';
296 break;
297 case '\b':
298 case '\177':
299 if (p > buf) {
300 putchar('\177');
301 p--;
302 }
303 continue;
304 default:
305 if (ch >= ' ' && ch < '\177') {
306 if (p - buf < n-1)
307 *p++ = ch;
308 else {
309 putchar('\007');
310 putchar('\177');
311 }
312 }
313 continue;
314 }
315 break;
316 }
317
318 return p - buf;
319 }
320
321
322
323
324
325
326 char *
327 nextword(char *p)
328 {
329
330 while (*p && *p != '\t' && *p != ' ')
331 p++;
332 if (*p) {
333 *p++ = '\0';
334 while (*p == '\t' || *p == ' ')
335 p++;
336 }
337 if (*p == '\0')
338 p = NULL;
339 return p;
340 }
341
342 static void
343 print_help(const struct cmd_table *ct)
344 {
345 for (; ct->cmd_name != NULL; ct++)
346 printf(" %s", ct->cmd_name);
347 putchar('\n');
348 }
349
350 static int
351 Xhelp(void)
352 {
353 printf("commands:");
354 print_help(cmd_table);
355 #ifdef MACHINE_CMD
356 return Xmachine();
357 #else
358 return 0;
359 #endif
360 }
361
362 #ifdef MACHINE_CMD
363 static int
364 Xmachine(void)
365 {
366 printf("machine:");
367 print_help(MACHINE_CMD);
368 return 0;
369 }
370 #endif
371
372 static int
373 Xecho(void)
374 {
375 int i;
376
377 for (i = 1; i < cmd.argc; i++)
378 printf("%s ", cmd.argv[i]);
379 putchar('\n');
380 return 0;
381 }
382
383 static int
384 Xstty(void)
385 {
386 int sp;
387 char *cp;
388 dev_t dev;
389
390 if (cmd.argc == 1)
391 printf("%s speed is %d\n", ttyname(0), cnspeed(0, -1));
392 else {
393 dev = ttydev(cmd.argv[1]);
394 if (dev == NODEV)
395 printf("%s not a console device\n", cmd.argv[1]);
396 else {
397 if (cmd.argc == 2)
398 printf("%s speed is %d\n", cmd.argv[1],
399 cnspeed(dev, -1));
400 else {
401 sp = 0;
402 for (cp = cmd.argv[2]; *cp && isdigit(*cp); cp++)
403 sp = sp * 10 + (*cp - '0');
404 cnspeed(dev, sp);
405 }
406 }
407 }
408
409 return 0;
410 }
411
412 static int
413 Xtime(void)
414 {
415 time_t tt = getsecs();
416
417 if (cmd.argc == 1)
418 printf(ctime(&tt));
419 else {
420 }
421
422 return 0;
423 }
424
425 static int
426 Xls(void)
427 {
428 struct stat sb;
429 char *p;
430 int fd;
431
432 if (stat(qualify((cmd.argv[1]? cmd.argv[1]: "/.")), &sb) < 0) {
433 printf("stat(%s): %s\n", cmd.path, strerror(errno));
434 return 0;
435 }
436
437 if ((sb.st_mode & S_IFMT) != S_IFDIR)
438 ls(cmd.path, &sb);
439 else {
440 if ((fd = opendir(cmd.path)) < 0) {
441 printf ("opendir(%s): %s\n", cmd.path,
442 strerror(errno));
443 return 0;
444 }
445
446
447 for (p = cmd.path; *p; p++)
448 ;
449 *p++ = '/';
450 *p = '\0';
451
452 while(readdir(fd, p) >= 0) {
453 if (stat(cmd.path, &sb) < 0)
454 printf("stat(%s): %s\n", cmd.path,
455 strerror(errno));
456 else
457 ls(p, &sb);
458 }
459 closedir (fd);
460 }
461 return 0;
462 }
463
464 #define lsrwx(mode,s) \
465 putchar ((mode) & S_IROTH? 'r' : '-'); \
466 putchar ((mode) & S_IWOTH? 'w' : '-'); \
467 putchar ((mode) & S_IXOTH? *(s): (s)[1]);
468
469 static void
470 ls(char *name, struct stat *sb)
471 {
472 putchar("-fc-d-b---l-s-w-"[(sb->st_mode & S_IFMT) >> 12]);
473 lsrwx(sb->st_mode >> 6, (sb->st_mode & S_ISUID? "sS" : "x-"));
474 lsrwx(sb->st_mode >> 3, (sb->st_mode & S_ISGID? "sS" : "x-"));
475 lsrwx(sb->st_mode , (sb->st_mode & S_ISTXT? "tT" : "x-"));
476
477 printf (" %u,%u\t%lu\t%s\n", sb->st_uid, sb->st_gid,
478 (u_long)sb->st_size, name);
479 }
480 #undef lsrwx
481
482 int doboot = 1;
483
484 static int
485 Xnop(void)
486 {
487 if (doboot) {
488 doboot = 0;
489 return (Xboot());
490 }
491
492 return 0;
493 }
494
495 static int
496 Xboot(void)
497 {
498 if (cmd.argc > 1 && cmd.argv[1][0] != '-') {
499 qualify((cmd.argv[1]? cmd.argv[1]: cmd.image));
500 if (bootparse(2))
501 return 0;
502 } else {
503 if (bootparse(1))
504 return 0;
505 snprintf(cmd.path, sizeof cmd.path, "%s:%s",
506 cmd.bootdev, cmd.image);
507 }
508
509 return 1;
510 }
511
512
513
514
515
516 static char *
517 qualify(char *name)
518 {
519 char *p;
520
521 for (p = name; *p; p++)
522 if (*p == ':')
523 break;
524 if (*p == ':')
525 strlcpy(cmd.path, name, sizeof(cmd.path));
526 else
527 snprintf(cmd.path, sizeof cmd.path, "%s:%s",
528 cmd.bootdev, name);
529 return cmd.path;
530 }
531
532 static int
533 Xreboot(void)
534 {
535 printf("Rebooting...\n");
536 exit();
537 return 0;
538 }
539