用C解析wtmp日志 [英] Parsing wtmp logs with C

查看:372
本文介绍了用C解析wtmp日志的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于我们的任务,我们得到了一个 wtmp log的副本,并且需要对它进行解析,并以排序后的格式输出,类似于 last



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



我读过 man utmp ,并且我已经成功地编写了一个程序来从所提供的二进制文件中读取结构。 (对于冗长的打印方法,我很抱歉)

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

void utmpprint(struct utmp * log);

int main(){

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

file = fopen(wtmp,rb); (文件){
fread(& log,sizeof(struct utmp),logsize,file);


for(i = 0; i< logsize; i ++){
utmpprint(& log [i]);
}
} else {
return(0);
}
return(0);


$ b 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,$ b $ e_exit:%i},ut_session:%i,timeval:{tv_sec:%i,tv_usec :%i},
ut_addr_v6:%i} \\\
\\\
,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]; / *终端名称后缀或inittab(5)ID * / 

我的输出:

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

我不太确定这里发生了什么。我认为可能会发生ut_id字段可能不存在于我正在阅读的结构中。我认为这可能解释了为什么ut_id字段显示为两边的字段压扁在一起。



我以为我可以使用fprintf格式来正确显示字段,但是您似乎只能将文本格式化为字符数组的一边,而不是抓取从字符串内部的特定部分。



否则,我很迷路。这只是在我的理解结构的差距?

不寻找答案,更多的只是在正确的方向prodding。

另外,终端名称后缀究竟是什么?这只是后面的数字 pts /

解决方案

man utmp 说:字符串字段由一个空字节('\ 0')结束if他们比这个领域的规模还要短。所以,特别是,如果它们与字段的大小相同,那么它们不是以空字节结尾的。格式良好的C字符串必须以空字节结尾。它看起来像 ut_id 字段的长度是4个字符,ts / 2表示它没有终止的空字节。



使用%s格式化参数打印字符数组 printf 。这将保持打印直到达到空字节。我建议你需要将 utmp 的每个字段复制到一个临时字符数组中,该数组的大小大于<$ c中的大小 $ c> utmp 结构。确保临时数组的最后一个字节是一个空字节,它应该打印出OK。


For our assignment we are given a copy of a wtmp log, and are expected to parse it, and output it in a sorted format, similar to the output of last.

Now, I know that the file wtmp consists of a list of utmp structures. The file provided is guaranteed to contain at least one utmp structure and I'm supposed to assume all structures in the binary file are constructed correctly.

I've read through man utmp, and I have successfully written a program to read in the structs from the binary file provided. (My apologies for the lengthy print method)

#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);
}

Now, the problem I'm having is that when I run this, the output for ut_id is different than what I expect it to be.

From: man utmp

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

My output:

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

I'm not quite sure what is going on here. What I think might be happening is that the ut_id field just might not exist in the struct that I am reading in. I think that might explain why the ut_id field is being displayed as the fields on either side of it squashed together.

I thought that I could possibly use fprintf formatting to get the field to display correctly, but it seems that you can only format text to one side of a char array or another, not grab specific parts from inside the string.

Otherwise, I'm pretty lost. Is this just a gap in my understanding of structs?

Not looking for answers, more so just some prodding in the right direction.

Also, what exactly is the terminal name suffix? Is that just the number that follows after pts/?

解决方案

man utmp says "String fields are terminated by a null byte ('\0') if they are shorter than the size of the field." So, in particular, if they are the same size as the field then they are not terminated by a null byte. Well formed C strings must be terminated by a null byte. The fact that it looks like the ut_id field is 4 characters long "ts/2" suggests that it does not have a terminating null byte.

You're printing the char arrays using the %s formatting argument to printf. This keeps printing until it reaches a null byte. I suggest that you need to copy each field of the utmp to a temporary char array, which is one bigger than the size in the utmp structure. Make sure the last byte of that temporary array is a null byte, and it should print out OK.

这篇关于用C解析wtmp日志的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆