[alt.sources] whoson - a better unix users command

aikc@castle.ed.ac.uk (Kenneth Cameron) (04/29/91)

Heres a little program I knocked up to provide 'users' type information
in a format used by a program running on Edinburghs EMAS machine.
,Kenneth.

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	whoson.c
#	whoson.1
# This archive created: Mon Apr 29 17:16:15 1991
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'whoson.c'
then
	echo shar: "will not over-write existing file 'whoson.c'"
else
cat << \SHAR_EOF > 'whoson.c'
/* Whoson - A Unix equivalent of the Emas command
Copyright (c) 1991, Kenneth Cameron.
This software has not been placed in the public domain
but may be freely distributed/used provided this notice remains intact.
  
This program is provided with no warranty that it will behave
in the way expected. Further, the author will not be responsible
for any loss resulting from the use or mis-use of this software. */

#include <stdio.h>
#include <string.h>
#include <utmp.h>

#define MAXU	1000	/* How many users should we cope with */

struct utmp User;
char users[MAXU][10];
int nsers[MAXU],total,number,visited;

sortu()
{
	int a,b,c;
	char temp[8],n;
	for(a=0;a<number;a++){
		b=a;
		for(c=a;c<number;c++)if(strcmp(users[b],users[c])>0)b=c;
		strcpy(temp,users[a]);strcpy(users[a],users[b]);
		strcpy(users[b],temp);n=nsers[a];nsers[a]=nsers[b];
		nsers[b]=n;
	}
	return;
}

main(argc,argv)
int argc;
char *argv[];
{
	FILE *fin;
	int x,y,z,n;
	char buf[20];
	/* check flags */
	for(x=1;x<argc;x++){
		if(!strcmp(argv[x],"-h")){
printf("Usage: %s [-h|-s]\n\n",argv[0]);
printf("Display a list of those logged on. If the -s option is not specified\n");
printf("then users logged on more than once will have the number shown in\n");
printf("brackets after their username. Number of users/logins also shown\n");
			exit(0);
		}
		if(strcmp(argv[x],"-s")){
			printf("Invalid option use -h for help.\n");
			exit(-1);
		}
	}
	/* clear the user info areas */
	total=number=visited=0;
	for(x=0;x<MAXU;x++){users[x][0]='\0';nsers[x]=0;}
	/* fetch the data we want from /etc/utmp */
	if((fin=fopen("/etc/utmp","rb"))==(FILE *)0){
		fprintf(stderr,
			"Can't open /etc/utmp. Your machine's F**KED.\n");
		exit(-1);
	}
	while(!feof(fin)){
		/*get file entry*/
		if(fread(&User,sizeof(User),1,fin)!=1)break;
		visited++;
		if(User.ut_host[0]=='\0')continue;/* Empty Slot */
		total++;
		for(x=0;x<MAXU;x++){
			if(users[x][0]=='\0'){
				strncpy(users[x],User.ut_name,8);
				users[x][8];
				number++;nsers[x]=1;
				break;
			}
			if(!strncmp(User.ut_name,users[x],8)){
				nsers[x]++;break;
			}
		}
	}
	fclose(fin);
	sortu();/* Sort the users into alphabetic order */
	printf("Users currently logged on are:\n");
	for(x=y=0;x<number;x++){
		if(y==0)printf("   ");y++;
		sprintf(buf,"%s",users[x]);
		if((argc==1)&&(nsers[x]>1))
			sprintf(buf,"%s(%d)",users[x],nsers[x]);
		n=strlen(buf);printf("%s",buf);
		if(y==6){y=0;printf("\n");}
		else for(z=n;z<12;z++)printf(" ");
	}
	if(y!=0)printf("\n");
	printf("               Total users: %d\tTotal logins: %d[%d]\n",number,
		total,visited);
}

SHAR_EOF
fi
if test -f 'whoson.1'
then
	echo shar: "will not over-write existing file 'whoson.1'"
else
cat << \SHAR_EOF > 'whoson.1'
.\" $Copyright:	$
.\" Copyright (c) 1991, Kenneth Cameron.
.\" This software has not been placed in the public domain
.\" but may be freely distributed/used provided this notice remains intact.
.\"  
.\" This program is provided with no warranty that it will behave
.\" in the way expected. Further, the author will not be responsible
.\" for any loss resulting from the use or mis-use of this software.
...
.V= $Header: whoson.1 91/04/28 $
.TH WHOSON 1 "\*(V)" "KMC"
.SH NAME
whoson \- a better list of users who are on the system
.SH SYNOPSIS
.B ~aikc/bin/whoson [-h|-s]
.SH DESCRIPTION
.I whoson
lists the login names of the users currently on the system in a sensible
format. Stripping out repeat entries, using a number in brackets instead.
.SH FILES
/etc/utmp
.SH SEE ALSO
who(1),users(1)
.SH BUGS
Because the nonuser(X) macro did n't work, the hack around misses
users if the login is local. This is better than if nonuser is used.
.SH AUTHOR
Kenneth Cameron
SHAR_EOF
fi
exit 0
#	End of shell archive