自己动手写shell命令之ls

时间:2021-11-20 22:27:17

linux下ls命令(支持-R参数)的c语言实现:

#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>
#include <string.h>

void do_ls(char *);
void do_stat(char *,char *);
void show_file_info(char *,struct stat *,char *);
void mode_to_letters(int ,char []);
char * uid_to_name(uid_t);
char * gid_to_name(gid_t);
int recursive = 0;

int main(int argc,char * argv[])
{
	int i;
	for(i = 1;i < argc;i++)
	{
		if(strcmp(argv[i],"-R") == 0)
		{
			recursive = 1;
			break;
		}
	}
	if(argc == 1 && recursive == 0)
		do_ls(".");
	else if(argc == 2 && recursive == 1)
		do_ls(".");
	else
	{
		int index = 1;
		while(argc > 1)
		{
			if(strcmp(argv[index],"-R") != 0)
				do_ls(argv[index]);
			index++;
			argc--;
		}
	}
	return 0;
}

void do_ls(char * path)
{
	DIR * dir;
	struct dirent * direntp;
	if((dir = opendir(path)) != NULL)
	{
		while((direntp = readdir(dir)) != NULL)
		{
			char absolute_pathname[255];
			strcpy(absolute_pathname,path);
			strcat(absolute_pathname,"/");
			strcat(absolute_pathname,direntp->d_name);
			printf("%s\n",absolute_pathname);
			do_stat(absolute_pathname,direntp->d_name);
		}
		closedir(dir);
	}
	else
		fprintf(stderr,"can't open %s",path);
}

void do_stat(char * absolute_filename,char * filename)
{
	struct stat  s;
	if(lstat(absolute_filename,&s) == -1)
		perror(absolute_filename);
	else
		show_file_info(absolute_filename,&s,filename);
}

void show_file_info(char * absolute_filename,struct stat * info,char * filename)
{
	char mode[11];
	mode_to_letters(info->st_mode,mode);
	printf("%s ",mode);
	printf("%d ",info->st_nlink);
	printf("%s ",uid_to_name(info->st_uid));
	printf("%s ",gid_to_name(info->st_gid));
	printf("%d ",info->st_size);
	printf("%.12s ",4+ctime(&info->st_mtime));
	printf("\n");
	if(recursive == 1)
	{
		if(S_ISDIR(info->st_mode) && strcmp(filename,".") != 0 && strcmp(filename,"..") != 0)
			do_ls(absolute_filename);
	}
}

void mode_to_letters(int mode,char * c_mode)
{
	strcpy(c_mode,"----------");

	if(S_ISDIR(mode))
		c_mode[0] = 'd';
	if(S_ISCHR(mode))
		c_mode[0] = 'c';
	if(S_ISBLK(mode))
		c_mode[0] = 'b';
	
	if(mode & S_IRUSR)
		c_mode[1] = 'r';
	if(mode & S_IWUSR)
		c_mode[2] = 'w';
	if(mode & S_IXUSR)
		c_mode[3] = 'x';

	if(mode & S_IRGRP)
                c_mode[4] = 'r';
        if(mode & S_IWGRP)
                c_mode[5] = 'w';
        if(mode & S_IXGRP)
                c_mode[6] = 'x';

	if(mode & S_IROTH)
                c_mode[7] = 'r';
        if(mode & S_IWOTH)
                c_mode[8] = 'w';
        if(mode & S_IXOTH)
                c_mode[9] = 'x';

	if(mode & S_ISUID)
		c_mode[3] = 's';
	if(mode & S_ISGID)
		c_mode[6] = 's';
	if(mode & S_ISVTX)
		c_mode[9] = 's';
}

char * uid_to_name(uid_t uid)
{
	struct passwd * passwd_pointer;
	passwd_pointer = getpwuid(uid);
	return passwd_pointer->pw_name;
}

char * gid_to_name(gid_t gid)
{
	
	struct group * group_pointer;
	static char numstr[10];
	if((group_pointer = getgrgid(gid)) == NULL)
	{
		sprintf(numstr,"%d",gid);
		return numstr;
	}
	return group_pointer->gr_name;
}