Unix-Linux编程实践教程——第三章

时间:2021-05-26 22:23:28

章节概要

本章节主要说明文件属性以及如何修改文件属性

fileinfo.c

/************************************************************** > File Name: fileinfo.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月07日 星期六 13时22分57秒 ************************************************************/

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>

void show_stat_info(char* fname,struct stat*buf){
    //文件类型和许可权限
    printf(" mode:%o\n",buf->st_mode);
    //文件链接数
    printf(" links:%lu\n",buf->st_nlink);
    //用户所有者ID
    printf(" user:%d\n",buf->st_uid);
    //用户所有组ID
    printf(" group:%d\n",buf->st_gid);
    //文件所占字节数
    printf(" size:%lu\n",buf->st_size);
    //文件最后修改时间
    printf(" modtime:%lu\n",buf->st_mtime);
    printf(" name:%s\n",fname);
}

int main(int ac,char* av[]){
    struct stat info;
    if(ac>1){
        //stat直接读取信息,通过文件名获取文件信息,并保存在info所指的结构体stat中
        if(stat(av[1],&info)!=-1){
            show_stat_info(av[1],&info);
            return 0;
        }else{
            perror(av[1]);
        }
    }
    return 1;
}

ls1.c

/******************************************************** > File Name: ls1.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月07日 星期六 13时07分57秒 ********************************************************/
#include<stdio.h>
#include<sys/types.h>
#include<dirent.h>
void do_ls(char[]);

int main(int ac,char* av[]){
    if(ac==1){
        do_ls(".");
    }else{
        while(--ac){
            printf("%s:\n",*++av);
            do_ls(*av);
        }
    }
    return 0;
}
//注意,文件名只存储在目录中,文件结构体中并没有文件名
//do_ls函数读取目录,列出文件名
void do_ls(char dirname[]){
    DIR *dir_ptr;
    struct dirent* direntp;
    if((dir_ptr=opendir(dirname))==NULL){
        fprintf(stderr,"ls1:cannot open%s\n",dirname);
    }else{
        while((direntp=readdir(dir_ptr))!=NULL){
            printf("%s\n",direntp->d_name);
        }
        closedir(dir_ptr);
    }
}

ls2.c

/************************************************************ > File Name: ls2.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月07日 星期六 13时07分57秒 *************************************************************/
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<dirent.h>
#include<string.h>
#include<grp.h>
#include<pwd.h>
#include<time.h>

void do_ls(char[]);
void dostat(char*);
void show_file_info(char*,struct stat*);
void mode_to_letters(int,char[]);
char* uid_to_name(uid_t);
char* gid_to_name(gid_t);

int main(int ac,char* av[]){
    if(ac==1){
        do_ls(".");
    }else{
        while(--ac){
            printf("%s:\n",*++av);
            do_ls(*av);
        }
    }
    return 0;
}

void do_ls(char dirname[]){
    DIR *dir_ptr;
    struct dirent* direntp;
    if((dir_ptr=opendir(dirname))==NULL){
        fprintf(stderr,"ls1:cannot open%s\n",dirname);
    }else{
        while((direntp=readdir(dir_ptr))!=NULL){
            dostat(direntp->d_name);
        }
        closedir(dir_ptr);
    }
}

void dostat(char* filename){
    struct stat info;
    if(stat(filename,&info)==-1)
        perror(filename);
    else
        show_file_info(filename,&info);
}

void show_file_info(char* filename,struct stat* info_p){
    char modestr[11];
    //显示文件的属性,文件所有者、所属组、其他用户的读写执行权限
    mode_to_letters(info_p->st_mode,modestr);
    printf("%s",modestr);
    printf(" %4d",(int)info_p->st_nlink);
    printf(" %-8s",uid_to_name(info_p->st_uid));
    printf(" %-8s",gid_to_name(info_p->st_gid));
    printf(" %8lu",info_p->st_size);
    printf(" %.12s",4+ctime(&info_p->st_mtime));
    printf(" %s\n",filename);
}

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';
}
//获取uid对应的用户名
char* uid_to_name(uid_t uid){
    struct passwd* pw_ptr;
    static char numstr[10];
    if((pw_ptr=getpwuid(uid))==NULL){
        sprintf(numstr,"%d",uid);
        return numstr;
    }else{
        return pw_ptr->pw_name;
    }
}
//获取gid对应的组名
char* gid_to_name(gid_t gid){
    struct group* grp_ptr;
    static char numstr2[10];
    if((grp_ptr=getgrgid(gid))==NULL){
        sprintf(numstr2,"%d",gid);
        return numstr2;
    }else{
        return grp_ptr->gr_name;
    }
}