【问题标题】:Time a user spent online using wtmp用户使用 wtmp 在线花费的时间
【发布时间】:2013-12-25 00:43:09
【问题描述】:

在使用 wtmp 时,我能够获取用户登录的 tty、登录时间和更多信息。但是,我希望能够知道用户在网上花费了多少时间。有没有办法获取注销时间?

谢谢,

#define WTMP "/var/log/wtmp"
#define K               1024

int main()
{
 struct utmp w;
 FILE *fd;
 time_t t;
 struct tm *timeinfo;
 char buffer[K];

 fd = fopen(WTMP, "r");

 if(fd == NULL) {
    fprintf(stderr, "cannot open %s\n", WTMP);
    exit(0);
 }

 while(fread(&w, sizeof(struct utmp), 1, fd) == 1) {
    if(w.ut_type == USER_PROCESS) {
        if( strcmp(w.ut_user, "user1") == 0) {

        /* get time in seconds, convert to struct tm, make printable formate*/
        t = w.ut_tv.tv_sec;
        timeinfo = localtime (&t);

        strftime (buffer, K, "%a %b %e %R (EST)", timeinfo);
        printf("time: %s  Login tty: %s\n", buffer, w.ut_line);

        }
    }
 } 
 fclose(fd);
}

【问题讨论】:

    标签: c login time logout


    【解决方案1】:

    来自“last”命令的源代码,您可以从http://ftp.de.debian.org/debian/pool/main/s/sysvinit/sysvinit_2.88dsf.orig.tar.gz 下载(下载后解压并检查sysvinit-2.88dsf/src/last.c):

        case USER_PROCESS:
            /*
             *  This was a login - show the first matching
             *  logout record and delete all records with
             *  the same ut_line.
             */
            c = 0;
            for (p = utmplist; p; p = next) {
                next = p->next;
                if (strncmp(p->ut.ut_line, ut.ut_line,
                    UT_LINESIZE) == 0) {
                    /* Show it */
                    if (c == 0) {
                        quit = list(&ut, p->ut.ut_time,
                            R_NORMAL);
                        c = 1;
                    }
                    if (p->next) p->next->prev = p->prev;
                    if (p->prev)
                        p->prev->next = p->next;
                    else
                        utmplist = p->next;
                    free(p);
                }
            }
            /*
             *  Not found? Then crashed, down, still
             *  logged in, or missing logout record.
             */
            if (c == 0) {
                if (lastboot == 0) {
                    c = R_NOW;
                    /* Is process still alive? */
                    if (ut.ut_pid > 0 &&
                        kill(ut.ut_pid, 0) != 0 &&
                        errno == ESRCH)
                        c = R_PHANTOM;
                } else
                    c = whydown;
                quit = list(&ut, lastboot, c);
            }
    

    【讨论】:

    • 感谢您的宝贵时间。我对这些东西还很陌生。我尝试了 ut_line 并获得了登录/注销的 tty,这是否意味着每个 2 个相同的 tty 都是登录和注销?
    • 是的 - 一旦用户登录到一个 tty,这个 tty 就会被用户“阻止”,所以唯一可能发生的事情就是用户再次注销。当然,如果系统崩溃,或者硬盘有写入错误,或者用户只是没有注销,您将看不到任何注销记录。这就是第二部分(在评论之后)的目的。
    • 我尝试了 ut_line 来获取注销/登录时间。但是,尽管用户未登录,但我得到了许多尚未关闭的 tty。
    • 在您的系统上运行“last”命令。将其输出与您的程序进行比较。如果标准的最后一条命令也显示仍然登录,那么您的系统中发生了一些事情,阻止了注销记录被写入。如果 last 的输出显示注销时间,请检查您的程序忽略相应 wtmp 记录的原因。
    • 显然没有 2 个相同的 tty 来指示登录/注销。每个 tty 都有一个注销/登录。 “最后”输出的一部分:user1 pts/3 Sat 12 月 7 日 14:14 仍然登录…… user1 pts/18 Sat 12 月 7 日 14:01 - 14:13 (00:12)。如果我已经知道 tty 和登录时间,对如何获取注销时间有任何想法吗?
    猜你喜欢
    • 2011-07-22
    • 1970-01-01
    • 1970-01-01
    • 2019-05-26
    • 1970-01-01
    • 2014-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多