2 * Simple ("tiny") shell to test filename and directory functions.
3 * Copyright (c) 2013, Christian Groessler, chris@groessler.org
6 #define VERSION_ASC "0.90"
11 #define UPPERCASE /* define (e.g. for Atari) to convert filenames etc. to upper case */
21 #include <sys/param.h>
25 #include <sys/types.h>
42 static unsigned char terminate;
43 static unsigned char cmd;
44 static unsigned char *cmd_asc, *arg1, *arg2, *arg3;
45 static unsigned char keyb_buf[KEYB_BUFSZ];
46 static size_t cpbuf_sz = 4096;
59 { "mkdir", CMD_MKDIR },
61 { "rmdir", CMD_RMDIR },
63 { "chdir", CMD_CHDIR },
69 { "ren", CMD_RENAME },
74 static void banner(void)
76 puts("\"tiny\" command line shell, v" VERSION_ASC);
77 puts("written by chris@groessler.org");
78 puts("type 'help' for help\n");
81 static void get_command(void)
85 arg1 = arg2 = arg3 = NULL;
90 /* get input from the user */
91 if (! fgets(keyb_buf, KEYB_BUFSZ, stdin)) {
97 /* split input into cmd, arg1, arg2, arg3 */
99 /* get and parse command */
100 cmd_asc = strtok(keyb_buf, " \t\n");
106 while (cmd_table[i].name) {
107 if (! strcmp(cmd_table[i].name, cmd_asc)) {
108 cmd = cmd_table[i].code;
115 arg1 = strtok(NULL, " \t\n");
118 arg2 = strtok(NULL, " \t\n");
121 arg3 = strtok(NULL, " \t\n");
124 static void cmd_help(void)
126 puts("quit, exit - exit shell");
127 puts("ls, dir - display current directory");
128 puts(" and drive contents");
129 puts("rm, del - delete file");
130 puts("cp, copy - copy file");
131 puts("mv, ren - rename file");
132 puts("cd, chdir - change directory or drive");
133 puts("md, mkdir - make directory or drive");
134 puts("rd, rmdir - remove directory or drive");
135 puts("sorry, you cannot start programs here");
138 static void cmd_ls(void)
142 struct dirent *dirent;
148 puts("usage: ls [dir]");
152 /* print directory listing */
158 /* not sure if this shouldn't be done by the runtime lib */
159 if (*(arg1 + strlen(arg1) - 1) == ':' || *(arg1 + strlen(arg1) - 1) == '>') {
160 arg = malloc(strlen(arg1) + 4);
162 printf("malloc failed: %s", strerror(errno));
166 memcpy(arg, arg1, strlen(arg1) + 1);
178 if (need_free) free(arg);
181 puts("opendir failed");
185 while (dirent = readdir(dir))
186 puts(dirent->d_name);
191 static void cmd_rm(void)
194 puts("usage: rm <file>");
203 printf("remove failed: %s\n", strerror(errno));
206 static void cmd_mkdir(void)
209 puts("usage: mkdir <dir>");
217 if (mkdir(arg1, 0777))
218 printf("mkdir failed: %s\n", strerror(errno));
221 static void cmd_rmdir(void)
224 puts("usage: rmdir <dir>");
233 printf("rmdir failed: %s\n", strerror(errno));
236 static void cmd_chdir(void)
239 puts("usage: cddir <dir>");
248 printf("chdir failed: %s\n", strerror(errno));
251 static void cmd_pwd(void)
260 buf = malloc(MAXPATHLEN);
262 printf("malloc %u bytes failed: %s\n", MAXPATHLEN, strerror(errno));
265 if (!getcwd(buf, MAXPATHLEN)) {
266 printf("getcwd failed: %s\n", strerror(errno));
275 static void cmd_rename(void)
278 puts("usage: mv <oldname> <newname>");
287 if (rename(arg1, arg2))
288 printf("rename failed: %s\n", strerror(errno));
291 static void cmd_copy(void)
293 int srcfd = -1, dstfd = -1;
298 puts("usage: cp <src> <dest>");
307 buf = malloc(cpbuf_sz);
309 printf("malloc %u bytes failed: %s\n", cpbuf_sz, strerror(errno));
315 srcfd = open(arg1, O_RDONLY);
317 printf("open(%s) failed: %s\n", arg1, strerror(errno));
322 readsz = read(srcfd, buf, cpbuf_sz);
324 printf("read error: %s\n", strerror(errno));
331 dstfd = open(arg2, O_WRONLY | O_CREAT | O_TRUNC, 0777);
333 printf("open(%s) failed: %s\n", arg2, strerror(errno));
338 writesz = write(dstfd, buf, readsz);
339 if (writesz < 0 || writesz != readsz) {
340 printf("write error: %s\n", strerror(errno));
343 if (readsz != cpbuf_sz)
348 if (srcfd >= 0) close(srcfd);
349 if (dstfd >= 0) close(dstfd);
352 static void run_command(void)
355 default: puts("internal error"); return;
356 case CMD_NOTHING: return;
357 case CMD_INVALID: puts("invalid command"); return;
358 case CMD_HELP: cmd_help(); return;
359 case CMD_QUIT: terminate = 1; return;
360 case CMD_LS: cmd_ls(); return;
361 case CMD_RM: cmd_rm(); return;
362 case CMD_CHDIR: cmd_chdir(); return;
363 case CMD_MKDIR: cmd_mkdir(); return;
364 case CMD_RMDIR: cmd_rmdir(); return;
365 case CMD_PWD: cmd_pwd(); return;
366 case CMD_RENAME: cmd_rename(); return;
367 case CMD_COPY: cmd_copy(); return;
375 while (! terminate) {
382 /* Local Variables: */
383 /* c-file-style: "cpg" */
384 /* c-basic-offset: 4 */