#include #include #include #include #include #include /* * who version 1 - read /var/run/utmp or argv[1], list its contents */ void show_info( struct utmp *utbufp ); int main(int ac, char *av[]) { struct utmp utbuf; /* read info into here */ int utmpfd; /* read from this descriptor */ char *info = ( ac > 1 ? av[1] : UTMP_FILE); if ( (utmpfd = open( info, O_RDONLY )) == -1 ){ fprintf(stderr,"%s: cannot open %s\n", *av, info); exit(1); } while ( read( utmpfd, &utbuf, sizeof(utbuf) ) == sizeof(utbuf) ) show_info( &utbuf ); close( utmpfd ); return 0; /* went ok */ } /* * show info() * displays contents of utmp struct in human-readable form * note: these sizes should not be hardwired * warn: these strings might not be nul-terminated, see docs */ void show_info( struct utmp *utbufp ) { if ( utbufp->ut_type != USER_PROCESS ) return; printf("%-8.32s", utbufp->ut_name); /* the logname */ /* better: "%-8.*s",UT_NAMESIZE,utbufp->ut_name) */ printf(" "); /* a space */ printf("%-8.8s", utbufp->ut_line); /* the tty */ /* 8 chrs, limit to 8 chrs, left justify */ printf(" "); /* a space */ printf("%10ld", (long) utbufp->ut_time); /* login time */ printf(" "); /* a space */ printf("(%.256s)", utbufp->ut_host); /* the host */ /* limit to 256 no min */ printf("\n"); /* newline */ } /* * idea: produce output like: wuensch pts/1 Feb 4 10:42 (palantir2.unix.fas.harvard.edu) jol7257 pts/2 Feb 5 20:16 (c-68-35-133-39.hsd1.al.comcast.net) vyc921 pts/3 Feb 6 20:35 (65.112.8.130) */