Kernel/debug - Clean up Debug() method, bind to #define config
[tpg/acess2.git] / KernelLand / Kernel / emergency_console.c
1 /*
2  * Acess 2 Kernel
3  * - By John Hodge (thePowersGang)
4  * 
5  * emergency_console.c
6  * - Kernel-land emergency console/shell
7  */
8 #include <acess.h>
9 #include <stdarg.h>
10
11 #define STDIN   0
12 #define STDOUT  1
13 #define STDERR  2
14
15 // === PROTOTYPES ===
16 void EmergencyConsole(void);
17 // -- Commands
18 void Command_ls(const char* path);
19 void Command_hd(const char* path);
20 void Command_mount(const char *fs, const char *dev, const char *point);
21 // --
22 static char **split_args(char *line);
23 static char *read_line(int fd);
24 static int dprintf(int fd, const char *fmt, ...);// __attribute__((printf(2,3)));
25
26 // === CODE ===
27 void EmergencyConsole(void)
28 {
29         for(;;)
30         {
31                 dprintf(STDOUT, "(kernel)$ ");
32                 char *line = read_line(STDIN);
33                 
34                 // Explode line into args
35                 char **args = split_args(line);
36                 // Get command from first arg
37                 ASSERT(args);
38                 ASSERT(args[0]);
39                 if( strcmp(args[0], "help") == 0 ) {
40                         dprintf(STDOUT,
41                                 "Commands:\n"
42                                 "ls <path> - List the contents of a directory\n"
43                                 "hd <path> - Dump a file in a 16 bytes/line hex format\n"
44                                 "mount <fs> <device> <point> - Mount a filesystem\n"
45                                 );
46                 }
47                 else if( strcmp(args[0], "ls") == 0 ) {
48                         Command_ls(args[1]); 
49                 }
50                 else if( strcmp(args[0], "hd") == 0 ) {
51                         Command_hd(args[1]);
52                 }
53                 else if( strcmp(args[0], "mount") == 0 ) {
54                         Command_mount(args[1], args[2], args[3]);
55                 }
56                 else
57                 {
58                         dprintf(STDERR, "Unknown command '%s'\n", args[0]);
59                 }
60                 // Free args
61                 free(args);
62                 free(line);
63         }
64 }
65
66 void Command_ls(const char* path)
67 {
68         dprintf(STDERR, "ls: TODO - Implement\n");
69 }
70 void Command_hd(const char* path)
71 {
72         dprintf(STDERR, "hd: TODO - Implement\n");
73 }
74 void Command_mount(const char *fs, const char *dev, const char *point)
75 {
76         dprintf(STDERR, "mount: TODO - Implement\n");
77 }
78
79 // Allocates return array (NUL terminated), but mangles input string
80 static int split_args_imp(char *line, char **buf)
81 {
82          int    argc = 0;
83          int    pos = 0;
84         enum {
85                 MODE_SPACE,
86                 MODE_NORM,
87                 MODE_SQUOTE,
88                 MODE_DQUOTE,
89         } mode = MODE_SPACE;
90         for( char *chp = line; *chp; chp ++ )
91         {
92                 if( *chp == ' ' ) {
93                         if( mode != MODE_SPACE ) {
94                                 if(buf) buf[argc][pos] = '\0';
95                                 argc ++;
96                         }
97                         mode = MODE_SPACE;
98                         continue ;
99                 }
100                 
101                 switch( mode )
102                 {
103                 case MODE_SPACE:
104                         if( buf )
105                                 buf[argc] = chp;
106                         pos = 0;
107                 case MODE_NORM:
108                         switch( *chp )
109                         {
110                         case '"':
111                                 mode = MODE_DQUOTE;
112                                 break;
113                         case '\'':
114                                 mode = MODE_SQUOTE;
115                                 break;
116                         case '\\':
117                                 chp ++;
118                                 switch( *chp )
119                                 {
120                                 case '\0':
121                                         dprintf(STDERR, "err: Trailing '\\'\n");
122                                         break;
123                                 case '\\':
124                                 case '\'':
125                                 case '"':
126                                         if(buf) buf[argc][pos++] = *chp;
127                                         break;
128                                 default:
129                                         dprintf(STDERR, "err: Unkown escape '%c'\n", *chp);
130                                         break;
131                                 }
132                                 break;
133                         default:
134                                 if(buf) buf[argc][pos++] = *chp;
135                                 break;
136                         }
137                         break;
138                 case MODE_SQUOTE:
139                         switch( *chp )
140                         {
141                         case '\'':
142                                 mode = MODE_NORM;
143                                 break;
144                         case '\0':
145                                 dprintf(STDERR, "err: Unterminated \' string\n");
146                                 break;
147                         default:
148                                 if(buf) buf[argc][pos++] = *chp;
149                                 break;
150                         }
151                         break;
152                 case MODE_DQUOTE:
153                         switch( *chp )
154                         {
155                         case '\"':
156                                 mode = MODE_NORM;
157                                 break;
158                         case '\\':
159                                 chp ++;
160                                 switch(*chp)
161                                 {
162                                 case '\0':
163                                         dprintf(STDERR, "err: Trailing '\\' in \" string\n");
164                                         break;
165                                 case '\\':
166                                 case '"':
167                                         if(buf) buf[argc][pos++] = *chp;
168                                         break;
169                                 default:
170                                         dprintf(STDERR, "err: Unkown escape '%c'\n", *chp);
171                                         break;
172                                 }
173                                 break;
174                         case '\0':
175                                 dprintf(STDERR, "err: Unterminated \" string\n");
176                                 break;
177                         default:
178                                 if(buf) buf[argc][pos++] = *chp;
179                                 break;
180                         }
181                         break;
182                 }
183         }
184
185         if(buf) buf[argc][pos++] = '\0';
186         argc ++;
187         return argc;
188 }
189 static char **split_args(char *line)
190 {
191         // 1. Count
192         int count = split_args_imp(line, NULL);
193         char **ret = malloc( (count + 1) * sizeof(char*) );
194         
195         split_args_imp(line, ret);
196         ret[count] = NULL;
197         return ret;
198 }
199
200 static char *read_line(int fd)
201 {
202         // Read line (or up to ~128 bytes)
203         // - This assumes a default PTY state (i.e. line buffered, echo on)
204         char *ret = malloc(128);
205         size_t len = VFS_Read(STDIN, 128, ret);
206         ret[len] = 0;
207         return ret;
208 }
209
210 static int dprintf(int fd, const char *fmt, ...)
211 {
212         va_list args;
213         va_start(args, fmt);
214         size_t len = vsnprintf(NULL, 0, fmt, args);
215         va_end(args);
216         
217         char buf[len+1];
218         va_start(args, fmt);
219         vsnprintf(buf, len+1, fmt, args);
220         va_end(args);
221         
222         VFS_Write(fd, len, buf);
223         
224         return len;
225 }
226

UCC git Repository :: git.ucc.asn.au