c - 用 C 解析 wtmp 日志

标签 c file-io struct fread

对于我们的作业,我们得到了一份 wtmp 日志的副本,我们希望对其进行解析,并以排序格式输出它,类似于 last 的输出>.

现在,我知道文件 wtmputmp 结构列表组成。提供的文件保证至少包含一个 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 格式化来使字段正确显示,但似乎您只能将文本格式化为 char 数组的一侧或另一侧,而不能从字符串内部获取特定部分。

否则,我会很迷茫。这只是我对结构理解的差距吗?

不是在寻找答案,更多的是朝着正确的方向努力。

另外,终端名称后缀到底是什么?这只是 pts/ 之后的数字吗?

最佳答案

man utmp说“如果字符串字段短于字段的大小,则字符串字段以空字节 ('\0') 终止。”因此,特别是,如果它们与字段的大小相同,则它们不会以空字节终止。格式良好的 C 字符串必须以空字节结尾。 ut_id 字段看起来是 4 个字符长的“ts/2”这一事实表明它没有终止空字节。

您正在使用 printf 的 %s 格式化参数打印字符数组。这会一直打印直到到达空字节。我建议你需要将utmp的每个字段复制到一个临时的char数组中,该数组比utmp结构中的大小 .确保该临时数组的最后一个字节是空字节,它应该打印出来。

关于c - 用 C 解析 wtmp 日志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11093218/

相关文章:

python - 在Python中写入txt文件的最快方法

swift - 如何断言结构符合协议(protocol)?

c - 关于 fork() 的问题

c - 接收特定消息的socket编程C

c++ - 具有重叠 I/O 的 FILE_FLAG_NO_BUFFERING - 字节读为零

c++ - 文件 I/O 行尾

c - 如何用C计算ISBN?

c - 解释这个 C 程序的输出?

c++ - "error: no matching function for call to"构造未初始化的结构时

Go - 实例化结构并获取指向它的指针的 "&MyStruct{1, 2}"语法何时有用?