*BSD News Article 30790


Return to BSD News archive

Path: sserve!newshost.anu.edu.au!harbinger.cc.monash.edu.au!msuinfo!uwm.edu!spool.mu.edu!howland.reston.ans.net!usc!elroy.jpl.nasa.gov!swrinde!ihnp4.ucsd.edu!pacbell.com!amdahl!amd!netcomsv!netcomsv!netcomsv!hawaii.verity.com!newshost!sky
From: sky@verity.com (Sky Schulz)
Newsgroups: comp.unix.bsd
Subject: Re: ?Perl/C access to wtmp,utmp?
Date: 24 May 1994 16:22:32 GMT
Organization: Verity, Inc.
Lines: 69
Message-ID: <SKY.94May24092232@raiden.verity.com>
References: <Cq8tnv.EvA@scu.edu.au>
Reply-To: Sky Golightly <sky@verity.com>
NNTP-Posting-Host: raiden.verity.com
In-reply-to: pshepher@scu.edu.au's message of 23 May 94 06:50:19 GMT

In article <Cq8tnv.EvA@scu.edu.au> pshepher@scu.edu.au (Philip Shepherd) writes:

   Is there any easy way to access the info stored in the 'wtmp' and 'utmp'
   files from Perl or C?

   In particular, I'm interested in the number of minutes a user has been 
   logged in ... this CAN be deduced from the 'login at' field of the 'w'
   command but ends up being very inefficient (especially in perl).

This doesn't count how long someone has been logged in, but it does
illustrate accessing utmp from perl...

#! /usr/local/bin/perl -- # -*-Perl-*-
sub gotoxy
{
  local($col, $row) = @_;
  &Tputs(&Tgoto($TC{'cm'},$col,$row), 0, 'STDOUT');
}

sub cls
{
  &Tputs($TC{'cd'},0,'STDOUT');
}

sub readutmp
{
  local($utmp,$tty,$name,$host,$time,$len);
  open(UTMP,'/etc/utmp');
  undef(%user);			# Reset users
  while($len = sysread(UTMP,$utmp,36)) {
    ($tty,$name,$host,$time) = unpack('A8 A8 A16 L', $utmp);
    if (length($name)) {
      $tty =~ s/tty//;
      $user{$name} .= $tty . " ";
    }
  }
  close(UTMP);
}

main:
{
  unshift (@INC, '/users/sky/lib/perl');
  print "\@INC = @INC\n";
  require 'sys/ioctl.ph';
  ioctl(TTY,&TIOCGETP,$params);
  ($ispeed,$ospeed) = unpack('cc',$params);
  $ospeed = $ispeed if ! $ospeed;
  require 'termcap.pl';
  require 'ctime.pl';
  $| = 1;

  &Tgetent($ENV{'TERM'});	# sets $TC{'cm'}, etc.
  &gotoxy(0,0);
  &cls;
  &gotoxy(0,0);
  print "User     Tty's\n-------- -----\n";
  while (1) {
    &readutmp;
    &gotoxy(0,2);
    &cls;
    foreach $name (sort (keys(%user))) {
      printf("%-8s %s\n", $name, $user{$name});
    }
    sleep(30);
  }
}
--

-- sky G.