/*who3.c - a first version of the who program * open read UTMP file, and show results */ #include #include #include #include #include #include #define SHOWHOST /* include remote machine on output */ void showtime(time_t); void show_info(struct utmp *); int main() { struct utmp *utbufp, /* holds pointer to next rec */ *utmp_next(); /* returns pointer to next */ if ( utmp_open(UTMP_FILE) == -1) { perror( UTMP_FILE ); /* UTMP_FILE is in utmp.h */ exit(1); } while ( (utbufp = utmp_next() ) != ((struct utmp *) NULL)) show_info( utbufp ); utmp_close(); return 0; /* went ok */ } /* * show info() * displays contents of the utmp struct in human readable form */ void show_info( struct utmp *utbufp ) { if ( utbufp -> ut_type != USER_PROCESS ) return; printf("%-8.8s", utbufp->ut_name); printf(" "); printf("%-8.8s", utbufp->ut_line); printf(" "); printf("%10ld", utbufp->ut_time); printf(" "); #ifdef SHOWHOST if (utbufp->ut_host[0] != '\0' ) printf(" (%s) ", utbufp->ut_host);/* the host */ #endif printf("\n"); } void showtime( long timeval ) /* * displays time in a format fit for human consumption * uses ctime to build a string then picks parts out of it * Note: %12.12s prints a string 12 chars wide and LIMITS * it to 12chars. */ { char *cp; /* to hold address of time */ char cp = ctime(&timeval); /* convert time to sting */ printf("%12.12s", cp+4 ); /* pick 12 chars form pos 4 */ } * utmplib.c - functions to buffer reads from utmp file * * functoins are * utmp_open (filename ) - open file * returns -1 on error * utmp_next () -returns pointer to next struct * returns NULL on eof * utmp_close() -close file * * read NRECS per read and the doles them out from the buffer */ #include #include #include #include #include #define NRECS 16 #define NULLUT ((struct utmp *)NULL) #define UTSIZE (sizeof(struct utmp)) static char utmpbuf[NRECS * UTSIZE]; static int num_recs; static int cur_rec; static int fd_utmp = -1; utmp_open ( char *filename ) { fd_utmp = open( filename, O_RDONLY); cur_rec = num_recs = 0; return fd_utmp; } struct utmp *utmp_next() { struct utmp *recp; if ( fd_utmp == -1 ) return NULLUT; if ( cur_rec==num_recs && utmp_reload()==0) return NULLUT; /* get address of next record */ recp = ( struct utmp *) &utmpbuf[cur_rec * UTSIZE]; cur_rec++; return recp; } int utmp_reload() /* * read next bunch of records into buffer */ { int amt_read; amt_read = read( fd_utmp, utmpbuf, NRECS * UTSIZE); /* how many did we get? */ num_recs = amt_read/UTSIZE; /* reset pointer */ cur_rec = 0; return num_recs; } void utmp_close() { if ( fd_utmp != -1) /* don't close if not */ close (fd_utmp); /* open */ }