#include<sys/types.h>
#include<dirent.h>
#include<unistd.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<grp.h>
#include<pwd.h>
#include<time.h>
#include<sys/stat.h>
#include<linux/limits.h>
typedef struct fileInfo
{
char fileName[255];
int fileSize;
struct fileInfo *next;
}fileNode , *fileList;
int max_size = 0;
char pwdName[100];
fileList buildFileList(fileList flist,char *dirName)
{
int count = 0;
DIR *dir;
struct dirent *ptr;
dir = opendir(dirName);
if(dir == NULL)
{
printf("open dir is failed....\n");
return NULL;
}
while((ptr = readdir(dir)) != NULL)
{
fileNode *file = (fileNode*)malloc(sizeof(fileNode));
strcpy(file->fileName,ptr->d_name);
file->fileSize = strlen(ptr->d_name);
if(max_size < file->fileSize)
max_size = file->fileSize;
file->next = flist->next;
flist->next = file;
count++;
}
closedir(dir);
// printf("list size : %d \n\n ",count);
return flist;
}
void display_attribute(struct stat buf,char *name){
char buf_time[32];
struct passwd *psd;
struct group *grp;
//获取并打印文件类型
if(S_ISLNK(buf.st_mode)){
printf("l");
}else if(S_ISREG(buf.st_mode)){
printf("-");
}else if(S_ISDIR(buf.st_mode)){
printf("d");
}else if(S_ISCHR(buf.st_mode)){
printf("c");
}else if(S_ISBLK(buf.st_mode)){
printf("b");
}else if(S_ISFIFO(buf.st_mode)){
printf("f");
}else if(S_ISSOCK(buf.st_mode)){
printf("s");
}
//获取并打印文件所有者的权限
if(buf.st_mode & S_IRUSR){
printf("r");
}else{
printf("-");
}
if(buf.st_mode & S_IWUSR){
printf("w");
}else{
printf("-");
}
if(buf.st_mode & S_IXUSR){
printf("x");
}else{
printf("-");
}
//获取并打印文件所有者同组的用户对该文件的操作权限
if(buf.st_mode & S_IRGRP){
printf("r");
}else{
printf("-");
}
if(buf.st_mode & S_IWGRP){
printf("w");
}else{
printf("-");
}
if(buf.st_mode & S_IXGRP){
printf("x");
}else{
printf("-");
}
//获取并打印其他用户对该文件的操作权限
if(buf.st_mode & S_IROTH){
printf("r");
}else{
printf("-");
}
if(buf.st_mode & S_IWOTH){
printf("w");
}else{
printf("-");
}
if(buf.st_mode & S_IXOTH){
printf("x");
}else{
printf("-");
}
if(buf.st_mode & S_ISUID){
printf("%d",1);
}else printf("%d",0);
if(buf.st_mode & S_ISGID){
printf("%d",1);
}else printf("%d",0);
if(buf.st_mode & S_ISVTX){
printf("%d",1);
}else printf("%d",0);
printf(" ");
//根据UID和GID获取文件所有者的用户名和组名
psd = getpwuid(buf.st_uid);
grp = getgrgid(buf.st_gid);
printf("%4d",buf.st_nlink); //打印文件的连接数
printf(" ");
printf("%-8s",psd->pw_name);
printf(" ");
printf("%-8s",grp->gr_name);
printf(" ");
printf("%6d",(int)buf.st_size); //打印文件的大小
printf(" ");
strcpy(buf_time,ctime(&buf.st_mtime));
buf_time[strlen(buf_time)-1] = '\0' ; //去掉换行符
printf("%s",buf_time); //打印文件的时间信息
printf(" ");
printf("%s",name);
}
int printFileList(fileList flist,int max,int screen_len,int flag) // ls ,ls -a
{
fileNode *ptr;
int count;
int index = 0;
int i;
int j;
ptr = flist->next;
count = screen_len/max;
if(flag == 0) //ls
{
while(ptr != NULL)
{
if(ptr->fileName[0] != '.')
{
printf("%-s",ptr->fileName);
index++;
j = max-(ptr->fileSize);
for(i=1;i <= j; i++)
printf(" ");
if((index % count) == 0)
printf("\n");
}
ptr = ptr->next;
}
}
if(flag == 1) //ls -a
{
while(ptr != NULL)
{
printf("%-s",ptr->fileName);
index++;
j = max-(ptr->fileSize);
for(i=1;i <= j; i++)
printf(" ");
if((index % count) == 0)
printf("\n");
ptr = ptr->next;
}
}
printf("\n");
return index;
}
int printInfo(fileList flist,int flag) //ls -l ,ls -al
{
fileNode *ptr;
char fullName[150];
struct stat buf;
ptr = flist->next;
strcat(pwdName,"/");
if(flag == 1) //ls -al
{
while(ptr != NULL)
{
strcpy(fullName,pwdName);
strcat(fullName,ptr->fileName);
if(stat(fullName,&buf) == -1)
{
printf("stat is error.....\n");
return -1;
}
display_attribute(buf,ptr->fileName);
ptr = ptr->next;
printf("\n");
}
}
if(flag == 0) //ls -l
{
while(ptr != NULL)
{ if(ptr->fileName[0] != '.')
{
strcpy(fullName,pwdName);
strcat(fullName,ptr->fileName);
if(stat(fullName,&buf) == -1)
{
printf("stat is error.....\n");
return -1;
}
display_attribute(buf,ptr->fileName);
printf("\n");
}
ptr = ptr->next;
}
}
printf("\n");
return 0;
}
int main(int argc , char *argv[])
{
int len = 0;
int i,j;
int k=0;
char param[10];
int flag = 0;
int type=0;
int sum =0;
int num = 0;
fileList flist = (struct fileInfo *)malloc(sizeof(struct fileInfo));
flist->next = NULL;
if(argc == 1) // ls .
{
strcpy(pwdName,".");
flist = buildFileList(flist,".");
printFileList(flist,max_size+2,200,0);
return 0;
}
else
{
for(i = 1; i < argc; i++)
{
if(argv[i][0] == '-')
{
flag = 1; //it has input param
for(j = 1; j < strlen(argv[i]); j++)
{
param[k] = argv[i][j];
k++;
}
param[k] = '\0';
num++;
}
else { strcpy(pwdName,argv[i]); }
}
if((num + 1) == argc) strcpy(pwdName,".");
flist = buildFileList(flist,pwdName);
if(flag == 1)
{
for(i = 0; i<k;i++)
{
// printf("%c",param[i]);
if(param[i] == 'a')
{
// -a
type = 1;
sum++;
}
else if(param[i] == 'l')
{
// -l
type = 2;
sum++;
}
else
{
printf("参数输入有误....\n");
return -1;
}
}
if((sum == 1) && (type == 1)) // ls -a
{
printFileList(flist,max_size+2,200,1);
return 0;
}
if((sum == 1 )&& (type == 2)) //ls -l
{
printInfo(flist,0);
return 0;
}
if(sum > 1) //ls -al ; ls -la
{
printInfo(flist,1);
return 0;
}
}
else
{
printFileList(flist,max_size+2,200,0); //ls dir
}
}
return 0;
}