Analyzing wtmp logs with C

For our purpose, we are provided with a copy of the wtmp log, and it is expected that it will parse it and display it in a sorted format, similar to the output of last .

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

I read man utmp and I successfully wrote a program to read in structures from the provided binary. (My apologies for the long printing 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 is that when I run this, the output for ut_id is different from what I expect.

From: man utmp

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

My conclusion:

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

I'm not quite sure what is going on here. I think it may happen that the ut_id field simply cannot exist in the structure in which I am reading. I think this may explain why the ut_id field is displayed as fields on either side of it, crushed together.

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

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

Do not look for answers, especially since you are producing in the right direction.

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

+1
source share
1 answer

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

You print char arrays using the% s formatting argument for printf . This keeps printing until it reaches zero byte. I suggest you copy each utmp field into a temporary char array that is larger than the size in the utmp structure. Make sure that the last byte of this temporary array is a zero byte, and it should print OK.

+2
source

Source: https://habr.com/ru/post/1201564/


All Articles