home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume8 / hint / part02 / tty.c < prev   
Encoding:
C/C++ Source or Header  |  1989-08-24  |  6.0 KB  |  281 lines

  1. /* tty.c -- functions dealing with terminals and termcap
  2.    Copyright (C) 1989 David MacKenzie
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 1, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
  17.  
  18. #include "hint.h"
  19.  
  20. /* Termcap codes.  */
  21. static char *tc_ts;        /* To status line. */
  22. static char *tc_fs;        /* From status line. */
  23. static char *tc_ds;        /* Disable (clear) status line. */
  24. static char *tc_bl;        /* Bell (possibly visual). */
  25. static short tc_ws;        /* Width (in columns) of status line. */
  26.  
  27. /* Send the message to `tt->tt_tty'.  Use hinttab to determine what the
  28.    status line codes for that terminal are.  */
  29.  
  30. void
  31. sendhint (tt)
  32.      struct ttylist *tt;
  33. {
  34.   int fd;
  35.  
  36.   if (!hintable (tt->tt_tty))
  37.     {
  38.       fprintf (stderr, "%s: %s on %s is no longer accepting hints\n",
  39.            program_name, tt->tt_user, tt->tt_tty);
  40.       return;
  41.     }
  42.   init_buffer ();
  43.   /* We put the beep here because bells sometimes don't work when in the
  44.      status line. */
  45.   tputs (tt->tt_ht.h_bl, 1, buffer_char);
  46.   tputs (tgoto (tt->tt_ht.h_ts, 0, 0), 1, buffer_char);
  47.   if (!name_at_end)
  48.     {
  49.       buffer_string ("(");
  50.       buffer_string (whoami ());
  51.       buffer_string (") ");
  52.     }
  53.   buffer_string (message);
  54.   if (name_at_end)
  55.     {
  56.       buffer_string (" - ");;
  57.       buffer_string (whoami ());
  58.     }
  59.   tputs (tt->tt_ht.h_fs, 1, buffer_char);
  60.  
  61.   fd = open (tt->tt_tty, O_WRONLY);
  62.   if (fd == -1)
  63.     pfatal (tt->tt_tty);
  64.   flush_buffer (fd);
  65.   close (fd);
  66. }
  67.  
  68. /* Erase the hint from `tt->tt_tty'.  */
  69.  
  70. void
  71. erasehint (tt)
  72.      struct ttylist *tt;
  73. {
  74.   int fd;
  75.  
  76.   init_buffer ();
  77.   tputs (tt->tt_ht.h_ds, 1, buffer_char);
  78.  
  79.   fd = open (tt->tt_tty, O_WRONLY);
  80.   if (fd == -1)
  81.     pfatal (tt->tt_tty);
  82.   flush_buffer (fd);
  83.   close (fd);
  84. }
  85.  
  86. /* Return our username.  First try utmp entry; if that fails, use uid.
  87.    Guaranteed to return a string 8 characters or shorter.  */
  88.  
  89. char *
  90. whoami ()
  91. {
  92.   char *me;
  93.  
  94.   me = getlogin ();
  95.   if (me == NULL)
  96.     me = pwname ();
  97.   if (strlen (me) > 8)
  98.     me[8] = 0;
  99.   return me;
  100. }
  101.  
  102. /* Return the passwd name based on our uid.  */
  103.  
  104. char *
  105. pwname ()
  106. {
  107.   struct passwd *pw;
  108.  
  109.   pw = getpwuid (getuid ());
  110.   if (pw == NULL)
  111.     return "";
  112.   else
  113.     return pw->pw_name;
  114. }
  115.  
  116. /* Set the entry in hinttab for tty `tty' (a full path).
  117.  
  118.    First we search for an existing (invalid) entry for `tty', and if
  119.    we find one, we update it.
  120.  
  121.    If we don't find one, we open the file in
  122.    APPEND mode, and add a new entry to the end.  Since we're using
  123.    atomic writes, we don't need to use any special file locking to
  124.    prevent competing hint processes from writing scrambled entries to
  125.    the end of the file.  */
  126.  
  127. void
  128. updatetab (tty)
  129.      char *tty;
  130. {
  131.   static struct hinttab h;
  132.  
  133.   /* Search the hinttab for an old entry for `tty'. */
  134.   sethtent ();
  135.   if (!gethttty (tty))
  136.     {
  137.       /* No previous entry for `tty'.  Add one. */
  138.       endhtent ();
  139.       sethtapp ();
  140.     }
  141.   setup_termcap ();
  142.   get_speed ();
  143.   strcpy (h.h_tty, tty);
  144.   strcpy (h.h_ts, tc_ts);
  145.   strcpy (h.h_fs, tc_fs);
  146.   strcpy (h.h_ds, tc_ds);
  147.   strcpy (h.h_bl, tc_bl);
  148.   h.h_ws = tc_ws;
  149.   writehtent (&h);
  150.   endhtent ();
  151. }
  152.  
  153. /* These functions do their best to provide atomic writes, since
  154.    we don't want our output getting mixed up with that of foreground
  155.    processes.  They don't check for overflows.  */
  156.  
  157. static char output_buffer[300];
  158. static int buffer_length;
  159.  
  160. void
  161. init_buffer ()
  162. {
  163.   buffer_length = 0;
  164. }
  165.  
  166. int
  167. buffer_char (c)
  168.      int c;
  169. {
  170.   output_buffer[buffer_length++] = c;
  171. }
  172.  
  173. /* `s' is a null-terminated string. */
  174.  
  175. void
  176. buffer_string (s)
  177.      char *s;
  178. {
  179.   while (*s)
  180.     output_buffer[buffer_length++] = *s++;
  181. }
  182.  
  183. void
  184. flush_buffer (fd)
  185.      int fd;
  186. {
  187.   write (fd, output_buffer, buffer_length);
  188. }
  189.  
  190. /* Output speed for tputs. */
  191. extern short ospeed;
  192.  
  193. /* Padding character for tputs. */
  194. extern char PC;
  195.  
  196. /* For tgoto. */
  197. extern char *BC, *UP;
  198.  
  199. /* Raw termcap entry. */
  200. static char entry[1024];
  201.  
  202. /* Extracted termcap strings. */
  203. static char strings[1024];
  204.  
  205. /* Initialize global termcap strings.  */
  206.  
  207. void
  208. setup_termcap ()
  209. {
  210.   char *tc_pc;            /* Padding character string. */
  211.  
  212.   if (term == NULL)
  213.     {
  214.       fprintf (stderr, "%s: TERM environment variable is not defined\n",
  215.            program_name);
  216.       exit (1);
  217.     }
  218.   switch (tgetent (entry, term))
  219.     {
  220.     case 0:
  221.       fprintf (stderr,
  222.            "%s: Terminal type %s is unknown\n", program_name, term);
  223.       exit (1);
  224.     case -1:
  225.       fprintf (stderr,
  226.        "%s: Cannot open terminal description database\n", program_name);
  227.       exit (1);
  228.     }
  229.  
  230.   /* Re-use term to point to space for next extracted string. */
  231.   term = strings;
  232.   tc_pc = tgetstr ("pc", &term);
  233.   PC = tc_pc ? *tc_pc : 0;
  234.   BC = UP = NULL;
  235.   if (tgetflag ("hs"))
  236.     {
  237.       /* tgetstr returns NULL if the capability was not found. */
  238.       tc_ts = tgetstr ("ts", &term);
  239.       tc_fs = tgetstr ("fs", &term);
  240.       tc_ds = tgetstr ("ds", &term);
  241.       tc_ws = tgetnum ("ws");
  242.       if (tc_ws == -1)
  243.     tc_ws = DEF_WS;
  244.     }
  245.   else
  246.     {
  247.       tc_ts = tc_fs = tc_ds = "";
  248.       tc_ws = DEF_WS;
  249.     }
  250.   if (use_vbell)
  251.     tc_bl = tgetstr ("vb", &term);
  252.   else
  253.     tc_bl = NULL;
  254.   if (use_bell && !tc_bl)
  255.     {
  256.       tc_bl = tgetstr ("bl", &term);
  257.       if (!tc_bl)
  258.     tc_bl = "\7";
  259.     }
  260.   else
  261.     tc_bl = "";
  262. }
  263.  
  264. void
  265. get_speed ()
  266. {
  267. #ifdef USG
  268.   struct termio tty_buffer;
  269.  
  270.   if (ioctl (1, TCGETA, &tty_buffer) != -1)
  271.     ospeed = tty_buffer.c_cflag & CBAUD;
  272. #else
  273.   struct sgttyb tty_buffer;
  274.  
  275.   if (gtty (1, &tty_buffer) != -1)
  276.     ospeed = tty_buffer.sg_ospeed;
  277. #endif
  278.   else
  279.     ospeed = 0;
  280. }
  281.