home *** CD-ROM | disk | FTP | other *** search
- /*
- * output.c -- terminal & output for new finger
- *
- * 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: output.c,v 3.0 90/07/06 13:11:28 budd Rel $";
- # endif /* lint not defined */
-
- # include "finger.h"
- # include <sys/types.h>
- # include <sys/ioctl.h>
- # include <sys/stat.h>
- # include <stdio.h>
- # ifdef TTY_GROUP
- # include <grp.h>
- # endif /* TTY_GROUP defined */
- # include "output.h"
- # include "args.h" /* sw_output (before luser.h) */
- # include "luser.h"
-
- extern char *getenv(); /* from library */
- extern int netfinger; /* from args.c */
-
- LOCAL int term_width; /* termcap width */
- LOCAL int output_col; /* keep track of chars outchar'ed */
- LOCAL int done_output; /* keep track for blank lines */
-
- # ifndef DEFWIDTH
- # define DEFWIDTH (MAXLINE-1)
- # endif /* DEFWIDTH not defined */
-
- GLOBAL void ptree( u, routine )
- register LUSER *u;
- int (*routine)();
- {
- if( u == NULL )
- return;
-
- if( u->u_left != NULL )
- ptree( u->u_left, routine );
-
- (*routine)(u);
-
- if( u->u_right != NULL )
- ptree( u->u_right, routine );
- } /* ptree */
-
- GLOBAL char *intstr(s, sex) /* print an interval */
- char *s; /* buffer to use (if needed) */
- long sex;
- {
- long min, hours, days;
-
- min = sex / 60; /* get minutes */
-
- s[0] = EOS; /* zap buffer */
- if( min <= 0 ) /* worth thinking about? */
- return( s );
-
- hours = min / 60; /* get hours */
- min = min % 60; /* cast out hours */
-
- days = hours / 24; /* get number of days */
- hours = hours % 24; /* cast out days */
-
- if( days > 0 ) { /* over a day? */
- if( days < 10 ) { /* but still 1 digit? */
- if( hours < 1 )
- sprintf(s, "%dday", days); /* don't print 0h */
- else if( hours < 10 )
- sprintf(s, "%dd%dh", days, hours ); /* <days>d<hours>h */
- else
- sprintf(s, "%dd%d", days, hours ); /* <days>d<hours> */
- } /* < 10 days */
- else {
- int weeks, d2;
-
- weeks = days / 7;
- d2 = days % 7;
- if( weeks < 10 ) {
- if( d2 == 0 ) {
- if( hours < 10 )
- sprintf(s, "%dw%dh", weeks, hours );
- else
- sprintf(s, "%dwks", weeks );
- }
- else
- sprintf(s, "%dw%dd", weeks, d2 );
- } /* < 10 weeks */
- else if( weeks < 100 ) { /* (693 days!) */
- if( d2 > 0 )
- sprintf(s, "%dw%d", weeks, d2 );
- else
- sprintf(s, "%dwk", weeks );
- } /* lt 100 weeks */
- else if( days < 1000 )
- sprintf(s, "%3dd", days); /* print three digits of day */
- else /* print years?? .... nah... */
- strcpy(s, "*:**"); /* P-U-N-T ! */
- } /* > 9 days */
- } /* days > 0 */
- else { /* days == 0 */
- if( hours == 0 ) /* less than an hour? */
- sprintf(s, "%4d", min); /* just minutes */
- else if( hours < 10 ) /* one digit of hours? */
- sprintf(s, "%1d:%02d", hours, min); /* print h:mn */
- else /* hours >= 10 (must be <= 23) */
- sprintf(s, "%2d:%1d", hours, min / 10); /* print hh:m */
- } /* days == 0 */
- return( s );
- } /* intstr */
-
- /*
- * termstat - given a LUSER record, get stat(2) information for terminal
- * returns TRUE for success
- */
-
- GLOBAL void termstat( u )
- LUSER *u;
- {
- char term[30];
- struct stat stb;
- # ifdef Umax
- LOCAL short rdpminor = -1;
- # endif /* Umax defined */
-
- # ifdef TTY_GROUP
- LOCAL int ttygroup = -1;
-
- if( ttygroup < 0 ) {
- struct group *gr;
- if( (gr = getgrnam("tty")) != NULL )
- ttygroup = gr->gr_gid;
- # ifdef TTY_GROUP_NUMBER
- else
- ttygroup = TTY_GROUP_NUMBER;
- # endif /* TTY_GROUP_NUMBER defined */
- endgrent();
- } /* get ttygroup */
- # endif /* TTY_GROUP defined */
-
- if( u == NULL )
- return;
-
- # ifdef Umax
- if( rdpminor == -1 ) {
- if( stat( "/dev/rdpcontrol", &stb ) == 0 &&
- (stb.st_mode & S_IFMT) == S_IFCHR )
- rdpminor = minor( stb.st_rdev );
- else
- rdpminor = -2;
- }
- # endif /* Umax defined */
-
- strcpy(term, "/dev/");
- strcat(term, u->u_line);
- if( stat(term, &stb) < 0 || (stb.st_mode & S_IFMT) != S_IFCHR ) {
- u->u_flags |= U_BADTTY; /* bad device!? */
- return;
- }
-
- if( sw_output )
- u->u_idle = time( 0 ) - stb.st_mtime; /* save (output) idle time */
- else
- u->u_idle = time( 0 ) - stb.st_atime; /* save idle time */
-
- u->u_ttydev = stb.st_rdev; /* save major/minor device numbers */
- # ifdef AIX3
- if( S_ISMPX( stb.st_mode ) ) {
- char *cp;
-
- cp = rindex( u->u_line, '/' );
- if( cp != NULL )
- u->u_ttydev += atoi( cp+1 );
- }
- # endif /* AIX3 defined */
-
- # ifdef Umax
- if( minor(stb.st_rdev) == rdpminor ) {
- u->u_ttyaddr = stb.st_rdaddr; /* annex/rdp inet addr */
- u->u_ttytype = stb.st_rdtype; /* annex/rdp device type */
- u->u_ttynum = stb.st_rdnum; /* annex/rdp line number */
- }
- else
- u->u_ttyaddr = 0; /* needed in Umax 4.3 (rel 4.0) */
- # endif /* Umax defined */
-
- if( (stb.st_mode & 0100) != 0 ) /* owner execute? */
- u->u_flags |= U_BIFF; /* yes, biff y */
-
- if( (stb.st_mode & 01) != 0 ) /* world execute? */
- u->u_flags |= U_HUNGRY; /* yes, is hungry! */
-
- # ifdef TTY_GROUP
- if( (stb.st_mode & 0002) == 0 &&
- (stb.st_gid != ttygroup || (stb.st_mode & 0020) == 0 ) )
- u->u_flags |= U_NOWRITE; /* no, msg n */
- # else /* TTY_GROUP not defined */
- if( (stb.st_mode & 0002) == 0 ) /* world write permission? */
- u->u_flags |= U_NOWRITE; /* no, msg n */
- # endif /* TTY_GROUP not defined */
-
- return;
- } /* termstat */
-
- GLOBAL char *gtname( s )
- char *s;
- {
- /* .see TTY_PREFIX (in getent.c) */
- if( *s == 't' && s[1] == 't' && s[2] == 'y' )
- return( s+3 );
- # ifdef UmaxV
- if( *s == 'r' && s[1] == 't' || *s == 'R' && s[1] == 'T' )
- return( s+2 );
- # endif /* UmaxV defined */
- return( s );
- } /* gtname */
-
- /*
- * outline - output a line of text, obeying width of device
- */
-
- GLOBAL void outchar(c)
- char c;
- {
- if( c == '\t' )
- output_col = (output_col + 8) & ~7;
- else if( c == '\n' ) {
- output_col = 0;
- if( netfinger )
- putc('\r', OUTPUT );
- }
- else
- output_col++;
- done_output = TRUE;
- putc(c, OUTPUT);
- } /* outchar */
-
- GLOBAL void outline( line )
- register char *line;
- {
- register int c;
-
- while( output_col < term_width ) {
- if( (c = *line++) == EOS )
- break;
- else
- outchar(c);
- } /* for col */
-
- outchar('\n');
- } /* outline */
-
- GLOBAL void blankline() {
- if( done_output )
- outchar( '\n' );
- done_output = FALSE;
- } /* blankline */
-
- GLOBAL void getterm() {
- # ifdef TIOCGWINSZ /* 4.3 */
- struct winsize ws;
- # endif /* TIOCGWINSZ defined */
- # ifdef TIOCGSIZE /* SOS3 */
- struct ttysize ts;
- # endif /* TIOCGSIZE defined */
- char tbuf[1024]; /* termcap defn */
- char *term; /* terminal type */
- int w; /* width */
-
- if( netfinger || !isatty(STD_OUTPUT) ) { /* stdout not a terminal? */
- term_width = PLUS_INF; /* no output truncation */
- return;
- }
- term_width = DEFWIDTH;
- w = -1;
-
- # ifdef TIOCGWINSZ /* 4.3 ioctl */
- if( ioctl( STD_OUTPUT, TIOCGWINSZ, &ws ) == 0 )
- w = ws.ws_col;
- # endif /* TIOCGWINSZ defined */
- # ifdef TIOCGSIZE
- if( w <= 0 && ioctl( STD_OUTPUT, TIOCGSIZE, &ts ) == 0 )
- w = ts.ts_cols;
- # endif /* TIOCGSIZE defined */
- if( (term = getenv("TERM")) != NULL && /* get terminal type */
- tgetent(tbuf, term) == 1 ) { /* get termcap entry into tbuf */
- if( w <= 0 )
- w = tgetnum("co"); /* get cols */
-
- if( tgetflag("am") ) /* auto wrap? */
- w--; /* yes, narrow by 1 */
- } /* got termcap entry */
- else
- w--; /* assume the worst */
-
- if( w > 0 ) /* get width? */
- term_width = w; /* set it */
- } /* getterm */
-
- /*
- * Local variables:
- * comment-column: 40
- * End:
- */
-