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

  1. /*
  2.  * ttyask.c -- front end for ttyloc -- ask about ttyplaces
  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: ttyask.c,v 3.0 90/07/06 13:11:57 budd Rel $";
  17. # endif /* lint not defined */
  18.  
  19. # include "finger.h"
  20. # include <pwd.h>
  21. # include <stdio.h>
  22. # include <ctype.h>
  23. # include <signal.h>
  24. # include <strings.h>
  25. # ifdef USG
  26. # include <termio.h>            /* POSIX too! */
  27. # else  /* USG not defined */
  28. # include <sgtty.h>
  29. # endif /* USG not defined */
  30.  
  31. # include "ttylocfile.h"
  32.  
  33. extern char *getttytype();        /* from getttytype.c */
  34. extern TTYLOC *findttyloc();        /* from readttylocfile.c */
  35.  
  36. # define TTYLOC_PROG "ttyloc"        /* program to set ttylocs */
  37. # define TTYPLACES ".ttyplaces"        /* file to read */
  38. # define MAXTTP 256
  39.  
  40. # ifndef DEFCYCLE
  41. # define DEFCYCLE 120            /* default cycle sleep time */
  42. # endif /* DEFCYCLE not defined */
  43.  
  44. # ifndef MINCYCLE
  45. # define MINCYCLE 60            /* minimum allowed cycle/random time */
  46. # endif /* MINCYCLE not defined */
  47.  
  48. char *pname;                /* name we were invoked as */
  49.  
  50. char *non_hardwire_types[] = {        /* if you are this in /etc/ttytype */
  51.                     /* (or /etc/ttys in 4.3) you are */
  52.                     /* probably NOT hardwired */
  53.     "su",    "stupid",
  54.     "du",    "dialup",    "sd",    "D2",
  55.     "sa",    "network",
  56.     "un",    "unknown",
  57.     "se",    "ethernet",
  58.     "sw",    "switch",
  59.     "sp",    "plugboard",    "patch",
  60.     "sb",    "arpanet",
  61.     "sc",    "bussiplexer",
  62. # ifdef Umax
  63.     "",                    /* CALL connections come in like this*/
  64.                     /* if tty type not set */
  65. # endif /* Umax defined */
  66. # ifdef NON_HARDWIRE_TYPES
  67.     NON_HARDWIRE_TYPES ,
  68. # endif /* NON_HARDWIRE_TYPES defined */
  69.     NULL
  70.     };
  71.  
  72. struct ttp {
  73.     char *t_name;
  74.     char *t_string;
  75. } ttp[MAXTTP];
  76. int nttp;
  77.  
  78. # ifdef USG
  79. struct termio old, new;
  80. # else  /* USG not defined */
  81. struct sgttyb old, new;
  82. # endif /* USG not defined */
  83.  
  84. FORWARD LOCAL BOOL check_hardwire();
  85. FORWARD LOCAL void
  86.     setup(), restore(), readttp(), do_ttyask(), do_ttyplace(),
  87.     do_ttyrandom(), do_ttycycle(), sayit(), setit(), terpri(),
  88.     whine(), catcher(), checkwho();
  89.  
  90. int hardwire = 0;
  91. int cycletime = 0;
  92. char mytty[ 512 ];
  93.  
  94. int main(argc, argv)
  95. int argc;
  96. char *argv[];
  97. {
  98.     enum { F_NONE=0, F_TTYASK, F_TTYPLACE, F_TTYRANDOM, F_TTYCYCLE } function;
  99.     char *ttpfile;            /* -f argument */
  100.     int err, arg;
  101.     char *cp;                /* temp char ptr */
  102.  
  103.     extern int getopt(), optind;
  104.     extern char *optarg;
  105.  
  106.     err = 0;
  107.     pname = argv[0];
  108.     function = F_NONE;
  109.  
  110.     if( (cp = rindex(pname, '/')) != NULL )
  111.     pname = cp + 1;
  112.     ttpfile = NULL;
  113.  
  114.     while( (arg = getopt(argc, argv, "acf:hprt:")) != -1 ) {
  115.     switch( arg ) {
  116.     case 'f':
  117.         ttpfile = optarg;
  118.         break;
  119.     case 'h':
  120.         hardwire = 1;
  121.         break;
  122.     case 'c':
  123.         function = F_TTYCYCLE;
  124.         break;
  125.     case 'p':
  126.         function = F_TTYPLACE;
  127.         break;
  128.     case 'r':
  129.         function = F_TTYRANDOM;
  130.         break;
  131.     case 'a':
  132.         function = F_TTYASK;
  133.         break;
  134.     case 't':
  135.         cycletime = atoi( optarg );
  136.         break;
  137.  
  138.     default:            /* ? or other junk */
  139.         err++;
  140.     } /* switch */
  141.     } /* while */
  142.  
  143.     if( err > 0 )
  144.     whine("-a -c -r -h -t <time> -f <file>");
  145.  
  146.     readttp( ttpfile );            /* read .ttyplaces (or other) file */
  147.  
  148.     if( function == F_NONE ) {
  149.     if( strcmp(pname, "ttyplace") == 0 )
  150.         function = F_TTYPLACE;
  151.     else if( strcmp(pname, "ttyrandom") == 0 )
  152.         function = F_TTYRANDOM;
  153.     else if( strcmp(pname, "ttycycle") == 0 )
  154.         function = F_TTYCYCLE;
  155.     } /* F_NONE */
  156.  
  157.     switch( function ) {
  158.     case F_NONE:
  159.     case F_TTYASK:
  160.     if( hardwire && check_hardwire() )
  161.         exit( 0 );
  162.     setup();
  163.     signal(SIGINT, catcher);
  164.     do_ttyask();
  165.     restore();
  166.     break;
  167.     case F_TTYPLACE:
  168.     if( optind < argc )
  169.         do_ttyplace( argv[optind] );
  170.     else
  171.         whine("must have string argument");
  172.     break;
  173.     case F_TTYRANDOM:
  174.     do_ttyrandom();
  175.     break;
  176.     case F_TTYCYCLE:
  177.     do_ttycycle();
  178.     break;
  179.     } /* switch */
  180.     return( 0 );            /* ANSI! */
  181. } /* main */
  182.  
  183. # define LEN 200
  184. LOCAL void readttp( file )
  185. char *file;
  186. {
  187.     char fname[ LEN ];
  188.     struct passwd *pw;
  189.     FILE *f;
  190.  
  191.     nttp = 0;
  192.     if( (pw = getpwuid( getuid() )) == NULL )
  193.     whine("no pw entry?");
  194.  
  195.     if( file == NULL ) {
  196.     strcpy(fname, pw->pw_dir);
  197.     strcat(fname, "/");
  198.     strcat(fname, TTYPLACES);
  199.     file = fname;
  200.     }
  201.  
  202.     if( (f = fopen(file, "r")) == NULL ) {
  203.     perror( file );
  204.     exit( 1 );
  205.     }
  206.  
  207.     while( fgets(fname, LEN, f) != NULL ) {
  208.     register int i;
  209.     register char *cp;
  210.     char *p2;
  211.  
  212.     i = strlen( fname );
  213.     if( i == 0 )
  214.         continue;
  215.  
  216.     if( i < LEN - 1 )
  217.         fname[ i - 1 ] = EOS;
  218.  
  219.     cp = fname;
  220.     while( *cp != EOS  && isspace( *cp ) )
  221.         cp++;
  222.     if( *cp == EOS )
  223.         continue;
  224.  
  225.     while( *cp != EOS  && !isspace( *cp ) )
  226.         cp++;
  227.  
  228.     if( *cp == EOS )
  229.         whine("no space on line: %s", fname);
  230.  
  231.     *cp++ = EOS;
  232.     while( *cp != EOS  &&  isspace( *cp ) )
  233.         cp++;
  234.  
  235.     if( *cp == EOS )
  236.         whine("no location for '%s'", fname);
  237.  
  238.     ttp[ nttp ].t_name = p2 = malloc( strlen( fname ) + 1 );
  239.     strcpy(p2, fname);
  240.  
  241.     ttp[ nttp ].t_string = p2 = malloc( strlen( cp ) + 1 );
  242.     strcpy(p2, cp);
  243.  
  244.     nttp++;
  245.     } /* while */
  246. } /* readttp */
  247.  
  248. LOCAL void do_ttyask() {
  249.     register int i, c;
  250.  
  251.     if( cycletime > 0 )
  252.     signal(SIGALRM, catcher );
  253.     for(i = 0; i < nttp; i++ ) {
  254.     for( ; ; ) {
  255.         printf("--%s--", ttp[i].t_name );
  256.         if( cycletime > 0 )        /* time limit? */
  257.         alarm( cycletime );    /* reset the clock! */
  258.         c = getchar();
  259.         terpri();
  260.         if( c == EOF )
  261.         return;            /* unlikely in CBREAK */
  262.         switch( c & 0177 ) {
  263.         case '\03':            /* ^C */
  264.         case '\04':            /* ^D */
  265.         case 'Q':
  266.         case 'q':
  267.         return;
  268.         case ' ':
  269.         case 'Y':
  270.         case 'y':
  271.         alarm( 0 );
  272.         setit( i );
  273.         return;
  274.         case '?':
  275.         case 'h':
  276.         case 'H':
  277.         printf("space, Y, y       = yes\r\n");
  278.         printf("<del>, N, n, <bs> = no\r\n");
  279.         printf("?, H, h           = this\r\n");
  280.         printf("Q, q, ^c, ^d      = quit\r\n");
  281.         break;
  282.         case 0177:
  283.         case '\b':
  284.         case 'N':
  285.         case 'n':
  286.         goto no;    /* sigh (must break switch & for) */
  287.         break;
  288.         default:
  289.         printf("? for help\r\n");
  290.         break;
  291.         } /* case */
  292.     } /* for ever */
  293.     no: ;            /* break forever */
  294.     } /* for i */
  295. } /* do_ttyask */
  296.  
  297. LOCAL int sort_item(a, b)
  298. struct ttp *a, *b;
  299. {
  300.     return( strcmp( a->t_name, b->t_name ) );
  301. } /* sort_item */
  302.  
  303. LOCAL void sort_all() {
  304.     qsort(ttp, nttp, sizeof( struct ttp ), sort_item );
  305. } /* sort_all */
  306.  
  307. LOCAL void do_ttyplace( name )
  308. char *name;
  309. {
  310.     register int i, it, len;
  311.  
  312.     sort_all();
  313.     it = -1;
  314.     len = strlen( name );
  315.  
  316.     for( i = 0; i < nttp; i++ ) {
  317.     if( strncmp(name, ttp[i].t_name, len) == 0 ) {
  318.         if( i+1 < nttp && strncmp(name, ttp[i+1].t_name, len) == 0 )
  319.         whine("ambiguous place '%s'", name);
  320.         else {
  321.         it = i;
  322.         break;
  323.         }
  324.     } /* if strncmp [i] */
  325.     } /* for */
  326.  
  327.     if( it != -1 )
  328.     sayit( it );
  329.     else
  330.     whine("no place called '%s'", name);
  331.  
  332. } /* do_ttyplace */
  333.  
  334. LOCAL void do_ttyrandom() {
  335.     int i;
  336.     unsigned long seed;
  337.  
  338.     if( cycletime > 0 && cycletime < MINCYCLE )
  339.     cycletime = MINCYCLE;
  340.  
  341.     seed = getpid() + time( 0 );
  342.     for( ; ; ) {
  343.     seed = (seed * 11109 + 13849) & 0xffff;
  344.     i = seed % nttp;
  345.     setit( i );
  346.     if( cycletime == 0 )
  347.         return;
  348.     else
  349.         sleep( cycletime );
  350.     checkwho();
  351.     }
  352. } /* do_ttyrandom */
  353.  
  354. LOCAL void do_ttycycle() {
  355.     int i;
  356.  
  357.     if( cycletime < MINCYCLE )
  358.     cycletime = DEFCYCLE;
  359.     for( ; ; ) {
  360.     for( i = 0; i < nttp; i++ ) {
  361.         setit( i );
  362.         sleep( cycletime );
  363.         checkwho();
  364.     } /* for i */
  365.     } /* for ever */
  366. } /* do_ttycycle */
  367.  
  368. LOCAL void sayit( i )
  369. int i;
  370. {
  371.     printf("%s (%s)\n", ttp[ i ].t_name, ttp[ i ].t_string );
  372.     setit( i );
  373. } /* sayit */
  374.  
  375. LOCAL void setit( i )
  376. int i;
  377. {
  378.     char line[250];
  379.  
  380.     line[0] = EOS;
  381.     sprintf(line, "%s %s", TTYLOC_PROG, ttp[i].t_string);
  382.  
  383.     system( line );
  384. } /* setit */
  385.  
  386. LOCAL void terpri() {
  387.     fputs("\r\n", stdout);        /* beware CBREAK mode */
  388. } /* terpri */
  389.  
  390. LOCAL void whine(s,a)
  391. char *s, *a;
  392. {
  393.     char buf[ 100 ];
  394.     sprintf(buf, s, a);
  395.     fprintf(stderr, "%s: %s\n", pname, buf);
  396.     exit( 1 );
  397. } /* whine */
  398.  
  399. LOCAL void catcher() {            /* here on signal */
  400.     restore();
  401.     exit( 1 );
  402. } /* catcher */
  403.  
  404. LOCAL void setup() {
  405. # ifdef USG                /* POSIX too! */
  406.     ioctl( STD_INPUT, TCGETA, &old );
  407.     new = old;
  408.     new.c_cc[VMIN] = 1;
  409.     new.c_lflag &=~ECHO;
  410.     new.c_lflag &= ~ICANON;
  411.     ioctl( STD_INPUT, TCSETA, &new );
  412. # else  /* USG not defined */
  413.     gtty( STD_INPUT, &old);
  414.     new = old;
  415.     new.sg_flags &= ~(CBREAK|ECHO);
  416.     new.sg_flags |= RAW;
  417.     stty( STD_INPUT, &new);
  418. # endif /* USG not defined */
  419. } /* setup */
  420.  
  421. LOCAL void restore() {
  422. # ifdef USG                /* POSIX too! */
  423.     ioctl( STD_INPUT, TCSETA, &old );
  424. # else  /* USG not defined */
  425.     stty( STD_INPUT, &old);
  426. # endif /* USG not defined */
  427. } /* restore */
  428.  
  429. /****************************************************************/
  430.  
  431. LOCAL void get_mytty() {
  432.     register char *tn, *tp;
  433.     extern char *ttyname();
  434.  
  435.     if( mytty[0] != EOS )
  436.     return;
  437.  
  438.     tn = ttyname( 0 );
  439.     if( tn == NULL )
  440.     return;
  441.     if( (tp = rindex( tn, '/')) != NULL )
  442.     tp++;
  443.     else
  444.     tp = tn;
  445.     strcpy( mytty, tp );
  446. }
  447.  
  448. LOCAL void checkwho() {
  449.     if( getppid() == INIT_PID )
  450.     exit( 0 );
  451. }
  452.  
  453. LOCAL BOOL check_hardwire() {
  454.     register char *ty, *cp;
  455.     register TTYLOC *tp;
  456.     register i;
  457.  
  458.     get_mytty();
  459.  
  460.     /* try to check line type from new ttyloc file */
  461.     if( readnewttylocfile() > 0 && (tp = findttyloc( mytty )) != NULL ) {
  462.     if( tp->t_type == LT_HARD || tp->t_type == LT_TTYLOC )
  463.         return( TRUE );
  464.     else
  465.         return( FALSE );
  466.     }
  467.  
  468.     /* get terminal type (/etc/ttytype in 4.2; /etc/ttys in 4.3) */
  469.     if( (ty = getttytype(mytty)) == NULL )
  470.     return( FALSE );
  471.  
  472.     /* look for type in list of known NON hardwired line types */
  473.     i = 0;
  474.     while( (cp = non_hardwire_types[ i ]) != NULL )
  475.     if( strcmp( cp, ty ) )
  476.         return( FALSE );        /* not a hardwire candidate */
  477.  
  478.     return( TRUE );
  479. } /* check_hardwire */
  480.  
  481. /*
  482.  * Local variables:
  483.  * comment-column: 40
  484.  * End:
  485.  */
  486.