Annotation of prex-old/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 512
45:
46: #ifdef CMDBOX
47: extern const struct cmd_entry builtin_cmds[];
48: extern int exec_builtin(cmd_func_t, int argc, char *argv[]);
49: #define main(argc, argv) sh_main(argc, argv)
50: #endif
51:
52: extern int exec_cmd(int argc, char *argv[]);
53: extern const struct cmd_entry internal_cmds[];
54:
55: static char *argv[20];
56:
57: /*
58: * Read command string.
59: */
60: static char *
61: read_line(char *line, int len)
62: {
63: int c, index = 0;
64:
65: for (;;) {
66: c = getchar();
67: switch (c) {
68: case '\n':
69: case EOF:
70: line[index] = 0;
71: return &line[index];
72:
73: default:
74: if (index > len) {
75: fprintf(stderr, "Command line overflow\n");
76: return (char *)-1;
77: }
78: if (c < 0x80) {
79: line[index] = (char)c;
80: index++;
81: }
82: break;
83: }
84: }
85: }
86:
87: /*
88: * Find command from the specifid table.
89: *
90: * Returns 0 if command is processed.
91: * Returns -1 if no command is found.
92: */
93: static cmd_func_t
94: find_cmd(const struct cmd_entry cmds[], char *cmd)
95: {
96: int i = 0;
97:
98: while (cmds[i].cmd != NULL) {
99: if (!strcmp(cmd, cmds[i].cmd))
100: return cmds[i].func;
101: i++;
102: }
103: return NULL;
104: }
105:
106: /*
107: * Parse an entire given line.
108: * Break it down into commands.
109: */
110: static void
111: parse_line(char *line)
112: {
113: char *p = line;
114: int argc = 0;
115: cmd_func_t cmd;
116:
117: /*
118: * Build argument list
119: */
120: for (;;) {
121: /* Skip space */
122: while (*p && isspace((int)*p))
123: p++;
124: if (*p == 0)
125: break;
126: argv[argc++] = p;
127:
128: /* Skip word */
129: while (*p && !isspace((int)*p))
130: p++;
131: if (*p == 0)
132: break;
133: *p++ = 0;
134: }
135: argv[argc] = NULL;
136:
137: /*
138: * Dispatch command
139: */
140: if (argc) {
141: optind = 1;
142:
143: /* Run it as internal command */
144: cmd = find_cmd(internal_cmds, argv[0]);
145: if (cmd != NULL) {
146: if ((cmd)(argc, argv) != 0) {
147: fprintf(stderr, "%s: %s\n", argv[0],
148: strerror(errno));
149: }
150: return;
151: }
152: #ifdef CMDBOX
153: /* Run it as shell built-in command */
154: cmd = find_cmd(builtin_cmds, argv[0]);
155: if (cmd != NULL) {
156: exec_builtin(cmd, argc, argv);
157: return;
158: }
159: #endif
160: /* Next, run it as external command */
161: exec_cmd(argc, argv);
162: }
163: }
164:
165: int
166: main(int dummy, char *argv[])
167: {
168: static char line[LINELEN];
169: static char cwd[PATH_MAX];
170: char *p;
171:
172: signal(SIGINT, SIG_IGN);
173: signal(SIGQUIT, SIG_IGN);
174: signal(SIGTERM, SIG_IGN);
175:
176: /*
177: * Command loop
178: */
179: for (;;) {
180: next:
181: /* Display prompt */
182: getcwd(cwd, PATH_MAX);
183: printf("\033[32m");
184: printf("[prex:%s]", cwd);
185: printf("\033[0m# ");
186:
187: /* Read and parse user input */
188: p = read_line(line, LINELEN);
189: if (p == NULL)
190: break;
191: if (p == (char *)-1)
192: continue;
193: while (*(p - 1) == '\\' && (p - 2) >= line
194: && *(p - 2) != '\\') {
195: *(p - 1) = ' ';
196: p = read_line(p, LINELEN - (p - line));
197: if (p == NULL)
198: break;
199: if (p == (char *)-1)
200: goto next;
201: }
202: parse_line(line);
203: }
204: return 0;
205: }
CVSweb