home *** CD-ROM | disk | FTP | other *** search
- /*
- * getttyloc.c -- get tty location for finger (December 1985)
- *
- * Copyright (C) 1988, 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: getttyloc.c,v 3.0 90/07/06 13:10:53 budd Rel $";
- # endif /* lint not defined */
-
- /*
- * This is pretty ad hoc and ugly. To add a new flavor of
- * display you need to take care of two cases; With and without
- * user string (long and short displays)
- *
- * TODO:
- *
- * User ttylocs are stored per tty in a spool area. Having the
- * user strings stored in a file containing an array of structs,
- * would save disk space.
- *
- * Keeping ALL information (default short, long; current short,
- * long) in a central, binary file would save CPU in addition.
- * This way random programs (ie; supdup) could get the correct,
- * full ttyloc.
- *
- * This could be done without tracking logins by date stamping
- * the user set and login dependant info (host, network, deamon)
- * The finger and ttyloc could update entries via set gid access.
- * (requies file and/or record locking?)
- *
- * Use sprintf less!!
- *
- * Could search cdevsw for ltaopen and ptcopen rather than using
- * LATPATH and PTYPATH
- */
-
- # ifndef X10_STR
- # define X10_STR "X10" /* if no "screen" number */
- # endif /* X10_STR not defined */
-
- # ifndef X11_STR
- # define X11_STR "X" /* if have "screen" number */
- # endif /* X11_STR not defined */
-
- # include <sys/types.h>
- # include <sys/stat.h>
- # include <strings.h>
- # include <ctype.h>
- # include <stdio.h>
- # include "finger.h"
- # include "person.h"
- # include "args.h" /* before luser.h */
- # include "luser.h"
- # include "ttylocfile.h"
- # include "daemon.h"
- # include "pr.h"
-
- # ifdef USG
- # include <sys/sysmacros.h> /* for major() macro */
- # endif /* USG defined */
-
- # ifdef ultrix
- # ifdef USE_DEVIOCGET
- # include <sys/file.h>
- # include <sys/ioctl.h>
- # include <sys/devio.h>
- # else /* USE_DEVIOCGET not defined */
- LOCAL int latmajor = -1;
- # define LATPATH "/dev/tty15"
- # endif /* USE_DEVIOCGET not defined */
- # endif /* ultrix defined */
-
- # ifndef DEFAULT_DAEMON
- # define DEFAULT_DAEMON "Virtual Terminal" /* NVT (host but no daemon found) */
- # endif /* DEFAULT_DAEMON not defined */
-
- /* for console window on Suns */
- # ifndef SMALL_CONSOLE
- /* # define SMALL_CONSOLE " [cons]" /**/
- # define SMALL_CONSOLE " [console]" /* enuf room for this! */
- # endif /* SMALL_CONSOLE not defined */
-
- # ifndef BIG_CONSOLE
- # define BIG_CONSOLE " [console]"
- # endif /* BIG_CONSOLE not defined */
-
- # ifndef PTYPATH
- # define PTYPATH "/dev/ttyp1" /* path for known pty-tty */
- # endif /* PTYPATH not defined */
-
- # ifdef Umax
- # include <netdb.h> /* for struct hostent */
- # include <sys/socket.h> /* for AF_INET */
- # endif /* Umax defined */
-
- # define USERLEN 32 /* max length of user string */
- # define LOCLEN 48 /* max length of ttyloc string */
-
- LOCAL char location[LOCLEN]; /* return value goes here */
- LOCAL char userstr[USERLEN]; /* user string (if any) here */
- LOCAL int ptymajor = -1; /* major device number for tty/pty */
- LOCAL int readfile; /* ture if we have read LOCFILE */
-
- EXTERN char *zup(), *cleanup(); /* from string.c */
- EXTERN char *locname(); /* from locname.c */
- EXTERN char *netlocname(); /* from locname.c */
-
- # ifdef sun
- EXTERN dev_t consdev, rconsdev; /* current and real console devs */
- # define ISCONS(d) (d == consdev && consdev != rconsdev)
- # else /* sun not defined */
- # define ISCONS(d) 0 /* smart compilers will remove this */
- # endif /* sun not defined */
-
- LOCAL BOOL onapty( u )
- LUSER *u;
- {
- struct stat stb;
-
- if( ptymajor == -1 ) { /* first time? */
- if( stat(PTYPATH, &stb) == 0 )
- ptymajor = major( stb.st_rdev );
- else {
- ptymajor = -2;
- return( FALSE );
- }
- } /* first time? */
-
- if( ptymajor > 0 && ptymajor == major( u->u_ttydev ) )
- return( TRUE );
- return( FALSE );
- } /* onapty */
-
- # ifdef ultrix
- LOCAL BOOL onlat( u )
- LUSER *u;
- {
- # ifdef USE_DEVIOCGET
- /* This is soooo dumb.
- * - Requires a fd (so only works when have write access to ttys!)
- * - returns *STRINGS*
- * - **FAILS** on pty's (Not a typewriter!)
- *
- * What twinkies.
- *
- * This will only be of any use if finger runs setuid to root.
- * (setgid group tty is pointless, since finger needs group kmem
- * as well). This is not (known to be) dangerous, just tasteless!
- *
- * Probably better to just put all LAT lines (!) into /etc/(n)ttyloc.
- */
- int fd, flag;
- char path[ 32 ];
- struct devget dg;
- static int checked = FALSE, notty = FALSE;
-
- strcpy( path, "/dev/" );
- strcat( path, u->u_line );
-
- if( !checked ) { /* check if we have a tty */
- if( (f = open( "/dev/tty", 1)) >= 0 )
- close( f ); /* yes we do */
- else
- notty = TRUE; /* we don't */
- checked = TRUE;
- }
-
- if( (fd = open (argv[i], O_RDONLY|O_NDELAY)) < 0 &&
- (fd = open (argv[i], O_WRONLY|O_NDELAY)) < 0 )
- return( FALSE );
-
- flag = ioctl( fd, DEVIOCGET, &dg ) == 0 &&
- strcmp( dg.interface, DEV_LAT ) == 0;
-
- (void) close( fd );
-
- /* flush tty association -- so fingerd doesn't get attached!! */
- if( notty && (fd = open( "/dev/tty", 1)) >= 0 ) { /* if no tty */
- ioctl( fd, TIOCNOTTY, 0 ); /* flush assoc with one */
- close( f ); /* we just opened */
- }
-
- return( flag );
- # else /* USE_DEVIOCGET not defined */
- if( latmajor == -1 ) { /* first time? */
- if( stat(LATPATH, &stb) == 0 )
- latmajor = major( stb.st_rdev );
- else {
- latmajor = -2;
- return( FALSE );
- }
- } /* first time? */
-
- if( latmajor > 0 && latmajor == major( u->u_ttydev ) )
- return( TRUE );
- return( FALSE );
- # endif /* USE_DEVIOCGET not defined */
- } /* onlat */
- # endif /* ultrix defined */
-
- GLOBAL void inittylocs() {
- if( !readfile ) {
- readfile = 1;
- if( readnewttylocfile() < 1 ) {
- int i;
- i = readttylocfile();
- # ifdef TTYENT
- if( i < 1 )
- i = readttyents();
- # endif /* TTYENT defined */
- }
- } /* try reading a ttyloc file */
- } /* inittylocs */
-
- GLOBAL char *getttyloc( u ) /* return ttyloc string */
- LUSER *u;
- {
- int f, cc; /* file */
- char *fname, *shortstr, *longstr;
- TTYLOC *tp;
-
- userstr[0] = EOS;
- if( !readfile )
- inittylocs();
-
- if( !u->u_sw.sw_location ) {
- fname = locname(u->u_line); /* try to find file in spool area */
- if( (f = open(fname, 0)) >= 0 ) {
- struct stat stb;
- if( fstat(f, &stb) == 0 && stb.st_mtime > u->u_time ) {
- # ifdef DEBUG
- puts(fname);
- # endif /* DEBUG defined */
- cc = read(f, userstr, USERLEN-1);
- if( cc > 0 )
- userstr[cc] = EOS;
- } /* fstat and recent */
- close(f);
- cleanup(userstr);
- } /* fname open */
-
- # ifdef OTTYLOC /* old style per user ttyloc */
- /* try ~/.ttyloc file -- this could be cached in the luser struct */
- if( userstr[0] == EOS && u->u_person != NULL) {
- strcpy(fname, u->u_person->p_home);
- strcat(fname, "/.ttyloc");
- if( (f = open(fname, 0)) >= 0 ) {
- cc = read(f, userstr, USERLEN-1);
- userstr[cc] = EOS;
- }
- close(f);
- cleanup(userstr);
- } /* no userstr yet, have person */
- # endif /* OTTYLOC defined */
- } /* not sw_location */
-
- shortstr = longstr = NULL;
-
- if( u->u_host[0] != EOS )
- checkhost( u->u_host, sizeof( u->u_host ) );
- # ifdef Umax
- else if( u->u_ttyaddr != 0 ) {
- struct hostent *hp;
- if( (hp = gethostbyaddr( &u->u_ttyaddr,
- sizeof( u->u_ttyaddr ), AF_INET )) != NULL )
- strzcpy( u->u_host, hp->h_name, sizeof( u->u_host ) - 1 );
- else
- strzcpy( u->u_host, inet_ntoa( u->u_ttyaddr ) );
- } /* no host */
- # endif /* Umax defined */
-
- if( u->u_host[0] != EOS ) { /* have host? */
- register char *cp;
-
- # ifndef NO_X_WINDOWS
- int display_number, decnet_display, screen_number;
- # define NOT_FOUND -1
- display_number = screen_number = NOT_FOUND;
-
- /* This botches on XNS addresses net:addr */
- if( (cp = index(u->u_host, ':')) != NULL ) { /* host:display */
- *cp++ = EOS; /* blast first ':' */
-
- if( *cp == ':' ) { /* second ':' ? (DECnet) */
- cp++; /* advance. */
- decnet_display = TRUE;
- } /* second ':' */
- else
- decnet_display = FALSE;
-
- if( isdigit( *cp ) ) { /* digits after ':'? */
- display_number = 0;
- do
- display_number = display_number * 10 + *cp++ - '0';
- while( isdigit(*cp) );
-
- if( *cp == '.' ) { /* display terminated by DOT? */
- screen_number = 0; /* X11 "screen number" */
- cp++; /* skip dot */
-
- while( isdigit(*cp) )
- screen_number = screen_number * 10 + *cp++ - '0';
- } /* collect screen */
- } /* digits after ':' */
- } /* found : */
- # endif /* NO_X_WINDOWS not defined */
-
- if( userstr[0] != EOS ) { /* have user str? */
- undomain( u->u_host, TRUE ); /* remove domains and prefixes */
-
- longstr = userstr;
- shortstr = NULL;
-
- # ifndef NO_X_WINDOWS
- if( display_number != NOT_FOUND ) {
- char screen[ 15 ];
- if( screen_number != NOT_FOUND && screen_number != 0 )
- sprintf( screen, ".%d", screen_number );
- else
- screen[0] = EOS;
-
- sprintf(location, "%s:%s%d%s",
- u->u_host,
- (decnet_display ? ":" : ""),
- display_number,
- screen );
- shortstr = location;
- } /* display != -1 */
- # endif /* NO_X_WINDOWS not defined */
- # ifdef Umax
- else if( u->u_ttyaddr != 0 ) {
- register int i;
- char *lt;
- static char *ltt[] = {
- "", "lp", /* BSD style driver */
- "V", "Vlp" }; /* SYSV style */
-
- i = u->u_ttytype;
- if( i < 1 || i-1 > ( sizeof( ltt ) / sizeof( char * ) ) )
- lt = "??";
- else
- lt = ltt[ i-1 ];
- sprintf(location, "%s_%s%d", /* A la ANF-10 !*/
- HZUP( u->u_host ),
- lt,
- u->u_ttynum );
- shortstr = location;
- } /* ttyaddr != 0 */
- # endif /* Umax defined */
- # ifdef ultrix
- else if( onlat( u ) )
- shortstr = "LAT";
- # endif /* ultrix defined */
- else
- shortstr = HZUP( u->u_host );
- } /* host and user str */
- else { /* host, no user string */
- undomain( u->u_host, FALSE ); /* just remove domains */
- # ifndef NO_X_WINDOWS
- if( display_number != NOT_FOUND ) { /* have x display number */
- char screen[ 15 ], *xv; /* X11 */
- screen[0] = EOS;
- xv = X10_STR;
- if( screen_number != NOT_FOUND ) {
- xv = X11_STR;
- if( screen_number != 0 )
- sprintf( screen, " screen %d",
- screen_number ); /* woof */
- }
- # ifdef X_LOCAL
- if( casecmp( u->u_host, "UNIX" ) )
- sprintf( location, "Local %s display %d%s%s",
- xv, display_number, screen,
- (ISCONS(u->u_ttydev) ? SMALL_CONSOLE : "") );
- else
- # endif /* X_LOCAL defined */
- sprintf(location, "%s (%s%s display %d%s)%s",
- u->u_host, /* zup'ed already */
- (decnet_display ? "DECnet " : ""), /* we use TCP */
- xv, display_number, screen,
- (ISCONS(u->u_ttydev) ? SMALL_CONSOLE : "") );
- return( location );
- } /* have display number */
- else
- # endif /* NO_X_WINDOWS not defined */
- # ifdef Umax
- if( u->u_ttyaddr != 0 ) { /* host, no user, is annex device */
- register int i;
- char *lt;
- static char *ltt[] = {
- "port", "lp", /* BSD devices */
- "Vport", "SYSV lp" /* SYS V devices */
- };
-
- # ifdef NETLOC
- int f;
- char portname[ 50 ];
-
- sprintf( portname, "%s:port%d", u->u_host, u->u_ttynum );
- fname = netlocname( portname );
- if( (f = open(fname, 0)) >= 0 ) {
- struct stat stb;
- if( fstat(f, &stb) == 0 && stb.st_mtime > u->u_time ) {
- cc = read(f, userstr, USERLEN-1);
- userstr[cc] = EOS;
- }
- close(f);
- cleanup(userstr);
- if( userstr[0] != EOS )
- return( userstr );
- } /* open ok */
- # endif /* NETLOC defined */
-
- i = u->u_ttytype;
- if( i < 1 || i-1 > ( sizeof( ltt ) / sizeof( char * ) ) )
- lt = "??";
- else
- lt = ltt[ i-1 ];
-
- sprintf(location, "%s (Annex Call) %s%d",
- HZUP( u->u_host ),
- lt,
- u->u_ttynum );
- return( location );
- } /* host, no user str, is annex */
- else
- # endif /* Umax defined */
- # ifdef ultrix
- else if( onlat( u ) ) { /* host, no user str, LAT */
- sprintf( location, "%s (LAT)", HZUP( u->u_host ) );
- return( location );
- } /* host, no user str, LAT */
- # endif /* ultrix defined */
- { /* host, nothing unusual */
- char *dp;
- if( u->u_daemon != NULL )
- dp = u->u_daemon->d_long;
- else if( u->u_daemonp != NULL &&
- u->u_daemonp->pr_cmd[0] != EOS )
- dp = u->u_daemonp->pr_cmd;
- else
- dp = DEFAULT_DAEMON;
- sprintf( location, "%s (%s)", HZUP( u->u_host ), dp );
- return( location );
- } /* host, nothing unusual */
- } /* host, no user string */
- } /* have host */
- else if( onapty( u ) ) { /* is pty, no host */
- if( userstr[0] != EOS ) { /* pty, no host, user string */
- if( u->u_daemon != NULL )
- shortstr = u->u_daemon->d_short;
- else if( u->u_daemonp != NULL &&
- u->u_daemonp->pr_cmd[0] != EOS )
- shortstr = u->u_daemonp->pr_cmd;
- else if( ISCONS(u->u_ttydev) )
- shortstr = "CONS";
- else
- shortstr = "PTY"; /* sigh */
- longstr = userstr;
- } /* pty, nohost, user string */
- else if( u->u_daemon != NULL ) { /* pty, nohost, nouser, daemon */
- char *cons;
- if( ISCONS(u->u_ttydev) ) /* pty nohost nouser daemon cons */
- cons = SMALL_CONSOLE;
- else
- cons = "";
- sprintf( location, "via %s%s", u->u_daemon->d_long, cons );
- return( location );
- } /* pty, nohost, nouser, daemon entry */
- else if( u->u_daemonp != NULL && u->u_daemonp->pr_cmd[0] != EOS ) {
- /* pty, nohost, nouser, daemon process (not in daemon table) */
- char *cons;
- if( ISCONS(u->u_ttydev) )
- cons = BIG_CONSOLE;
- else
- cons = "";
- sprintf( location, "child of %s%s", u->u_daemonp->pr_cmd, cons );
- return( location );
- } /* pty, nohost, nouser, daemon process */
- else if( ISCONS(u->u_ttydev) ) /* pty, nohost, nouser, nodaemon, con*/
- return( "Pseudo Console" );
- # ifndef NO_X_WINDOWS
- else if( strcmp( u->u_line, "ttyv0" ) == 0 )
- return( "X login window");
- # endif /* NO_X_WINDOWS not defined */
- else /* pty, nohost, nouser, nodae, nocon */
- return( "Pseudo Terminal" );
- } /* is pty */
- # ifdef ultrix
- else if( onlat( u ) ) { /* no host, LAT */
- if( userstr[0] == EOS ) /* LAT, no host, no userstr */
- return( "via LAT" );
- else
- shortstr = "LAT";
- } /* LAT, no host */
- # endif /* ultrix defined */
- else { /* normal line (no host, no pty) */
- # ifdef NETLOC
- if( userstr[0] == EOS ) { /* normal line, no userstr */
- fname = netlocname(u->u_line); /* try to find file in spool area */
- f = open( fname, 0 );
- if( f >= 0 ) {
- struct stat stb;
- if( fstat(f, &stb) == 0 && stb.st_mtime > u->u_time ) {
- cc = read(f, userstr, USERLEN-1);
- userstr[cc] = EOS;
- }
- close(f);
- cleanup( userstr );
- } /* opened file */
- } /* no userstr */
- # endif /* NETLOC defined */
-
- if( (tp = findttyloc( u->u_line )) != NULL ) { /* get from file */
- if( userstr[0] != EOS ) { /* found ttyloc, have userstr */
- shortstr = tp->t_short;
- longstr = userstr;
- } /* found ttyloc, have userstr */
- else if( tp->t_locn != NULL )
- return( tp->t_locn );
- /* fall back on t_short??? WISH */
- } /* found tp entry */
- # ifdef UmaxV
- else if( u->u_line[0] == 'r' && u->u_line[1] == 't' ) {
- /* mls rdp device; rtAAPPSS */
- if( userstr[0] == EOS ) {
- if( strlen( u->u_line ) == 7 ) {
- char session[ 10 ];
-
- if( u->u_line[6] != '0' )
- sprintf( session, " session %c",
- u->u_line[6] );
- else
- session[0] = EOS;
-
- sprintf( location, "annex %c%c port %c%c%s",
- u->u_line[2], u->u_line[3],
- u->u_line[4], u->u_line[5],
- session );
- return( location );
- }
- else
- return( "annex RDP connection" );
- }
- else
- shortstr = "annex"; /* "RDP" */
-
- }
- else if( u->u_line[0] == 'R' && u->u_line[1] == 'T' ) {
- /* mls rdp device RTxxxxx for unknown annex */
- if( userstr[0] == EOS ) {
- sprintf( location, "foreign annex %s",
- u->u_line+2 );
- return( location );
- }
- else
- shortstr = "annex";
- }
- # endif /* UmaxV defined */
- else if( userstr[0] != EOS )
- return( userstr );
- } /* normal line (no host, no user) */
-
- if( longstr == NULL ) {
- if( strcmp( u->u_line, "console" ) == 0
- # ifdef AIX3
- || strcmp( u->u_line, "hft/1" ) == 0
- # endif /* AIX3 defined */
- )
- longstr = "Console Terminal"; /* physical console */
- }
-
- if( shortstr != NULL ) { /* have short string */
- if( longstr != NULL ) {
- /* was once ':' */
- sprintf( location, "%s; %s", shortstr, longstr );
- return( location );
- }
- else
- return( shortstr );
- } /* short str */
- else if( longstr != NULL )
- return( longstr );
- return( "Unknown" );
- } /* getttyloc */
-
- /*
- * Local variables:
- * comment-column: 40
- * End:
- */
-