home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume25 / finger / part04 / output.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-03  |  7.7 KB  |  316 lines

  1. /*
  2.  * output.c -- terminal & output for new finger
  3.  *
  4.  * Copyright (C) 1986, 1990  Philip L. Budne
  5.  *
  6.  * This file is part of "Phil's Finger Program".
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 1, or (at your option)
  11.  * any later version.
  12.  *
  13.  */
  14.  
  15. # ifndef lint
  16. static char *rcsid = "$Id: output.c,v 3.0 90/07/06 13:11:28 budd Rel $";
  17. # endif /* lint not defined */
  18.  
  19. # include "finger.h"
  20. # include <sys/types.h>
  21. # include <sys/ioctl.h>
  22. # include <sys/stat.h>
  23. # include <stdio.h>
  24. # ifdef TTY_GROUP
  25. # include <grp.h>
  26. # endif /* TTY_GROUP defined */
  27. # include "output.h"
  28. # include "args.h"            /* sw_output (before luser.h) */
  29. # include "luser.h"
  30.  
  31. extern char *getenv();            /* from library */
  32. extern int netfinger;            /* from args.c */
  33.  
  34. LOCAL int term_width;            /* termcap width */
  35. LOCAL int output_col;            /* keep track of chars outchar'ed */
  36. LOCAL int done_output;            /* keep track for blank lines */
  37.  
  38. # ifndef DEFWIDTH
  39. # define DEFWIDTH (MAXLINE-1)
  40. # endif /* DEFWIDTH not defined */
  41.  
  42. GLOBAL void ptree( u, routine )
  43. register LUSER *u;
  44. int (*routine)();
  45. {
  46.     if( u == NULL )
  47.         return;
  48.  
  49.     if( u->u_left != NULL )
  50.         ptree( u->u_left, routine );
  51.  
  52.     (*routine)(u);
  53.  
  54.     if( u->u_right != NULL )
  55.         ptree( u->u_right, routine );
  56. } /* ptree */
  57.  
  58. GLOBAL char *intstr(s, sex)        /* print an interval */
  59. char *s;                /* buffer to use (if needed) */
  60. long sex;
  61. {
  62.     long min, hours, days;
  63.  
  64.     min = sex / 60;            /* get minutes */
  65.  
  66.     s[0] = EOS;                /* zap buffer */
  67.     if( min <= 0 )            /* worth thinking about? */
  68.     return( s );
  69.  
  70.     hours = min / 60;            /* get hours */
  71.     min = min % 60;            /* cast out hours */
  72.  
  73.     days = hours / 24;            /* get number of days */
  74.     hours = hours % 24;            /* cast out days */
  75.  
  76.     if( days > 0 ) {            /* over a day? */
  77.         if( days < 10 ) {        /* but still 1 digit? */
  78.         if( hours < 1 )
  79.         sprintf(s, "%dday", days); /* don't print 0h */
  80.         else if( hours < 10 )
  81.         sprintf(s, "%dd%dh", days, hours ); /* <days>d<hours>h */
  82.         else
  83.         sprintf(s, "%dd%d", days, hours ); /* <days>d<hours> */
  84.     } /* < 10 days */
  85.     else {
  86.         int weeks, d2;
  87.  
  88.         weeks = days / 7;
  89.         d2 = days % 7;
  90.         if( weeks < 10 ) {
  91.         if( d2 == 0 ) {
  92.             if( hours < 10 )
  93.             sprintf(s, "%dw%dh", weeks, hours );
  94.             else
  95.             sprintf(s, "%dwks", weeks );
  96.         }
  97.         else
  98.             sprintf(s, "%dw%dd", weeks, d2 );
  99.         } /* < 10 weeks */
  100.         else if( weeks < 100 ) {     /* (693 days!) */
  101.         if( d2 > 0 )
  102.             sprintf(s, "%dw%d", weeks, d2 );
  103.         else
  104.             sprintf(s, "%dwk", weeks );
  105.         } /* lt 100 weeks */
  106.         else if( days < 1000 )
  107.         sprintf(s, "%3dd", days); /* print three digits of day */
  108.         else            /* print years?? .... nah... */
  109.         strcpy(s, "*:**");    /* P-U-N-T ! */
  110.     } /* > 9 days */
  111.     } /* days > 0 */
  112.     else {                /* days == 0 */
  113.     if( hours == 0 )        /* less than an hour? */
  114.         sprintf(s, "%4d", min);     /* just minutes */
  115.     else if( hours < 10 )        /* one digit of hours? */
  116.         sprintf(s, "%1d:%02d", hours, min);    /* print h:mn */
  117.     else                /* hours >= 10 (must be <= 23) */
  118.         sprintf(s, "%2d:%1d", hours, min / 10); /* print hh:m */
  119.     } /* days == 0 */
  120.     return( s );      
  121. } /* intstr */
  122.  
  123. /*
  124.  *    termstat - given a LUSER record, get stat(2) information for terminal
  125.  *           returns TRUE for success
  126.  */
  127.  
  128. GLOBAL void termstat( u )
  129. LUSER *u;
  130. {
  131.     char term[30];
  132.     struct stat stb;
  133. # ifdef Umax
  134.     LOCAL short rdpminor = -1;
  135. # endif /* Umax defined */
  136.  
  137. # ifdef TTY_GROUP
  138.     LOCAL int ttygroup = -1;
  139.  
  140.     if( ttygroup < 0 ) {
  141.     struct group *gr;
  142.     if( (gr = getgrnam("tty")) != NULL )
  143.         ttygroup = gr->gr_gid;
  144. # ifdef TTY_GROUP_NUMBER
  145.     else
  146.         ttygroup = TTY_GROUP_NUMBER;
  147. # endif /* TTY_GROUP_NUMBER defined */
  148.     endgrent();
  149.     } /* get ttygroup */
  150. # endif /* TTY_GROUP defined */
  151.  
  152.     if( u == NULL )
  153.     return;
  154.  
  155. # ifdef Umax
  156.     if( rdpminor == -1 ) {
  157.     if( stat( "/dev/rdpcontrol", &stb ) == 0 && 
  158.        (stb.st_mode & S_IFMT) == S_IFCHR )
  159.         rdpminor = minor( stb.st_rdev );
  160.     else
  161.         rdpminor = -2;
  162.     }
  163. # endif /* Umax defined */
  164.  
  165.     strcpy(term, "/dev/");
  166.     strcat(term, u->u_line);
  167.     if( stat(term, &stb) < 0 || (stb.st_mode & S_IFMT) != S_IFCHR ) {
  168.     u->u_flags |= U_BADTTY;        /* bad device!? */
  169.     return;
  170.     }
  171.  
  172.     if( sw_output )
  173.     u->u_idle = time( 0 ) - stb.st_mtime; /* save (output) idle time */
  174.     else
  175.     u->u_idle = time( 0 ) - stb.st_atime; /* save idle time */
  176.  
  177.     u->u_ttydev = stb.st_rdev;        /* save major/minor device numbers */
  178. # ifdef AIX3
  179.     if( S_ISMPX( stb.st_mode ) ) {
  180.     char *cp;
  181.  
  182.     cp = rindex( u->u_line, '/' );
  183.     if( cp != NULL )
  184.         u->u_ttydev += atoi( cp+1 );
  185.     }
  186. # endif /* AIX3 defined */
  187.  
  188. # ifdef Umax
  189.     if( minor(stb.st_rdev) == rdpminor ) {
  190.     u->u_ttyaddr = stb.st_rdaddr;     /* annex/rdp inet addr */
  191.     u->u_ttytype = stb.st_rdtype;    /* annex/rdp device type */
  192.     u->u_ttynum =  stb.st_rdnum;    /* annex/rdp line number */
  193.     }
  194.     else
  195.     u->u_ttyaddr = 0;        /* needed in Umax 4.3 (rel 4.0) */
  196. # endif /* Umax defined */
  197.  
  198.     if( (stb.st_mode & 0100) != 0 )    /* owner execute? */
  199.     u->u_flags |= U_BIFF;        /* yes, biff y */
  200.  
  201.     if( (stb.st_mode & 01) != 0 )    /* world execute? */
  202.     u->u_flags |= U_HUNGRY;        /* yes, is hungry! */
  203.  
  204. # ifdef TTY_GROUP
  205.     if( (stb.st_mode & 0002) == 0 && 
  206.        (stb.st_gid != ttygroup || (stb.st_mode & 0020) == 0 ) )
  207.     u->u_flags |= U_NOWRITE;    /* no, msg n */
  208. # else  /* TTY_GROUP not defined */
  209.     if( (stb.st_mode & 0002) == 0 )    /* world write permission? */
  210.     u->u_flags |= U_NOWRITE;    /* no, msg n */
  211. # endif /* TTY_GROUP not defined */
  212.     
  213.     return;
  214. } /* termstat */
  215.  
  216. GLOBAL char *gtname( s )
  217. char *s;
  218. {
  219.     /* .see TTY_PREFIX (in getent.c) */
  220.     if( *s == 't' && s[1] == 't' && s[2] == 'y' )
  221.     return( s+3 );
  222. # ifdef UmaxV
  223.     if( *s == 'r' && s[1] == 't' || *s == 'R' && s[1] == 'T' )
  224.     return( s+2 );
  225. # endif /* UmaxV defined */
  226.     return( s );
  227. } /* gtname */
  228.  
  229. /*
  230.  *    outline - output a line of text, obeying width of device
  231.  */
  232.  
  233. GLOBAL void outchar(c)
  234. char c;
  235. {
  236.     if( c == '\t' )
  237.     output_col = (output_col + 8) & ~7;
  238.     else if( c == '\n' ) {
  239.     output_col = 0;
  240.     if( netfinger )
  241.         putc('\r', OUTPUT );
  242.     }
  243.     else
  244.     output_col++;
  245.     done_output = TRUE;
  246.     putc(c, OUTPUT);
  247. } /* outchar */
  248.  
  249. GLOBAL void outline( line )
  250. register char *line;
  251. {
  252.     register int c;
  253.  
  254.     while( output_col < term_width ) {
  255.     if( (c = *line++) == EOS )
  256.         break;
  257.     else
  258.         outchar(c);
  259.     } /* for col */
  260.  
  261.     outchar('\n');
  262. } /* outline */
  263.  
  264. GLOBAL void blankline() {
  265.     if( done_output )
  266.     outchar( '\n' );
  267.     done_output = FALSE;
  268. } /* blankline */
  269.  
  270. GLOBAL void getterm() {
  271. # ifdef TIOCGWINSZ            /* 4.3 */
  272.     struct winsize ws;
  273. # endif /* TIOCGWINSZ defined */
  274. # ifdef TIOCGSIZE            /* SOS3 */
  275.     struct ttysize ts;
  276. # endif /* TIOCGSIZE defined */
  277.     char tbuf[1024];            /* termcap defn */
  278.     char *term;                /* terminal type */
  279.     int w;                /* width */
  280.  
  281.     if( netfinger || !isatty(STD_OUTPUT) ) { /* stdout not a terminal? */
  282.     term_width = PLUS_INF;        /* no output truncation */
  283.     return;
  284.     }
  285.     term_width = DEFWIDTH;
  286.     w = -1;
  287.  
  288. # ifdef TIOCGWINSZ            /* 4.3 ioctl */
  289.     if( ioctl( STD_OUTPUT, TIOCGWINSZ, &ws ) == 0 )
  290.     w = ws.ws_col;
  291. # endif /* TIOCGWINSZ defined */
  292. # ifdef TIOCGSIZE
  293.     if( w <= 0 && ioctl( STD_OUTPUT, TIOCGSIZE, &ts ) == 0 )
  294.     w = ts.ts_cols;
  295. # endif /* TIOCGSIZE defined */
  296.     if( (term = getenv("TERM")) != NULL && /* get terminal type */
  297.        tgetent(tbuf, term) == 1 ) {    /* get termcap entry into tbuf */
  298.     if( w <= 0 )
  299.         w = tgetnum("co");        /* get cols */
  300.  
  301.     if( tgetflag("am") )        /* auto wrap? */
  302.         w--;            /* yes, narrow by 1 */
  303.     } /* got termcap entry */
  304.     else
  305.     w--;                /* assume the worst */
  306.  
  307.     if( w > 0 )                /* get width? */
  308.     term_width = w;            /* set it */
  309. } /* getterm */
  310.  
  311. /*
  312.  * Local variables:
  313.  * comment-column: 40
  314.  * End:
  315.  */
  316.