#include
#include
#include
#include
int main()
{
struct utmp *p_utent;
long t;
setutent();
while((p_utent = getutent()) != NULL){
//getutent()每次讀一個struct utmp結構體
if(p_utent->ut_type != USER_PROCESS)
continue;
printf("%s\t", p_utent->ut_user);
printf("%s\t", p_utent->ut_line);
t = p_utent->ut_tv.tv_sec;
printf("%.20s\t", ctime(&t) + 4);
printf("(%s)\n", p_utent->ut_host);
}
endutent();
return 0;
}
/var/run/utmp -- database of currently logged-in users
/var/log/wtmp -- database of past user logins
(utmp文件中保存的是當前正在本系統中的用戶的信息。wtmp文件中保存的是登錄過本系統的用戶的信息)
它們保存的信息是基於下面的結構體struct utmp的(/usr/include/bits/utmp.h):
struct exit_status
{
short int e_termination;
short int e_exit;
};
struct utmp
{
short int ut_type;
pid_t ut_pid;
char ut_line[UT_LINESIZE];
char ut_id[4];
char ut_user[UT_NAMESIZE];
char ut_host[UT_HOSTSIZE];
struct exit_status ut_exit;
#if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
int32_t ut_session;
struct
{
int32_t tv_sec;
int32_t tv_usec;
} ut_tv;
#else
long int ut_session;
struct timeval ut_tv;
#endif
int32_t ut_addr_v6[4];
char __unused[20];
};
#define EMPTY 0
#define RUN_LVL 1
#define BOOT_TIME 2
#define NEW_TIME 3
#define OLD_TIME 4
#define INIT_PROCESS 5
#define LOGIN_PROCESS 6
#define USER_PROCESS 7
#define DEAD_PROCESS 8
#define ACCOUNTING 9
而讀取和修改這些文件的函數如下:
#include
struct utmp *getutent(void);
//函數從文件utmp中,每次讀取一個struct utmp的結構體。讀取失敗返回NULL
struct utmp *getutid(struct utmp *ut);
struct utmp *getutline(struct utmp *ut);
struct utmp *pututline(struct utmp *ut);
void setutent(void);// 函數打開文件utmp,並且將文件指針指向文件的最開始
void endutent(void);// 函數關閉文件utmp
int utmpname(const char *file);
utmpname()函數設定utmp文件所在的路徑,默認的路徑爲宏 _PATH_UTMP,該宏定義在/usr/include/paths.h中:
#define _PATH_UTMP "/var/run/utmp"
pututline() //函數將一個struct utmp結構體寫進文件utmp中