Usermode - More hackery to get glib compiling
[tpg/acess2.git] / Usermode / Applications / ls_src / main.c
index 82f9c2a..973013b 100644 (file)
@@ -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
+}

UCC git Repository :: git.ucc.asn.au