#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 ---
int main(int argc, char *argv[])
{
int fd, tmp;
+ int i;
char buf[BUF_SIZE+1];
t_sysFInfo info;
int space = 0;
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)) )
{
// Sort File List according to rules passed
SortFileList();
+ // Show the file list
+ for( i = 0; i < giNumFiles; i ++ )
+ {
+ DisplayFile( gFileList[i] );
+ }
+
close(fd);
printf("\n");
{
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 = open(path, 0);
+ if(fd == -1) {
+ fprintf(stderr, "Unable to open '%s'\n", path);
+ }
+ else {
+ // Get Info
+ finfo(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.group = 0; acl.id = 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.group = 1; acl.id = info.gid;
+ _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.group = 1; acl.id = -1;
+ _SysGetACL(fd, &acl);
+ if(acl.perms & 1) perms |= 0004; // R
+ if(acl.perms & 2) perms |= 0002; // W
+ if(acl.perms & 8) perms |= 0001; // X
+ }
+ 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) {
+ if(size < 2048) { // < 2 KiB
+ printf("%8lli B ", size);
+ }
+ else if(size < 2048*1024) { // < 2 MiB
+ printf("%8lli KiB ", size>>10);
+ }
+ else if(size < (uint64_t)2048*1024*1024) { // < 2 GiB
+ printf("%8lli MiB ", size>>20);
+ }
+ else if(size < (uint64_t)2048*1024*1024*1024) { // < 2 TiB
+ printf("%8lli GiB ", size>>30);
+ }
+ else { // Greater than 2 TiB
+ printf("%8i TiB ", size>>40);
+ }
+ } else {
+ printf("%8i ", size);
+ }
+ }
+
+ printf("%s\n", Filename);
+}