/* 命令who可输出,当前登录到主机的用户名、终端、登录时间 */ #include <stdio.h> #include <utmp.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <time.h> int main(int argc, char* argv[]) { int fp; struct tm *temp; struct utmp buf; time_t t1; char buf1[50]; int n = sizeof(struct utmp); //访问UTMP_FILE文件,即/var/run/utmp文件 fp = open(UTMP_FILE, O_RDONLY); //fp = open("/var/run/utmp", O_RDONLY); if (fp == -1) { perror("/var/run/umtp"); exit(1); } while (read(fp, &buf, n) == n) if (buf.ut_type == 7) { //将按秒时间转换为time_t格式时间 t1 = buf.ut_tv.tv_sec; //输出适当格式 temp = localtime(&t1); strftime(buf1, 50, "%F %R", temp); printf("%s\t%s\t%s\n", buf.ut_user, buf.ut_line, buf1); //printf("%s\t%s\t%s", buf.ut_user, buf.ut_line, ctime(&t1)); } close(fp); }
/* 此版本采用缓存机制,read_record函数,一次从文件中读取多个结构单元 */ #include <stdio.h> #include <utmp.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <time.h> #define NUM 16 int read_record(int fp, char* buf, int num) { int n; n = read(fp, buf, num*sizeof(struct utmp)); return n/sizeof(struct utmp); } int main(int argc, char* argv[]) { int fp; struct tm *temp; struct utmp *buf; time_t t1; char buf2[NUM*sizeof(struct utmp)]; char buf1[50]; int count, current; int n = sizeof(struct utmp); fp = open(UTMP_FILE, O_RDONLY); if (fp == -1) { perror("/var/run/umtp"); exit(1); } while ((count =read_record(fp, buf2, NUM)) != 0) { current = 0; while (count--) { buf = (struct utmp*)buf2+current*sizeof(struct utmp); if (buf->ut_type == 7) { t1 = buf->ut_tv.tv_sec; temp = localtime(&t1); strftime(buf1, 50, "%F %R", temp); printf("%s\t%s\t%s\n", buf->ut_user, buf->ut_line, buf1); } current++; } } close(fp); }
/* 模拟用户退出时,修改utmp文件 格式 logout username */ #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <utmp.h> #include <time.h> int main(int argc, char* argv[]) { int fd; struct utmp buf; int n; n = sizeof(struct utmp); if (argc == 1) { fprintf(stderr, "logout:missing file operand"); exit(1); } fd = open("utmp", O_RDWR); if (fd == -1) { perror("open failed"); exit(1); } while (read(fd, &buf, n) == n) if (buf.ut_type == 7 && (!strcmp(buf.ut_line, argv[1]))) { buf.ut_type = DEAD_PROCESS; if (time(&buf.ut_time) == -1) { perror("time update"); exit(1); } if (lseek(fd, -n, SEEK_CUR) == -1) { perror("lseek error"); exit(1); } if (write(fd, &buf, n) != n) { perror("write error"); exit(1); } break; } close(fd); return 0; }
总结:
时间处理函数,localtime和gtime,localtime会考虑时区,gtime则不会,gtime可能导致时间晚几个(8个)小时。