stat命令的实现-mysate

stat命令的实现

一、学习使用stat(1)

man 1 stat显示stat命令用法

  • stat -L:显示符号链接文件本身信息
  • stat -f:获取文件系统信息
  • stat -c FORMAT:获取所指定的文件属性

FORMAT

%A 用文件权限代码表示,如-rw-r--r--

%a 用八进制数字表示文件权限

%b 占用的区块数量

%B 用%b计算区块数量时,每一区块的大小,预设是512bytes

%D 用16进制表示设备编号

%d 用10进制表示设备编号

%F 文件形态,即文件类型

%f raw mode以16进制表示

%G 文件拥有者的组名

%g 文件拥有着的群组编号

%h 硬链接的数量

%i inode编号

%N 将符号链接的文件明和其指向的文件的文件名,用引号包含,'1.sh'->'h.sh'

%n 文件名

%o IO区块的大小,预设是4096bytes

%s 文件大小

%T 16进制表示Minor次要设备代码

%t 16进制表示Major主要设备代码

%U 文件拥有者的使用者名称

%u 文件拥有者的使用者编号

%X 取用时间,用1900.1.1至取用时间的秒数

%x 取用时间

%Y 修改时间,类似取用时间

%y 修改时间

%Z 属性改动时间

%z 属性改动时间

  • stat -t:以简洁方式显示

二、查找stat(2)

使用man -k stat | grep stat查看

使用man 2 stat查看函数

所需头文件:

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

结构体内容:

 struct stat {
               dev_t     st_dev;         /* ID of device containing file */
               ino_t     st_ino;         /* Inode number */
               mode_t    st_mode;        /* File type and mode */
               nlink_t   st_nlink;       /* Number of hard links */
               uid_t     st_uid;         /* User ID of owner */
               gid_t     st_gid;         /* Group ID of owner */
               dev_t     st_rdev;        /* Device ID (if special file) */
               off_t     st_size;        /* Total size, in bytes */
               blksize_t st_blksize;     /* Block size for filesystem I/O */
               blkcnt_t  st_blocks;      /* Number of 512B blocks allocated */

               /* Since Linux 2.6, the kernel supports nanosecond
                  precision for the following timestamp fields.
                  For the details before Linux 2.6, see NOTES. */

               struct timespec st_atim;  /* Time of last access */
               struct timespec st_mtim;  /* Time of last modification */
               struct timespec st_ctim;  /* Time of last status change */

           #define st_atime st_atim.tv_sec      /* Backward compatibility */
           #define st_mtime st_mtim.tv_sec
           #define st_ctime st_ctim.tv_sec
           };

三、伪代码

读取文件地址
if(传入参数不合法)
{
	在stderr中打印错误信息
}
else
{
	调用printfStatu函数打印
}

printfStatu
{
	switch(文件掩码)
	{
		判断文件类型
	}
	依次访问结构体打印信息
    通过getmod获取文件操作权限
    通过showtime打印日期
}

getmod
{
    switch(文件掩码)
	{
		判断文件操作权限
	}
}

shoutime
{
	调用gmttime并访问结构体打印时间
}

四、产品代码

华为云代码仓库

"head.h"

#ifndef HEAD_H_INCLUDED
#define HEAD_H_INCLUDED
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <time.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>
void printfStatu(struct stat* FileStatu,char* fileName);
void getmod(mode_t mode, char *line, int *pline);
void showtime(long localtime);
char *myGetUidName(uid_t uid);
char *myGteGidName(gid_t gid);
#endif // HEAD_H_INCLUDED

"main.c"

#include "head.h"

int main(int argc, char *argv[])
{
    struct stat* FileStatu;
    FileStatu = (struct stat*)malloc(sizeof(struct stat));
    if(argc == 1)
    {
        fprintf(stderr, "stat: missing operand\n");
        return 1;
    }
    else if(stat(argv[1],FileStatu) == -1)
    {
         perror("stat");
         return 1;
    }
    printfStatu(FileStatu, argv[1]);
    return 1;
}

printfStatu.c

#include "head.h"

void printfStatu(struct stat *FileStatu, char* fileName)
{
    char *FileType;
    switch (FileStatu->st_mode & S_IFMT)
    {
    case S_IFSOCK:
        FileType = "socket";
        break;

    case S_IFLNK:
        FileType = "link";
        break;

    case S_IFREG:
        FileType = "regular";
        break;

    case S_IFBLK:
        FileType = "block device";
        break;

    case S_IFDIR:
        FileType = "directory";
        break;

    case S_IFCHR:
        FileType = "character device";
        break;

    case S_IFIFO:
        FileType = "fifo";
        break;

    default:
        FileType = "unknown file type";
        break;
    }
    printf("  File: %s\n", fileName);
    printf("  SIZE: %lld\t\t\t", (long long)FileStatu->st_size);
    printf("Blocks: %lld\t\t", (long long)FileStatu->st_blocks);
    printf("IO Blcok: %ld\t", (long)FileStatu->st_blksize);
    printf("%s\n", FileType);
    printf("Device: %lxh/%ldd  ", FileStatu->st_dev,FileStatu->st_dev);
    printf("Inode: %ld  ", FileStatu->st_ino);
    printf("Links: %ld\n", (long)FileStatu->st_nlink);

    char *Authority = (char *)malloc(sizeof(char) * 11);
    int *AuthNum = (int *)malloc(sizeof(int)*4);
    getmod(FileStatu->st_mode, Authority,AuthNum);
    printf("Access: (%d%d%d%d/%s)  ",AuthNum[0],AuthNum[1],AuthNum[2],AuthNum[3], Authority);
    printf("Uid: (%ld/\t%s)\t", (long)FileStatu->st_uid,myGetUidName((uid_t)FileStatu->st_uid));
    printf("Gid: (%ld/\t%s)\n", (long)FileStatu->st_gid,myGteGidName((gid_t)FileStatu->st_gid));

    printf("Access: ");
    showtime(FileStatu->st_atime);

    printf("Modify: ");
    showtime(FileStatu->st_mtime);

    printf("Change: ");
    showtime(FileStatu->st_ctime);
    printf(" Birth: -\n");
}

getmod.c

#include "head.h"

void getmod(mode_t mode, char *line, int *pline) /*生成权限描述字符串*/
{
    memset(line, 0, sizeof(char) * 11);
    memset(pline,0,sizeof(int) * 4);
    switch (mode & S_IFMT){
        case S_IFLNK:
            strcat(line, "l");
         break;

         case S_IFDIR:
             strcat(line, "d");
             break;

        default:
             strcat(line, "-");
             break;

    }

 
	    if(((mode & S_IRWXU) & S_IRUSR)){
		     strcat(line, "r");
		     pline[1] += 4;
	    }
	    else{
		    strcat(line, "-");
                     pline[1] += 0;
	    }

	    if(((mode & S_IRWXU) & S_IWUSR)){
		     strcat(line, "w");
                     pline[1] += 2;
	    }
	    else{
		    strcat(line, "-");
                     pline[1] += 0;
	    }

	    if(((mode & S_IRWXU) & S_IXUSR)){
                     strcat(line, "x");
                     pline[1] += 1;
            }
	    else{
		     strcat(line, "-");
		     pline[1] += 0;
	    }

	    
            if((mode & S_IRWXG) & S_IRGRP){
                     strcat(line, "r");
                     pline[2] += 4;
            }
	    else{
                     strcat(line, "-");
                     pline[2] += 0;
            }

            if((mode & S_IRWXG) & S_IWGRP){
                     strcat(line, "w");
                     pline[2] += 2;
            }
	    else{
                     strcat(line, "-");
                     pline[2] += 0;
            }

            if((mode & S_IRWXG) & S_IXGRP){
                     strcat(line, "x");
                     pline[2] += 1;
            }
            else{
                     strcat(line, "-");
                     pline[2] += 0;
            }


            if((mode & S_IRWXO) & S_IROTH){
                     strcat(line, "r");
                     pline[3] += 4;
            }
	    else{
                     strcat(line, "-");
                     pline[3] += 0;
                }
            
	    if((mode & S_IRWXO) & S_IWOTH){
                     strcat(line, "w");
                     pline[3] += 2;
            }
	    else{
                     strcat(line, "-");
                     pline[3] += 0;
                }

            if((mode & S_IRWXO) & S_IXOTH){
                     strcat(line, "x");
                     pline[3] += 1;
            }
            else{
                     strcat(line, "-");
                     pline[3] += 0;
                }
}

myshowtime.c

#include "head.h"

void showtime(long localtime)
{
  struct tm *cp;
  cp = gmtime(&localtime);
  printf("%d-%d-%d %d:%d\n",cp -> tm_year+1900,cp ->tm_mon+1,cp -> tm_mday, ((cp -> tm_hour)+8)%24,cp ->tm_min);
}

“myGetGidName.c”

#include "head.h"
char *myGteGidName(gid_t gid){
	struct group *GName;
	GName = getgrgid(gid);
	char *GidName = GName -> gr_name;
	return GidName;
}

"myGetUidName.c"

#include "head.h"
char *myGetUidName(uid_t uid){
	struct passwd * UName;
	UName = getpwuid(uid);
	char *User = UName -> pw_name;
	return User;
}

五、测试代码

posted @ 2021-11-07 22:12  WangYuHan20191323  阅读(83)  评论(0编辑  收藏  举报