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;
}