自己写的小ls

/*

 *只支持当前目录下的-a, -l, -al的显示。希望对初学者有所帮助。

 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/types.h>
#include <linux/limits.h>
#include <dirent.h>
#include <grp.h>
#include <pwd.h>
#include <error.h>

#define NONE 0 //没有参数

#define HAVE_A 1 //参数是-a

#define HAVE_L 2 //参数是-l

#define HAVE_AL 3

#define HANGMAX 123 //一行最多打印的字符数

#define FILEMAX    256

int leave_max = HANGMAX; //记录一行剩余的字符数

int len_max;         //目录下最长的文件

int count = 0;

typedef struct file{    //记录当前目录下的所用文件名和文件长度    

    char filename[FILEMAX][30];
    int filelen[FILEMAX];
}filelan;

/*
 *函数名称:filelan copy_file(char *pathname)
 *函数功能:将当前目录下的所用文件拷贝到结构体filelan里
 *传递参数:pathname:当前的目录
 *返回类型:将拷贝完的文件返回给filelan F
 */

filelan copy_file(char *pathname)
{
    DIR *dp;
    struct dirent *dirp;
    filelan F;
    int i;

    if((dp = opendir(pathname)) == NULL)
        printf("Cannot open %s\n", pathname);
    len_max = 0;
    i = 0;
    while((dirp = readdir(dp)) != NULL){
        if(len_max < (strlen(dirp->d_name)))
            len_max = strlen(dirp->d_name);
        F.filelen[i] = strlen(dirp->d_name);
        strcpy(F.filename[i], dirp->d_name);
        i++;
        count++;
    }
    if(count > FILEMAX){
        printf("Too Many Files!\n");
        exit(0);
    }
//    printf("i = %d\n", i);

//    printf("count = %d\n", count);

//    printf("len_max = %d\n", len_max);

    closedir(dp);
    return F;
}
/*
 *函数名称:int part_parameter(int argc, char **argv)
 *函数功能:分离主函数传入的参数
 *传递参数:argc:主函数参数个数,argv:主函数参数本身
 *返回类型:flag:参数分离的结果
 */

int part_parameter(int argc, char **argv)
{
    int flag;
    if(argc == 1)
        flag = NONE;
    else if(argc == 2){
        if((strcmp(argv[1], "-a")) == 0)
            flag = HAVE_A;
        else if((strcmp(argv[1], "-l")) == 0)
            flag = HAVE_L;
        else if((strcmp(argv[1], "-al")) == 0 ||(strcmp(argv[1], "-la")) == 0)
            flag = HAVE_AL;
        else{
            perror("ERROR: <1>can shu\n");
            exit(0);
        }
    }
    else if(argc == 3){
        if(((strcmp(argv[1], "-a")) == 0) && ((strcmp(argv[2], "-l"))) == 0)
            flag = HAVE_AL;
        else if(((strcmp(argv[1], "-l")) == 0) && ((strcmp(argv[2], "-a"))) == 0)
            flag = HAVE_AL;
        else{
            perror("ERROR: <2>cna shu\n");
            exit(0);
        }
    }
    return flag;
}
/*
 *函数名称:show_file(int flag, filelan F)
 *函数功能:显示当前目录下的文件。
 *传递参数:flag:判断是否为-a的参数。F:将拷贝好的结构体传入此函数。
 *返回类型:无
 */

void show_file(int flag, filelan F)
{
    int i, j;
    int len;
    for(i = 0; i < count; i++)
    {
        if(len_max > leave_max){
            printf("\n");
            leave_max = HANGMAX;
        }
        if(flag == NONE)
            if(F.filename[i][0] == '.')
                continue;
        len = F.filelen[i];
        len = len_max - len;
        printf("%s", F.filename[i]);
        for(j = 0; j < len; j++)
            printf(" ");
        printf(" ");
        leave_max = leave_max - (len_max+2);
    }
    printf("\n");
}

/*
 *函数名称:void show_file_l(char *filename)
 *函数功能:主要显示有-l参数的文件
 *传递参数:filename:要显示的文件名
 *返回类型:无
 */

void show_file_l(char *filename)
{
    char file_time[32];
    struct stat file_stat;
    struct passwd *psd;    //获得文件所有者的用户名

    struct group *grp;    //获取文件所有者的所属组的组名

    
    if(lstat(filename, &file_stat) == -1){
        perror("Cannot get the information of the file!\n");
        exit(0);
    }
    //获取并打印文件类型

    if(S_ISREG(file_stat.st_mode))
        printf("-");
    else if(S_ISDIR(file_stat.st_mode))
        printf("d");
    else if(S_ISCHR(file_stat.st_mode))
        printf("c");
    else if(S_ISBLK(file_stat.st_mode))
        printf("b");
    else if(S_ISFIFO(file_stat.st_mode))
        printf("f");
    else if(S_ISLNK(file_stat.st_mode))
        printf("l");
    else if(S_ISSOCK(file_stat.st_mode))
        printf("s");

    //获取并打印文件所有者的权限

    if(file_stat.st_mode & S_IRUSR)
        printf("r");
    else printf("-");
    if(file_stat.st_mode & S_IWUSR)
        printf("w");
    else printf("-");
    if(file_stat.st_mode & S_IXUSR)
        printf("x");
    else printf("-");

    //获取并打印文件所有者同组成员的权限

    if(file_stat.st_mode & S_IRGRP)
        printf("r");
    else printf("-");
    if(file_stat.st_mode & S_IWGRP)
        printf("w");
    else printf("-");
    if(file_stat.st_mode & S_IXGRP)
        printf("x");
    else printf("-");

    //获取并打印其他用户的权限

    if(file_stat.st_mode & S_IROTH)
        printf("r");
    else printf("-");
    if(file_stat.st_mode & S_IWOTH)
        printf("w");
    else printf("-");
    if(file_stat.st_mode & S_IXOTH)
        printf("x");
    else printf("-");

    printf(" ");

    psd = getpwuid(file_stat.st_uid);
    grp = getgrgid(file_stat.st_gid);

    printf("%4d ", file_stat.st_nlink);
    printf("%-8s", psd->pw_name);
    printf("%-8s", grp->gr_name);
    printf("%6d ", file_stat.st_size);
    
    strcpy(file_time, ctime(&file_stat.st_mtime));
    file_time[strlen(file_time) - 1] = '\0';
    printf(" %s", file_time);
    printf(" %s\n", filename);
}

//主函数:分离参数并且调用以上函数实现功能

int main(int argc, char **argv)
{
    int flag,i;
    filelan F;
    F = copy_file("./");
    flag = part_parameter(argc, argv);

//    printf("flag = %d\n", flag);

    switch(flag){
        case NONE:
            show_file(NONE, F);
            break;

        case HAVE_A:
            show_file(HAVE_A, F);
            break;

        case HAVE_L:
            for(i = 0; i < count; i++){
                if(F.filename[i][0] == '.')
                    continue;
                show_file_l(F.filename[i]);            
            }
            break;

        case HAVE_AL:
            for(i = 0; i < count; i++){
                show_file_l(F.filename[i]);
            }
            break;
    }
    return 0;
}

<script type=text/javascript charset=utf-8 src="http://static.bshare.cn/b/buttonLite.js#style=-1&uuid=&pophcol=3&lang=zh"></script> <script type=text/javascript charset=utf-8 src="http://static.bshare.cn/b/bshareC0.js"></script>
阅读(392) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值