tholm@uvicctr.UUCP (Terrence W. Holm) (11/09/88)
EFTH MINIX report #55 - November 1988 - users(1) There follows an implementation of users(1) for MINIX. ---------------------------------------------------------- echo x - users.1 gres '^X' '' > users.1 << '/' XCOMMANDS X users(1) - short list of who is logged on X XINVOCATION X users X XEXPLANATION X One line is printed, containing the names of everyone X logged on. X XREFERENCES X who(1) / echo x - users.c gres '^X' '' > users.c << '/' X/* users(1) X * X * Author: Terrence W. Holm Nov. 1988 X * X * X * Usage: users X * X * A simple users(1) command for MINIX. Assumes tty0 X * to tty9 are the only possible login devices. X * See last.c for more robust code for reading wtmp. X */ X X X#include <stdio.h> X#include <utmp.h> X X#ifndef WTMP X#define WTMP "/usr/adm/wtmp" X#endif X X#define min( a, b ) ( (a < b) ? a : b ) X X#define BUFFER_SIZE 1024 /* Room for wtmp records */ X#define MAX_WTMP_COUNT ( BUFFER_SIZE / sizeof(struct utmp) ) X Xstruct utmp wtmp_buffer[ MAX_WTMP_COUNT ]; X X Xmain() X { X FILE *f; X long size; /* Number of wtmp records in the file */ X int wtmp_count; /* How many to read into wtmp_buffer */ X int used = 0; X int user_count = 0; X char users[ 10 ][ 8 ]; X X X if( (f = fopen( WTMP, "r" )) == NULL ) X /* No login/logout records kept */ X exit( 0 ); X X if ( fseek( f, 0L, 2 ) != 0 || (size = ftell(f)) % sizeof(struct utmp) != 0 ) X { X fprintf( stderr, "users: invalid wtmp file\n" ); X exit( 1 ); X } X X X size /= sizeof(struct utmp); /* Number of records in wtmp */ X X X while( size > 0 ) X { X wtmp_count = (int) min( size, MAX_WTMP_COUNT ); X X size -= (long) wtmp_count; X X fseek( f, size * sizeof(struct utmp), 0 ); X X if ( fread( &wtmp_buffer[ 0 ], sizeof(struct utmp), wtmp_count, f ) != wtmp_count ) X { X fprintf( stderr, "users: read error on wtmp file\n" ); X exit( 1 ); X } X X X while ( --wtmp_count >= 0 ) X { X int tty; X X if ( strcmp( wtmp_buffer[ wtmp_count ].ut_line, "~" ) == 0 ) X { X Print_Users( user_count, users ); X exit( 0 ); X } X X tty = wtmp_buffer[ wtmp_count ].ut_line[3] - '0'; X X if ( tty < 0 || tty > 9 ) X { X fprintf( stderr, "users: encountered unknown tty in wtmp file\n" ); X exit( 1 ); X } X X if ( ! (used & (1 << tty)) ) X { X used |= 1 << tty; X memcpy( users[ user_count ], wtmp_buffer[ wtmp_count ].ut_name, 8 ); X X if ( users[ user_count ][ 0 ] != '\0' ) X ++user_count; X } X } X X } /* end while( size > 0 ) */ X X Print_Users( user_count, users ); X X exit( 0 ); X } X X X XStrncmp( str1, str2 ) X char *str1; X char *str2; X X { X return( strncmp( str1, str2, 8 ) ); X } X X X XPrint_Users( user_count, users ) X int user_count; X char *users; X X { X int i; X X qsort( users, user_count, 8, Strncmp ); X X for ( i = 0; i < user_count - 1; ++i ) X { X printf( "%.8s ", users ); X users += 8; X } X X if ( user_count > 0 ) X printf( "%.8s\n", users ); X } / ---------------------------------------------------------- Terrence W. Holm uw-beaver!uvicctr!tholm