• ls命令的简单实现


    ls命令的简单实现

    目标:简单的实现ls命令

    实现的mic_ls命令主要功能

    1.循环遍历目录
    2.列出目标目录所有的子目录和文件
    3.列出文件的文件权限,所有者,文件大小等详细信息

    参数

    -r 循环遍历
    -a 列出全部文件
    -l 列出详细信息(文件类型、权限。。。)

    环境

    ubuntu 14.04 gcc.real (Ubuntu 4.8.2-19ubuntu1) 4.8.2

    代码

    新手菜鸟 如有错误 欢迎指正

    #include<stdio.h>
    #include<unistd.h>
    #include<stdlib.h>
    #include<stdbool.h>
    #include<dirent.h>
    #include<string.h>
    #include<sys/stat.h>
    #include<pwd.h>
    #include<grp.h>
    bool show_all=false;
    bool show_list=false;
    bool show_recursion=false;
    void do_ls_r(char *pathname,int depth);
    void do_ls(char *pathname);
    int judge_dir(char *pathname);
    void do_showlist(DIR *dp);
    void mode_to_letters(int mode,char str[]);
    char *uid_to_name(uid_t uid);
    char *gid_to_name(gid_t gid);
    
    
    int main(int argc,char *argv[])
    {
    	int opt;
    	while((opt=getopt(argc,argv,"arl"))!=-1){
    		switch(opt){
    			case 'a':
    				show_all=true;
    				break;
    			case 'r':
    				show_recursion=true;
    				break;
    			case 'l':
    				show_list=true;
    				break;
    			case '?':
    				printf("unknow option :%c
    ",optopt);
    				exit(1);
    		}
    	}
    	if(show_recursion){
    		if(argc==optind)
    		  do_ls_r(".",4);
    		else{
    			for(;optind<argc;optind++){
    				if(judge_dir(argv[optind])){
    					printf("%s:
    ",argv[optind]);
    				    do_ls_r(argv[optind],4);
    				}
    				else{
    					printf("not a directory!
    ");
    					exit(1);
    				}
    			}
    		}
    	}
    	else{
    		if(argc==optind)
    		  do_ls(".");
    		else{
    			for(;optind<argc;optind++){
    				if(judge_dir(argv[optind])){
    					printf("%s:
    ",argv[optind]);
    				    do_ls(argv[optind]);
    				}
    				else{
    					printf("not a directory!
    ");
    					exit(1);
    				}
    			}
    		}
    	}
    
    }
    
    int judge_dir(char *pathname)
    {
    	struct stat statbuf;
    	if((lstat(pathname,&statbuf))<0){
    	  printf("error in lstat!
    ");
    	  exit(1);
    	}
    	if(S_ISDIR(statbuf.st_mode))
    	  return 1;
    	else
    	  return -1;
    }
    void do_ls_r(char *pathname,int depth)
    {
    	DIR *dp;
    	struct dirent *entry;
    	struct stat statbuf;
    	if((dp=opendir(pathname))==NULL){
    		printf("can't open dir:%s
    ",pathname);
    		exit(1);
    	}
    	chdir(pathname);
    	while((entry=readdir(dp))!=NULL){
    		lstat(entry->d_name,&statbuf);
    		if(S_ISDIR(statbuf.st_mode)){
    			if(strcmp(".",entry->d_name)==0||strcmp("..",entry->d_name)==0)
    			  continue;
    			printf("%*s%s/
    ",depth," ",entry->d_name);
    			do_ls_r(entry->d_name,depth+4);
    		}
    		else
    		  printf("%*s%s
    ",depth," ",entry->d_name);
    	}
    	chdir("..");
    	closedir(dp);
    
    }
    void do_ls(char *pathname)
    {
    	DIR *dp;
    	struct dirent *entry;
    	if((dp=opendir(pathname))==NULL){
    			printf("can't open dir:%s
    ",pathname);
    			exit(1);
    		}
    	if(show_list){
    		chdir(pathname);
    	    do_showlist(dp);
    	}
    	else{
    			while((entry=readdir(dp))!=NULL){
    			if(!show_all)
    			  if(*(entry->d_name)=='.')
    				continue;
    			printf("%s
    ",entry->d_name);
    		}
    		closedir(dp);
    	}
    }
    void do_showlist(DIR *dp)
    {
    	struct dirent *entry;
    	struct stat statbuf;
    	char l_mode[11];
    	while((entry=readdir(dp))!=NULL){
    		if((lstat(entry->d_name,&statbuf))<0){
    			printf("error :in lstat
    ");
    			exit(1);
    		}
    		if(!show_all)
    		  if(*(entry->d_name)=='.')
    			continue;
    		mode_to_letters(statbuf.st_mode,l_mode);
    		printf("%s",l_mode);
    		printf("%4d ",(int)statbuf.st_nlink);
    		printf("%-8s ",uid_to_name(statbuf.st_uid));
            printf("%-8s ",gid_to_name(statbuf.st_gid));
    		printf("%8ld ",(long)statbuf.st_size);
    		printf("    %s ",entry->d_name);
    		printf("
    ");
    	}
    }
    void mode_to_letters(int mode,char str[])
    {
    	strcpy(str,"----------");
    	if(S_ISDIR(mode)) str[0]='d';
    	if(S_ISCHR(mode)) str[0]='c';
    	if(S_ISBLK(mode)) str[0]='b';
    
    	if(mode&S_IRUSR)  str[1]='r';
    	if(mode&S_IWUSR)  str[2]='w';
    	if(mode&S_IXUSR)  str[3]='x';
    
    	if(mode&S_IRGRP)  str[4]='r';
       	if(mode&S_IWGRP)  str[5]='w';
    	if(mode&S_IXGRP)  str[6]='x';
    
    	if(mode&S_IROTH)  str[7]='r';
    	if(mode&S_IWOTH)  str[8]='w';
    	if(mode&S_IXOTH)  str[9]='x';
    }
    
    char *uid_to_name(uid_t uid)
    {
    	struct passwd *getpwuid(),*pw_ptr;
    	if((pw_ptr=getpwuid(uid))!=NULL)
    	  return (pw_ptr->pw_name);
    	else
    	  return NULL;
    }
    char *gid_to_name(gid_t gid)
    {
    	struct group *getgrid,*grp_ptr;
    	if((grp_ptr=getgrgid(gid))!=NULL)
    	  return (grp_ptr->gr_name);
    	else
    	  return NULL;
    }
    
  • 相关阅读:
    JSON
    什么是Jsonp?
    用border做三角形
    前端模块化
    Web 前端
    前端性能优化
    Ajax的原理
    node.js基础语法
    【真·新手初篇】菜鸟们都戳进来看看(欢迎大神指导)
    2019.11.20 开启一天的工作
  • 原文地址:https://www.cnblogs.com/battzion/p/4227341.html
Copyright © 2020-2023  润新知