X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FApplications%2Fls_src%2Fmain.c;h=973013b0dbcf03c6fb6c1e6471465fbaf60334e8;hb=85362e8a4c919b58cd261345d29f26bae4ad75e2;hp=82f9c2a6fdb12c48c6fbf99c5f92d3db1f8a0a15;hpb=9d3800f60f2212432e550a4e003ae65b498a4d36;p=tpg%2Facess2.git diff --git a/Usermode/Applications/ls_src/main.c b/Usermode/Applications/ls_src/main.c index 82f9c2a6..973013b0 100644 --- a/Usermode/Applications/ls_src/main.c +++ b/Usermode/Applications/ls_src/main.c @@ -8,11 +8,20 @@ #define BUF_SIZE 1024 +// === CONSTANTS === +enum eFileTypes { + FTYPE_NORMAL, + FTYPE_EXEC, + FTYPE_DIR, + FTYPE_SYMLINK +}; + // === PROTOTYPES === int main(int argc, char *argv[]); void ShowUsage(char *ProgName); void ParseArguments(int argc, char *argv[]); void SortFileList(); +void DisplayFile(char *Filename); // === GLOBALS === // --- Flags --- @@ -33,6 +42,7 @@ char **gFileList; int main(int argc, char *argv[]) { int fd, tmp; + int i; char buf[BUF_SIZE+1]; t_sysFInfo info; int space = 0; @@ -41,26 +51,35 @@ int main(int argc, char *argv[]) ParseArguments(argc, argv); // Open Directory - fd = open(gsDirectory, OPENFLAG_READ|OPENFLAG_EXEC); + fd = _SysOpen(gsDirectory, OPENFLAG_READ|OPENFLAG_EXEC); if(fd == -1) { printf("Unable to open '%s' for reading\n", gsDirectory); return EXIT_FAILURE; } // Check that it is a directory - finfo(fd, &info, 0); + _SysFInfo(fd, &info, 0); if( !(info.flags & FILEFLAG_DIRECTORY) ) { - fprintf(stderr, "'%s' is a directory\n", gsDirectory); - close(fd); + fprintf(stderr, "'%s' is not a directory\n", gsDirectory); + _SysClose(fd); return EXIT_FAILURE; } + // Check if we should include the implicit . and .. + if(gbShowImplicit) + { + space = 16; + gFileList = malloc(space*sizeof(char*)); + gFileList[giNumFiles++] = "."; + gFileList[giNumFiles++] = ".."; + } + // Traverse Directory - while( (tmp = readdir(fd, buf)) ) + while( (tmp = _SysReadDir(fd, buf)) > 0 ) { // Error check if(tmp < 0) { - close(fd); + _SysClose(fd); return EXIT_FAILURE; } @@ -70,7 +89,7 @@ int main(int argc, char *argv[]) space += 16; gFileList = realloc(gFileList, space*sizeof(char*)); if(gFileList == NULL) { - close(fd); + _SysClose(fd); return EXIT_FAILURE; } } @@ -80,7 +99,13 @@ int main(int argc, char *argv[]) // Sort File List according to rules passed SortFileList(); - close(fd); + // Show the file list + for( i = 0; i < giNumFiles; i ++ ) + { + DisplayFile( gFileList[i] ); + } + + _SysClose(fd); printf("\n"); return EXIT_SUCCESS; @@ -127,7 +152,7 @@ void ParseArguments(int argc, char *argv[]) // Human readable sizes case 'h': gbViewHumanReadable = 1; continue; default: - fprintf(stderr, "%s: Unknown option '%c'\n", *str); + fprintf(stderr, "%s: Unknown option '%c'\n", argv[0], *str); ShowUsage(argv[0]); exit(EXIT_FAILURE); } @@ -142,8 +167,6 @@ void ParseArguments(int argc, char *argv[]) // Apply Defaults if(!gsDirectory) gsDirectory = "."; - - printf("gsDirectory = '%s'\n", gsDirectory); } /** @@ -163,3 +186,128 @@ void SortFileList() { qsort(gFileList, giNumFiles, sizeof(char*), strcmpp); } + +/** + * \fn void DisplayFile(char *Filename) + * \brief Prints out the information for a file + */ +void DisplayFile(char *Filename) +{ + t_sysFInfo info; + t_sysACL acl; + char *path; + int fd; + int dirLen = strlen(gsDirectory); + int type = FTYPE_NORMAL, perms = 0; + uint64_t size = 0; + int owner = 0, group = 0; + + // Check if we should skip this file + if(!gbShowAll && Filename[0] == '.') return; + + // Allocate path + path = malloc(dirLen+1+strlen(Filename)+1); + if(!path) { + fprintf(stderr, "heap exhausted\n"); + exit(EXIT_FAILURE); + } + + // Create path + strcpy(path, gsDirectory); + path[dirLen] = '/'; + strcpy(&path[dirLen+1], Filename); + + // Get file type + fd = _SysOpen(path, 0); + if(fd == -1) { + fprintf(stderr, "Unable to open '%s'\n", path); + } + else { + // Get Info + _SysFInfo(fd, &info, 0); + // Get Type + if(info.flags & FILEFLAG_DIRECTORY) { + type = FTYPE_DIR; + } + else if(info.flags & FILEFLAG_SYMLINK) { + type = FTYPE_SYMLINK; + } + else { + type = FTYPE_NORMAL; + } + // Get Size + size = info.size; + // Get Owner and Group + owner = info.uid; + group = info.gid; + + // Get Permissions + // - Owner + acl.object = info.uid; + _SysGetACL(fd, &acl); + if(acl.perms & 1) perms |= 0400; // R + if(acl.perms & 2) perms |= 0200; // W + if(acl.perms & 8) perms |= 0100; // X + // - Group + acl.object = info.gid | 0x80000000; + _SysGetACL(fd, &acl); + if(acl.perms & 1) perms |= 0040; // R + if(acl.perms & 2) perms |= 0020; // W + if(acl.perms & 8) perms |= 0010; // X + // - World + acl.object = 0xFFFFFFFF; + _SysGetACL(fd, &acl); + if(acl.perms & 1) perms |= 0004; // R + if(acl.perms & 2) perms |= 0002; // W + if(acl.perms & 8) perms |= 0001; // X + + // Close file + _SysClose(fd); + } + free(path); // We're finished with it + + // Extended view? + if(gbViewExtended) + { + char permStr[11] = " ---------"; + if(type == FTYPE_DIR) permStr[0] = 'd'; + if(perms & 0400) permStr[1] = 'r'; + if(perms & 0200) permStr[2] = 'w'; + if(perms & 0100) permStr[3] = 'x'; + if(perms & 0040) permStr[4] = 'r'; + if(perms & 0020) permStr[5] = 'w'; + if(perms & 0010) permStr[6] = 'x'; + if(perms & 0004) permStr[7] = 'r'; + if(perms & 0002) permStr[8] = 'w'; + if(perms & 0001) permStr[9] = 'x'; + printf("%s %4i %4i ", permStr, owner, group); + if(gbViewHumanReadable && type != FTYPE_DIR) { + if(size < 2048) { // < 2 KiB + printf("%4lli B ", size); + } + else if(size < 2048*1024) { // < 2 MiB + printf("%4lli KiB ", size>>10); + } + else if(size < (uint64_t)2048*1024*1024) { // < 2 GiB + printf("%4lli MiB ", size>>20); + } + else if(size < (uint64_t)2048*1024*1024*1024) { // < 2 TiB + printf("%4lli GiB ", size>>30); + } + else { // Greater than 2 TiB (if your files are larger than this, you are Doing It Wrong [TM]) + printf("%4lli TiB ", size>>40); + } + } else { + printf("%8lli ", size); + } + } + + switch(type) + { + case FTYPE_DIR: printf("\x1B[32m"); break; // Green + case FTYPE_SYMLINK: printf("\x1B[34m"); break; // Blue + case FTYPE_NORMAL: break; + } + printf("%s%s\n", Filename, (type==FTYPE_DIR?"/":"")); + printf("\x1B[00m"); // Reset +}