[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now


details on "last" logins

Posted on 1998-04-08
Medium Priority
Last Modified: 2010-04-21
the last command keeps track of the last logins into a system (user, from where, what time etc).  The info (as specified in the man page) is stored in /var/adm/wtmpx.  From what people have told me, that file is a sparse file.  My problem is that the info obtained from typing last is formatted to fit the screen.  In doing so, the location from which the user connected is truncated to ~16 characters.

Is there a way to get last to display that to the full length?  if not, is there somewhere where I can get a program to analyze the wtmpx file with?
Question by:cokeman_
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4

Expert Comment

ID: 2009097
you can write a 'C' program to access these details directly as
explained in the following code.
(Note: this code is for SunOS 5.x, but should be able to use on
other platforms too.)  
This code uses 'getutxent' call to get the utmp entries.  On
other machines this fucntion could be 'getutent'.

#include <stdio.h>
#include <utmpx.h>
        struct utmpx *wt;
        int i = 0;
        utmpxname(WTMPX_FILE);  /* Change database to /var/adm/wtmpx */
        while ( (wt = getutxent()) != NULL ) {
                printf("%s\t",  wt->ut_user);   /*User Name */
                printf("%s\n", wt->ut_host);


Please note these issues:
1. There are lot more fields in the 'utmpx' structure that are
   not processed here.
2. getutxent function gets a entry from the begining of the
   'utmpx/wtmpx' file.  Where as 'last' command displays info
   from the bottom of the file to top.
3. Your platform may support only 16 characters to store the
   remote host name.  In that case even writing a 'C' as above
   will not help.  Verify this by man utmp and check how the
   field ut_host is defined in the utmp structure.

Hope this helps.  BTW, what is your platform?  


Expert Comment

ID: 2009098
One more issue:  You would want to skip a lot of entries
based on the 'ut_type' field - just as 'last' does.

Author Comment

ID: 2009099
I'm using SunOS 5.5.1, and I've included some of the output from the man page of utmp below:

     #define  UTMP_FILE                  "/var/adm/utmp"
     #define  WTMP_FILE                  "/var/adm/wtmp"
     #define  ut_name                    ut_user

     struct utmp {
              char  ut_user[8];          /* user login name */
              char  ut_id[4];            /* /sbin/inittab id (created by */
                                         /* process that puts entry in utmp) */
              char  ut_line[12];         /* device name (console, lnxx) */
              short ut_pid;              /* process id */
              short ut_type;             /* type of entry */
              struct exit_status {
                   short e_termination;  /* process termination status */
                   short e_exit;         /* process exit status */
              } ut_exit;                 /* exit status of a process
                                         /* marked as DEAD_PROCESS */
              time_t ut_time;            /* time entry was made */
     /*  Definitions for ut_type  */
     #define  EMPTY          0
     #define  RUN_LVL        1
     #define  BOOT_TIME      2
     #define  OLD_TIME       3
     #define  NEW_TIME       4
     #define  INIT_PROCESS   5         /* process spawned by "init" */
     #define  LOGIN_PROCESS  6         /* a "getty" process waiting for login */
     #define  USER_PROCESS   7         /* a user process */
     #define  DEAD_PROCESS   8
     #define  ACCOUNTING     9
     #define  UTMAXTYPE      ACCOUNTING  /* max legal value of ut_type */
     /*  Below are special strings or formats used in the "ut_line"  */
     /*  field when  accounting for something other than a process.  */
     /*  No string for the ut_line field can be more than 11 chars + */
     /*  a null character in length.  */
     #define  RUNLVL_MSG     "run-level %c"
     #define  BOOT_MSG       "system boot"
     #define  OTIME_MSG      "old time"
     #define  NTIME_MSG      "new time"

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.


Author Comment

ID: 2009100
ooops, sorry.. I guess I should have looked up the man page for utmpx instead of utmp.. I've added that below:

     utmpx is an extended version of utmp(4).

     utmpx and wtmpx hold user  and  accounting  information  for
     commands  such  as  who, write, and login.  These files have
     the following structure as defined by <utmpx.h>:

     #define  UTMPX_FILE                    "/var/adm/utmpx"
     #define  WTMPX_FILE                    "/var/adm/wtmpx"
     #define  ut_name                       ut_user
     #define  ut_xtime                      ut_tv.tv_sec
     struct utmpx  {
        char    ut_user[32];                /* user login name */
        char    ut_id[4];                   /* inittab id */
        char    ut_line[32];                /* device name */
                                            /* (console, lnxx) */
        pid_t   ut_pid;                     /* process id */
        short   ut_type;                    /* type of entry */
        struct  exit_status ut_exit;        /* process termination/exit */
                                            /* status */
        struct  timeval ut_tv;              /* time entry was made */
        long    ut_session;                 /* session ID, used for */
                                            /* windowing */
        long    pad[5];                     /* reserved for future use */
        short   ut_syslen;                  /* significant length of */
                                            /* ut_host */
                                            /* including terminating null */
        char    ut_host[257];               /* remote host name */
     /* Definitions for ut_type */
     #define  EMPTY             0
     #define  RUN_LVL           1
     #define  BOOT_TIME         2
     #define  OLD_TIME          3
     #define  NEW_TIME          4
     #define  INIT_PROCESS      5           /* Process spawned by "init" */
     #define  LOGIN_PROCESS     6           /* A "getty" process waiting */
                                            /* for login */
     #define  USER_PROCESS      7           /* A user process */
     #define  DEAD_PROCESS      8
     #define  ACCOUNTING        9

     #define  UTMAXTYPE  ACCOUNTING         /* Largest legal value */
                                            /* of ut_type */

     /* Below are special strings or formats used in the "ut_line" */
     /* field when accounting for something other than a process. */
     /* No string for the ut_line field can be more than 11 chars + */
     /* a null character in length. */

     #define  RUNLVL_MSG                    "run-level %c"
     #define  BOOT_MSG                      "system boot"
     #define  OTIME_MSG                     "old time"
     #define  NTIME_MSG                     "new time"
     #define  MOD_WIN                       10


Author Comment

ID: 2009101
       char    ut_host[257];               /* remote host name */

it appears that this string is definitely long enough.. hmm.. out of curiousity, do you know why they used 257 instead of something like 255 or 256?  I've never seen 257 being used =)

I'll try this out when I get a chance tomorrow.  Thanks for your help.. it seems like it should give me what I need.

Expert Comment

ID: 2009102
257?  No, neither have I.  But could it be 256 + 1 for the null?
Please note the ut_syslen field.  This must be used to find
the number of significant characters in 'ut_host'.  The maximum
for ut_syslen in my machine(Sun OS 5.5.1) was only 16.  But it
could be different in your machine - depending on the entries.

Expert Comment

ID: 2009103
Did it work for you?

Author Comment

ID: 2009104
it did.. it gave two of everything.. but looking at wt->ut_type, it was coded 7 and 8, i guess indicating login and logout.

hey, do you know how to deal with the timeval struct? ie, to get it into a date/time?


Accepted Solution

seedy earned 400 total points
ID: 2009105
The field ut_tv is of type struct timeval.  This structure
is same as that is used in 'gettimeofday' function.
Read man pages for more info.  You can use ctime to convert
this to the character string.  So,
will  do the trick for you.
Ps:  Last actually does a lot more.  It looks at both the login
and logout records and prints the duration of the session.

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When you do backups in the Solaris Operating System, the file system must be inactive. Otherwise, the output may be inconsistent. A file system is inactive when it's unmounted or it's write-locked by the operating system. Although the fssnap utility…
I promised to write further about my project, and here I am.  First, I needed to setup the Primary Server.  You can read how in this article: Setup FreeBSD Server with full HDD encryption (http://www.experts-exchange.com/OS/Unix/BSD/FreeBSD/A_3660-S…
Learn how to find files with the shell using the find and locate commands. Use locate to find a needle in a haystack.: With locate, check if the file still exists.: Use find to get the actual location of the file.:
Learn how to navigate the file tree with the shell. Use pwd to print the current working directory: Use ls to list a directory's contents: Use cd to change to a new directory: Use wildcards instead of typing out long directory names: Use ../ to move…
Suggested Courses

650 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question