home *** CD-ROM | disk | FTP | other *** search
- /*
- * finger.c -- output formatting for finger (main is in args.c)
- *
- * Copyright (C) 1986, 1990 Philip L. Budne
- *
- * This file is part of "Phil's Finger Program".
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 1, or (at your option)
- * any later version.
- *
- */
-
- # ifndef lint
- static char *rcsid = "$Id: finger.c,v 3.0 90/07/06 13:10:35 budd Rel $";
- # endif /* lint not defined */
-
- # include <sys/types.h>
- # include <stdio.h>
- # include "person.h"
- # include "output.h"
- # include "args.h" /* before luser.h */
- # include "luser.h"
- # include "finger.h"
- # include "pr.h"
- # include "inquire.h" /* for INQUIRE */
- # include "ttylocfile.h"
-
- # define PID_COL /* display /pid in seperate column */
-
- /*# define RELATION /* display REL if this is defined */
- /*# define REL_SUP "" /* (define as quoted string of relations */
- /* to supress display of) */
-
- FORWARD LOCAL void
- # ifdef RELATION
- prelation(),
- # endif /* RELATION defined */
- pusername(), pgroup(), pspace(), ppname(),
- pcmd(), pidle(), pbiff(), ptty(), pmesg(), plocation(), ppid(),
- pstr(), pchar(), togoal();
-
- LOCAL int outcol, goalcol;
-
- # define USER_WID 8
- # define PROG_WID 7 /* 6 prog + 1 flag */
-
- # ifndef TTY_WID
- # ifdef AIX3
- # define TTY_WID 6
- # else /* AIX3 not defined */
- # if defined(UmaxV) || defined(PTS_PTY_NAMES)
- # define TTY_WID 5 /* rtAAPPS or ptsNN */
- # else /* not defined(UmaxV) || defined(PTS_PTY_NAMES) */
- # define TTY_WID 3
- # endif /* not defined(UmaxV) || defined(PTS_PTY_NAMES) */
- # endif /* AIX3 not defined */
- # endif /* TTY_WID not defined */
-
- # define BASE_PER_WID (22+3+3) /* base person width */
-
- typedef void (*FPTR)();
-
- FPTR fields[] = {
- pusername,
- pspace,
- pgroup,
- # ifdef RELATION
- # define GRPREL_WID 3 /* 2 + space */
- prelation,
- # else /* RELATION not defined */
- # define GRPREL_WID 2 /* 1 + space */
- # endif /* RELATION not defined */
- pspace,
- ppname,
- NULL
- }; /* fields */
-
- # define PER_WID (BASE_PER_WID-TTY_WID-GRPREL_WID)
-
-
- FPTR fields2[] = {
- # ifdef PID_COL
- ppid,
- # endif /* PID_COL defined */
- # ifndef SUPPRESS_WHAT
- pcmd,
- # endif /* SUPPRESS_WHAT not defined */
- pidle,
- pbiff,
- ptty,
- pmesg,
- plocation,
- NULL
- }; /* fields2 */
-
- /* display when program running from another uid */
- # ifndef SUID_ROOT
- # define SUID_ROOT '+'
- # endif /* SUID_ROOT not defined */
-
- # ifndef SUID_OTHER
- # define SUID_OTHER '!'
- # endif /* SUID_OTHER not defined */
-
- /* when no command found */
- # ifndef EMPTY_CMD
- # define EMPTY_CMD "??"
- # endif /* EMPTY_CMD not defined */
-
- # define NO_GROUP ' '
-
- # ifdef RELATION
- # define REL_HEADER 'R'
- # define GRP_HEADER 'G'
- # else /* RELATION not defined */
- # define GRP_HEADER ' ' /* or 'G' */
- # endif /* RELATION not defined */
-
- /****** what to show when there is no person structure ******/
- # define NO_RELATION ' '
-
- # ifdef INQUIRE
- # define NO_NAME "--No inquire entry--"
- # else /* INQUIRE not defined */
- # define NO_NAME "--No password entry--" /* acucntrl locks?!*/
- # endif /* INQUIRE not defined */
-
- extern LTREE *maketree(); /* from getent.c */
- extern struct pr *getcommand(); /* from getcommand.c */
- extern char *getttyloc(); /* from gettyloc.c */
- extern int pwtree(); /* from getperson.c */
- extern whois(), plan(); /* from whois.c */
- extern char *gtname(), *intstr(); /* from output.c */
-
- LOCAL time_t now; /* current time */
- LOCAL int personwidth; /* calculated at runtime! */
-
- LOCAL void /* forwards.. */
- finguser(),
- fingheader(),
- dogecos();
-
- GLOBAL void dofinger( t )
- LTREE *t;
- {
- int n;
-
- personwidth = PER_WID;
- # ifdef PID_COL
- # define PID_WID 6
- if( sw_pid )
- personwidth -= PID_WID/2;
- # endif /* PID_COL defined */
-
- # ifdef LASTLOG
- llopen(); /* open lastlog file */
- # endif /* LASTLOG defined */
-
- time( &now ); /* get current time */
- if( t == NULL ) /* nothing? */
- pwtree( (t = maketree()) ); /* get tree of all logged in users */
-
- n = treesize( t ); /* count users */
- if( n == 0 )
- puts("No one logged in.");
- else {
- # ifndef ALWAYS_PRINT_HEADER
- if( n > 1 ) /* be like oz finger */
- # endif /* ALWAYS_PRINT_HEADER not defined */
- fingheader(); /* print header */
-
- ptree( t, finguser ); /* print tree */
- } /* n != 0 */
-
- # ifdef LASTLOG
- llclose(); /* close lastlog file */
- # endif /* LASTLOG defined */
- } /* finger */
-
- LOCAL BOOL same;
-
- LOCAL void finguser(u)
- register LUSER *u;
- {
- static PERSON *person;
- static int incarnations;
- register FPTR *fp;
-
- if( u->u_person != NULL ) {
- if( (u->u_person->p_flags & P_RC) != 0 ) { /* pw_gecos == "RC" ?*/
- dogecos( u );
- return;
- } /* RC hack */
- } /* run command */
-
- if( u->u_flags & U_NLI ) { /* not logged in */
- char location[ 50 ];
- time_t ltime; /* last login time */
- int host;
- PERSON *p;
-
- p = u->u_person;
- same = FALSE; /* crock, pass as arg? *TODO* */
- for( fp = fields; *fp != NULL; fp++ )
- (*fp)( FALSE, u, p );
- goalcol++; /* space */
-
- /* get last login time from lastlog */
- if( p == NULL || (p->p_flags & P_NOPWENT) )
- pstr( "NO PASSWORD ENTRY (EXPIRED ACCOUNT?)" ); /* no pw ent? */
- # ifdef LASTLOG
- else if( !lltime( p->p_uid, location, <ime, &host ) || ltime == 0 )
- pstr( "Login Unknown" ); /* no login time */
- else { /* have login time. format it */
- int printed;
- TTYLOC *tp;
-
- pstr( "Login " );
- pstr( nicetime( ltime ) );
-
- /* TODO: if sw_its no "from...." */
- pstr( " from " );
- printed = FALSE;
- inittylocs();
- if( !host && (tp = findttyloc( location )) != NULL ) {
- char *s;
- if( tp->t_short != NULL )
- s = tp->t_short;
- else if( tp->t_locn != NULL )
- s = tp->t_locn;
- else
- s = NULL;
- if( s != NULL ) {
- printed = TRUE;
- pstr( s );
- pchar('{');
- pstr( location );
- pchar('}');
- }
- } /* foundttyloc */
- if( !printed )
- pstr( location );
- } /* have login time */
- # endif /* LASTLOG defined */
- /* if sw_its check plan */
- pchar('\n');
- incarnations = 1;
- } /* not logged in */
- else { /* is logged in */
- termstat( u ); /* get tty status (before getcommand) */
- # ifndef SUPPRESS_WHAT
- getcommand( u ); /* get command/daemon procs */
- # endif /* SUPPRESS_WHAT not defined */
-
- # ifndef NEVER_SAME
- if( u->u_person != NULL && u->u_person == person ) /* same person */
- same = TRUE; /* as before? */
- else
- # endif /* NEVER_SAME not defined */
- same = FALSE;
-
- person = u->u_person;
- if( !same )
- if( person != NULL )
- incarnations = person->p_count;
- else
- incarnations = 1;
-
- for( fp = fields; *fp != NULL; fp++ )
- (*fp)( FALSE, u, person );
- goalcol++; /* blank space */
- for( fp = fields2; *fp != NULL; fp++ )
- (*fp)( FALSE, u, person );
- pchar( '\n' );
- } /* logged in */
-
- if( incarnations-- == 1 ) { /* final incarnation? */
- if( sw_whois ) { /* do whois stuff */
- whois( u );
- blankline();
- }
-
- if( u->u_sw.sw_mail || sw_whois || (u->u_flags & U_NLI) ) {
- mcheck( u );
- blankline();
- }
-
- if( sw_whois ) {
- remarks( u );
- blankline();
- }
-
- /*
- * show plan if asked for. if user not logged in
- * show unless prohibited.
- */
- if( u->u_sw.sw_plan || (u->u_flags & U_NLI) && !u->u_sw.sw_noplan ) {
- plan( u );
- blankline();
- }
- } /* last incarnation */
- } /* finguser */
-
- LOCAL void fingheader() {
- FPTR *fp;
-
- for( fp = fields; *fp != NULL; fp++ )
- (*fp)( TRUE, NULL, NULL );
- goalcol++; /* blank space */
- for( fp = fields2; *fp != NULL; fp++ )
- (*fp)( TRUE, NULL, NULL );
- pchar( '\n' );
- fflush(OUTPUT);
- } /* fingheader */
-
- LOCAL void dogecos( u ) /* here if PNAME == "RC" */
- LUSER *u;
- {
- int pid, wpid;
-
- pid = fork(); /* no vfork uses stdio */
- if( pid == 0 ) { /* be childish */
- PERSON *p;
- p = u->u_person;
-
- chdir(p->p_home);
- setuid(p->p_uid);
- setgid(p->p_gid);
- printf("%s/%s:\n", p->p_home, u->u_user);
- fflush( stdout );
- execl(u->u_user, u->u_user, 0);
- perror("Sorry");
- exit(1);
- }
- else if( pid < 0 )
- perror("fork");
-
- while( (wpid = wait(0)) > 0 && wpid != pid ) /* lassie come home!! */
- ;
- } /* dogecos */
-
- LOCAL void
- _pchar( c )
- char c;
- {
- static char linebuf[ 512 ], *lp = linebuf;
- if( c == '\n' ) {
- *lp = EOS;
- outline( linebuf );
- outcol = goalcol = 0;
- lp = linebuf;
- } /* newline */
- else { /* not newline */
- if( c == '\t' )
- outcol = (outcol + 8) & ~7;
- else
- outcol++;
- *lp++ = c;
- } /* not newline */
- } /* _pchar */
-
- LOCAL void
- togoal() {
- while( outcol < goalcol ) {
- int temp;
- temp = (outcol + 8) & ~7;
- if( temp <= goalcol )
- _pchar( '\t' );
- else
- _pchar( ' ' );
- }
- goalcol = outcol;
- } /* togoal */
-
- LOCAL void
- pchar( c )
- char c;
- {
- if( outcol < goalcol ) /* save extra calls */
- togoal();
- _pchar( c );
- } /* pchar */
-
- LOCAL void
- pstr( s )
- register char *s;
- {
- if( s == NULL )
- return;
- togoal();
- while( *s )
- _pchar( *s++ );
- } /* pstr */
-
- LOCAL void
- pcount( c, s )
- register c;
- register char *s;
- {
- if( s == NULL )
- return;
- togoal();
- while( c-- && *s )
- _pchar( *s++ );
- } /* pcount */
-
- LOCAL void
- pusername( title, u, p )
- BOOL title;
- LUSER *u;
- PERSON *p;
- {
- if( title )
- pstr( "-User-" );
- else if( !same )
- pcount( USER_WID, u->u_user );
- goalcol += USER_WID;
- } /* pusername */
-
- # ifdef INQUIRE
- # ifdef RELATION
- LOCAL void
- prelation( title, u, p )
- BOOL title;
- LUSER *u;
- PERSON *p;
- {
- char rel;
- if( title )
- pchar( REL_HEADER ); /* title */
- else if( !same ) /* not same as last */
- if( p != NULL ) { /* have person info */
- rel = p->p_relation;
- # ifdef REL_SUP
- if( sw_whois || index(REL_SUP, rel) == NULL ) /* whois or */
- # endif /* REL_SUP defined */
- pchar( rel ); /* not suppressed */
- } /* have person */
- else
- pchar( NO_REL );
- goalcol++;
- } /* prelation */
- # endif /* RELATION defined */
- # endif /* INQUIRE defined */
-
- LOCAL void
- pgroup( title, u, p )
- BOOL title;
- LUSER *u;
- PERSON *p;
- {
-
- if( title )
- pchar( GRP_HEADER ); /* title */
- else if( !same && p != NULL ) /* not same and have person */
- pchar( p->p_group );
-
- goalcol++;
- } /* pgroup */
-
- LOCAL void
- pspace( title, u, p )
- BOOL title;
- LUSER *u;
- PERSON *p;
- {
- goalcol++;
- } /* pspace */
-
- LOCAL void
- ppname( title, u, p )
- BOOL title;
- LUSER *u;
- PERSON *p;
- {
- if( title )
- pstr( "--Full name--" );
- else if( !same )
- if( p != NULL )
- pcount( personwidth, p->p_personal );
- else
- pstr( NO_NAME );
- goalcol += personwidth;
- } /* ppname */
-
- LOCAL void
- pcmd( title, u, p )
- BOOL title;
- LUSER *u;
- PERSON *p;
- {
- struct pr *pr;
-
- if( title ) {
- pstr( (sw_its ? "Jobnam" : "-What-") );
- goalcol += PROG_WID;
- return;
- }
-
- pr = u->u_command;
- if( pr != NULL ) {
- char suid;
-
- if( p == NULL || pr->pr_uid == p->p_uid ) /* same uid? */
- suid = ' '; /* no flag */
- else if( pr->pr_uid == 0 ) /* super user? */
- suid = SUID_ROOT; /* flag it */
- else /* someone else */
- suid = SUID_OTHER;
-
- pcount( PROG_WID-1, pr->pr_cmd ); /* leave one for suid */
- pchar( suid );
- } /* pr not null */
- else
- pstr( EMPTY_CMD );
-
- goalcol += PROG_WID;
- } /* pcmd */
-
- # ifdef PID_COL
- LOCAL void
- ppid( title, u, p )
- BOOL title;
- LUSER *u;
- PERSON *p;
- {
- if( !sw_pid )
- return; /* takes no space!! */
-
- if( title )
- pstr(" Pid"); /* two leading spaces */
- else if( u->u_command != NULL ) {
- char tbuf[10];
- sprintf(tbuf, "%5d", u->u_command->pr_pid );
- pstr( tbuf );
- }
- goalcol += PID_WID; /* leave space after */
- } /* ppid */
- # endif /* PID_COL defined */
-
- LOCAL void
- pidle( title, u, p )
- BOOL title;
- LUSER *u;
- PERSON *p;
- {
- if( title ) {
- if( sw_age )
- pstr( "-On-" );
- else if( sw_state )
- pstr( "Stat" );
- # ifndef PID_COL
- else if( sw_pid )
- pstr( " Pid" ); /* two spaces!! */
- # endif /* PID_COL not defined */
- else
- pstr( "Idle" );
- } /* title */
- else { /* real thing */
- char idbuf[ 100 ];
- strcpy( idbuf, "??" );
-
- if( sw_age )
- intstr(idbuf, now - u->u_time ); /* get time on */
- else if( sw_state ) {
- if( u->u_command != NULL )
- getstate( idbuf, u->u_command ); /* get state */
- }
- # ifndef PID_COL
- else if( sw_pid ) {
- if( u->u_command != NULL )
- sprintf(idbuf, "%5d", u->u_command->pr_pid );
- }
- # endif /* PID_COL not defined */
- else if( u->u_flags & U_BADTTY )
- strcpy( idbuf, "*:**" );
- else
- intstr(idbuf, u->u_idle ); /* get idle time */
- pstr( idbuf );
- }
-
- # ifndef PID_COL
- if( sw_pid ) /* variable width!! */
- goalcol += 5;
- else
- # endif /* PID_COL not defined */
- goalcol += 4;
- } /* pidle */
-
- LOCAL void
- pbiff( title, u, p )
- BOOL title;
- LUSER *u;
- PERSON *p;
- {
- /* alright, I lost control. C at its ugliest
- * nothing - space
- * biff - dot
- * hungry - comma
- * both - semi
- */
- if( !title )
- pchar( " .,;"[ ((u->u_flags & U_BIFF) ? 01 : 0) |
- ((u->u_flags & U_HUNGRY) ? 02 : 0) ] );
- goalcol++;
- } /* pbiff */
-
- LOCAL void
- ptty( title, u, p )
- BOOL title;
- LUSER *u;
- PERSON *p;
- {
- if( title )
- pstr("TTY");
- else
- pcount( TTY_WID, gtname( u->u_line ) ); /* get trimmed tty name */
- goalcol += TTY_WID;
- } /* ptty */
-
- LOCAL void
- pmesg( title, u, p )
- BOOL title;
- LUSER *u;
- PERSON *p;
- {
- if( !title && (u->u_flags & U_NOWRITE) )
- pchar( '*' );
- goalcol++;
- } /* pmesg */
-
- LOCAL void
- plocation( title, u, p )
- BOOL title;
- LUSER *u;
- PERSON *p;
- {
- if( title )
- pstr( "-Console Location-" );
- else
- pstr( getttyloc( u ) ); /* tty location */
- /* no new goal!! */
- } /* plocation */
-
- /*
- * Local variables:
- * comment-column: 40
- * End:
- */
-