001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019 #include <crt.h>
020 #include <libc.h>
021 #include <stdarg.h>
022 #include <string.h>
023 #include <debug.h>
024 #include <drivers/devices.h>
025
026 #include "fstest_utils.h"
027
028
029
030
031
032
033
034 static int shell_uname (int argc, char *argv[])
035 {
036 printf ("SOS article 9\n");
037 return 0;
038 }
039
040 static void shell_ls_internal(int detailed, int recursive, int reclevel)
041 {
042 char tab[256], *c;
043 int i;
044 struct dirent * dirent;
045 DIR * here;
046
047 here = opendir(".");
048 if (! here)
049 return;
050
051
052 if (recursive)
053 {
054 for (c = tab, i = 0 ; (i < reclevel) && (i < sizeof(tab)/2) ; i++)
055 {
056 *c++ = ' ';
057 *c++ = ' ';
058 }
059 *c++ = '\0';
060 }
061 else
062 *tab = '\0';
063
064 while ((dirent = readdir(here)) != NULL)
065 {
066 char entrychar;
067 char * entrysuffix;
068
069 switch(dirent->type)
070 {
071 case S_IFREG: entrychar='-'; entrysuffix=""; break;
072 case S_IFDIR: entrychar='d'; entrysuffix="/"; break;
073 case S_IFLNK: entrychar='l'; entrysuffix="@"; break;
074 case S_IFCHR: entrychar='c'; entrysuffix=NULL; break;
075 default: entrychar='?'; entrysuffix="?!?"; break;
076 }
077
078 if (detailed)
079 {
080 struct stat stat;
081 char target_name[SOS_FS_DIRENT_NAME_MAXLEN];
082 char majorminor[24];
083
084 if (lstat(dirent->name, & stat))
085 continue;
086
087 *target_name = '\0';
088 if (stat.st_type == S_IFLNK)
089 {
090 int fd = open(dirent->name, O_RDONLY | O_NOFOLLOW);
091 if (fd >= 0)
092 {
093 int len = read(fd, target_name, sizeof(target_name) - 1);
094 if (len < 0)
095 *target_name='\0';
096 else
097 target_name[len] = '\0';
098 close(fd);
099 }
100 }
101 else if (stat.st_type == S_IFCHR)
102 {
103 snprintf(majorminor, sizeof(majorminor), " %d,%d",
104 stat.st_rdev_major, stat.st_rdev_minor);
105 entrysuffix = majorminor;
106 }
107
108 printf("%s%c%c%c%c %lld %s%s%s%s (location=0x%llx)\n",
109 tab, entrychar,
110 (stat.st_access_rights&S_IRUSR)?'r':'-',
111 (stat.st_access_rights&S_IWUSR)?'w':'-',
112 (stat.st_access_rights&S_IXUSR)?'x':'-',
113 stat.st_size,
114 dirent->name,
115 entrysuffix,
116 (stat.st_type==S_IFLNK)?" -> ":"",
117 target_name,
118 stat.st_storage_location);
119 }
120 else
121 printf("%s%s%s\n",
122 tab, dirent->name, entrysuffix);
123
124
125 if (recursive)
126 {
127 int fd_here = dirfd(here);
128 if (chdir(dirent->name))
129 continue;
130 shell_ls_internal(detailed, recursive, reclevel+1);
131 if(fchdir(fd_here))
132 {
133 closedir(here);
134 return;
135 }
136 }
137 }
138 closedir(here);
139 }
140
141 static void shell_ls(const char * path, int detailed, int recursive)
142 {
143 int fd_here = open(".", O_RDONLY | O_DIRECTORY);
144 if (fd_here < 0)
145 return;
146
147 if (chdir(path))
148 {
149 close(fd_here);
150 return;
151 }
152
153 shell_ls_internal(detailed, recursive, 1);
154
155 fchdir(fd_here);
156 close(fd_here);
157 }
158
159 static int shell_touch (int argc, char *argv[])
160 {
161 return creat (argv[1], S_IRUSR | S_IWUSR);
162 }
163
164 static int shell_mkdir (int argc, char *argv[])
165 {
166 return mkdir (argv[1], S_IRUSR | S_IWUSR | S_IXUSR);
167 }
168
169 static int shell_cat (int argc, char *argv[])
170 {
171 int fd;
172 char buf[4096];
173 int len;
174
175 fd = open (argv[1], O_RDONLY);
176 if (fd < 0) {
177 printf ("Cannot open '%s'\n", argv[1]);
178 return -1;
179 }
180
181 while (1)
182 {
183 len = read (fd, buf, sizeof(buf)-1);
184 if (len <= 0)
185 break;
186 buf[len] = '\0';
187
188 printf ("%s", buf);
189 }
190
191 close (fd);
192 return 0;
193 }
194
195 static int shell_edit (int argc, char *argv[])
196 {
197 int fd;
198 char buf[16];
199 int len;
200
201 fd = open (argv[1], O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
202 if (fd < 0) {
203 printf ("Cannot create '%s': %d\n", argv[1], fd);
204 return -1;
205 }
206
207
208 ioctl (0, SOS_IOCTL_TTY_SETPARAM, SOS_IOCTLPARAM_TTY_ECHO);
209 ioctl (0, SOS_IOCTL_TTY_SETPARAM, SOS_IOCTLPARAM_TTY_CANON);
210
211 while (1)
212 {
213 len = read (0, buf, sizeof(buf));
214 if (len <= 1)
215 break;
216
217 bochs_printf ("Writing %d bytes\n", len);
218 len = write (fd, buf, len);
219 if (len <= 0) {
220 printf ("Cannot write to '%s': %d\n", argv[1], len);
221 break;
222 }
223 }
224
225
226 ioctl (0, SOS_IOCTL_TTY_RESETPARAM, SOS_IOCTLPARAM_TTY_ECHO);
227 ioctl (0, SOS_IOCTL_TTY_RESETPARAM, SOS_IOCTLPARAM_TTY_CANON);
228
229 close (fd);
230 return 0;
231 }
232
233 static int shell_hexdump (int argc, char *argv[])
234 {
235 int fd;
236 char buf[16];
237 int count = 0;
238 int len;
239
240 fd = open (argv[1], O_RDONLY);
241 if (fd < 0) {
242 printf ("Cannot open '%s': %d\n", argv[1], fd);
243 return -1;
244 }
245
246 while (1)
247 {
248 int i;
249
250 len = read (fd, buf, sizeof(buf));
251 if (len <= 0)
252 break;
253
254 if (count < 0x10)
255 printf ("00%x ", count);
256 else if (count < 0x100)
257 printf ("0%x ", count);
258 else if (count < 0x1000)
259 printf ("%x ", count);
260
261 for (i = 0; i < len; i++)
262 {
263 if (buf[i] < 0x10)
264 printf ("0%x ", buf[i]);
265 else
266 printf ("%x ", buf[i]);
267 }
268
269 printf ("\n");
270
271 count += len;
272 }
273
274 close (fd);
275 return 0;
276 }
277
278 static int shell_test (int argc, char *argv[])
279 {
280 int i;
281 for (i = 0; i < argc; i++)
282 {
283 printf ("argv[%d] = %s\n", i, argv[i]);
284 }
285 return 0;
286 }
287
288
289 static int shell_devtest (int argc, char *argv[])
290 {
291 bochs_printf("WARNING: This test will eventually write 0 on kernel code !\n");
292 bochs_printf("This WILL crash the kernel (as expected...) !\n");
293 printf("WARNING: This test will eventually write 0 on kernel code !\n");
294 printf("This WILL crash the kernel (as expected...) !\n");
295 if (fork() == 0)
296 exec("devtest");
297 return 0;
298 }
299
300
301 static int shell_fstest (int argc, char *argv[])
302 {
303 if (fork() == 0)
304 exec("fstest");
305 return 0;
306 }
307
308 void command_exec (char * cmd)
309 {
310 char *c;
311 int argc = 1, i;
312 char **argv;
313
314 for (c = cmd; *c != '\0'; c++)
315 if (*c == ' ')
316 argc++;
317
318 argv = malloc (argc * sizeof(char*));
319 if (argv == NULL)
320 return;
321
322 for (i = 0, c = cmd; i < argc; i++)
323 {
324 argv[i] = c;
325 while (*c != ' ' && *c != '\0')
326 c++;
327 *c = '\0';
328 c++;
329 }
330
331 if (! strcmp (argv[0], "uname"))
332 shell_uname(argc, argv);
333
334 else if (! strcmp (argv[0], "ls"))
335 {
336 if (argv[1])
337 shell_ls (argv[1], 1, 0);
338 else
339 shell_ls (".", 1, 0);
340 }
341
342 else if (! strcmp (argv[0], "touch"))
343 {
344 shell_touch (argc, argv);
345 }
346
347 else if (! strcmp (argv[0], "mkdir"))
348 {
349 shell_mkdir (argc, argv);
350 }
351
352 else if (! strcmp (argv[0], "cat"))
353 {
354 shell_cat (argc, argv);
355 }
356
357 else if (! strcmp (argv[0], "edit"))
358 {
359 shell_edit (argc, argv);
360 }
361
362 else if (! strcmp (argv[0], "hexdump"))
363 {
364 shell_hexdump (argc, argv);
365 }
366 else if (! strcmp (argv[0], "test"))
367 {
368 shell_test (argc, argv);
369 }
370 else if (! strcmp (argv[0], "devtest"))
371 {
372 shell_devtest (argc, argv);
373 }
374 else if (! strcmp (argv[0], "fstest"))
375 {
376 shell_fstest (argc, argv);
377 }
378
379
380 else
381 printf ("Command not found\n");
382
383 free (argv);
384 }
385
386 int main()
387 {
388 char buffer[256];
389 int i;
390 char chr;
391
392 ioctl (0, SOS_IOCTL_TTY_RESETPARAM, SOS_IOCTLPARAM_TTY_CANON);
393
394 while (1)
395 {
396 memset (buffer, 0, sizeof(buffer));
397 i = 0;
398 printf ("$ ");
399
400 while (1)
401 {
402 read (0, & chr, 1);
403 if (chr == '\n')
404 {
405 buffer[i] = '\0';
406 printf ("\n");
407 if (i != 0)
408 command_exec (buffer);
409 break;
410 }
411 else if (chr == '\b')
412 {
413 if (i > 0)
414 {
415 i--;
416 printf ("\b");
417 }
418 }
419
420 else if (i < 256)
421 {
422 buffer[i++] = chr;
423 printf ("%c", chr);
424 }
425 else
426 printf ("%c", chr);
427 }
428 }
429
430 return 0;
431 }