#!/usr/bin/perl -w # # dumptz # John Simpson 2007-03-06 # # dumps the binary content of a "tzinfo" file # these are usually found in /usr/share/zoneinfo # ############################################################################### # # Copyright (C) 2007 John Simpson. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # or visit http://www.gnu.org/licenses/gpl.txt # ############################################################################### require 5.003 ; use strict ; my ( @ttime , @ltime , @tt_gmtoff , @tt_isdst , @tt_abbrind , @ls_when , @ls_add , @tt_isstd , @tt_isgmt , @ttline ) ; sub grab($) { my $count = shift ; my $buf = "" ; if ( $count ) { my $rv = read ( I , $buf , $count ) ; die "grab(): wanted $count bytes, received $rv\n" unless ( $rv == $count ) ; } return $buf ; } sub mktzname($$) { my $str = shift ; my $pos = shift ; my $rv = substr ( $str , $pos ) ; $rv =~ s/\0.*// ; return $rv ; } sub ptime($) { my $t = shift ; my @d = gmtime ( $t ) ; return sprintf ( "%04d-%02d-%02d %02d:%02d:%02d" , $d[5]+1900 , $d[4]+1 , $d[3] , $d[2] , $d[1] , $d[0] ) ; } ############################################################################### ############################################################################### ############################################################################### my $file = ( shift || die "No filename specified.\n" ) ; open ( I , "<$file" ) or die "Can\'t read \"$file\": $!\n" ; ######################################## # check magic number "TZif" my $x = grab ( 4 ) ; if ( $x ne "TZif" ) { close I ; die "Wrong magic number: this is not a tzinfo file\n" ; } ######################################## # skip 16 bytes reserved grab ( 16 ) ; ######################################## # grab six counters my $tzh_ttisgmtcnt = unpack ( "N" , grab ( 4 ) ) ; my $tzh_ttisstdcnt = unpack ( "N" , grab ( 4 ) ) ; my $tzh_leapcnt = unpack ( "N" , grab ( 4 ) ) ; my $tzh_timecnt = unpack ( "N" , grab ( 4 ) ) ; my $tzh_typecnt = unpack ( "N" , grab ( 4 ) ) ; my $tzh_charcnt = unpack ( "N" , grab ( 4 ) ) ; ######################################## # grab $tzh_timecnt longs map { push ( @ttime , unpack ( "N" , grab ( 4 ) ) ) } ( 1 .. $tzh_timecnt ) ; ######################################## # grab $tzh_timecnt "local time type" values map { push ( @ltime , unpack ( "C" , grab ( 1 ) ) ) } ( 1 .. $tzh_timecnt ) ; ######################################## # grab "local time type" info structures for my $n ( 1 .. $tzh_typecnt ) { push ( @tt_gmtoff , unpack ( "N" , grab ( 4 ) ) ) ; push ( @tt_isdst , unpack ( "C" , grab ( 1 ) ) ) ; push ( @tt_abbrind , unpack ( "C" , grab ( 1 ) ) ) ; } ######################################## # grab time zone names my $tznames = grab ( $tzh_charcnt ) ; ######################################## # grab leap second info for my $n ( 1 .. $tzh_leapcnt ) { push ( @ls_when , unpack ( "N" , grab ( 4 ) ) ) ; push ( @ls_add , unpack ( "N" , grab ( 4 ) ) ) ; } ######################################## # grab std/wall indicators map { push ( @tt_isstd , unpack ( "C" , grab ( 1 ) ) ) } ( 1 .. $tzh_ttisstdcnt ) ; ######################################## # grab UTC/local indicators map { push ( @tt_isgmt , unpack ( "C" , grab ( 1 ) ) ) } ( 1 .. $tzh_ttisgmtcnt ) ; ######################################## # done, generate output close I ; for my $n ( 0 .. $#tt_gmtoff ) { $ttline[$n] = sprintf ( "%10d %3d %-8s %3d %3d" , $tt_gmtoff[$n] , $tt_isdst[$n] , mktzname ( $tznames , $tt_abbrind[$n] ) , $tt_isstd[$n] , $tt_isgmt[$n] ) ; } print <