对于我们的任务,我们得到了一份wtmp日志的副本,并希望对其进行解析,然后以类似于last的输出的排序格式输出它。
现在,我知道文件wtmp由一系列utmp结构组成。提供的文件保证包含至少一个utmp结构,我假设二进制文件中的所有结构都是正确构造的。
我已经通过man utmp进行了读取,并且我已经成功地编写了一个程序来从所提供的二进制文件中读取结构。(很抱歉使用了冗长的print方法)
#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/之后的数字吗?
发布于 2012-06-19 09:29:47
man utmp说:“如果字符串字段比字段的大小短,则以空字节('\0')终止。”因此,特别是,如果它们与字段的大小相同,则它们不会以空字节结束。格式正确的C字符串必须以空字节结尾。事实上,ut_id字段看起来有4个字符的长度"ts/2“,这表明它没有终止空字节。
您正在使用printf的%s格式化参数打印字符数组。这将继续打印,直到它达到空字节。我建议您需要将utmp的每个字段复制到一个临时字符数组中,该数组比utmp结构中的大小大一。确保临时数组的最后一个字节是空字节,它应该打印出OK。
https://stackoverflow.com/questions/11093218
复制相似问题