自己动手写shell命令之ls

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;
}
时间: 2024-10-14 08:09:11

自己动手写shell命令之ls的相关文章

自己动手写shell命令之ls -R1fF

ls命令的R参数代表递归的列出所有子文件夹中的所有文件,1表示每一行只显示一个文件或文件夹,f表示不排序即输出,F表示在每项的输出的最后根据其文件类型相应的加上*/=>@|字符.通过c语言实现ls -R1fF命令的效果,其源代码如下: #include <stdio.h> #include <sys/types.h> #include <dirent.h> #include <sys/stat.h> #include <pwd.h> #in

自己动手写shell命令之write

Linux下write命令允许用户跟其他终端上的用户对话.用c语言实现shell命令write,代码如下: #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <utmp.h> #include <pwd.h> #include <sys/types.h> #include <stdlib.h> #include <sys/stat.h

自己动手写shell命令之du

du命令可以查看指定文件夹占用的磁块数,以下为linux下c语言实现shell du指令的代码(支持-k选项): #include <stdio.h> #include <sys/types.h> #include <dirent.h> #include <sys/stat.h> #include <string.h> int disk_usage(char *); int k = 0; int main(int argc,char * argv

自己动手写shell命令之who

思路:在unix系统中有一个名为utmp的文件,里面存着当前登录到系统中用户的信息.utmp这个文件里面保存的是结构数组,数组元素是utmp类型的结构.实现who命令,只要依次从utmp文件中读出utmp类型的结构体,然后通过合适的方式将它显示出来即可.如果每一次只从文件里面读一个结构体数据,那么每一个结构体都要进行依次系统调用.而又因为系统调用比较耗时(涉及到用户态到核心态的切换),所以这样会造成程序低效.我们使用缓冲技术,每次从文件中读若干结构体数据到内存中,当这些数据都已经显示在终端后,我

自己动手写shell命令之more

unix下more命令的简单实现: #include <stdio.h> #define PAGELEN 24 #define LINELEN 512 int do_more(FILE * file); int see_more(FILE * file); int main(int argc,char * argv[]) { FILE * fp; if(argc == 1) do_more(stdin); else { int argv_index = 1; while(argc > 1

自己动手写shell命令之pwd

思路:(1)得到"."的i节点号,称其为n(使用stat) (2)chdir ..(使用chdir) (3)找到inode号为n的节点,得到其文件名. 重复上述操作直到当前目录"."的inode值等于".."的inode值 #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <dirent.h> ino_t

Linux Shell 学习笔记 二 Shell 命令行 ls

ls 是查看目录及目录里的文件的命令 接下来我们看这个命令的用法 ls ls 的语法主要有 ls     查看目录内容 ls -l 查看文件夹详细信息 ls -a 查看隐藏文件 ls -A 查看隐藏文件,但不显示"."和".."目录信息 ls -d 将目录象文件相同显现,而不是显现其下的文件 ls -h 显示文件大小单位(通常和其他参数一起用) ls -R 递归显示目录和子目录的内容 ls -S 文件从大到小排列 也可以和其他参数一起使用 ls -t 文件按创建时间

自己动手写shell之chgrp,chown,chmod

1.chgrp实现 #include <grp.h> #include <unistd.h> void chgrp(char * groupname,char * filename) { struct group * groupinfo = NULL; if((groupinfo = getgrnam(groupname)) == NULL) { printf("groupname does not exist\n"); return; } if(access(

自己写shell命令pwd

思维:(1)得到"."的i节点号,叫n(使用stat) (2)chdir ..(使用chdir) (3)找到inode号为n的节点,得到其文件名称. 反复上述操作直到当前文件夹"."的inode值等于".."的inode值 #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <dirent.h> ino_t