📄 fsh.c
字号:
/* This file contains a simple file system "shell" that lets you manipulate a file system. There is a simple command table that contains the available functions. It is very easy to extend. THIS CODE COPYRIGHT DOMINIC GIAMPAOLO. NO WARRANTY IS EXPRESSED OR IMPLIED. YOU MAY USE THIS CODE AND FREELY DISTRIBUTE IT FOR NON-COMMERCIAL USE AS LONG AS THIS NOTICE REMAINS ATTACHED. FOR COMMERCIAL USE, CONTACT DOMINIC GIAMPAOLO (dbg@be.com). Dominic Giampaolo dbg@be.com*/#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <string.h>#include <sys/time.h>#include "myfs.h"#include "kprotos.h"#include "argv.h"static void do_fsh(void);intmain(int argc, char **argv){ int seed; char *disk_name = "big_file"; myfs_info *myfs; if (argv[1] != NULL && !isdigit(argv[1][0])) disk_name = argv[1]; else if (argv[1] && isdigit(argv[1][0])) seed = strtoul(argv[1], NULL, 0); else seed = getpid() * time(NULL) | 1; printf("random seed == 0x%x\n", seed); srand(seed); myfs = init_fs(disk_name); do_fsh(); if (sys_unmount(1, -1, "/myfs") != 0) { printf("could not un-mount /myfs\n"); return 5; } shutdown_block_cache(); return 0; }static voidmake_random_name(char *buf, int len){ int i, max = (rand() % (len - 5 - 3)) + 2; strcpy(buf, "/myfs/"); for(i=0; i < max; i++) { buf[i+6] = 'a' + (rand() % 26); } buf[i] = '\0';}static voidSubTime(struct timeval *a, struct timeval *b, struct timeval *c){ if ((long)(a->tv_usec - b->tv_usec) < 0) { a->tv_sec--; a->tv_usec += 1000000; } c->tv_sec = a->tv_sec - b->tv_sec; c->tv_usec = a->tv_usec - b->tv_usec;}int cur_fd = -1;static voiddo_close(int argc, char **argv){ int err; err = sys_close(1, cur_fd);/* printf("close of fd %d returned: %d\n", cur_fd, err); */ cur_fd = -1;}static voiddo_open(int argc, char **argv){ int err; char name[64], buff[64]; if (cur_fd >= 0) do_close(0, NULL); if (argc < 2) make_random_name(name, sizeof(name)); else sprintf(name, "/myfs/%s", &argv[1][0]); cur_fd = sys_open(1, -1, name, O_RDWR, MY_S_IFREG, 0); if (cur_fd < 0) printf("error opening %s : %s (%d)\n", name, strerror(cur_fd), cur_fd); else printf("opened: %s\n", name);}static voiddo_make(int argc, char **argv){ int err; char name[64], buff[64]; if (cur_fd >= 0) do_close(0, NULL); if (argc < 2) make_random_name(name, sizeof(name)); else if (argv[1][0] != '/') sprintf(name, "/myfs/%s", &argv[1][0]); else strcpy(name, &argv[1][0]); cur_fd = sys_open(1, -1, name, O_RDWR|O_CREAT, 0666, 0); if (cur_fd < 0) { printf("error creating: %s: %s\n", name, strerror(cur_fd)); return; }/* printf("created: %s (fd %d)\n", name, cur_fd); */}static voiddo_mkdir(int argc, char **argv){ int err; char name[64], buff[64]; if (argc < 2) make_random_name(name, sizeof(name)); else sprintf(name, "/myfs/%s", &argv[1][0]); err = sys_mkdir(1, -1, name, MY_S_IRWXU); if (err) printf("mkdir of %s returned: %s (%d)\n", name, strerror(err), err);}static voiddo_read_test(int argc, char **argv){ int i, err; char *buff; size_t len = 256; if (cur_fd < 0) { printf("no file open! (open or create one with open or make)\n"); return; } if (argv[1][0] && isdigit(argv[1][0])) len = strtoul(&argv[1][0], NULL, 0); buff = malloc(len); if (buff == NULL) { printf("no memory for write buffer of %d bytes\n", len); return; } for(i=0; i < len; i++) buff[i] = (char)0xff; err = sys_read(1, cur_fd, buff, len); if (len < 512) hexdump(buff, len); else hexdump(buff, 512); free(buff); printf("read read %d bytes and returned %d\n", len, err);}static voiddo_write_test(int argc, char **argv){ int i, err; char *buff; size_t len = 256; if (cur_fd < 0) { printf("no file open! (open or create one with open or make)\n"); return; } if (argv[1][0] && isdigit(argv[1][0])) len = strtoul(&argv[1][0], NULL, 0); buff = malloc(len); if (buff == NULL) { printf("no memory for write buffer of %d bytes\n", len); return; } for(i=0; i < len; i++) buff[i] = i; err = sys_write(1, cur_fd, buff, len); free(buff); printf("write wrote %d bytes and returned %d\n", len, err);}static voidmode_bits_to_str(int mode, char *str){ int i; strcpy(str, "----------"); if (MY_S_ISDIR(mode)) str[0] = 'd'; else if (MY_S_ISLNK(mode)) str[0] = 'l'; else if (MY_S_ISBLK(mode)) str[0] = 'b'; else if (MY_S_ISCHR(mode)) str[0] = 'c'; for(i=7; i > 0; i-=3, mode >>= 3) { if (mode & MY_S_IROTH) str[i] = 'r'; if (mode & MY_S_IWOTH) str[i+1] = 'w'; if (mode & MY_S_IXOTH) str[i+2] = 'x'; }}static voiddo_dir(int argc, char **argv){ int dirfd, err, fd, max_err = 10; char dirname[128], buff[512], time_buf[64] = { '\0', }; size_t len; struct my_dirent *dent; struct my_stat st; struct tm *tm; char mode_str[16]; dent = (struct my_dirent *)buff; strcpy(dirname, "/myfs/"); if (argc > 1) strcat(dirname, &argv[1][0]); if ((dirfd = sys_opendir(1, -1, dirname, 0)) < 0) { printf("dir: error opening: %s\n", dirname); return; } printf("Directory listing for: %s\n", dirname); printf(" inode# mode bits uid gid size " "Date Name\n"); while(1) { len = 1; err = sys_readdir(1, dirfd, dent, sizeof(buff), len); if (err < 0) { printf("readdir failed for: %s\n", dent->d_name); if (max_err-- <= 0) break; continue; } if (err == 0) break; err = sys_rstat(1, dirfd, dent->d_name, &st, 1); if (err != 0) { printf("stat failed for: %s (%ld)\n", dent->d_name, dent->d_ino); if (max_err-- <= 0) break; continue; } tm = localtime(&st.mtime); strftime(time_buf, sizeof(time_buf), "%b %d %I:%M", tm); mode_bits_to_str(st.mode, mode_str); printf("%12ld %s %6d %6d %12ld %s %s\n", st.ino, mode_str, st.uid, st.gid, st.size, time_buf, dent->d_name); } if (err != 0) { printf("readdir failed on: %s\n", dent->d_name); } sys_closedir(1, dirfd);}static voiddo_rmall(int argc, char **argv){ int dirfd, err, fd, max_err = 10; char dirname[128], fname[512], buff[512]; size_t len; struct my_dirent *dent; struct my_stat st; struct tm *tm; dent = (struct my_dirent *)buff; strcpy(dirname, "/myfs/"); if (argc > 1) strcat(dirname, &argv[1][0]); if ((dirfd = sys_opendir(1, -1, dirname, 0)) < 0) { printf("dir: error opening: %s\n", dirname); return; } while(1) { len = 1; err = sys_readdir(1, dirfd, dent, sizeof(buff), len); if (err < 0) { printf("readdir failed for: %s\n", dent->d_name); if (max_err-- <= 0) break; continue; } if (err == 0) break; if (strcmp(dent->d_name, "..") == 0 || strcmp(dent->d_name, ".") == 0) continue; sprintf(fname, "%s/%s", dirname, dent->d_name); err = sys_unlink(1, -1, fname); if (err != 0) { printf("unlink failed for: %s (%ld)\n", fname, dent->d_ino); } } if (err != 0) { printf("readdir failed on: %s\n", dent->d_name); } sys_closedir(1, dirfd);}static voiddo_trunc(int argc, char **argv){ int err, new_size; char fname[256]; struct my_stat st; strcpy(fname, "/myfs/"); if (argc < 2) { printf("usage: trunc fname newsize\n"); return; } strcat(fname, &argv[1][0]); new_size = strtoul(&argv[2][0], NULL, 0); st.size = new_size; err = sys_wstat(1, -1, fname, &st, WSTAT_SIZE, 0); if (err != 0) { printf("truncate to %d bytes failed for %s\n", new_size, fname); }}static voiddo_seek(int argc, char **argv){ fs_off_t err; fs_off_t pos; if (cur_fd < 0) { printf("no file open! (open or create one with open or make)\n"); return; } if (argc < 2) { printf("usage: seek pos\n"); return; } pos = strtoul(&argv[1][0], NULL, 0); err = sys_lseek(1, cur_fd, pos, SEEK_SET); if (err != pos) { printf("seek to %ld failed (%ld)\n", pos, err); }}static voiddo_rm(int argc, char **argv){ int err; char name[256], buff[256]; if (cur_fd >= 0) do_close(0, NULL); if (argc < 2) { printf("rm: need a file name to remove\n"); return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -