]>
cygwin.com Git - cygwin-apps/cygutils.git/blob - src/last/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 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 in version 2 of the License.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
35 /* special requirements moved to common.h */
38 #include <netinet/in.h>
39 #include <arpa/inet.h>
41 /* end special requirements */
45 char * strptime ( const char *, const char *, struct tm
*);
48 oldtonew ( struct oldutmp src
)
52 memset (& dest
, 0 , sizeof dest
);
53 dest
. ut_type
= src
. ut_type
;
54 dest
. ut_pid
= src
. ut_pid
;
55 dest
. ut_time
= src
. ut_oldtime
;
56 dest
. ut_addr
= src
. ut_oldaddr
;
57 strncpy ( dest
. ut_id
, src
. ut_id
, 4 );
58 strncpy ( dest
. ut_line
, src
. ut_line
, OLD_LINESIZE
);
59 strncpy ( dest
. ut_user
, src
. ut_user
, OLD_NAMESIZE
);
60 strncpy ( dest
. ut_host
, src
. ut_host
, OLD_HOSTSIZE
);
66 newtoold ( struct utmp src
)
70 memset (& dest
, 0 , sizeof dest
);
71 dest
. ut_type
= src
. ut_type
;
72 dest
. ut_pid
= src
. ut_pid
;
73 dest
. ut_oldtime
= src
. ut_time
;
74 dest
. ut_oldaddr
= src
. ut_addr
;
75 strncpy ( dest
. ut_id
, src
. ut_id
, 4 );
76 strncpy ( dest
. ut_line
, src
. ut_line
, OLD_LINESIZE
);
77 strncpy ( dest
. ut_user
, src
. ut_user
, OLD_NAMESIZE
);
78 strncpy ( dest
. ut_host
, src
. ut_host
, OLD_HOSTSIZE
);
84 timetostr ( const time_t time
)
86 static char s
[ 29 ]; /* [Sun Sep 01 00:00:00 1998 PST] */
89 strftime ( s
, 29 , "%a %b %d %T %Y %Z" , localtime (& time
));
97 strtotime ( const char * s_time
)
99 struct tm
* tm
= malloc ( sizeof (* tm
));
101 if ( s_time
[ 0 ] == ' ' || s_time
[ 0 ] == '\0' )
104 strptime ( s_time
, "%a %b %d %T %Y" , tm
);
106 /* Cheesy way of checking for DST */
107 if ( s_time
[ 26 ] == 'D' )
113 #define cleanse(x) xcleanse(x, sizeof(x))
115 xcleanse ( char * s
, int len
)
117 for ( ; * s
&& len
-- > 0 ; s
++)
118 if (! isprint (* s
) || * s
== '[' || * s
== ']' )
123 unspace ( char * s
, int len
)
125 while (* s
&& * s
!= ' ' && len
--)
133 print_utline ( struct utmp ut
)
135 char * addr_string
, * time_string
;
138 in
. s_addr
= ut
. ut_addr
;
139 addr_string
= inet_ntoa ( in
);
140 time_string
= timetostr ( ut
. ut_time
);
146 /* pid id user line host addr time */
147 printf ( "[%d] [%05d] [%-4.4s] [%-*.*s] [%-*.*s] [%-*.*s] [%-15.15s] [%-28.28s] \n " ,
148 ut
. ut_type
, ut
. ut_pid
, ut
. ut_id
, 8 , UT_NAMESIZE
, ut
. ut_user
,
149 12 , UT_LINESIZE
, ut
. ut_line
, 20 , UT_HOSTSIZE
, ut
. ut_host
,
150 addr_string
, time_string
);
154 dump ( FILE * fp
, int forever
, int oldfmt
)
160 fseek ( fp
, - 10 * ( oldfmt
? sizeof uto
: sizeof ut
), SEEK_END
);
164 while ( fread (& uto
, sizeof uto
, 1 , fp
) == 1 )
165 print_utline ( oldtonew ( uto
));
167 while ( fread (& ut
, sizeof ut
, 1 , fp
) == 1 )
169 if ( forever
) sleep ( 1 );
173 /* This function won't work properly if there's a ']' or a ' ' in the real
174 * token. Thankfully, this should never happen. */
176 gettok ( char * line
, char * dest
, int size
, int eatspace
)
178 int bpos
, epos
, eaten
;
181 bpos
= strchr ( line
, '[' ) - line
;
183 fprintf ( stderr
, "Extraneous newline in file. Exiting." );
188 epos
= strchr ( line
, ']' ) - line
;
190 fprintf ( stderr
, "Extraneous newline in file. Exiting." );
195 eaten
= bpos
+ epos
+ 1 ;
198 if (( t
= strchr ( line
, ' ' )))
201 strncpy ( dest
, line
, size
);
207 undump ( FILE * fp
, int forever
, int oldfmt
)
211 char s_addr
[ 16 ], s_time
[ 29 ], * linestart
, * line
;
214 line
= linestart
= malloc ( 1024 * sizeof * linestart
);
218 while ( fgets ( linestart
, 1023 , fp
))
221 memset (& ut
, '\0' , sizeof ( ut
));
222 sscanf ( line
, "[%hd] [%d] [%4c] " , & ut
. ut_type
, & ut
. ut_pid
, ut
. ut_id
);
225 line
+= gettok ( line
, ut
. ut_user
, sizeof ( ut
. ut_user
), 1 );
226 line
+= gettok ( line
, ut
. ut_line
, sizeof ( ut
. ut_line
), 1 );
227 line
+= gettok ( line
, ut
. ut_host
, sizeof ( ut
. ut_host
), 1 );
228 line
+= gettok ( line
, s_addr
, sizeof ( s_addr
)- 1 , 1 );
229 line
+= gettok ( line
, s_time
, sizeof ( s_time
)- 1 , 0 );
231 ut
. ut_addr
= inet_addr ( s_addr
);
232 ut
. ut_time
= strtotime ( s_time
);
236 fwrite (& uto
, sizeof ( uto
), 1 , stdout
);
238 fwrite (& ut
, sizeof ( ut
), 1 , stdout
);
249 printf ( "Usage: utmpdump [ -froh ] [ filename ] \n " );
253 int main ( int argc
, char ** argv
)
257 int reverse
= 0 , forever
= 0 , oldfmt
= 0 ;
259 while (( c
= getopt ( argc
, argv
, "froh" )) != EOF
) {
283 fprintf ( stderr
, "Utmp %sdump of %s \n " , reverse
? "un" : "" , argv
[ optind
]);
284 if (( fp
= fopen ( argv
[ optind
], "r" )) == NULL
) {
285 perror ( "Unable to open file" );
290 fprintf ( stderr
, "Utmp %sdump of stdin \n " , reverse
? "un" : "" );
295 undump ( fp
, forever
, oldfmt
);
297 dump ( fp
, forever
, oldfmt
);
305 Everything after this point should be removed when the new cygwin dll is released, as this functionality has been added to it. The current dll is 1.3.6.
308 static const char * abb_weekdays
[] = {
319 static const char * full_weekdays
[] = {
330 static const char * abb_month
[] = {
346 static const char * full_month
[] = {
362 static const char * ampm
[] = {
369 * tm_year is relative this year */
370 const int tm_year_base
= 1900 ;
373 * Return TRUE iff `year' was a leap year.
377 is_leap_year ( int year
)
379 return ( year
% 4 ) == 0 && (( year
% 100 ) != 0 || ( year
% 400 ) == 0 );
383 match_string ( const char ** buf
, const char ** strs
)
387 for ( i
= 0 ; strs
[ i
] != NULL
; ++ i
) {
388 int len
= strlen ( strs
[ i
]);
390 if ( strncasecmp (* buf
, strs
[ i
], len
) == 0 ) {
403 for (; year
> 1970 ; -- year
)
404 ret
= ( ret
+ 365 + is_leap_year ( year
) ? 1 : 0 ) % 7 ;
409 * Set `timeptr' given `wnum' (week number [0, 53])
413 set_week_number_sun ( struct tm
* timeptr
, int wnum
)
415 int fday
= first_day ( timeptr
-> tm_year
+ tm_year_base
);
417 timeptr
-> tm_yday
= wnum
* 7 + timeptr
-> tm_wday
- fday
;
418 if ( timeptr
-> tm_yday
< 0 ) {
419 timeptr
-> tm_wday
= fday
;
420 timeptr
-> tm_yday
= 0 ;
425 * Set `timeptr' given `wnum' (week number [0, 53])
429 set_week_number_mon ( struct tm
* timeptr
, int wnum
)
431 int fday
= ( first_day ( timeptr
-> tm_year
+ tm_year_base
) + 6 ) % 7 ;
433 timeptr
-> tm_yday
= wnum
* 7 + ( timeptr
-> tm_wday
+ 6 ) % 7 - fday
;
434 if ( timeptr
-> tm_yday
< 0 ) {
435 timeptr
-> tm_wday
= ( fday
+ 1 ) % 7 ;
436 timeptr
-> tm_yday
= 0 ;
441 * Set `timeptr' given `wnum' (week number [0, 53])
445 set_week_number_mon4 ( struct tm
* timeptr
, int wnum
)
447 int fday
= ( first_day ( timeptr
-> tm_year
+ tm_year_base
) + 6 ) % 7 ;
453 timeptr
-> tm_yday
= offset
+ ( wnum
- 1 ) * 7 + timeptr
-> tm_wday
- fday
;
454 if ( timeptr
-> tm_yday
< 0 ) {
455 timeptr
-> tm_wday
= fday
;
456 timeptr
-> tm_yday
= 0 ;
460 /* strptime: roken */
462 strptime ( const char * buf
, const char * format
, struct tm
* timeptr
)
466 for (; ( c
= * format
) != '\0' ; ++ format
) {
471 while ( isspace (* buf
))
473 } else if ( c
== '%' && format
[ 1 ] != '\0' ) {
475 if ( c
== 'E' || c
== 'O' )
479 ret
= match_string (& buf
, full_weekdays
);
482 timeptr
-> tm_wday
= ret
;
485 ret
= match_string (& buf
, abb_weekdays
);
488 timeptr
-> tm_wday
= ret
;
491 ret
= match_string (& buf
, full_month
);
494 timeptr
-> tm_mon
= ret
;
498 ret
= match_string (& buf
, abb_month
);
501 timeptr
-> tm_mon
= ret
;
504 ret
= strtol ( buf
, & s
, 10 );
507 timeptr
-> tm_year
= ( ret
* 100 ) - tm_year_base
;
512 case 'D' : /* %m/%d/%y */
513 s
= strptime ( buf
, "%m/%d/%y" , timeptr
);
520 ret
= strtol ( buf
, & s
, 10 );
523 timeptr
-> tm_mday
= ret
;
528 ret
= strtol ( buf
, & s
, 10 );
531 timeptr
-> tm_hour
= ret
;
536 ret
= strtol ( buf
, & s
, 10 );
540 timeptr
-> tm_hour
= 0 ;
542 timeptr
-> tm_hour
= ret
;
546 ret
= strtol ( buf
, & s
, 10 );
549 timeptr
-> tm_yday
= ret
- 1 ;
553 ret
= strtol ( buf
, & s
, 10 );
556 timeptr
-> tm_mon
= ret
- 1 ;
560 ret
= strtol ( buf
, & s
, 10 );
563 timeptr
-> tm_min
= ret
;
573 ret
= match_string (& buf
, ampm
);
576 if ( timeptr
-> tm_hour
== 0 ) {
578 timeptr
-> tm_hour
= 12 ;
580 timeptr
-> tm_hour
+= 12 ;
582 case 'r' : /* %I:%M:%S %p */
583 s
= strptime ( buf
, "%I:%M:%S %p" , timeptr
);
588 case 'R' : /* %H:%M */
589 s
= strptime ( buf
, "%H:%M" , timeptr
);
595 ret
= strtol ( buf
, & s
, 10 );
598 timeptr
-> tm_sec
= ret
;
607 case 'T' : /* %H:%M:%S */
609 s
= strptime ( buf
, "%H:%M:%S" , timeptr
);
615 ret
= strtol ( buf
, & s
, 10 );
618 timeptr
-> tm_wday
= ret
- 1 ;
622 ret
= strtol ( buf
, & s
, 10 );
625 timeptr
-> tm_wday
= ret
;
629 ret
= strtol ( buf
, & s
, 10 );
632 set_week_number_sun ( timeptr
, ret
);
636 ret
= strtol ( buf
, & s
, 10 );
639 set_week_number_mon4 ( timeptr
, ret
);
643 ret
= strtol ( buf
, & s
, 10 );
646 set_week_number_mon ( timeptr
, ret
);
650 s
= strptime ( buf
, "%Y:%m:%d" , timeptr
);
656 ret
= strtol ( buf
, & s
, 10 );
660 timeptr
-> tm_year
= 100 + ret
;
662 timeptr
-> tm_year
= ret
;
666 ret
= strtol ( buf
, & s
, 10 );
669 timeptr
-> tm_year
= ret
- tm_year_base
;
684 if (* buf
== '%' || *++ buf
== c
)
This page took 0.068561 seconds and 5 git commands to generate.