Linux系统调用六、stat函数与 struct stat 文件信息结构体深度刨析(三)

简介: Linux系统调用六、stat函数与 struct stat 文件信息结构体深度刨析

🎈4. 实现 ls -l filename命令

我们可以通过stat函数来实现 ls -l 命令的功能,下面我们实现查看指定文件的 ls -l 命令,即

ls -l filename

实现代码如下

/************************************************************
  >File Name  : mls.c
  >Author     : QQ
  >Company    : QQ
  >Create Time: 2022年05月15日 星期日 16时29分01秒
  >实现目标:-rw-r--r--. 2 root root 11 5月  14 15:02 file.txt
************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>
int main(int argc, char* argv[])
{
  if(argc < 2)
  {
    printf("not found filename\n");
    return -1;
  }
  /*通过stat函数获取文件信息*/
  struct stat fstatus;
  stat(argv[1], &fstatus); /*穿透*/
    /*lstat(argv[1], &fstatus); 非穿透 */
  /*解析文件信息,st_mode st_uid st_gid time*/
  /*-rw-r--r--.*/
  char stmode[11];
  memset(stmode, '-', sizeof(stmode));
  /*使用宏来判断文件属性*/
  if(S_ISREG(fstatus.st_mode)) /* regular file */
  {
    stmode[0] = '-';
  }
  if(S_ISDIR(fstatus.st_mode))
    {
    stmode[0] = 'd';
  }
  if(S_ISCHR(fstatus.st_mode))
  {
    stmode[0] = 'c';
  }
  if(S_ISBLK(fstatus.st_mode))
  {
    stmode[0] = 'b';
  }
    if(S_ISFIFO(fstatus.st_mode))
  {
    stmode[0] = 'p';
  }
  if(S_ISLNK(fstatus.st_mode))
  {
    stmode[0] = 'l';
  }      
  if(S_ISSOCK(fstatus.st_mode))
  {
    stmode[0] = 's';
  }
  /*解析权限位*/
  if(fstatus.st_mode & S_IRUSR) 
  {/*为真表示拥有该权限,否则无权限,因为整块内存已初始化为 - 所以不需要else分支*/
    stmode[1] = 'r';
  }
  if(fstatus.st_mode & S_IWUSR) 
  {
    stmode[2] = 'w';
  }
  if(fstatus.st_mode & S_IXUSR) 
  {
    stmode[3] = 'x';
  }
  if(fstatus.st_mode & S_IRGRP) 
  {
    stmode[4] = 'r';
  }
  if(fstatus.st_mode & S_IWGRP) 
  {
    stmode[5] = 'w';
  }
  if(fstatus.st_mode & S_IXGRP) 
  {
    stmode[6] = 'x';
  }
  if(fstatus.st_mode & S_IROTH) 
  {
    stmode[7] = 'r';
  }
  if(fstatus.st_mode & S_IWOTH) 
  {
    stmode[8] = 'w';
  }
  if(fstatus.st_mode & S_IXOTH) 
  {
    stmode[9] = 'x';
  }
  stmode[10] = '\0';
  /*获取时间  localtime() 函数(非系统调用)
  *原型:struct tm *localtime(const time_t *timep);
  *参数:time_t类型,struct stat中time_t st_atime,这里应该是文件访问时间
  *返回:struct tm {
               int tm_sec;          seconds (0-60 )
               int tm_min;          minutes (0-59) 
               int tm_hour;         hours (0-23) 
               int tm_mday;         day of the month (1-31) 
               int tm_mon;          month (0-11) 
               int tm_year;         year (-1900)  如果要求实际年份,应加上1990
               int tm_wday;         day of the week sunday=0
               int tm_yday;         day in the year 
               int tm_isdst;        daylight saving time 
           };
  */
  struct tm* filetime = localtime(&fstatus.st_atim.tv_sec);
  char timebuf[20] = {0};
  sprintf(timebuf, "%d月  %d %02d:%02d", \
          filetime->tm_mon + 1, \
          filetime->tm_mday, \
          filetime->tm_hour, \
          filetime->tm_min);
  /*打印格式 -rw-r--r--. 2 root root 11 5月  14 15:02 file.txt*/
  printf("%s %ld %s %s %ld %s %s\n", \
      stmode, \
      fstatus.st_nlink, \
      getpwuid(fstatus.st_uid)->pw_name, \
      getgrgid(fstatus.st_gid)->gr_name, \
      fstatus.st_size, \
      timebuf, \
      argv[1]);
  /* 两个函数(非系统调用)
  struct passwd *getpwuid(uid_t uid); 根据uid获取用户信息
  struct passwd {
               char   *pw_name;        username 
               char   *pw_passwd;      user password 
               uid_t   pw_uid;         user ID 
               gid_t   pw_gid;         group ID 
               char   *pw_gecos;       real name 
               char   *pw_dir;         home directory 
               char   *pw_shell;       shell program 
           };
   struct group *getgrgid(gid_t gid); 根据gid获取组信息
   struct group {
               char   *gr_name;        group name 
               char   *gr_passwd;      group password 
               gid_t   gr_gid;         group ID 
               char  **gr_mem;         group members 
           };
  */
  return 0;
}

测试一下效果

🎈5. 穿透与非穿透

上面介绍了stat函数并通过stat函数实现了 ls -l 命令的功能。我们上面演示了使用自己实现的 ./mls 查看文件信息,假如说使用 ./mls 查看一个链接文件是什么效果呢,下面演示一下。

通过对比我们可以看到,符号链接(软链接)file.txt.soft的实际大小是8,但是我们自己实现的 ./mls 命令显示的大小是11。实际上,原因是这样的,我们在实现 ./mls 命令的时候是基于stat函数来获取文件信息的,stat函数有一个特性就是在获取链接文件信息的时候会进行穿透,去追溯符号链接的源文件,也就是说我们通过上面的命令 ./mls file.txt.soft 获取到的大小实际上是源文件file.txt的大小,我们可以验证一下。

那么我们自己如何实现获取符号链接的实际大小呢,这就用到了非穿透函数lstat,只要把上面代码实现中的函数调用stat替换为lstat就可以了,下面测试一下。

lstat(argv[1], &fstatus);

相关文章
|
3天前
|
Linux Shell 网络安全
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
本指南介绍如何利用 HTA 文件和 Metasploit 框架进行渗透测试。通过创建反向 shell、生成 HTA 文件、设置 HTTP 服务器和发送文件,最终实现对目标系统的控制。适用于教育目的,需合法授权。
24 9
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
|
1月前
|
Linux 开发工具 Perl
在Linux中,有一个文件,如何删除包含“www“字样的字符?
在Linux中,如果你想删除一个文件中包含特定字样(如“www”)的所有字符或行,你可以使用多种文本处理工具来实现。以下是一些常见的方法:
41 5
|
1月前
|
安全 Linux 数据安全/隐私保护
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。本文介绍了使用 `ls -l` 和 `stat` 命令查找文件所有者的基本方法,以及通过文件路径、通配符和结合其他命令的高级技巧。还提供了实际案例分析和注意事项,帮助读者更好地掌握这一操作。
47 6
|
1月前
|
Linux
在 Linux 系统中,`find` 命令是一个强大的文件查找工具
在 Linux 系统中,`find` 命令是一个强大的文件查找工具。本文详细介绍了 `find` 命令的基本语法、常用选项和具体应用示例,帮助用户快速掌握如何根据文件名、类型、大小、修改时间等条件查找文件,并展示了如何结合逻辑运算符、正则表达式和排除特定目录等高级用法。
74 6
|
1月前
|
监控 Linux Perl
Linux 命令小技巧:显示文件指定行的内容
在 Linux 系统中,处理文本文件是一项常见任务。本文介绍了如何使用 head、tail、sed 和 awk 等命令快速显示文件中的指定行内容,帮助你高效处理文本文件。通过实际应用场景和案例分析,展示了这些命令在代码审查、日志分析和文本处理中的具体用途。同时,还提供了注意事项和技巧,帮助你更好地掌握这些命令。
49 4
|
1月前
|
网络协议 Linux
linux系统重要文件目录
本文介绍了Linux系统中的重要目录及其历史背景,包括根目录、/usr、/etc、/var/log和/proc等目录的结构和功能。其中,/etc目录下包含了许多关键配置文件,如网卡配置、DNS解析、主机名设置等。文章还详细解释了各目录和文件的作用,帮助读者更好地理解和管理Linux系统。
55 2
|
1月前
|
缓存 监控 Linux
|
Linux Perl
LINUX获取当前用户及信息的命令
LINUX获取当前用户及信息的命令
135 0
|
28天前
|
Linux 网络安全 数据安全/隐私保护
Linux 超级强大的十六进制 dump 工具:XXD 命令,我教你应该如何使用!
在 Linux 系统中,xxd 命令是一个强大的十六进制 dump 工具,可以将文件或数据以十六进制和 ASCII 字符形式显示,帮助用户深入了解和分析数据。本文详细介绍了 xxd 命令的基本用法、高级功能及实际应用案例,包括查看文件内容、指定输出格式、写入文件、数据比较、数据提取、数据转换和数据加密解密等。通过掌握这些技巧,用户可以更高效地处理各种数据问题。
69 8
|
28天前
|
监控 Linux
如何检查 Linux 内存使用量是否耗尽?这 5 个命令堪称绝了!
本文介绍了在Linux系统中检查内存使用情况的5个常用命令:`free`、`top`、`vmstat`、`pidstat` 和 `/proc/meminfo` 文件,帮助用户准确监控内存状态,确保系统稳定运行。
189 6