]>
git.wh0rd.org - sysvinit.git/blob - src/utmpdump.c
2 * utmpdump Simple program to dump UTMP and WTMP files in
3 * raw format, so they can be examined.
5 * Author: Miquel van Smoorenburg, <miquels@cistron.nl>
6 * Danek Duvall <duvall@alumni.princeton.edu>
8 * Version: @(#)utmpdump 2.79 12-Sep-2000
10 * This file is part of the sysvinit suite,
11 * Copyright (C) 1991-2000 Miquel van Smoorenburg.
13 * Additional Copyright on this file 1998 Danek Duvall.
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
37 #include <netinet/in.h>
38 #include <arpa/inet.h>
42 oldtonew(struct oldutmp src
)
46 memset(&dest
, 0, sizeof dest
);
47 dest
.ut_type
= src
.ut_type
;
48 dest
.ut_pid
= src
.ut_pid
;
49 dest
.ut_time
= src
.ut_oldtime
;
50 dest
.ut_addr
= src
.ut_oldaddr
;
51 strncpy(dest
.ut_id
, src
.ut_id
, 4);
52 strncpy(dest
.ut_line
, src
.ut_line
, OLD_LINESIZE
);
53 strncpy(dest
.ut_user
, src
.ut_user
, OLD_NAMESIZE
);
54 strncpy(dest
.ut_host
, src
.ut_host
, OLD_HOSTSIZE
);
60 newtoold(struct utmp src
)
64 memset(&dest
, 0, sizeof dest
);
65 dest
.ut_type
= src
.ut_type
;
66 dest
.ut_pid
= src
.ut_pid
;
67 dest
.ut_oldtime
= src
.ut_time
;
68 dest
.ut_oldaddr
= src
.ut_addr
;
69 strncpy(dest
.ut_id
, src
.ut_id
, 4);
70 strncpy(dest
.ut_line
, src
.ut_line
, OLD_LINESIZE
);
71 strncpy(dest
.ut_user
, src
.ut_user
, OLD_NAMESIZE
);
72 strncpy(dest
.ut_host
, src
.ut_host
, OLD_HOSTSIZE
);
78 timetostr(const time_t time
)
80 static char s
[29]; /* [Sun Sep 01 00:00:00 1998 PST] */
83 strftime(s
, 29, "%a %b %d %T %Y %Z", localtime(&time
));
91 strtotime(const char *s_time
)
95 memset(&tm
, '\0', sizeof(struct tm
));
97 if (s_time
[0] == ' ' || s_time
[0] == '\0')
100 strptime(s_time
, "%a %b %d %T %Y", &tm
);
102 /* Cheesy way of checking for DST */
103 if (s_time
[26] == 'D')
109 #define cleanse(x) xcleanse(x, sizeof(x))
111 xcleanse(char *s
, int len
)
113 for ( ; *s
&& len
-- > 0; s
++)
114 if (!isprint(*s
) || *s
== '[' || *s
== ']')
119 unspace(char *s
, int len
)
121 while (*s
&& *s
!= ' ' && len
--)
129 print_utline(struct utmp ut
)
131 char addr_buf
[INET6_ADDRSTRLEN
+1];
132 const char *addr_string
, *time_string
;
133 void *in_addr
= &ut
.ut_addr_v6
;
134 size_t addr_length
= INET6_ADDRSTRLEN
;
135 int addr_family
= AF_INET6
;
137 if (!ut
.ut_addr_v6
[1] && !ut
.ut_addr_v6
[2] && !ut
.ut_addr_v6
[3]) {
138 addr_family
= AF_INET
;
139 addr_length
= INET_ADDRSTRLEN
;
140 in_addr
= &ut
.ut_addr
;
142 if ((addr_string
= inet_ntop(addr_family
, in_addr
, addr_buf
, addr_length
)) == 0) {
144 addr_string
= &addr_buf
[0];
146 time_string
= timetostr(ut
.ut_time
);
152 /* pid id user line host addr time */
153 printf("[%d] [%05d] [%-4.4s] [%-*.*s] [%-*.*s] [%-*.*s] [%-15.15s] [%-28.28s]\n",
154 ut
.ut_type
, ut
.ut_pid
, ut
.ut_id
, 8, UT_NAMESIZE
, ut
.ut_user
,
155 12, UT_LINESIZE
, ut
.ut_line
, 20, UT_HOSTSIZE
, ut
.ut_host
,
156 addr_string
, time_string
);
160 dump(FILE *fp
, int forever
, int oldfmt
)
166 fseek(fp
, -10 * (oldfmt
? sizeof uto
: sizeof ut
), SEEK_END
);
170 while (fread(&uto
, sizeof uto
, 1, fp
) == 1)
171 print_utline(oldtonew(uto
));
173 while (fread(&ut
, sizeof ut
, 1, fp
) == 1)
175 if (forever
) sleep(1);
179 /* This function won't work properly if there's a ']' or a ' ' in the real
180 * token. Thankfully, this should never happen. */
182 gettok(char *line
, char *dest
, int size
, int eatspace
)
184 int bpos
, epos
, eaten
;
187 bpos
= strchr(line
, '[') - line
;
189 fprintf(stderr
, "Extraneous newline in file. Exiting.");
194 epos
= strchr(line
, ']') - line
;
196 fprintf(stderr
, "Extraneous newline in file. Exiting.");
201 eaten
= bpos
+ epos
+ 1;
204 if ((t
= strchr(line
, ' ')))
207 strncpy(dest
, line
, size
);
214 undump(FILE *fp
, int forever
__attribute__((unused
)), int oldfmt
)
216 undump(FILE *fp
, int forever
, int oldfmt
)
221 char s_addr
[16], s_time
[29], *linestart
;
224 linestart
= malloc(1024 * sizeof *linestart
);
228 while(fgets(linestart
, 1023, fp
))
230 char *line
= linestart
;
231 memset(&ut
, '\0', sizeof(ut
));
232 sscanf(line
, "[%hd] [%d] [%4c] ", &ut
.ut_type
, &ut
.ut_pid
, ut
.ut_id
);
235 line
+= gettok(line
, ut
.ut_user
, sizeof(ut
.ut_user
), 1);
236 line
+= gettok(line
, ut
.ut_line
, sizeof(ut
.ut_line
), 1);
237 line
+= gettok(line
, ut
.ut_host
, sizeof(ut
.ut_host
), 1);
238 line
+= gettok(line
, s_addr
, sizeof(s_addr
)-1, 1);
239 line
+= gettok(line
, s_time
, sizeof(s_time
)-1, 0);
240 (void)line
; /* Quiet down static source analyzers */
242 ut
.ut_addr
= inet_addr(s_addr
);
243 ut
.ut_time
= strtotime(s_time
);
247 fwrite(&uto
, sizeof(uto
), 1, stdout
);
249 fwrite(&ut
, sizeof(ut
), 1, stdout
);
260 printf("Usage: utmpdump [ -froh ] [ filename ]\n");
264 int main(int argc
, char **argv
)
268 int reverse
= 0, forever
= 0, oldfmt
= 0;
270 while ((c
= getopt(argc
, argv
, "froh")) != EOF
) {
294 fprintf(stderr
, "Utmp %sdump of %s\n", reverse
? "un" : "", argv
[optind
]);
295 if ((fp
= fopen(argv
[optind
], "r")) == NULL
) {
296 perror("Unable to open file");
301 fprintf(stderr
, "Utmp %sdump of stdin\n", reverse
? "un" : "");
306 undump(fp
, forever
, oldfmt
);
308 dump(fp
, forever
, oldfmt
);