// A clone of ls
// Still unfinished
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
unsigned char flags = 0;
// 1: -a, 2: -l, 4: -G, 8: -s, 16: -t
unsigned char tflags = 0;
// 1: on, 2: reg, 4: dir, 8: lin, 16: dev
void printfile( struct dirent * );
int main( int argc, char **argv ){
char *dirname;
int cols = 3;
// Parse command line parameters
for( int i = 1; i < argc; i++ ){
if( tflags & 0x1 ){
// Type options not implemented yet
switch( argv[i][0] ){
case 'f' : tflags |= 0x2;
break;
case 'd' : tflags |= 0x4;
break;
case 'l' : tflags |= 0x8;
break;
case 'v' : tflags |= 0x10;
break;
default : tflags |= 0x1e;
}
tflags--;
}
if( argv[i][0] == '-' ){
int optlen = strlen( argv[i] );
printf( "%d\n", optlen );
for( int j = 1; j < optlen; j++ ){
if( argv[i][j] > 0x30 && argv[i][j] < 0x40 ){
// Number of columns
cols = argv[i][j] - 0x30;
}
else if( argv[i][j] == 'a' ){
// List all files
flags |= 0x1;
}
else if( argv[i][j] == 'l' ){
// List files in long format
flags |= 0x2;
cols = 1;
}
else if( argv[i][j] == 'G' ){
// List files with color
flags |= 0x4;
}
else if( argv[i][j] == 's' ){
// Show file sizes
flags |= 0x8;
cols = 1;
}
else if( argv[i][j] == 't' ){
// List by type
tflags |= 0x1;
cols = 1;
}
}
}
else{
dirname = argv[i];
}
}
// End parse parameters
chdir( dirname );
char buf[256];
DIR *dp = opendir( getcwd( buf, 256 ) );
struct dirent *entry;
if( cols < 1 ){
closedir( dp );
return 0;
}
else if( cols > 1 ){
int counter = 0;
while( (entry = readdir( dp )) != NULL ){
if( (flags & 0x1) == 0 ){
// if -a is not set
if( entry->d_name[0] != '.' ){
// Only print if not a dot file
printfile( entry );
if( ++counter % cols == 0 ){
// newline after counter times
putchar( '\n' );
}
}
}
else{
// if -a is set print unconditionally
printfile( entry );
if( ++counter % cols == 0 ){
putchar( '\n' );
}
}
}
if( counter % cols != 0 ){
putchar( '\n' );
}
}
else{
while( (entry = readdir( dp )) != NULL ){
if( (flags & 0x1) || (entry->d_name[0] != '.') ){
printfile( entry );
putchar( '\n' );
}
}
}
return 0;
}
void printfile( struct dirent *entry ){
struct stat inode;
lstat( entry->d_name, &inode );
int ftype = inode.st_mode;
int acmod = inode.st_mode;
ftype >>= 9;
acmod &= 0777;
// Least significant nine bits are the access mode
if( (flags & 0x2 ) ){ // If -l
// Print file type:
switch( ftype ){
case 0100 : putchar( '-' );
// Regular file
break;
case 040 : putchar( 'd' );
// Directory
break;
case 0120 : putchar( 'l' );
// Symbolic link
break;
case 010 : putchar( 'p' );
// Named pipe
break;
case 060 : putchar( 'b' );
// Block special file
break;
case 020 : putchar( 'c' );
// Character special file
break;
case 016 : putchar( 'b' );
// Block file
break;
default : putchar( '?' );
}
// Print access mode:
if( acmod & 0400 )
putchar( 'r' );
else
putchar( '-' );
if( acmod & 0200 )
putchar( 'w' );
else
putchar( '-' );
if( acmod & 0100 )
putchar( 'x' );
else
putchar( '-' );
if( acmod & 040 )
putchar( 'r' );
else
putchar( '-' );
if( acmod & 020 )
putchar( 'w' );
else
putchar( '-' );
if( acmod & 010 )
putchar( 'x' );
else
putchar( '-' );
if( acmod & 04 )
putchar( 'r' );
else
putchar( '-' );
if( acmod & 02 )
putchar( 'w' );
else
putchar( '-' );
if( acmod & 01 )
putchar( 'x' );
else
putchar( '-' );
}
if( flags & 0xa ){ // if -l or -s
printf( "%10d", inode.st_size );
putchar( '\t' );
}
if( flags & 0x4 ){
switch( ftype ){
case 0100 : printf( "\e[37m" );
// Regular file
break;
case 040 : printf( "\e[34m" );
// Directory
break;
case 0120 : printf( "\e[36m" );
// Symbolic link
break;
case 010 : printf( "\e[33m" );
// Named pipe
break;
case 060 : printf( "\e[32m" );
// Block special file
break;
case 016 : printf( "\e[35m" );
// Character special file
break;
case 020 : printf( "\e[35m" );
// Device file
break;
default : putchar( '?' );
}
}
char nbuf[256];
if( (ftype == 0120) && (flags & 0x2) ){
char lbuf[64];
int llen = readlink( entry->d_name, lbuf, 64 );
// Have to get the length because the result is not null-terminated for some reason
snprintf( nbuf, strlen( entry->d_name ) + llen + 6, "%s --> %s", entry->d_name, lbuf );
}
else{
snprintf( nbuf, 256, "%s", entry->d_name );
}
printf( "%-28s", nbuf );
if( flags & 0x4 ){
// Prints escape sequences in less if I don't do this
printf( "\e[0m" );
}
}
Edited by DarkLordofthePenguins, 18 September 2011 - 05:51 PM.


Sign In
Create Account


Back to top









