home *** CD-ROM | disk | FTP | other *** search
- /*
- * This finger program is public domain, written by Mr A.N.Onymous at
- * Imperial College London Dept. of Computing.
- */
-
- #ifndef lint
- static char SccsId[] = "@(#)finger.c 1.3 (IC DoC) 1/28/86";
- #endif
-
- /* This is a finger program. It prints out useful information about users
- * by digging it up from various system files. It is not very portable
- * because the most useful parts of the information (the full user name,
- * office, and phone numbers) are all stored in the VAX-unused gecos field
- * of /etc/passwd, which, unfortunately, other UNIXes use for other things.
- *
- * There are three output formats, all of which give login name, teletype
- * line number, and login time. The short output format is reminiscent
- * of finger on ITS, and gives one line of information per user containing
- * in addition to the minimum basic requirements (MBR), the full name of
- * the user, his idle time and office location and phone number. The
- * quick style output is UNIX who-like, giving only name, teletype and
- * login time. Finally, the long style output give the same information
- * as the short (in more legible format), the home directory and shell
- * of the user, and, if it exits, a copy of the file .plan in the users
- * home directory. Finger may be called with or without a list of people
- * to finger -- if no list is given, all the people currently logged in
- * are fingered.
- *
- * The program is validly called by one of the following:
- *
- * finger {short form list of users}
- * finger -l {long form list of users}
- * finger -b {briefer long form list of users}
- * finger -q {quick list of users}
- * finger -i {quick list of users with idle times}
- * finger namelist {long format list of specified users}
- * finger -s namelist {short format list of specified users}
- * finger -w namelist {narrow short format list of specified users}
- *
- * 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 <time.h>
-
- #define UTMP_FILE "/etc/utmp"
-
- 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 */
- #ifdef ICDOC
- #ifdef ERCC
- #define JCMB 'J' /* J.C.M.B. */
- #endif ERCC
- #define HUXLEY 'H' /* huxley building */
- #endif ICDOC
- #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 );
-
- #define HAVE_LASTLOG
- #ifdef HAVE_LASTLOG
- char LASTLOG[] = "/var/adm/lastlog"; /* last login info */
- #endif
- #ifdef UTMP_FILE
- char USERLOG[] = UTMP_FILE; /* who is logged in */
- #else
- char USERLOG[] = "/etc/utmp"; /* who is logged in */
- #endif
- 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 ) {
- #ifdef USER_PROCESS
- user.ut_type = EMPTY;
- while( user.ut_type != USER_PROCESS )
- #else
- user.ut_name[0] = NULL;
- while( user.ut_name[0] == NULL )
- #endif
- {
- if( read( uf, (char *) &user, usize ) != usize ) {
- printf( "\nNo one logged on\n" );
- exit( 0 );
- }
- }
- #ifdef DEBUG
- printf("name = %s, line = %s\n", user.ut_name, user.ut_line);
- #endif
- 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 ) {
- #ifdef USER_PROCESS
- if( user.ut_type != USER_PROCESS ) continue;
- #else
- if( user.ut_name[0] == NULL ) continue;
- #endif
- 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 );
- i++;
- person1 = (struct person *) malloc( persize );
- strcpy( person1->name, (argv++)[ 0 ] );
- person1->loggedin = 0;
- person1->pwd = NILPWD;
- numnames++;
- p = person1;
- while( i++ <= argc ) {
- 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 ) {
- #ifdef USER_PROCESS
- if( user.ut_type != USER_PROCESS ) continue;
- #else
- if( user.ut_name[0] == NULL ) continue;
- #endif
- 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 );
- #ifndef MINT
- if( ( fp = fopen( s, "r") ) == NULL ) {
- #else
- if( ( fp = fopen( s, "rb") ) == NULL ) {
- #endif
- 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] == 's') && (buf[1] == 'x') && (buf[2] == 't') ) {
- printf( "lx " );
- }
- else {
- 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.
- */
-
- personprint( pers )
-
- struct person *pers;
- {
- struct passwd *pwdt = pers->pwd;
- int idleprinted;
-
- if( pwdt == NILPWD ) {
- printf( "Login name: %-10s", pers->name );
- printf( " " );
- printf( "In real life: ???\n");
- return;
- }
- printf( "Login name: %-10s", pwdt->pw_name );
- if( pers->loggedin ) {
- if( pers->writeable ) {
- printf( " " );
- }
- else {
- printf( " (messages off) " );
- }
- }
- else {
- printf( " " );
- }
- if( strlen( pers->realname ) > 0 ) {
- printf( "In real life: %-s", pers->realname );
- }
- if( strlen( pers->office ) > 0 ) {
- printf( "\nOffice: %-.11s", pers->office );
- if( strlen( pers->officephone ) > 0 ) {
- printf( ", %s", pers->officephone );
- if( strlen( pers->homephone ) > 0 ) {
- printf( " Home phone: %s", pers->homephone );
- }
- else {
- if( strlen( pers->random ) > 0 ) {
- printf( " %s", pers->random );
- }
- }
- }
- else {
- if( strlen( pers->homephone ) > 0 ) {
- printf(" Home phone: %s",pers->homephone);
- }
- if( strlen( pers->random ) > 0 ) {
- printf( " %s", pers->random );
- }
- }
- }
- else {
- if( strlen( pers->officephone ) > 0 ) {
- printf( "\nPhone: %s", pers->officephone );
- if( strlen( pers->homephone ) > 0 ) {
- printf( "\n, %s", pers->homephone );
- if( strlen( pers->random ) > 0 ) {
- printf( ", %s", pers->random );
- }
- }
- else {
- if( strlen( pers->random ) > 0 ) {
- printf( "\n, %s", pers->random );
- }
- }
- }
- else {
- if( strlen( pers->homephone ) > 0 ) {
- printf( "\nPhone: %s", pers->homephone );
- if( strlen( pers->random ) > 0 ) {
- printf( ", %s", pers->random );
- }
- }
- else {
- if( strlen( pers->random ) > 0 ) {
- printf( "\n%s", pers->random );
- }
- }
- }
- }
- if( unbrief ) {
- printf( "\n" );
- printf( "Directory: %-25s", pwdt->pw_dir );
- if( strlen( pwdt->pw_shell ) > 0 ) {
- printf( " Shell: %-s", pwdt->pw_shell );
- }
- }
- if( pers->loggedin ) {
- register char *ep = ctime( &pers->loginat );
- printf("\nOn since %15.15s on %-*.*s ", &ep[4], LMAX, LMAX, pers->tty );
- idleprinted = ltimeprint( &pers->idletime );
- if( idleprinted ) {
- printf( " Idle Time" );
- }
- }
- else if (pers->loginat == 0)
- #ifdef HAVE_LASTLOG
- printf("\nNever logged in.");
- #else
- printf("\nNot logged in.");
- #endif
- else if (tloc - pers->loginat > 180 * 24 * 60 * 60) {
- register char *ep = ctime( &pers->loginat );
- printf("\nLast login %10.10s, %4.4s on %.*s", ep, ep+20, LMAX, pers->tty);
- }
- else {
- register char *ep = ctime( &pers->loginat );
- printf("\nLast login %16.16s on %.*s", ep, LMAX, pers->tty );
- }
- printf( "\n" );
- }
-
-
- /*
- * very hacky section of code to format phone numbers. filled with
- * magic constants like 4, 7 and 10.
- */
-
- char *phone( s, len )
-
- char *s;
- int len;
- {
- char *strsave();
- char fonebuf[ 15 ];
- int i;
-
- switch( len ) {
-
- case 4:
- #ifdef ICDOC
- fonebuf[ 0 ] = ' ';
- fonebuf[ 1 ] = 'x';
- for( i = 0; i <= 3; i++ ) {
- fonebuf[ 2 + i ] = *s++;
- }
- fonebuf[ 6 ] = NULL;
- #else
- fonebuf[ 0 ] = ' ';
- fonebuf[ 1 ] = 'x';
- fonebuf[ 2 ] = '2';
- fonebuf[ 3 ] = '-';
- for( i = 0; i <= 3; i++ ) {
- fonebuf[ 4 + i ] = *s++;
- }
- fonebuf[ 8 ] = NULL;
- #endif
- return( strsave( &fonebuf[0] ) );
- break;
-
- case 7:
- for( i = 0; i <= 2; i++ ) {
- fonebuf[ i ] = *s++;
- }
- #ifdef ICDOC
- fonebuf[ 3 ] = ' '; /* BT plc standard! */
- #else
- fonebuf[ 3 ] = '-';
- #endif
- for( i = 0; i <= 3; i++ ) {
- fonebuf[ 4 + i ] = *s++;
- }
- fonebuf[ 8 ] = NULL;
- return( strsave( &fonebuf[0] ) );
- break;
-
- case 10:
- for( i = 0; i <= 2; i++ ) {
- fonebuf[ i ] = *s++;
- }
- fonebuf[ 3 ] = '-';
- for( i = 0; i <= 2; i++ ) {
- fonebuf[ 4 + i ] = *s++;
- }
- fonebuf[ 7 ] = '-';
- for( i = 0; i <= 3; i++ ) {
- fonebuf[ 8 + i ] = *s++;
- }
- fonebuf[ 12 ] = NULL;
- return( strsave( &fonebuf[0] ) );
- break;
-
- default:
- fprintf( stderr, "finger: error in phone numbering\n" );
- return( strsave(s) );
- break;
- }
- }
-
-
- /* decode the information in the gecos field of /etc/passwd
- * another hacky section of code, but given the format the stuff is in...
- */
-
- decode( pers )
-
- struct person *pers;
-
- {
- struct passwd *pwdt = pers->pwd;
- char buffer[ 256 ], *bp, *gp, *lp;
- char *phone();
- int alldigits;
- int len;
- int i;
-
- pers->realname = NULLSTR;
- pers->office = NULLSTR;
- pers->officephone = NULLSTR;
- pers->homephone = NULLSTR;
- pers->random = NULLSTR;
- if( pwdt != NILPWD ) {
- gp = pwdt->pw_gecos;
- #ifdef DEBUG
- fprintf(stderr, "gecos = %s\n", gp);
- #endif
- bp = &buffer[ 0 ];
- if( *gp == ASTERISK ) {
- gp++;
- }
- while( (*gp != NULL) && (*gp != COMMA) ) { /* name */
- if( *gp == SAMENAME ) {
- lp = pwdt->pw_name;
- *bp++ = CAPITALIZE(*lp++);
- while( *lp != NULL ) {
- *bp++ = *lp++;
- }
- }
- else {
- *bp++ = *gp;
- }
- gp++;
- }
- *bp = NULL;
- pers->realname = malloc( strlen( &buffer[0] ) + 1 );
- strcpy( pers->realname, &buffer[0] );
- #ifdef DEBUG
- fprintf(stderr, "name = %s\n", pers->realname);
- #endif
- if( *gp++ == COMMA ) { /* office, supposedly */
- #ifdef DEBUG
- fprintf(stderr, "office...");
- #endif
- alldigits = 1;
- bp = &buffer[ 0 ];
- while( (*gp != NULL) && (*gp != COMMA) ) {
- *bp = *gp++;
- alldigits = alldigits && ('0' <= *bp) && (*bp <= '9');
- bp++;
- }
- *bp = NULL;
- len = strlen( &buffer[0] );
- #ifdef DEBUG
- fprintf(stderr, "got %s...", buffer);
- #endif
- #ifdef ICDOC
- if( buffer[ len - 1 ] == HUXLEY ) {
- #ifdef ERCC
- strcpy( &buffer[ len - 1 ], " JCMB" );
- #else
- strcpy( &buffer[ len - 1 ], " Huxley" );
- #endif ERCC
- pers->office = malloc( len + 5 );
- strcpy( pers->office, &buffer[0] );
- } else {
- #endif
- if( buffer[ len - 1 ] == CORY ) {
- strcpy( &buffer[ len - 1 ], " Cory" );
- pers->office = malloc( len + 5 );
- strcpy( pers->office, &buffer[0] );
- }
- else {
- if( buffer[ len - 1 ] == EVANS ) {
- strcpy( &buffer[ len - 1 ], " Evans" );
- pers->office = malloc( len + 6 );
- strcpy( pers->office, &buffer[0] );
- }
- else {
- if( buffer[ len - 1 ] == 'L' ) {
- strcpy( &buffer[ len - 1 ], " LBL" );
- pers->office = malloc( len + 4 );
- strcpy( pers->office, &buffer[0] );
- }
- else {
- if( alldigits ) {
- if( len == 4 ) {
- pers->officephone = phone(&buffer[0], len);
- }
- else {
- if( (len == 7) || (len == 10) ) {
- pers->homephone = phone(&buffer[0],len);
- }
- }
- }
- else {
- pers->random = malloc( len + 1 );
- strcpy( pers->random, &buffer[0] );
- }
- }
- }
- }
- #ifdef ICDOC
- /*}*/
- #endif
- #ifdef DEBUG
- fprintf(stderr, "ended up with %s\n", pers->office);
- #endif
- if( *gp++ == COMMA ) { /* office phone, theoretically */
- #ifdef DEBUG
- fprintf(stderr, "Processing %s\n", gp);
- #endif
- bp = &buffer[ 0 ];
- alldigits = 1;
- while( (*gp != NULL) && (*gp != COMMA) ) {
- *bp = *gp++;
- alldigits = alldigits && ('0' <= *bp) && (*bp <= '9');
- bp++;
- }
- *bp = NULL;
- #ifdef DEBUG
- fprintf(stderr, "Got %s...", buffer);
- #endif
- len = strlen( &buffer[0] );
- if( alldigits ) {
- if( len != 4 ) {
- if( (len == 7) || (len == 10) ) {
- pers->homephone = phone( &buffer[0], len );
- }
- else {
- pers->random = malloc( len + 1 );
- strcpy( pers->random, &buffer[0] );
- }
- }
- else {
- #ifdef DEBUG
- fprintf(stderr, "len == 4, so officephone\n");
- #endif
- pers->officephone = phone( &buffer[0], len );
- }
- }
- else {
- pers->random = malloc( len + 1 );
- strcpy( pers->random, &buffer[0] );
- }
- if( *gp++ == COMMA ) { /* home phone?? */
- #ifdef DEBUG
- fprintf(stderr, "looking for home phone in %s\n", gp);
- #endif
- bp = &buffer[ 0 ];
- alldigits = 1;
- while( (*gp != NULL) && (*gp != COMMA) ) {
- *bp = *gp++;
- alldigits = alldigits && ('0' <= *bp) &&
- (*bp <= '9');
- bp++;
- }
- *bp = NULL;
- len = strlen( &buffer[0] );
- if( alldigits && ( (len == 7) || (len == 10) ) ) {
- if( *pers->homephone != NULL ) {
- pers->officephone = pers->homephone;
- }
- pers->homephone = phone( &buffer[0], len );
- }
- else {
- pers->random = malloc( strlen( &buffer[0] ) + 1 );
- strcpy( pers->random, &buffer[0] );
- }
- }
- }
- }
- if( pers->loggedin == 0 ) {
- findwhen( pers );
- }
- else {
- findidle( pers );
- }
- }
- }
-
-
- /* find the last log in of a user by checking the LASTLOG file.
- * the entry is indexed by the uid, so this can only be done if
- * the uid is known (which it isn't in quick mode)
- */
-
- fwopen()
- {
- #ifdef HAVE_LASTLOG
- if( ( lf = open(LASTLOG, 0) ) >= 0 ) {
- llopenerr = 0;
- }
- else {
- fprintf( stderr, "finger: lastlog open error\n" );
- llopenerr = 1;
- }
- #else
- llopenerr = 1;
- #endif
- }
-
-
- findwhen( pers )
-
- struct person *pers;
- {
- #ifdef HAVE_LASTLOG
- struct passwd *pwdt = pers->pwd;
- struct lastlog ll;
- int llsize = sizeof ll;
- int i;
-
- if( !llopenerr ) {
- lseek( lf, pwdt->pw_uid*llsize, 0 );
- if ((i = read( lf, (char *) &ll, llsize )) == llsize) {
- for( i = 0; i < LMAX; i++ ) {
- pers->tty[ i ] = ll.ll_line[ i ];
- }
- pers->tty[ LMAX ] = NULL;
- pers->loginat = ll.ll_time;
- }
- else {
- if (i != 0)
- fprintf(stderr, "finger: lastlog read error\n");
- pers->tty[ 0 ] = NULL;
- pers->loginat = 0L;
- }
- }
- else {
- pers->tty[ 0 ] = NULL;
- pers->loginat = 0L;
- }
- #else
- pers->tty[ 0 ] = NULL;
- pers->loginat = 0L;
- #endif
- }
-
-
- fwclose()
- {
- if( !llopenerr ) {
- close( lf );
- }
- }
-
-
- /* find the idle time of a user by doing a stat on /dev/histty,
- * where histty has been gotten from USERLOG, supposedly.
- */
-
- findidle( pers )
-
- struct person *pers;
- {
- struct stat ttystatus;
- struct passwd *pwdt = pers->pwd;
- char buffer[ 20 ];
- char *TTY = "/dev/";
- int TTYLEN = strlen( TTY );
- int i;
-
- strcpy( &buffer[0], TTY );
- i = 0;
- do {
- buffer[ TTYLEN + i ] = pers->tty[ i ];
- } while( ++i <= LMAX );
- if( stat( &buffer[0], &ttystatus ) >= 0 ) {
- time( &tloc );
- if( tloc < ttystatus.st_atime ) {
- pers->idletime = 0L;
- }
- else {
- pers->idletime = tloc - ttystatus.st_atime;
- }
- if( (ttystatus.st_mode & TALKABLE) == TALKABLE ) {
- pers->writeable = 1;
- }
- else {
- pers->writeable = 0;
- }
- }
- else {
- fprintf( stderr, "finger: error STATing %s\n", &buffer[0] );
- exit( 4 );
- }
- }
-
-
- /* print idle time in short format; this program always prints 4 characters;
- * if the idle time is zero, it prints 4 blanks.
- */
-
- stimeprint( dt )
-
- long *dt;
- {
- struct tm *gmtime();
- struct tm *delta;
-
- delta = gmtime( dt );
- if( delta->tm_yday == 0 ) {
- if( delta->tm_hour == 0 ) {
- if( delta->tm_min >= 10 ) {
- printf( " %2.2d ", delta->tm_min );
- }
- else {
- if( delta->tm_min == 0 ) {
- printf( " " );
- }
- else {
- printf( " %1.1d ", delta->tm_min );
- }
- }
- }
- else {
- if( delta->tm_hour >= 10 ) {
- printf( "%3.3d:", delta->tm_hour );
- }
- else {
- printf( "%1.1d:%02.2d", delta->tm_hour, delta->tm_min );
- }
- }
- }
- else {
- printf( "%3dd", delta->tm_yday );
- }
- }
-
-
- /* print idle time in long format with care being taken not to pluralize
- * 1 minutes or 1 hours or 1 days.
- */
-
- ltimeprint( dt )
-
- long *dt;
- {
- struct tm *gmtime();
- struct tm *delta;
- int printed = 1;
-
- delta = gmtime( dt );
- if( delta->tm_yday == 0 ) {
- if( delta->tm_hour == 0 ) {
- if( delta->tm_min >= 10 ) {
- printf( "%2d minutes", delta->tm_min );
- }
- else {
- if( delta->tm_min == 0 ) {
- if( delta->tm_sec > 10 ) {
- printf( "%2d seconds", delta->tm_sec );
- }
- else {
- printed = 0;
- }
- }
- else {
- if( delta->tm_min == 1 ) {
- if( delta->tm_sec == 1 ) {
- printf( "%1d minute %1d second",
- delta->tm_min, delta->tm_sec );
- }
- else {
- printf( "%1d minute %d seconds",
- delta->tm_min, delta->tm_sec );
- }
- }
- else {
- if( delta->tm_sec == 1 ) {
- printf( "%1d minutes %1d second",
- delta->tm_min, delta->tm_sec );
- }
- else {
- printf( "%1d minutes %d seconds",
- delta->tm_min, delta->tm_sec );
- }
- }
- }
- }
- }
- else {
- if( delta->tm_hour >= 10 ) {
- printf( "%2d hours", delta->tm_hour );
- }
- else {
- if( delta->tm_hour == 1 ) {
- if( delta->tm_min == 1 ) {
- printf( "%1d hour %1d minute",
- delta->tm_hour, delta->tm_min );
- }
- else {
- printf( "%1d hour %2d minutes",
- delta->tm_hour, delta->tm_min );
- }
- }
- else {
- if( delta->tm_min == 1 ) {
- printf( "%1d hours %1d minute",
- delta->tm_hour, delta->tm_min );
- }
- else {
- printf( "%1d hours %2d minutes",
- delta->tm_hour, delta->tm_min );
- }
- }
- }
- }
- }
- else {
- if( delta->tm_yday >= 10 ) {
- printf( "%2d days", delta->tm_yday );
- }
- else {
- if( delta->tm_yday == 1 ) {
- if( delta->tm_hour == 1 ) {
- printf( "%1d day %1d hour",
- delta->tm_yday, delta->tm_hour );
- }
- else {
- printf( "%1d day %2d hours",
- delta->tm_yday, delta->tm_hour );
- }
- }
- else {
- if( delta->tm_hour == 1 ) {
- printf( "%1d days %1d hour",
- delta->tm_yday, delta->tm_hour );
- }
- else {
- printf( "%1d days %2d hours",
- delta->tm_yday, delta->tm_hour );
- }
- }
- }
- }
- return( printed );
- }
-
-
- matchcmp( gname, login, given )
-
- char *gname;
- char *login;
- char *given;
- {
- char buffer[ 20 ];
- char c;
- int flag, i, unfound;
-
- if( !match ) {
- return( 0 );
- }
- else {
- if( namecmp( login, given ) ) {
- return( 1 );
- }
- else if (*gname == '\0')
- return (0);
- else {
- if( *gname == ASTERISK ) {
- gname++;
- }
- flag = 1;
- i = 0;
- unfound = 1;
- while( unfound ) {
- if( flag ) {
- c = *gname++;
- if( c == SAMENAME ) {
- flag = 0;
- c = *login++;
- }
- else {
- unfound = (*gname != COMMA) && (*gname != NULL);
- }
- }
- else {
- c = *login++;
- if( c == NULL ) {
- if( (*gname == COMMA) || (*gname == NULL) ) {
- break;
- }
- else {
- flag = 1;
- continue;
- }
- }
- }
- if( c == BLANK ) {
- buffer[i++] = NULL;
- if( namecmp( buffer, given ) ) {
- return( 1 );
- }
- i = 0;
- flag = 1;
- }
- else {
- buffer[ i++ ] = c;
- }
- }
- buffer[i++] = NULL;
- if( namecmp( buffer, given ) ) {
- return( 1 );
- }
- else {
- return( 0 );
- }
- }
- }
- }
-
-
- namecmp( name1, name2 )
-
- char *name1;
- char *name2;
- {
- char c1, c2;
-
- c1 = *name1;
- if( (('A' <= c1) && (c1 <= 'Z')) || (('a' <= c1) && (c1 <= 'z')) ) {
- c1 = CAPITALIZE( c1 );
- }
- c2 = *name2;
- if( (('A' <= c2) && (c2 <= 'Z')) || (('a' <= c2) && (c2 <= 'z')) ) {
- c2 = CAPITALIZE( c2 );
- }
- while( c1 == c2 ) {
- if( c1 == NULL ) {
- return( 1 );
- }
- c1 = *++name1;
- if( (('A'<=c1) && (c1<='Z')) || (('a'<=c1) && (c1<='z')) ) {
- c1 = CAPITALIZE( c1 );
- }
- c2 = *++name2;
- if( (('A'<=c2) && (c2<='Z')) || (('a'<=c2) && (c2<='z')) ) {
- c2 = CAPITALIZE( c2 );
- }
- }
- if( *name1 == NULL ) {
- while( ('0' <= *name2) && (*name2 <= '9') ) {
- name2++;
- }
- if( *name2 == NULL ) {
- return( 1 );
- }
- }
- else {
- if( *name2 == NULL ) {
- while( ('0' <= *name1) && (*name1 <= '9') ) {
- name1++;
- }
- if( *name1 == NULL ) {
- return( 1 );
- }
- }
- }
- return( 0 );
- }
-
-
- char *strsave( s )
-
- char *s;
- {
- char *malloc();
- char *p;
-
- p = malloc( strlen( s ) + 1 );
- strcpy( p, s );
- }
-