解析wtmp文件记录以C(Parsing wtmp logs with C)

2019-09-30 04:38发布

对于我们的任务,我们都给予了副本wtmp记录,并有望解析它,并把它输出的排序格式,类似于输出last

现在,我知道该文件wtmp由列表的utmp结构。 所提供的文件是保证至少包含一个utmp的结构,我应该承担的二进制文件中的所有结构构建正确。

我已经通过阅读man utmp ,我已经成功地写了一个程序,从提供的二进制文件中的结构来读取。 (我对冗长的印刷方法的道歉)

#include <stdio.h>
#include <string.h>
#include <utmp.h>
#include <stdlib.h>

void utmpprint(struct utmp *log);

int main() {

    int logsize = 10;
    FILE *file;
    struct utmp log[logsize];
    int i = 0;

    file = fopen("wtmp", "rb");

    if (file) {
            fread(&log, sizeof(struct utmp), logsize, file);
            for(i = 0; i < logsize; i++) {
                    utmpprint(&log[i]);
            }
    } else {
            return(0);
    }
    return(0);
}


void utmpprint(struct utmp *log) {
    printf("{ ut_type: %i, ut_pid: %i, ut_line: %s, ut_id: %s,
        ut_user: %s, ut_host:   %s, ut_exit: { e_termination: %i,
        e_exit: %i }, ut_session: %i, timeval: { tv_sec: %i, tv_usec: %i },
        ut_addr_v6: %i }\n\n", log->ut_type, log->ut_pid, log->ut_line,
        log->ut_id, log->ut_user, log->ut_host, log->ut_exit.e_termination,
        log->ut_exit.e_exit, log->ut_session, log->ut_tv.tv_sec,
        log->ut_tv.tv_usec, log->ut_addr_v6);
}

现在,我遇到的问题是,当我运行此,输出为ut_id比我期望它是不同的。

来源: man utmp

char ut_id[4];      /*Terminal name suffix, or inittab(5) ID */

我的输出:

... ut_line: pts/2, ut_id: ts/2jsmith, ut_user: jsmith, ...

我不太清楚是怎么回事。 我想可能发生的是,ut_id场只是可能不在,我读的结构存在。我认为这或许可以解释为什么它挤压在一起ut_id领域正在被显示的字段两侧。

我想我可能用格式fprintf中获取字段才能正确显示,但似乎你只能格式的文本字符数组的一侧或另一侧,而不是从字符串中抓取特定部分。

否则,我几乎失去了。 这只是在我的结构的理解差距?

不是为了寻找答案,更何况只是在正确的方向上的一些打回原形。

此外,究竟什么是终端后缀名? 那是刚过后面的数pts/

Answer 1:

男人的utmp说:“字符串字段由空字节(‘\ 0’),如果他们是不是字段的大小更短的终止。” 因此,特别是,如果它们是相同大小的字段,则它们不是由一个空字节终止。 那么形成C字符串必须以空字节终止。 它看起来像一个事实ut_id字段是4个字符长的“TS / 2”,这表明它没有终止空字节。

你打印使用%S格式参数的字符数组printf 。 这使打印,直到它到达一个空字节。 我建议你需要在每个字段复制utmp到一个临时字符数组,这比规模更大的一个 utmp结构。 确保临时数组的最后一个字节是一个空字节,它应该打印出来确定。



文章来源: Parsing wtmp logs with C