点击(此处)折叠或打开
-
/*
-
*【带缓冲who命令简单实现】
-
*who:用来查看当前有哪些用户登录到了本台机器上。
-
*添加 whats_my_line支持who am i命令
-
*/
-
#include<stdio.h>
-
#include<stdlib.h>
-
#include<fcntl.h>
-
#include<utmp.h>
-
#include<time.h>
-
-
#define UTMP_SIZE (sizeof(struct utmp))
-
#define UTMP_NRECS 16
-
-
char utmp_buf[UTMP_NRECS*UTMP_SIZE];
-
-
int cur_rec = 0; //当前记录
-
int num_recs = 0; //记录个数
-
-
struct utmp * utmp_next(int fd_utmp);
-
int utmp_reload(int fd_utmp);
-
-
char * whats_my_line(int fd);
-
void show_info(struct utmp * utbuf_fp);
-
-
-
int main(int argc,char *argv[])
-
{
-
int fd_utmp;
-
char *my_line = NULL;
-
-
if(argc == 3) //who am i情况
-
my_line = whats_my_line(0);
-
-
if( (fd_utmp = open(UTMP_FILE,O_RDONLY)) == -1)
-
{
-
perror("open UTMP_FILE failed");
-
exit(1);
-
}
-
-
struct utmp * utmp_p;
-
while( (utmp_p = utmp_next(fd_utmp)) != NULL)
-
{
-
if(my_line == NULL || strcmp(utmp_p->ut_line,my_line) == 0)
-
show_info(utmp_p);
-
}
-
-
if(close(fd_utmp) == -1 )
-
{
-
perror("close file failed");
-
exit(1);
-
}
-
return 0;
-
}
-
-
struct utmp * utmp_next(int fd_utmp)
-
{
-
if( (cur_rec == num_recs) && (utmp_reload(fd_utmp)==0) ) //缓冲区数据取完
-
return (struct utmp *)NULL;
-
-
return (struct utmp *)&utmp_buf[cur_rec++ * UTMP_SIZE]; //下一个记录
-
}
-
-
int utmp_reload(int fd_utmp)
-
{ //缓冲区数据读取完,重新放数据到缓冲区utmp_buf
-
cur_rec = num_recs = 0;
-
int bytes_r = read(fd_utmp,utmp_buf,UTMP_SIZE*UTMP_NRECS);
-
if(bytes_r == -1)
-
{
-
perror("read failed");
-
return 0;
-
}
-
num_recs = bytes_r / UTMP_SIZE;
-
-
return num_recs;
-
}
-
-
char * whats_my_line(int fd)
-
{ //获取当前终端名称
-
char * tty_name;
-
if( tty_name = ttyname(fd) )
-
{
-
printf("%s\n",tty_name);
-
if( strncmp("/dev/",tty_name,5) == 0 )
-
tty_name += 5;
-
}
-
return tty_name;
-
}
-
-
void show_info(struct utmp * utbuf_fp)
-
{
-
if(utbuf_fp->ut_type != USER_PROCESS)//没有登录的用户
-
return;
-
printf("%-8.8s ",utbuf_fp->ut_name);
-
printf("%-8.8s ",utbuf_fp->ut_line);
-
printf("%s",ctime(&utbuf_fp->ut_time));//ctime转换后带\n
-
- }