Annotation of prex/usr/bin/sh/sh.c, Revision 1.1.1.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:
44: #define LINELEN 256
45: #define ARGMAX 32
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:
56: static char *args[ARGMAX];
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;
85: int i, argc;
86: cmd_func_t cmd;
87:
88: /*
89: * Build argument list
90: */
91: i = 0;
92: do {
93: /* Ignore whitespace at beginning */
94: while (*p && isspace((int)*p))
95: p++;
96: if (*p == '\0')
97: break;
98: args[i] = p;
99: i++;
100:
101: /* Skip word */
102: while (*p && !isspace((int)*p))
103: p++;
104: if (*p == '\0')
105: break;
106: *p++ = '\0';
107: } while (i < ARGMAX - 1);
108:
109: if (i == ARGMAX) {
110: fprintf(stderr, "Too many args\n");
111: return;
112: }
113: args[i] = NULL;
114: argc = i;
115:
116: /*
117: * Dispatch command
118: */
119: if (argc > 0) {
120: optind = 1;
121:
122: /* Run it as internal command */
123: cmd = find_cmd(internal_cmds, args[0]);
124: if (cmd != NULL) {
125: if ((*cmd)(argc, args) != 0) {
126: fprintf(stderr, "%s: %s\n", args[0],
127: strerror(errno));
128: }
129: return;
130: }
131: #ifdef CMDBOX
132: /* Run it as shell built-in command */
133: cmd = find_cmd(builtin_cmds, args[0]);
134: if (cmd != NULL) {
135: exec_builtin(cmd, argc, args);
136: return;
137: }
138: #endif
139: /* Next, run it as external command */
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;
167: }
168: fprintf(stderr, "Command line overflow\n");
169: return (char *)-1;
170: }
171:
172: int
173: main(int argc, char **argv)
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);
182: signal(SIGTSTP, SIG_IGN); /* temporary... */
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 */
196: p = read_line(line, LINELEN, 0);
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) = ' ';
204: p = read_line(p, LINELEN - (p - line), 0);
205: if (p == NULL)
206: break;
207: if (p == (char *)-1)
208: goto next;
209: }
210: parse_line(line);
211: }
212: printf("bye!\n");
213: exit(0);
214: return 0;
215: }
CVSweb