如何用perl 读取二进制文件(/var/log/wtmp)

如何用perl 读取二进制文件(/var/log/wtmp)

./ltest.pl

#!/usr/bin/perl
# for more information
     $template = "s l A12 A4 A32 A256 s2 l i2 i4 A20";
# determine the size of a record
      $recordsize = length(pack($template,( )));
# open the file
    open(WTMP,"/var/log/wtmp" or die "Unable to open wtmpx!\n";
# read through it one record at a time
while (read(WTMP,$record,$recordsize)) {
    ($ut_type,$ut_pid,$ut_line,$ut_id,$ut_user,$ut_host,$ut_e_termination,
        $ut_e_exit,$ut_session,$ut_tv_sec,$ut_tv_usec,$ut_addr,$ut_unused) =
          unpack($template,$record);

  print "type of login =>$ut_type
         pid of login process => $ut_pid
         init id => $ut_id
         user name => $ut_user
          hostname for remote login => $ut_host
          IP address of remote host => $ut_addr\n";
}
close(WTMP);
输出有乱码,而且得不到想要的变量;
请问各位高手指点下,
如何读取二进制文件!

uname -r
    linux  2.6.9-22.EL

man wtmp

          #define UT_LINESIZE           12
          #define UT_NAMESIZE           32
          #define UT_HOSTSIZE           256

          struct exit_status {
            short int e_termination;    /* process termination status.  */
            short int e_exit;           /* process exit status.  */
          };

          struct utmp {
            short ut_type;              /* type of login */
            pid_t ut_pid;               /* pid of login process */
            char ut_line[UT_LINESIZE];  /* device name of tty - "/dev/" */
            char ut_id[4];              /* init id or abbrev. ttyname */
            char ut_user[UT_NAMESIZE];  /* user name */
            char ut_host[UT_HOSTSIZE];  /* hostname for remote login */
            struct exit_status ut_exit; /* The exit status of a process
                                           marked as DEAD_PROCESS. */
            long ut_session;            /* session ID, used for windowing*/
            struct timeval ut_tv;       /* time entry was made.  */
            int32_t ut_addr_v6[4];      /* IP address of remote host.  */
            char __unused[20];          /* Reserved for future use.  */
          };



more /usr/include/bits/utmp.h

#define UT_LINESIZE     32
#define UT_NAMESIZE     32
#define UT_HOSTSIZE     256


/* The structure describing an entry in the database of
   previous logins.  */
struct lastlog
  {
#if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
    int32_t ll_time;
#else
    __time_t ll_time;
#endif
    char ll_line[UT_LINESIZE];
    char ll_host[UT_HOSTSIZE];
  };


/* The structure describing the status of a terminated process.  This
   type is used in `struct utmp' below.  */
struct exit_status
  {
    short int e_termination;    /* Process termination status.  */
    short int e_exit;           /* Process exit status.  */
  };

struct utmp
{
  short int ut_type;         
  pid_t ut_pid;                 
  char ut_line[UT_LINESIZE];   
  char ut_id[4];               
  char ut_user[UT_NAMESIZE];   
  char ut_host[UT_HOSTSIZE];   
  struct exit_status ut_exit;   
                              

  struct
  {
    int32_t tv_sec;         
    int32_t tv_usec;         
  } ut_tv;                    
#else
  long int ut_session;        
  struct timeval ut_tv;         
#endif

  int32_t ut_addr_v6[4];        
  char __unused[20];            
};
那位大哥指点下,或者用哪个模块可以读取二进制文件
haha 问题解决了
原来是 man wtmp查到的数据类型和 /var/log/wtmp的 数据类型有些差别
大侠你好啊,可以发改好了的源码给我吗,谢谢.
代码不是在上边嘛.

还是让我给你一份参考吧.

http://www.oreilly.com/catalog/perlsysadm/chapter/ch09.html
$template = "s l A12 A4 A32 A256 s2 i i2 i4 A20";

晕了.这个结构体真实的结构到底是怎么样的.我这个是按man wtmp写出来的.也不行.
#!/usr/bin/perl
# for more information
     $template = "s l A32 A4 A32 A256 s2 l i2 i4 A20";
# determine the size of a record
      $recordsize = length(pack($template,( )));
# open the file
    open(WTMP,"/var/log/wtmp") or die "Unable to open wtmpx!\n";
# read through it one record at a time
while (read(WTMP,$record,$recordsize)) {
    ($ut_type,$ut_pid,$ut_line,$ut_id,$ut_user,$ut_host,$ut_e_termination,
        $ut_e_exit,$ut_session,$ut_tv_sec,$ut_tv_usec,$ut_addr,$ut_unused) =
          unpack($template,$record);

  print "type of login =>$ut_type
         pid of login process => $ut_pid
         init id => $ut_id
         user name => $ut_user
          hostname for remote login => $ut_host
          IP address of remote host => $ut_addr\n";
}
close(WTMP);