Annotation of prex-old/usr/bin/sh/sh.c, Revision 1.1.1.1.2.1
1.1 nbrk 1: /*
2: * Copyright (c) 2005-2007, Kohsuke Ohtani
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. Neither the name of the author nor the names of any co-contributors
14: * may be used to endorse or promote products derived from this software
15: * without specific prior written permission.
16: *
17: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27: * SUCH DAMAGE.
28: */
29:
30: #include <prex/prex.h>
31: #include <prex/keycode.h>
32: #include <sys/syslog.h>
33:
34: #include <limits.h>
35: #include <termios.h>
36: #include <ctype.h>
37: #include <unistd.h>
38: #include <string.h>
39: #include <stdio.h>
40: #include <errno.h>
41:
42: #include "sh.h"
43:
1.1.1.1.2.1! nbrk 44: #define LINELEN 256
! 45: #define ARGMAX 32
1.1 nbrk 46:
47: #ifdef CMDBOX
48: extern const struct cmd_entry builtin_cmds[];
49: extern int exec_builtin(cmd_func_t, int argc, char *argv[]);
50: #define main(argc, argv) sh_main(argc, argv)
51: #endif
52:
53: extern int exec_cmd(int argc, char *argv[]);
54: extern const struct cmd_entry internal_cmds[];
55:
1.1.1.1.2.1! nbrk 56: static char *args[ARGMAX];
1.1 nbrk 57:
58: /*
59: * Find command from the specifid table.
60: *
61: * Returns 0 if command is processed.
62: * Returns -1 if no command is found.
63: */
64: static cmd_func_t
65: find_cmd(const struct cmd_entry cmds[], char *cmd)
66: {
67: int i = 0;
68:
69: while (cmds[i].cmd != NULL) {
70: if (!strcmp(cmd, cmds[i].cmd))
71: return cmds[i].func;
72: i++;
73: }
74: return NULL;
75: }
76:
77: /*
78: * Parse an entire given line.
79: * Break it down into commands.
80: */
81: static void
82: parse_line(char *line)
83: {
84: char *p = line;
1.1.1.1.2.1! nbrk 85: int i, argc;
1.1 nbrk 86: cmd_func_t cmd;
87:
88: /*
89: * Build argument list
90: */
1.1.1.1.2.1! nbrk 91: i = 0;
! 92: do {
! 93: /* Ignore whitespace at beginning */
1.1 nbrk 94: while (*p && isspace((int)*p))
95: p++;
1.1.1.1.2.1! nbrk 96: if (*p == '\0')
1.1 nbrk 97: break;
1.1.1.1.2.1! nbrk 98: args[i] = p;
! 99: i++;
1.1 nbrk 100:
101: /* Skip word */
102: while (*p && !isspace((int)*p))
103: p++;
1.1.1.1.2.1! nbrk 104: if (*p == '\0')
1.1 nbrk 105: break;
1.1.1.1.2.1! nbrk 106: *p++ = '\0';
! 107: } while (i < ARGMAX - 1);
! 108:
! 109: if (i == ARGMAX) {
! 110: fprintf(stderr, "Too many args\n");
! 111: return;
1.1 nbrk 112: }
1.1.1.1.2.1! nbrk 113: args[i] = NULL;
! 114: argc = i;
1.1 nbrk 115:
116: /*
117: * Dispatch command
118: */
1.1.1.1.2.1! nbrk 119: if (argc > 0) {
1.1 nbrk 120: optind = 1;
121:
122: /* Run it as internal command */
1.1.1.1.2.1! nbrk 123: cmd = find_cmd(internal_cmds, args[0]);
1.1 nbrk 124: if (cmd != NULL) {
1.1.1.1.2.1! nbrk 125: if ((*cmd)(argc, args) != 0) {
! 126: fprintf(stderr, "%s: %s\n", args[0],
1.1 nbrk 127: strerror(errno));
128: }
129: return;
130: }
131: #ifdef CMDBOX
132: /* Run it as shell built-in command */
1.1.1.1.2.1! nbrk 133: cmd = find_cmd(builtin_cmds, args[0]);
1.1 nbrk 134: if (cmd != NULL) {
1.1.1.1.2.1! nbrk 135: exec_builtin(cmd, argc, args);
1.1 nbrk 136: return;
137: }
138: #endif
139: /* Next, run it as external command */
1.1.1.1.2.1! nbrk 140: exec_cmd(argc, args);
! 141: }
! 142: }
! 143:
! 144: /*
! 145: * Read command string.
! 146: */
! 147: static char *
! 148: read_line(char *line, int len, int fd)
! 149: {
! 150: char *p, *end;
! 151: int c;
! 152:
! 153: end = line + len;
! 154: for (p = line; p < end; p++) {
! 155: c = getchar();
! 156: if (c == EOF) {
! 157: if (p == line)
! 158: return NULL;
! 159: *p = '\0';
! 160: return p;
! 161: }
! 162: if (c == '\n') {
! 163: *p = '\0';
! 164: return p;
! 165: }
! 166: *p = (char)c;
1.1 nbrk 167: }
1.1.1.1.2.1! nbrk 168: fprintf(stderr, "Command line overflow\n");
! 169: return (char *)-1;
1.1 nbrk 170: }
171:
172: int
1.1.1.1.2.1! nbrk 173: main(int argc, char **argv)
1.1 nbrk 174: {
175: static char line[LINELEN];
176: static char cwd[PATH_MAX];
177: char *p;
178:
179: signal(SIGINT, SIG_IGN);
180: signal(SIGQUIT, SIG_IGN);
181: signal(SIGTERM, SIG_IGN);
1.1.1.1.2.1! nbrk 182: signal(SIGTSTP, SIG_IGN); /* temporary... */
1.1 nbrk 183:
184: /*
185: * Command loop
186: */
187: for (;;) {
188: next:
189: /* Display prompt */
190: getcwd(cwd, PATH_MAX);
191: printf("\033[32m");
192: printf("[prex:%s]", cwd);
193: printf("\033[0m# ");
194:
195: /* Read and parse user input */
1.1.1.1.2.1! nbrk 196: p = read_line(line, LINELEN, 0);
1.1 nbrk 197: if (p == NULL)
198: break;
199: if (p == (char *)-1)
200: continue;
201: while (*(p - 1) == '\\' && (p - 2) >= line
202: && *(p - 2) != '\\') {
203: *(p - 1) = ' ';
1.1.1.1.2.1! nbrk 204: p = read_line(p, LINELEN - (p - line), 0);
1.1 nbrk 205: if (p == NULL)
206: break;
207: if (p == (char *)-1)
208: goto next;
209: }
210: parse_line(line);
211: }
1.1.1.1.2.1! nbrk 212: printf("bye!\n");
! 213: exit(0);
1.1 nbrk 214: return 0;
215: }
CVSweb