#include "kernel/types.h" #include "kernel/stat.h" #include "user/user.h" #include "kernel/fs.h" #include "mkfs/fsformat.h" #include "kernel/fcntl.h" char buf[FSFORMAT_NAMESIZE_NEW+1]; char* fmtname(char *path) { char *p; // Find first character after last slash. for(p=path+strlen(path); p >= path && *p != '/'; p--) ; p++; // Return blank-padded name. if(strlen(p) >= 32) return p; memmove(buf, p, strlen(p)); memset(buf+strlen(p), ' ', 32-strlen(p)); return buf; } // Syscall to get dirents in standardised format int lsdir(int fd, void* buff, int sz); void ls(char *path) { char buf[512], *p; int fd; fsformat_dirent_v1_t de; struct stat st; if((fd = open(path, O_RDONLY)) < 0){ fprintf(2, "ls: cannot open %s\n", path); return; } if(fstat(fd, &st) < 0){ fprintf(2, "ls: cannot stat %s\n", path); close(fd); return; } switch(st.type){ case T_DEVICE: case T_FILE: printf("%s %d %d %d\n", fmtname(path), st.type, st.ino, (int) (st.size)); break; case T_DIR: if(strlen(path) + 1 + FSFORMAT_NAMESIZE_NEW + 1 > 512 /*sizeof buf*/){ printf("ls: path too long\n"); break; } strcpy(buf, path); p = buf+strlen(buf); *p++ = '/'; while(lsdir(fd, &de, sizeof(fsformat_dirent_v1_t /*de*/)) == sizeof(fsformat_dirent_v1_t /*de*/)){ if(de.datainode == 0) continue; memmove(p, de.filename, FSFORMAT_NAMESIZE_NEW); p[FSFORMAT_NAMESIZE_NEW] = 0; if(stat(buf, &st) < 0){ printf("ls: cannot stat %s\n", buf); continue; } printf("%s %d %d %d\n", fmtname(buf), st.type, st.ino, (int) (st.size)); } break; } close(fd); } int main(int argc, char *argv[]) { int i; if(argc < 2){ ls("."); exit(0); } for(i=1; i