使用C解析wtmp日志

对于我们的赋值,我们得到一个wtmp日志的副本,并期望解析它,并以排序的格式输出它,类似于last的输出。

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

我通过man utmp阅读,并且我已成功编写了一个程序来读取所提供的二进制文件的结构。 (我为漫长的打印方法道歉)

 #include  #include  #include  #include  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 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”表明它没有终止空字节。

您正在使用%s格式化参数将printf数组打印到printf 。 这样可以保持打印直到达到空字节。 我建议你需要将utmp每个字段复制到一个临时字符数组,这个数组 utmp结构中的字符 。 确保该临时数组的最后一个字节是空字节,并且应该打印出OK。