CentOS命令的简单实现(1):who命令

 

写这博客只是为了理清个人的思路以渡过学习Linux的前期,另外也想给博客园服务器加点压力,所以各位大牛请飘过。

今天又是一年一度的开学日,一大群师妹送进来,就要到嘴了。我却和舍友在宿舍对着那些个字符,而且时不时还因为自己犯的某些逗B错误爆个粗。虽然我没说,但你们知道我有多痛心吗?唉,不说了,我有双手就好,让我的双手带我装逼带我飞吧!!! ^_^

(1).who 实现了什么功能?

  

  一个不带选项的who就是列出当前登陆的用户,第1列是用户名,第2列是终端名,第3列是登录时间,第4列是登录地址。

(2).who是怎么实现的呢?

  我们先来man 一下吧。在man的最后,可以看到,

  

  默认情况下,它是通过将utmp文件的内容读出来,来实现这个指令的。那么,utmp这个文件,肯定保存有这些数据。

  

  这样的话,我们不访用 utmp 做为关键词搜索一下联机帮助。

  

  在倒数第四行的说明处, "login records", 应该就是我们要的。再去 man 一下。

  man 5 utmp

  

  其中有提到 utmp.h 这个头文件。

 

  那我们不访来打开这个头文件来看一下。vi /usr/include/utmp.h

  

  文件里除了一堆函数声明,就只有上面这些东东了。

  打开上面两个头文件,并没什么有价值的东西,这里就不提了。而下面的四个宏,很明显是一个路径来的。那好,我们先记住它,等下一定要看下他记的是什么路径。

  下面,我们先进入,<bits/utmp.h> 里看看。

  

  这里定义了一个叫 utmp 的结构体。再看下他们成员,可以肯定,他就是记录登录信息的结构体了。

  其中 ut_user : 用户名(下面也有将他#define ut_name ut_user)

    ut_line   : 终端号

    ut_tv   : 登录时间(登录时间,64位和32位他执行的语句不同,但是事实上效果是差不多一样的。所以不用理会。)

    ut_host  : 主机号

  

  

  另外,我们来看下他包含的头文件。我们还有一个名为_PATH_UTMP 的路径未找到,我们就到<paths.h>里找找吧。

  

  恩,它记录的就是我们man who时,联机帮助里说的who命令要读取的文件。

 

  好。到现在,已经大概知道who命令是怎么执行的了。who 命令就是读取文件 "/var/rum/utmp" ,然后显示出来,而且,它是通过保存结构体 struct utmp 来保存的。所以我们读取时,也要通过这个结构体来读取。好。现在我们就来正式开始写程序吧。

 1 #include <stdlib.h>
 2 #include <stdio.h>
 3 #include <utmp.h>
 4 #include <fcntl.h>
 5 #include <unistd.h>
 6 #include <time.h>
 7 
 8 #define SHOWHOST
 9 
10 void show_info(struct utmp * utbufp);
11 int main(int argc, char *argv[]) {
12     struct utmp current_record;
13     int reclen = sizeof(current_record);
14     int utmpfd;
15     if ((utmpfd = open(UTMP_FILE ,O_RDONLY)) == -1) {
16         perror(UTMP_FILE);
17         exit(1);
18     }
19     while (read(utmpfd, &current_record, reclen) == reclen) {
20         show_info(&current_record);
21     }
22     close(utmpfd);
23 
24     return 0;
25 }
26 
27 void show_info(struct utmp *utbufp) {
28     if (utbufp->ut_type != USER_PROCESS) {
29         return;
30     }
31     printf("%-8s", utbufp->ut_name);
32     printf(" ");
33     printf("%-8s", utbufp->ut_line);
34     printf(" ");
35     struct tm *login_time;
36     login_time = localtime(&(utbufp->ut_xtime));
37     printf("%04d", login_time->tm_year + 1900);
38     printf("-");
39     printf("%02d", login_time->tm_mon + 1);
40     printf("-");
41     printf("%02d", login_time->tm_mday);
42     printf(" ");
43     printf("%02d", login_time->tm_hour);
44     printf(":");
45     printf("%02d", login_time->tm_min);
46     printf(" ");
47 #ifdef SHOWHOST
48     printf("(%s)", utbufp->ut_host);
49 #endif
50     printf("\n");
51 }

 

  28~30行 : 是为将不是用户登录记录的行去掉。(默认有些空白记录,和系统登陆记录)

  36行    : 用到函数 localtime,man一下它,它的原型是:

       返回一个struct tm。联机帮助下方,有给struct tm的定义

        

       

       而且tm_year是从1900年开始算的,所以要 +1900, tm_mon值的范围是0~11,所以要 +1。

 

  编译后,进行,就可以看到,我们写的简单版的who, 和系统命令who 效果是一样的。

  

 

转载于:https://www.cnblogs.com/hyhvirgil/p/3971558.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值