#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <lastlog.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <pwd.h>
const char* LASTLOG_FILE = "/var/log/lastlog";
static void print_one(const char* uname, const struct lastlog* log)
{
printf("%s", uname);
if (!log->ll_line[0] && !log->ll_host[0]){
printf(" ** NEVER logged in **\n");
}else{
printf(" logged in from %s at %s on %s\n",
log->ll_line, log->ll_host, ctime(&log->ll_time));
}
}
static void usage(const char* prog)
{
printf("Usage:%s username\n", prog);
exit(0);
}
int main(int argc, char* argv[])
{
int user_id;
struct lastlog log;
struct stat statbuf;
FILE* fp;
struct passwd* passwd;
// calculate the offset
if (argc != 2)
usage(argv[0]);
passwd = getpwnam(argv[1]);
if (passwd == NULL){
printf("User [%s] not found\n", argv[1]);
return -1;
}
off_t offset = passwd->pw_uid *sizeof(log);
fp = fopen(LASTLOG_FILE, "rb");
if (fp == NULL) {perror("fopen"); return -1;}
if (fstat (fileno(fp), &statbuf)) {
perror("fstat");
return -1;
}
// check if the file is large enough
if (offset >= statbuf.st_size)
return -1;
// seek to the offset
fseek (fp, offset, SEEK_SET);
// read in the struct
if (fread ((char *) &log, sizeof(log), 1, fp) == 1)
print_one(argv[1], &log);
else
perror (LASTLOG_FILE);
return 0;
}
struct lastlog
{
#if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
int32_t ll_time;
#else
__time_t ll_time;-- 时间
#endif
char ll_line[UT_LINESIZE]; --哪个终端
char ll_host[UT_HOSTSIZE]; --哪个主机
};