写这博客只是为了理清个人的思路以渡过学习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
文件里除了一堆函数声明,就只有上面这些东东了。
打开上面两个头文件,并没什么有价值的东西,这里就不提了。而下面的四个宏,很明显是一个路径来的。那好,我们先记住它,等下一定要看下他记的是什么路径。
下面,我们先进入,
这里定义了一个叫 utmp 的结构体。再看下他们成员,可以肯定,他就是记录登录信息的结构体了。
其中 ut_user : 用户名(下面也有将他#define ut_name ut_user)
ut_line : 终端号
ut_tv : 登录时间(登录时间,64位和32位他执行的语句不同,但是事实上效果是差不多一样的。所以不用理会。)
ut_host : 主机号
另外,我们来看下他包含的头文件。我们还有一个名为_PATH_UTMP 的路径未找到,我们就到
恩,它记录的就是我们man who时,联机帮助里说的who命令要读取的文件。
好。到现在,已经大概知道who命令是怎么执行的了。who 命令就是读取文件 "/var/rum/utmp" ,然后显示出来,而且,它是通过保存结构体 struct utmp 来保存的。所以我们读取时,也要通过这个结构体来读取。好。现在我们就来正式开始写程序吧。
1 #include2 #include 3 #include 4 #include 5 #include 6 #include 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, ¤t_record, reclen) == reclen) { 20 show_info(¤t_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 效果是一样的。