Code:
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>
#include <unistd.h>
#define SIZE 256
char* workdir(){
const size_t BUFSIZE = 1024;
char curdir[BUFSIZE];
if (getcwd(curdir,BUFSIZE) != curdir){
if( errno == ERANGE )
fprintf( stderr, "Path too long.\n" );
else
fprintf( stderr, "Can't access current directory\n" );
exit( EXIT_FAILURE );
}else
return curdir;
}
void printDetails(char *filename){
struct passwd *my_passwd;
struct group *my_group;
struct stat sbuf;
struct tm *strtime;
int fdes;
unsigned char type ='?';
unsigned char usr[] = "---";
unsigned char grp[] = "---";
unsigned char oth[] = "---";
unsigned char uid[9], gid[9];
unsigned char mod[13];
mode_t mode;
char* curdir;
time_t now;
int year;
/*Concatenate dir names*/
curdir = workdir();
strcat(curdir,"/");
strcat(curdir,filename);
/*stat the final dir name*/
if(stat(curdir,&sbuf) != -1){
if(S_ISLNK(sbuf.st_mode)){
if(lstat(curdir,&sbuf) == -1){
fprintf(stderr,"Can't stat %s\n",filename);
return;
}
}else if(S_ISREG(sbuf.st_mode)){
if((fdes = open(curdir,O_RDONLY)) != ENOENT){
if(fstat(fdes,&sbuf) == -1){
fprintf(stderr,"Can't stat %s\n",filename);
return;
}
close(fdes);
}else{
fprintf(stderr,"Can't open %s\n",filename);
return;
}
}
}else{
fprintf(stderr,"Can't stat %s\n",filename);
return;
}
/*format information*/
mode = sbuf.st_mode;
if( S_ISLNK( mode ) ) type = 'l'; /*symlink*/
else if( S_ISDIR ( mode ) ) type = 'd'; /*directory*/
else if( S_ISCHR ( mode ) ) type = 'c'; /*character raw device*/
else if( S_ISBLK ( mode ) ) type = 'b'; /*block raw device*/
else if( S_ISFIFO( mode ) ) type = 'p'; /*named pipe*/
else if( S_ISSOCK( mode ) ) type = 's'; /*Unix domain socket*/
else if( S_ISREG ( mode ) ) type = '-'; /*regular file*/
if( mode & S_IRUSR ) usr[0] = 'r';
if( mode & S_IWUSR ) usr[1] = 'w';
if( mode & S_IXUSR ) usr[2] = 'x';
if( mode & S_ISUID ) usr[2] = 's'; /* set UID bit*/
if( mode & S_IRGRP ) grp[0] = 'r';
if( mode & S_IWGRP ) grp[1] = 'w';
if( mode & S_IXGRP ) grp[2] = 'x';
if( mode & S_ISGID ) grp[2] = 's'; /* set GID bit*/
if( mode & S_IROTH ) oth[0] = 'r';
if( mode & S_IWOTH ) oth[1] = 'w';
if( mode & S_IXOTH ) oth[2] = 'x';
my_passwd = getpwuid(sbuf.st_uid);
if(my_passwd)
strncpy(uid,my_passwd->pw_name,8);
else
snprintf(uid,9,"%d",sbuf.st_uid);
my_group = getgrgid(sbuf.st_gid);
if(my_group)
strncpy(gid,my_group->gr_name,8);
else
snprintf(gid,9,"%d",sbuf.st_gid);
time(&now);
year = localtime(&now)->tm_year;
strtime = localtime(&sbuf.st_ctime);
if(strtime->tm_year == year)
strftime(mod,13,"%b %e %R",strtime);
else
strftime(mod,13,"%b %e %Y",strtime);
/*print the details*/
printf("%c%s%s%s %4u %-8s %81u %12s %s\n",
type,usr,grp,oth,sbuf.st_nlink,
uid,gid,sbuf.st_size,mod,filename);
}
void main(int argc, char **argv) {
int count,index;
char *curdir;
struct stat sbuf;
struct dirent **direntp;
curdir = workdir();
if(argv[1] != '\0'){
if(stat(argv[1], &sbuf) != -1){
if(S_ISDIR(sbuf.st_mode)){ /* Is a directory */
count = scandir(argv[1],&direntp,NULL,alphasort);
if(count){
for(index=0; index<count; ++index){
printDetails(direntp[index]->d_name);
free(direntp[index]);
}
}else{
fprintf(stderr,"Can't open %s\n",argv[1]);
exit(EXIT_FAILURE);
}
}else if(S_ISREG(sbuf.st_mode)) /* Is a regular file */
printDetails(argv[1]);
}else
printf("Can't stat %s\n", argv[1]);
}else{
printf("%s\n",curdir);
if(stat(curdir,&sbuf) !=-1){
count = scandir(curdir,&direntp,NULL,alphasort);
if(count){
for(index=0; index<count; ++index){
printDetails(direntp[index]->d_name);
free(direntp[index]);
}
}else{
fprintf(stderr,"Can't open %s\n",curdir);
exit(EXIT_FAILURE);
}
}else
fprintf(stderr,"Can't stat %s\n",curdir);
}
free(direntp);
}