- * where 'namelist' is a list of users login names.
- * The other options can all be given after one '-', or each can have its
- * own '-'. The -f option disables the printing of headers for short and
- * quick outputs. The -b option briefens long format outputs. The -p
- * option turns off plans for long format outputs.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sgtty.h>
-#include <utmp.h>
-#include <signal.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <lastlog.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-
-struct utmp utmp; /* for sizeof */
-#define NMAX sizeof(utmp.ut_name)
-#define LMAX sizeof(utmp.ut_line)
-
-#define ASTERISK '*' /* ignore this in real name */
-#define BLANK ' ' /* blank character (i.e. space) */
-#define CAPITALIZE 0137& /* capitalize character macro */
-#define COMMA ',' /* separator in pw_gecos field */
-#define COMMAND '-' /* command line flag char */
-#define CORY 'C' /* cory hall office */
-#define EVANS 'E' /* evans hall office */
-#define LINEBREAK 012 /* line feed */
-#define NULLSTR "" /* the null string, opposed to NULL */
-#define SAMENAME '&' /* repeat login name in real name */
-#define TALKABLE 0222 /* tty is writeable if 222 mode */
-
-struct person { /* one for each person fingered */
- char name[NMAX+1]; /* login name */
- char tty[LMAX+1]; /* NULL terminated tty line */
- long loginat; /* time of login (possibly last) */
- long idletime; /* how long idle (if logged in) */
- short int loggedin; /* flag for being logged in */
- short int writeable; /* flag for tty being writeable */
- char *realname; /* pointer to full name */
- char *office; /* pointer to office name */
- char *officephone; /* pointer to office phone no. */
- char *homephone; /* pointer to home phone no. */
- char *random; /* for any random stuff in pw_gecos */
- struct passwd *pwd; /* structure of /etc/passwd stuff */
- struct person *link; /* link to next person */
-};
-
-struct passwd *NILPWD = 0;
-struct person *NILPERS = 0;
-
-int persize = sizeof( struct person );
-int pwdsize = sizeof( struct passwd );
-
-char LASTLOG[] = "/usr/adm/lastlog"; /* last login info */
-char USERLOG[] = "/etc/utmp"; /* who is logged in */
-char outbuf[BUFSIZ]; /* output buffer */
-char *ctime();
-
-int unbrief = 1; /* -b option default */
-int header = 1; /* -f option default */
-int hack = 1; /* -h option default */
-int idle = 0; /* -i option default */
-int large = 0; /* -l option default */
-int match = 1; /* -m option default */
-int plan = 1; /* -p option default */
-int unquick = 1; /* -q option default */
-int small = 0; /* -s option default */
-int wide = 1; /* -w option default */
-
-int lf;
-int llopenerr;
-
-long tloc; /* current time */
-
-
-
-main( argc, argv )
-
- int argc;
- char *argv[];
-
-{
- FILE *fp, *fopen(); /* for plans */
- struct passwd *getpwent(); /* read /etc/passwd */
- struct person *person1, *p, *pend; /* people */
- struct passwd *pw; /* temporary */
- struct utmp user; /* ditto */
- char *malloc();
- char *s, *pn, *ln;
- char c;
- char *PLAN = "/.plan"; /* what plan file is */
- char *PROJ = "/.project"; /* what project file */
- int PLANLEN = strlen( PLAN );
- int PROJLEN = strlen( PROJ );
- int numnames = 0;
- int orgnumnames;
- int uf;
- int usize = sizeof user;
- int unshort;
- int i, j;
- int fngrlogin;
-
- setbuf( stdout, outbuf ); /* buffer output */
-
- /* parse command line for (optional) arguments */
-
- i = 1;
- if( strcmp( *argv, "sh" ) ) {
- fngrlogin = 0;
- while( i++ < argc && (*++argv)[0] == COMMAND ) {
- for( s = argv[0] + 1; *s != NULL; s++ ) {
- switch (*s) {
-
- case 'b':
- unbrief = 0;
- break;
-
- case 'f':
- header = 0;
- break;
-
- case 'h':
- hack = 0;
- break;
-
- case 'i':
- idle = 1;
- unquick = 0;
- break;
-
- case 'l':
- large = 1;
- break;
-
- case 'm':
- match = 0;
- break;
-
- case 'p':
- plan = 0;
- break;
-
- case 'q':
- unquick = 0;
- break;
-
- case 's':
- small = 1;
- break;
-
- case 'w':
- wide = 0;
- break;
-
- default:
- fprintf( stderr, "finger: Usage -- 'finger [-bfhilmpqsw] [login1 [login2 ...] ]'\n" );
- exit( 1 );
- }
- }
- }
- }
- else {
- fngrlogin = 1;
- }
- if( unquick ) {
- time( &tloc );
- }
- else {
- if( idle ) {
- time( &tloc );
- }
- }
-
- /* i > argc means no login names given so get them by reading USERLOG */
-
- if( (i > argc) || fngrlogin ) {
- unshort = large;
- if( ( uf = open(USERLOG, 0) ) >= 0 ) {
- user.ut_name[0] = NULL;
- while( user.ut_name[0] == NULL ) {
- if( read( uf, (char *) &user, usize ) != usize ) {
- printf( "No one logged on\n" );
- exit( 0 );
- }
- }
- person1 = (struct person *) malloc( persize );
- for( j = 0; j < NMAX; j++ ) {
- person1->tty[j] = user.ut_line[j];
- person1->name[j] = user.ut_name[j];
- }
- person1->name[NMAX] = NULL;
- person1->tty[NMAX] = NULL;
- person1->loginat = user.ut_time;
- person1->pwd = NILPWD;
- person1->loggedin = 1;
- numnames++;
- p = person1;
- while( read( uf, (char *) &user, usize ) == usize ) {
- if( user.ut_name[0] == NULL ) continue;
- p->link = (struct person *) malloc( persize );
- p = p->link;
- for( j = 0; j < NMAX; j++ ) {
- p->tty[j] = user.ut_line[j];
- p->name[j] = user.ut_name[j];
- }
- p->name[NMAX] = NULL;
- p->tty[NMAX] = NULL;
- p->loginat = user.ut_time;
- p->pwd = NILPWD;
- p->loggedin = 1;
- numnames++;
- }
- p->link = NILPERS;
- close( uf );
- }
- else {
- fprintf( stderr, "finger: error opening %s\n", USERLOG );
- exit( 2 );
- }
-
- /* if we are doing it, read /etc/passwd for the useful info */
-
- if( unquick ) {
- setpwent();
- fwopen();
- i = numnames;
- while( ( (pw = getpwent()) != NILPWD ) && ( i > 0 ) ) {
- p = person1;
- do {
- if( p->pwd == NILPWD ) {
- if( strcmp( p->name, pw->pw_name ) == 0 ) {
- p->pwd = (struct passwd *) malloc( pwdsize );
- pwdcopy( p->pwd, pw );
- decode( p );
- i--;
- }
- }
- p = p->link;
- } while( p != NILPERS );
- }
- fwclose();
- endpwent();
- }
- }
-
- /* get names from command line and check to see if they're logged in */
-
- else {
- unshort = ( small == 1 ? 0 : 1 );
- while (i <= argc && netfinger(*argv)) {
- i++;
- argv++;
- }
- if (i++ > argc)
- exit(0);
- person1 = (struct person *) malloc( persize );
- strcpy( person1->name, (argv++)[ 0 ] );
- person1->loggedin = 0;
- person1->pwd = NILPWD;
- numnames++;
- p = person1;
- while( i++ <= argc ) {
- if (netfinger(*argv)) {
- argv++;
- continue;
- }
- p->link = (struct person *) malloc( persize );
- p = p->link;
- strcpy( p->name, (argv++)[ 0 ] );
- p->loggedin = 0;
- p->pwd = NILPWD;
- numnames++;
- }
- p->link = NILPERS;
- pend = p;
-
- /* if we are doing it, read /etc/passwd for the useful info */
-
- orgnumnames = numnames;
- if( unquick ) {
- setpwent();
- while( ( pw = getpwent() ) != NILPWD ) {
- p = person1;
- i = 0;
- do {
- if( strcmp( p->name, pw->pw_name ) == 0 ||
- matchcmp( pw->pw_gecos, pw->pw_name, p->name ) ) {
- if( p->pwd == NILPWD ) {
- p->pwd = (struct passwd *) malloc( pwdsize );
- pwdcopy( p->pwd, pw );
- }
- else { /* handle multiple logins -- append new
- "duplicate" entry to end of list */
- pend->link = (struct person *) malloc(persize);
- pend = pend->link;
- pend->link = NILPERS;
- strcpy( pend->name, p->name );
- pend->pwd = (struct passwd *) malloc(pwdsize);
- pwdcopy( pend->pwd, pw );
- numnames++;
- }
- }
- p = p->link;
- } while( ++i < orgnumnames );
- }
- endpwent();
- }
-
- /* Now get login information */
-
- if( ( uf = open(USERLOG, 0) ) >= 0 ) {
- while( read( uf, (char *) &user, usize ) == usize ) {
- if( user.ut_name[0] == NULL ) continue;
- p = person1;
- do {
- pw = p->pwd;
- if( pw == NILPWD ) {
- i = ( strcmp( p->name, user.ut_name ) ? 0 : NMAX );
- }
- else {
- i = 0;
- while( (i < NMAX) &&
- ( pw->pw_name[i] == user.ut_name[i]) ) {
- if( pw->pw_name[i] == NULL ) {
- i = NMAX;
- break;
- }
- i++;
- }
- }
- if( i == NMAX ) {
- if( p->loggedin == 1 ) {
- pend->link = (struct person *) malloc(persize);
- pend = pend->link;
- pend->link = NILPERS;
- strcpy( pend->name, p->name );
- for( j = 0; j < NMAX; j++ ) {
- pend->tty[j] = user.ut_line[j];
- }
- pend->tty[ NMAX ] = NULL;
- pend->loginat = user.ut_time;
- pend->loggedin = 2;
- if( pw == NILPWD ) {
- pend ->pwd = NILPWD;
- }
- else {
- pend->pwd = (struct passwd *) malloc(pwdsize);
- pwdcopy( pend->pwd, pw );
- }
- numnames++;
- }
- else {
- if( p->loggedin != 2 ) {
- for( j = 0; j < NMAX; j++ ) {
- p->tty[j] = user.ut_line[j];
- }
- p->tty[ NMAX ] = NULL;
- p->loginat = user.ut_time;
- p->loggedin = 1;
- }
- }
- }
- p = p->link;
- } while( p != NILPERS );
- }
- fwopen();
- p = person1;
- while( p != NILPERS ) {
- if( p->loggedin == 2 ) {
- p->loggedin = 1;
- }
- decode( p );
- p = p->link;
- }
- fwclose();
- close( uf );
- }
- else {
- fprintf( stderr, "finger: error opening %s\n", USERLOG );
- exit( 2 );
- }
- }
-
- /* print out what we got */
-
- if( header ) {
- if( unquick ) {
- if( !unshort ) {
- if( wide ) {
- printf(
-"Login Name TTY Idle When Office\n" );
- }
- else {
- printf(
-"Login TTY Idle When Office\n" );
- }
- }
- }
- else {
- printf( "Login TTY When" );
- if( idle ) {
- printf( " Idle" );
- }
- printf( "\n" );
- }
- }
- p = person1;
- do {
- if( unquick ) {
- if( unshort ) {
- personprint( p );
- if( p->pwd != NILPWD ) {
- if( hack ) {
- s = malloc(strlen((p->pwd)->pw_dir) + PROJLEN + 1 );
- strcpy( s, (p->pwd)->pw_dir );
- strcat( s, PROJ );
- if( ( fp = fopen( s, "r") ) != NULL ) {
- printf( "Project: " );
- while( ( c = getc(fp) ) != EOF ) {
- if( c == LINEBREAK ) {
- break;
- }
- putc( c, stdout );
- }
- fclose( fp );
- printf( "\n" );
- }
- }
- if( plan ) {
- s = malloc( strlen( (p->pwd)->pw_dir ) + PLANLEN + 1 );
- strcpy( s, (p->pwd)->pw_dir );
- strcat( s, PLAN );
- if( ( fp = fopen( s, "r") ) == NULL ) {
- printf( "No Plan.\n" );
- }
- else {
- printf( "Plan:\n" );
- while( ( c = getc(fp) ) != EOF ) {
- putc( c, stdout );
- }
- fclose( fp );
- }
- }
- }
- if( p->link != NILPERS ) {
- printf( "\n" );
- }
- }
- else {
- shortprint( p );
- }
- }
- else {
- quickprint( p );
- }
- p = p->link;
- } while( p != NILPERS );
- exit(0);
-}
-
-
-/* given a pointer to a pwd (pfrom) copy it to another one, allocating
- * space for all the stuff in it. Note: Only the useful (what the
- * program currently uses) things are copied.
- */
-
-pwdcopy( pto, pfrom ) /* copy relevant fields only */
-
- struct passwd *pto, *pfrom;
-{
- pto->pw_name = malloc( strlen( pfrom->pw_name ) + 1 );
- strcpy( pto->pw_name, pfrom->pw_name );
- pto->pw_uid = pfrom->pw_uid;
- pto->pw_gecos = malloc( strlen( pfrom->pw_gecos ) + 1 );
- strcpy( pto->pw_gecos, pfrom->pw_gecos );
- pto->pw_dir = malloc( strlen( pfrom->pw_dir ) + 1 );
- strcpy( pto->pw_dir, pfrom->pw_dir );
- pto->pw_shell = malloc( strlen( pfrom->pw_shell ) + 1 );
- strcpy( pto->pw_shell, pfrom->pw_shell );
-}
-
-
-/* print out information on quick format giving just name, tty, login time
- * and idle time if idle is set.
- */
-
-quickprint( pers )
-
- struct person *pers;
-{
- int idleprinted;
-
- printf( "%-*.*s", NMAX, NMAX, pers->name );
- printf( " " );
- if( pers->loggedin ) {
- if( idle ) {
- findidle( pers );
- if( pers->writeable ) {
- printf( " %-*.*s %-16.16s", LMAX, LMAX,
- pers->tty, ctime( &pers->loginat ) );
- }
- else {
- printf( "*%-*.*s %-16.16s", LMAX, LMAX,
- pers->tty, ctime( &pers->loginat ) );
- }
- printf( " " );
- idleprinted = ltimeprint( &pers->idletime );
- }
- else {
- printf( " %-*.*s %-16.16s", LMAX, LMAX,
- pers->tty, ctime( &pers->loginat ) );
- }
- }
- else {
- printf( " Not Logged In" );
- }
- printf( "\n" );
-}
-
-
-/* print out information in short format, giving login name, full name,
- * tty, idle time, login time, office location and phone.
- */
-
-shortprint( pers )
-
- struct person *pers;
-
-{
- struct passwd *pwdt = pers->pwd;
- char buf[ 26 ];
- int i, len, offset, dialup;
-
- if( pwdt == NILPWD ) {
- printf( "%-*.*s", NMAX, NMAX, pers->name );
- printf( " ???\n" );
- return;
- }
- printf( "%-*.*s", NMAX, NMAX, pwdt->pw_name );
- dialup = 0;
- if( wide ) {
- if( strlen( pers->realname ) > 0 ) {
- printf( " %-20.20s", pers->realname );
- }
- else {
- printf( " ??? " );
- }
- }
- if( pers->loggedin ) {
- if( pers->writeable ) {
- printf( " " );
- }
- else {
- printf( " *" );
- }
- }
- else {
- printf( " " );
- }
- if( strlen( pers->tty ) > 0 ) {
- strcpy( buf, pers->tty );
- if( (buf[0] == 't') && (buf[1] == 't') && (buf[2] == 'y') ) {
- offset = 3;
- for( i = 0; i < 2; i++ ) {
- buf[i] = buf[i + offset];
- }
- }
- if( (buf[0] == 'd') && pers->loggedin ) {
- dialup = 1;
- }
- printf( "%-2.2s ", buf );
- }
- else {
- printf( " " );
- }
- strcpy(buf, ctime(&pers->loginat));
- if( pers->loggedin ) {
- stimeprint( &pers->idletime );
- offset = 7;
- for( i = 4; i < 19; i++ ) {
- buf[i] = buf[i + offset];
- }
- printf( " %-9.9s ", buf );
- }
- else if (pers->loginat == 0)
- printf(" < . . . . >");
- else if (tloc - pers->loginat >= 180 * 24 * 60 * 60)
- printf( " <%-6.6s, %-4.4s>", buf+4, buf+20 );
- else
- printf(" <%-12.12s>", buf+4);
- len = strlen( pers->homephone );
- if( dialup && (len > 0) ) {
- if( len == 8 ) {
- printf( " " );
- }
- else {
- if( len == 12 ) {
- printf( " " );
- }
- else {
- for( i = 1; i <= 21 - len; i++ ) {
- printf( " " );
- }
- }
- }
- printf( "%s", pers->homephone );
- }
- else {
- if( strlen( pers->office ) > 0 ) {
- printf( " %-11.11s", pers->office );
- if( strlen( pers->officephone ) > 0 ) {
- printf( " %8.8s", pers->officephone );
- }
- else {
- if( len == 8 ) {
- printf( " %8.8s", pers->homephone );
- }
- }
- }
- else {
- if( strlen( pers->officephone ) > 0 ) {
- printf( " %8.8s", pers->officephone );
- }
- else {
- if( len == 8 ) {
- printf( " %8.8s", pers->homephone );
- }
- else {
- if( len == 12 ) {
- printf( " %12.12s", pers->homephone );
- }
- }
- }
- }
- }
- printf( "\n" );
-}
-
-
-/* print out a person in long format giving all possible information.
- * directory and shell are inhibited if unbrief is clear.