#include <sys/types.h>
#include <sys/stat.h>
//#include <sys/dir.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *PERM[] = {
"---", "--x", "-w-", "-wx",
"r--", "r-x", "rw-", "rwx",
};
static void list(char * FILE_NAME, struct stat STR_BUF);
static int printout(char* dir, char* FILE_NAME);
int main(int argc, char** argv)
{
struct stat STR_BUF;
//If no arguments, list current directory
if (argc < 2 ){
//printf("argc<0case\n");
list(".", STR_BUF);
exit(0);
}
//Process arguments
while(--argv){
//see what the file is.
if (stat(*++argv, &STR_BUF) < 0){
perror(*argv);
continue;
}
//if it's a directory we list it,
//otherwise just print the info about the file
if((S_ISDIR(STR_BUF.st_mode & S_IFMT))&&(*argv != "."||"..")){
printf("aaaaaa\n");
list(*++argv, STR_BUF);
}
else{
list(*++argv, STR_BUF);
//printout(".", *argv);
break;
}
}
exit(0);
}
//list --read a directory and list the files it contains.
void list(char * FILE_NAME, struct stat STR_BUF)
{
DIR *dp;
struct dirent *dir;
//Open direct *dir;
//printf("List is called\n");
if ((dp = opendir(FILE_NAME)) == NULL){
fprintf(stderr, "%s: cannot open.\n", FILE_NAME);
return;
}
//For each entry
while ((dir = readdir(dp)) != NULL){
//skip removed files.
if(dir->d_ino == 0)
{continue;}
//print it out;
if((S_ISDIR(STR_BUF.st_mode & S_IFMT))&&(FILE_NAME != "."||"..")){
printf("@@");
list(dir->d_name, STR_BUF);
}else{
//printf("PrintOut is called\n");
printout(FILE_NAME, dir->d_name);
}
}
closedir(dp);
}
//print out --print out the information about a file
int printout(char* dir, char* FILE_NAME)
{
int i, j;
char PERM_INIT[10];
struct stat STR_BUF;
char NAME_MOD[1024];
//make full path FILE_NAME,
//so we have a legal path.
sprintf(NAME_MOD, "%s/%s", dir, FILE_NAME);
//at this point we know the file exists,
//so this won't fail.
stat(NAME_MOD, &STR_BUF);
//Print size in kbytes.
printf("%5d ", (int)((STR_BUF.st_size + 1023)/1024));
//get file type.
switch(STR_BUF.st_mode & S_IFMT){
case S_IFREG: putchar('-'); break;//regular mask
case S_IFDIR: putchar('d'); break;//directory mask
case S_IFCHR: putchar('c'); break;//character mask
case S_IFBLK: putchar('b'); break;//block mask
default: putchar('?'); break;
}
*PERM_INIT = 0x00;
for(i=2; i>=0; i--){
//Since we are subscripting, we don't need the
//constants. Just get a value between 0 and 7.
j=(STR_BUF.st_mode >> (i*3)) & 07;
//get perm bits
strcat(PERM_INIT, PERM[j]);
}
//Handle special bits which replace the 'x' in places.
if((STR_BUF.st_mode & S_ISUID) != 0){
PERM_INIT[2] = 's';
}
if((STR_BUF.st_mode & S_ISGID) != 0){
PERM_INIT[5] = 's';
}
if((STR_BUF.st_mode & S_ISVTX) != 0){
PERM_INIT[8] = 't';
}
// Print permissions, number of links,
// user and group ids.
printf("%s%3d %5d/%-5d ", PERM_INIT, STR_BUF.st_nlink, STR_BUF.st_uid, STR_BUF.st_gid);
//Print the size of the file in bytes and the last modification time.
//The ctime routine converts a time to ASCII;
printf("%7d %.12s ", (int)STR_BUF.st_size, ctime(&STR_BUF.st_mtime)+4);
//Finally, print the filename
printf("%s\n", FILE_NAME);
return 0;
}