Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<stdio.h>
- #include<stdlib.h>
- #include<sys/stat.h>
- #include<sys/types.h>
- #include<dirent.h>
- #include<unistd.h>
- #include<pwd.h>
- #include<grp.h>
- #include<string.h>
- #include<time.h>
- const double version=1.0;
- int command_l=0;
- int command_R=0;
- int command_h=0;
- int currentYear;
- typedef struct File{
- char accessRights[11];
- int userId;
- int groupId;
- unsigned long size;
- time_t time;
- char name[256];
- int isDir;
- } File;
- char *getPath(char *path, char *file)
- {
- int pathLen=strlen(path);
- int fileLen=strlen(path);
- char *fullPath=(char*)malloc((pathLen+fileLen+2)*sizeof(char));
- strcpy(fullPath,path);
- if(pathLen && path[pathLen-1]!='/')
- {
- fullPath[pathLen]='/';
- strcpy(fullPath+pathLen+1,file);
- fullPath[pathLen+fileLen+1]='\0';
- }
- else
- {
- strcpy(fullPath+pathLen+1,file);
- fullPath[pathLen+fileLen+1]='\0';
- }
- return fullPath;
- }
- void getAccessRights(File *container, struct stat *file)
- {
- container->accessRights[0]=S_ISDIR(file->st_mode) ? 'd' : '-';
- container->accessRights[1]=(file->st_mode & S_IRUSR) ? 'r' : '-';
- container->accessRights[2]=(file->st_mode & S_IWUSR) ? 'w' : '-';
- container->accessRights[3]=(file->st_mode & S_IXUSR) ? 'x' : '-';
- container->accessRights[4]=(file->st_mode & S_IRGRP) ? 'r' : '-';
- container->accessRights[5]=(file->st_mode & S_IWGRP) ? 'w' : '-';
- container->accessRights[6]=(file->st_mode & S_IXGRP) ? 'x' : '-';
- container->accessRights[7]=(file->st_mode & S_IROTH) ? 'r' : '-';
- container->accessRights[8]=(file->st_mode & S_IWOTH) ? 'w' : '-';
- container->accessRights[9]=(file->st_mode & S_IXOTH) ? 'x' : '-';
- container->accessRights[10]='\0';
- }
- char *humanReadable(unsigned long bytes)
- {
- double bytesDouble=(double)bytes;
- char *sizestr=(char*)malloc(12*sizeof(char));
- char symbols[6]={'B','K','M','G','T','P'};
- int i=0;
- while(i<=5 && bytesDouble>=1024.0)
- {
- bytesDouble/=1024.0;
- i++;
- }
- if((int)(10*bytesDouble)%10==0)
- sprintf(sizestr,"%d%c",(int)bytesDouble,symbols[i]);
- else
- sprintf(sizestr,"%.1lf%c",bytesDouble,symbols[i]);
- return sizestr;
- }
- char *convertTime(unsigned long time)
- {
- time_t now=time;
- struct tm *ptm=localtime(&time);
- char *timestr=(char*) malloc(256*sizeof(char));
- if (ptm->tm_year==currentYear)
- strftime(timestr,256,"%d %b %R",ptm);
- else
- strftime(timestr,256,"%d %b %G",ptm);
- return timestr;
- }
- void printFile(File *container, int l, int h)
- {
- if(container->name[0]=='.')
- return;
- if(l)
- {
- struct passwd *uid=getpwuid(container->userId);
- struct group *gid=getgrgid(container->groupId);
- char *tm=convertTime(container->time);
- printf("%s %s %s ", container->accessRights, uid->pw_name, gid->gr_name);
- if(h)
- {
- char *humanReadableSize=humanReadable(container->size);
- printf("%s ", humanReadableSize);
- }
- else
- printf("%ld ",container->size);
- printf("%s %s\n",tm,container->name);
- }
- else
- printf("%s\t",container->name);
- }
- void printHelp()
- {
- printf("This program lists the files and subdirectories in a given directory.\n\n");
- printf("The following options are available:\n\n");
- printf(" -l\t\tLists files in the long format, including access rights, number of links, owner name, group name, size, date of last modification and name of file.\n\n");
- printf(" -h\t\tWhen used with the -l option, lists sizes with unit suffixes: (B)yte, (K)ilobyte, (M)egabyte, (G)igabyte, (T)erabyte and (P)etabyte.\n\n");
- printf(" -R\t\tRecursively lists subdirectories encountered.\n\n");
- printf(" --help\t\tLists available options.\n\n");
- printf(" --version\tPrints current version and author.\n");
- exit(0);
- }
- void printVersion()
- {
- printf("MyLS version %.1lf\n",version);
- printf("Made by Mateusz Wlodarczyk\n");
- printf("UMK 2019\n");
- exit(0);
- }
- void listDir(char *name, int l, int R, int h)
- {
- DIR *dir;
- struct dirent *dp;
- struct stat statbuf;
- if((dir=opendir(name))==NULL)
- {
- perror("Couldn't open the directory");
- return;
- }
- int filesNumber=0;
- while((dp=readdir(dir))!=NULL)
- filesNumber++;
- closedir(dir);
- if(filesNumber==2) return;
- File *allFiles=(File*)malloc(sizeof(File)*(filesNumber));
- int filesOpened=0;
- int dirNumber= 0;
- int iDir=0;
- int i;
- if((dir=opendir(name))==NULL)
- {
- perror("Couldn't open the directory");
- return;
- }
- while((dp=readdir(dir))!=NULL)
- {
- char *fullName=getPath(name,dp->d_name);
- File *file=allFiles+filesOpened;
- if(stat(fullName,&statbuf))
- {
- perror("Couldn't open the file");
- free(fullName);
- continue;
- }
- strcpy(file->name,dp->d_name);
- getAccessRights(file,&statbuf);
- file->size=(long)statbuf.st_size;
- file->userId=statbuf.st_uid;
- file->groupId=statbuf.st_gid;
- file->time=statbuf.st_mtime;
- file->isDir=dp->d_type==DT_DIR ? 1 : 0;
- if(file->isDir==1)
- dirNumber++;
- filesOpened++;
- free(fullName);
- }
- for(i=0;i<filesOpened;i++)
- printFile(allFiles+i, l, h);
- printf("\n");
- if(!R || dirNumber==2)
- {
- free(allFiles);
- closedir(dir);
- return;
- }
- File *dirList=(File*)malloc(sizeof(File)*dirNumber);
- for(i=0;i<filesOpened;i++)
- {
- if(allFiles[i].isDir)
- {
- if(strcmp(allFiles[i].name,".")==0 || strcmp(allFiles[i].name,"..")==0)
- continue;
- dirList[iDir++]=allFiles[i];
- }
- }
- free(allFiles);
- closedir(dir);
- for(i = 0;i<iDir;i++)
- {
- char *Name=getPath(name,dirList[i].name);
- listDir(Name,l,R,h);
- free(Name);
- }
- free(dirList);
- }
- int main(int argc, char **argv)
- {
- int i;
- while((i=getopt(argc,argv,"lRh"))!=-1)
- {
- switch(i)
- {
- case 'l':
- command_l=1;
- break;
- case 'R':
- command_R=1;
- break;
- case 'h':
- command_h=1;
- break;
- }
- }
- for(i=1;i<argc;i++)
- {
- if(strcmp(argv[i],"--help")==0)
- printHelp();
- else if(strcmp(argv[i],"--version")==0)
- printVersion();
- }
- time_t currentTime=time(NULL);
- struct tm *pctm=localtime(¤tTime);
- currentYear=pctm->tm_year;
- if(optind<argc)
- listDir(argv[optind],command_l,command_R,command_h);
- else
- listDir(".",command_l,command_R,command_h);
- exit(0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement