[comp.sources.bugs] Bugfixes/Enhancements to "screen"

matt@srs.UUCP (Matt Goheen) (07/22/87)

Here are some nifty things for "screen" the common man's window package.
See the README file for details.

						Matt Goheen
						S.R. Systems

-----cut-----cut-----cut-----cut-----ok ok already----------------------
#!/bin/sh
#
# shar archiver, delete everything above the #!/bin/sh line
# and run through sh (not csh)
#
echo 'shar: extracting "README" (1522 characters)'
# 'README' has a checksum of 15316 on BSD and 58694 on System V.
sed 's/^X//' > README << 'XXX_EOF_XXX'
X
XHere is an update for the "screen" program posted several months ago.
XThis package consists of several patches:
X
X    patch1:  From the original author.  This fixes a problem that
X	     causes "screen" to crash on systems that can't handle
X	     referencing NULL pointers (I think).  Definitely
X	     install this.
X
X    patch2:  Fixes a small bug that would crash "screen" when run
X	     under SunWindows (terminal type = sun).  May have crashed
X	     other types as well.  This is from the author too.
X
X    patch3:  Various updates from our site.  These include:
X		1) The ability to explicitly name each window
X		2) The ability to change the default name for all
X		   windows via an environment variable
X		3) Doesn't redraw the current window if you happen
X		   to change to the same one (via "^A[0-9]")
X		4) The addition of another file, "utmp.c", to
X		   support 5)...
X		5) Makes an entry into "/etc/utmp" so that programs
X		   like "talk", "su" and "who" know about which
X		   ptys "screen" is using (i.e. "talk" used to say,
X		   "You don't exist, go away!").  This code is stolen
X		   from the "grotwin" package (thank you).  On the
X		   Sun system, "/etc/utmp" is world writable, if
X		   yours isn't, you may have to change this (or make
X		   "screen" SUID to root - not a good idea at this
X		   point).
X		6) An updated manual page describing these features
X
X
X					Enjoy,
X					    Matt Goheen
X					    S.R. Systems
X			    {seismo,allegra,ames,rutgers}!rochester!srs!matt
X
XP.S. I didn't write screen, but I love it.
XXX_EOF_XXX
if test 1522 -ne "`wc -c < README`"
then
    echo 'shar: transmission error on "README"'
fi
chk=`sum README | awk '{print $1}'`
if test 15316 -ne $chk -a 58694 -ne $chk
then
    echo 'shar: checksum error on "README"'
fi
echo 'shar: extracting "HINT" (1448 characters)'
# 'HINT' has a checksum of 29599 on BSD and 57808 on System V.
sed 's/^X//' > HINT << 'XXX_EOF_XXX'
XIf you use screen to handle remote sessions on other machines (i.e.
Xhaving one or more of the screen windows on remote machines), you
Xwill have to find some way of getting the "TERMCAP" variable across
Xthe connection.  One way is to re-write "rlogin".  Another way is
Xto put whatever screen puts into your TERMCAP environment variable
Xinto a file and source that into an environment variable on the
Xremote side.  What I've found to be the best way is to add a "screen"
Xterminal type to "/etc/termcap" and put into it the 'best' entry
Xyou can come up with.  If your site is like ours, we have mostly
Xone terminal type and it turns out that most work the same anyway
X(as far as screen is concerned, i.e. most have 'so' and 'us').
XHere is what we use, note that our terminals DON'T support scrolling
Xregions and so neither does this termcap entry:
X
XSC|screen|VT 100/ANSI X3.64 virtual terminal:\
X	:DO=\E[%dB:LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:bs:bt=\E[Z:cd=\E[J:\
X	:ce=\E[K:cl=\E[2J\E[H:cm=\E[%i%d;%dH:ct=\E[3g:do=\E[B:nd=\E[C:\
X	:pt:rc=\E8:rs=\Ec:sc=\E7:st=\EH:up=\E[A:li#24:co#80:\
X	:vb=\E[?5h\E[?5l:us=\E[4m:ue=\E[24m:so=\E[3m:se=\E[23m:\
X	:sr=\EM:al=\E[L:AL=\E[%dL:dl=\E[M:DL=\E[%dM:dc=\E[P:\
X	:DC=\E[%dP:im=\E[4h:ei=\E[4l:ic=:IC=\E[%d@:k0=^A@^M:\
X	:k1=^AA^M:k2=^AB^M:k3=^AC^M:k4=^AD^M:kd=^J:kl=^H:\
X	:ko=cl,ho,ku,kd,kl,kr:kr=^L:ku=^K:
X
XSince the TERM environment variable IS poked out across the rlogin
Xsession, this works great...
X
X					Matt Goheen
X
XXX_EOF_XXX
if test 1448 -ne "`wc -c < HINT`"
then
    echo 'shar: transmission error on "HINT"'
fi
chk=`sum HINT | awk '{print $1}'`
if test 29599 -ne $chk -a 57808 -ne $chk
then
    echo 'shar: checksum error on "HINT"'
fi
echo 'shar: extracting "patch1" (620 characters)'
# 'patch1' has a checksum of 50511 on BSD and 41209 on System V.
sed 's/^X//' > patch1 << 'XXX_EOF_XXX'
X*** screen.c.orig	Fri Jul 17 08:26:48 1987
X--- screen.c	Fri Jul 17 08:15:37 1987
X***************
X*** 8,14 ****
X   * not modified.
X   */
X  
X! static char ScreenVersion[] = "screen 1.1b 20-Mar-87";
X  
X  #include <stdio.h>
X  #include <sgtty.h>
X--- 8,14 ----
X   * not modified.
X   */
X  
X! static char ScreenVersion[] = "screen 1.1c 23-Mar-87";
X  
X  #include <stdio.h>
X  #include <sgtty.h>
X***************
X*** 551,556 ****
X--- 551,557 ----
X  	goto nomem;
X      ResetScreen (p);
X      p->active = 0;
X+     p->outlen = 0;
X      p->ptyfd = f;
X      strncpy (p->cmd, Filename (args[0]), MAXSTR-1);
X      p->cmd[MAXSTR-1] = '\0';
XXX_EOF_XXX
if test 620 -ne "`wc -c < patch1`"
then
    echo 'shar: transmission error on "patch1"'
fi
chk=`sum patch1 | awk '{print $1}'`
if test 50511 -ne $chk -a 41209 -ne $chk
then
    echo 'shar: checksum error on "patch1"'
fi
echo 'shar: extracting "patch2" (951 characters)'
# 'patch2' has a checksum of 15227 on BSD and 62683 on System V.
sed 's/^X//' > patch2 << 'XXX_EOF_XXX'
X*** ansi.c.orig	Wed Jul 22 13:08:47 1987
X--- ansi.c	Wed Jul 22 09:08:13 1987
X***************
X*** 8,14 ****
X   * not modified.
X   */
X  
X! char AnsiVersion[] = "ansi 1.0c 18-Mar-87";
X  
X  #include <stdio.h>
X  #include <sys/types.h>
X--- 8,14 ----
X   * not modified.
X   */
X  
X! char AnsiVersion[] = "ansi 1.0d 26-Mar-87";
X  
X  #include <stdio.h>
X  #include <sys/types.h>
X***************
X*** 137,143 ****
X  	 * clearly specified by the termcap manual.
X  	 * Anyway, we should at least look whether ME and SE/UE are equal:
X  	 */
X! 	if (SE && UE && ME && strcmp (SE, UE) == 0 || strcmp (ME, UE) == 0)
X  	    UE = 0;
X  	if (SE && ME && strcmp (SE, ME) == 0)
X  	    SE = 0;
X--- 137,143 ----
X  	 * clearly specified by the termcap manual.
X  	 * Anyway, we should at least look whether ME and SE/UE are equal:
X  	 */
X! 	if (SE && UE && ME && (strcmp (SE, UE) == 0 || strcmp (ME, UE) == 0))
X  	    UE = 0;
X  	if (SE && ME && strcmp (SE, ME) == 0)
X  	    SE = 0;
XXX_EOF_XXX
if test 951 -ne "`wc -c < patch2`"
then
    echo 'shar: transmission error on "patch2"'
fi
chk=`sum patch2 | awk '{print $1}'`
if test 15227 -ne $chk -a 62683 -ne $chk
then
    echo 'shar: checksum error on "patch2"'
fi
echo 'shar: extracting "patch3" (10342 characters)'
# 'patch3' has a checksum of 47267 on BSD and 13449 on System V.
sed 's/^X//' > patch3 << 'XXX_EOF_XXX'
X*** Makefile.orig	Wed Jul 22 11:47:33 1987
X--- Makefile	Wed Jul 22 11:09:06 1987
X***************
X*** 1,6 ****
X! CFILES= screen.c ansi.c
X! OFILES= screen.o ansi.o
X! CFLAGS= -O
X  
X  screen: $(OFILES)
X  	cc $(CFLAGS) -o screen $(OFILES) -ltermcap
X--- 1,6 ----
X! CFILES= screen.c ansi.c utmp.c
X! OFILES= screen.o ansi.o utmp.o
X! CFLAGS= -O -Usun
X  
X  screen: $(OFILES)
X  	cc $(CFLAGS) -o screen $(OFILES) -ltermcap
X*** screen.h.orig	Wed Jul 22 09:15:06 1987
X--- screen.h	Wed Jul 22 10:51:47 1987
X***************
X*** 32,37 ****
X--- 32,38 ----
X      int wpid;
X      int ptyfd;
X      char outbuf[IOSIZE];
X+     char ttyname[8];
X      int outlen;
X      char cmd[MAXSTR];
X      char **image;
X*** screen.1.orig	Wed Jul 22 11:46:40 1987
X--- screen.1	Wed Jul 22 15:06:12 1987
X***************
X*** 48,53 ****
X--- 48,58 ----
X  when no more windows are left,
X  .I screen
X  exits.
X+ .PP
X+ If the environment variable WNAME is present when
X+ .I screen
X+ is invoked, its value is used as the window name rather than
X+ the default of the command name.
X  .SH "COMMAND KEYS"
X  An easier way to create a new window is to type \*QC-a c\*U (the notation
X  \*QC-x\*U will be used as a shorthand for Control-x in this manual; x is
X***************
X*** 102,107 ****
X--- 107,116 ----
X  Display the version.
X  .IP "\fBC-a a\fP\0\0\0\0\0"
X  Send the character \*QC-a\*U to the processes running in the window.
X+ .IP "\fBC-a x\fP or \fBC-a C-x\fP"
X+ Prompt for a new name for the current window.  This new name is displayed
X+ when the "\fBC-w\fP" command is issued.  For more information on naming
X+ windows, see the description of the `.screenrc' file, below.
X  .IP
X  .PP
X  The
X***************
X*** 168,173 ****
X--- 177,210 ----
X  when the above `.screenrc' is used.
X  .PP
X  .ne 3
X+ .B "name \fIn\fP \fIwindow_name\fP"
X+ .PP
X+ Use `window_name' as the name for the given window number.  The window
X+ must already have been created with the `screen' command.  Thus,
X+ it is impossible to name the default window in this manner.  The
X+ only way to name the default window without using the "\fBC-a x\fP"
X+ command from within
X+ .I screen
X+ is to use the WNAME environment variable and issue `name' commands
X+ for each window you wish to rename.  For example, the following
X+ setup seems to work well:
X+ .PP
X+ .nf
X+ 	# in your .login (for csh)
X+ 	setenv WNAME `hostname`
X+ 
X+ 	# in your .screenrc
X+ 	screen 1
X+ 	screen 2 /usr/hosts/fastsun
X+ 	name 2 fastsun
X+ .fi
X+ .PP
X+ This setup will create three windows.  The default window (0 in
X+ this case) and window 1 will be called by the local host name.
X+ Window 2 will be a remote login to another machine and will be
X+ called `fastsun'.
X+ .PP
X+ .ne 3
X  .B "bind \fIkey\fP [\fIfunction\fP | \fIcmd args\fP]"
X  .PP
X  Bind a function to a key.
X***************
X*** 189,200 ****
X  	shell	Create new window with a shell
X  	kill	Kill the current window
X  	other	Switch to previously displayed window
X  	next	Switch to the next window
X  	prev	Switch to the previous window
X  	redisplay	Redisplay current window
X  	hardcopy	Make hardcopy of current window
X  	suspend	Suspend \fIscreen\fP
X! 	windows	Display list of window
X  	version	Display the version
X  	select0	Switch to window #0
X  	\0\0...
X--- 226,238 ----
X  	shell	Create new window with a shell
X  	kill	Kill the current window
X  	other	Switch to previously displayed window
X+ 	name	Rename the current window
X  	next	Switch to the next window
X  	prev	Switch to the previous window
X  	redisplay	Redisplay current window
X  	hardcopy	Make hardcopy of current window
X  	suspend	Suspend \fIscreen\fP
X! 	windows	Display list of window commands/names
X  	version	Display the version
X  	select0	Switch to window #0
X  	\0\0...
X***************
X*** 500,505 ****
X--- 538,546 ----
X  correctly (they are ignored). 
X  .PP
X  Different character sets are not supported.
X+ .PP
X+ You cannot use the `name' token in the `.screenrc' file to name the
X+ default window.  Use the environment variable WNAME for this.
X  .PP
X  `ms' is not advertised in the termcap entry (in order to compensate
X  a bug in
X*** screen.c.orig	Fri Jul 17 08:15:37 1987
X--- screen.c	Wed Jul 22 15:06:10 1987
X***************
X*** 46,55 ****
X--- 46,57 ----
X  extern sys_nerr;
X  extern char *sys_errlist[];
X  extern char *rindex(), *malloc(), *getenv(), *MakeTermcap(), *ttyname();
X+ extern char *WindowName();
X  static SigChld();
X  static char *Filename(), **SaveArgs();
X  
X  static char PtyName[32], TtyName[32];
X+ static char *WindName;
X  static char *ShellProg;
X  static char *ShellArgs[2];
X  static char inbuf[IOSIZE];
X***************
X*** 113,119 ****
X  #define KEY_7             18
X  #define KEY_8             19
X  #define KEY_9             20
X! #define KEY_CREATE        21
X  
X  struct key {
X      int type;
X--- 115,122 ----
X  #define KEY_7             18
X  #define KEY_8             19
X  #define KEY_9             20
X! #define KEY_NAME          21
X! #define KEY_CREATE        22
X  
X  struct key {
X      int type;
X***************
X*** 123,132 ****
X  char *KeyNames[] = {
X      "hardcopy", "suspend", "shell", "next", "prev", "kill", "redisplay",
X      "windows", "version", "other", "select0", "select1", "select2", "select3",
X!     "select4", "select5", "select6", "select7", "select8", "select9",
X      0
X  };
X  
X  main (ac, av) char **av; {
X      register n, len;
X      register struct win **pp, *p;
X--- 126,137 ----
X  char *KeyNames[] = {
X      "hardcopy", "suspend", "shell", "next", "prev", "kill", "redisplay",
X      "windows", "version", "other", "select0", "select1", "select2", "select3",
X!     "select4", "select5", "select6", "select7", "select8", "select9", "name",
X      0
X  };
X  
X+ char * myname;              /* for utmp entries */
X+ 
X  main (ac, av) char **av; {
X      register n, len;
X      register struct win **pp, *p;
X***************
X*** 135,143 ****
X      int aflag = 0;
X      struct timeval tv;
X      time_t now;
X!     char buf[IOSIZE], *myname = (ac == 0) ? "screen" : av[0];
X      char rc[256];
X  
X      while (--ac) {
X  	ap = *++av;
X  	if (strcmp (ap, "-c") == 0) {
X--- 140,149 ----
X      int aflag = 0;
X      struct timeval tv;
X      time_t now;
X!     char buf[IOSIZE];
X      char rc[256];
X  
X+     myname = (ac == 0) ? "screen" : av[0];
X      while (--ac) {
X  	ap = *++av;
X  	if (strcmp (ap, "-c") == 0) {
X***************
X*** 168,173 ****
X--- 174,180 ----
X      }
X      if ((ShellProg = getenv ("SHELL")) == 0)
X  	ShellProg = DEFAULT_SHELL;
X+     WindName = getenv ("WNAME");	/* returns NULL if no WNAME */
X      ShellArgs[0] = ShellProg;
X      CheckSockName (0);
X      s = MakeServerSocket ();
X***************
X*** 353,358 ****
X--- 360,366 ----
X      ktab['l'].type = ktab[Ctrl('l')].type = KEY_REDISPLAY;
X      ktab['w'].type = ktab[Ctrl('w')].type = KEY_WINDOWS;
X      ktab['v'].type = ktab[Ctrl('v')].type = KEY_VERSION;
X+     ktab['x'].type = ktab[Ctrl('x')].type = KEY_NAME;
X      ktab[Esc].type = KEY_OTHER;
X      for (i = 0; i <= 9; i++)
X  	ktab[i+'0'].type = KEY_0+i;
X***************
X*** 360,366 ****
X  
X  static ProcessInput (buf, len) char *buf; {
X      register n, k;
X!     register char *s, *p;
X  
X      for (s = p = buf; len > 0; len--, s++) {
X  	if (*s == Esc) {
X--- 368,374 ----
X  
X  static ProcessInput (buf, len) char *buf; {
X      register n, k;
X!     register char *s, *p, *name;
X  
X      for (s = p = buf; len > 0; len--, s++) {
X  	if (*s == Esc) {
X***************
X*** 422,427 ****
X--- 430,442 ----
X  		    p = buf;
X  		    SwitchWindow (OtherNum);
X  		    break;
X+ 		case KEY_NAME:
X+ 		    p = buf;
X+ 		    if ((name = WindowName ()) != NULL)  {
X+ 			strncpy (wtab[CurrNum] -> cmd, name, MAXSTR);
X+ 			wtab[CurrNum] -> cmd[MAXSTR-1] = '\0';
X+ 			}
X+ 		    break;
X  		case KEY_CREATE:
X  		    p = buf;
X  		    if ((n = MakeWindow (ktab[*s].args[0], ktab[*s].args,
X***************
X*** 435,443 ****
X--- 450,487 ----
X      return p - buf;
X  }
X  
X+ static char * WindowName ()
X+ 
X+ {
X+     static char namebuf[IOSIZE];
X+     static char backup[] = "\b \b";
X+     register char * s = namebuf;
X+     register char * e = namebuf + IOSIZE - 1;
X+ 
X+     Msg (0, "Enter name for window ");
X+     while (read (0, s, 1) == 1)  {
X+ 	if (*s == '\n' || *s == '\r')
X+ 	    break;
X+ 	if (*s == '\b' || *s == '\177')  {
X+ 	    if (s > namebuf)  {
X+ 		write (1, backup, 3);
X+ 		--s;
X+ 		}
X+ 	}  else if (isprint (*s))
X+ 	    if (s >= e)
X+ 		write (1, "\007", 1);          /* ping the bell */
X+ 	    else
X+ 		write (1, s++, 1);
X+ 	}
X+     *s = '\0';
X+     return namebuf;
X+ }
X+ 
X  static SwitchWindow (n) {
X      if (!wtab[n])
X  	return;
X+     if (CurrNum == n)    /* we are at this window already */
X+ 	return;
X      SetCurrWindow (n);
X      Activate (wtab[n]);
X  }
X***************
X*** 494,499 ****
X--- 538,544 ----
X      register i;
X  
X      close (wp->ptyfd);
X+     utmp_delete (wp -> ttyname);
X      for (i = 0; i < rows; ++i) {
X  	free (wp->image[i]);
X  	free (wp->attr[i]);
X***************
X*** 553,560 ****
X      p->active = 0;
X      p->outlen = 0;
X      p->ptyfd = f;
X!     strncpy (p->cmd, Filename (args[0]), MAXSTR-1);
X      p->cmd[MAXSTR-1] = '\0';
X      switch (p->wpid = fork ()) {
X      case -1:
X  	Msg (errno, "Cannot fork");
X--- 598,606 ----
X      p->active = 0;
X      p->outlen = 0;
X      p->ptyfd = f;
X!     strncpy (p->cmd, WindName == NULL ? Filename(args[0]) : WindName, MAXSTR-1);
X      p->cmd[MAXSTR-1] = '\0';
X+     strcpy (p->ttyname, rindex (TtyName, '/')+1);
X      switch (p->wpid = fork ()) {
X      case -1:
X  	Msg (errno, "Cannot fork");
X***************
X*** 649,654 ****
X--- 695,701 ----
X  		TtyName[i+1] = p[1];
X  		if ((tf = open (TtyName, O_RDWR)) != -1) {
X  		    close (tf);
X+ 		    utmp_insert (rindex (TtyName, '/') + 1, myname);
X  		    return f;
X  		}
X  		close (f);
X***************
X*** 844,849 ****
X--- 891,910 ----
X  		Msg (0, "%s: two characters required after escape.", fn);
X  	    Esc = *p++;
X  	    MetaEsc = *p;
X+ 	} else if (strcmp (ap[0], "name") == 0) {
X+ 	    num = 0;
X+ 	    if (argc > 1 && IsNum (ap[1], 10)) {
X+ 		num = atoi (ap[1]);
X+ 		if (num < 0 || num > MAXWIN-1)
X+ 		    Msg (0, "%s: illegal screen number %d.", fn, num);
X+ 		--argc; ++ap;
X+ 	    }
X+ 	    if (argc < 2) {
X+ 		ap[1] = WindName; argc = 2;
X+ 	    }
X+ 	    ap[argc] = 0;
X+ 	    if (wtab[num])
X+ 		strncpy (wtab[num] -> cmd, ap[1], MAXSTR);
X  	} else if (strcmp (ap[0], "screen") == 0) {
X  	    num = 0;
X  	    if (argc > 1 && IsNum (ap[1], 10)) {
XXX_EOF_XXX
if test 10342 -ne "`wc -c < patch3`"
then
    echo 'shar: transmission error on "patch3"'
fi
chk=`sum patch3 | awk '{print $1}'`
if test 47267 -ne $chk -a 13449 -ne $chk
then
    echo 'shar: checksum error on "patch3"'
fi
echo 'shar: extracting "utmp.c" (3641 characters)'
# 'utmp.c' has a checksum of 17023 on BSD and 18791 on System V.
sed 's/^X//' > utmp.c << 'XXX_EOF_XXX'
X#ifndef lint
Xstatic char sccsid[] = "@(#)utmp.c  2.2  [ (C) Nigel Holder 1986 ]";
X#endif
X
X/**************************************
X*
X*	Author  :  Nigel Holder
X*
X*	Date    :  10 July 1986
X*
X*
X*	Copyright (C) 1986  by Nigel Holder 
X* 
X*	   Permission to use this program is granted, provided it is not
X*	sold, or distributed for direct commercial advantage, and includes
X*	the copyright notice and this clause.
X* 
X*	  This program attempts to overcome the deficiences of 4.2 not
X*	having any visible routines to update the utmp file like Sys V.
X*	  Utmp is used by utilities such as who to find out who is
X*	logged on.  On Sun 4.2, /etc/utmp can be written by
X*	anyone, so no setuid etc. is required to alter it.
X*
X*	  Accessed only via utmp_insert(tty, id) and utmp_delete(tty)
X*	to enable routines to be kept internal.  Uses host field
X*	to indicate that pseudo tty is being used by grotwin (I know its
X*	not what the field is meant for, but it looks better all the same).
X*
X*	  Getpwent() appears to hunk in approx 30 K of unnecessary code
X*	to deal with remote hosts etc.
X*
X**************************************/
X
X
X#include <stdio.h>
X#include <utmp.h>
X#include <pwd.h>
X
X
X#define		UTMP_INSERT		( 1 )
X#define		UTMP_DELETE		( 2 )
X
X/*  max length of tty name entry in /etc/ttys file  */
X#define		TTYS_MAXLEN		( 20 )
X
X
Xtypedef		enum { FALSE, TRUE }	bool;
X
X
X
Xutmp_insert(tty, id)		/*  add entry to utmp  */
X
Xchar	*tty, *id;
X
X{
X	return(utmp_update(tty, id, UTMP_INSERT));
X}
X
X
X
Xutmp_delete(tty)		/*  delete entry from utmp  */
X
Xchar	*tty;
X
X{
X	return(utmp_update(tty, "", UTMP_DELETE));
X}
X
X
X
X
Xstatic
Xutmp_update(tty, id, mode)		/*  update utmp file  */
X
Xchar	*tty, *id;
Xint	mode;
X
X{
X	static char	utmp[] = "/etc/utmp";
X
X	struct utmp	entry;
X	struct passwd	*getpwuid(), *passwd_entry;
X	FILE		*fp, *fopen();
X	long		*time();
X	int		position, i;
X	char		*getlogin(), *user_name;
X
X	position = utmp_pos(tty);
X	if (position == -1)   {
X		return(-1);
X	}
X	if ((fp = fopen(utmp, "r+")) == NULL)   {
X		return(-1);
X	}
X
X	if (mode == UTMP_INSERT)   {		/*  try to find user  */
X		if ((user_name = getlogin()) == NULL)   {
X			if ((passwd_entry = getpwuid(getuid())) == NULL)   {
X				return(-1);		/*  give up  */
X			}
X			user_name = passwd_entry->pw_name;
X		}
X
X		/*******************
X		*   In case strings are too long to fit utmp structure,
X		*   copy max - 1 chars and null terminate at end.
X		*******************/
X
X		strncpy(entry.ut_name, user_name, sizeof(entry.ut_name) - 1);
X		entry.ut_host[sizeof(entry.ut_name) - 1] = '\0';
X		strncpy(entry.ut_host, id, sizeof(entry.ut_host) - 1);
X		entry.ut_host[sizeof(entry.ut_host) - 1] = '\0';
X	}
X	else   {	/*  UTMP_DELETE  */
X		for (i = 0 ; i < sizeof(entry.ut_name) ; ++i)   {
X			entry.ut_name[i] = '\0';
X		}
X		for (i = 0 ; i < sizeof(entry.ut_host) ; ++i)   {
X			entry.ut_host[i] = '\0';
X		}
X	}
X
X	strncpy(entry.ut_line, tty, sizeof(entry.ut_line) - 1);
X	entry.ut_line[sizeof(entry.ut_host) - 1] = '\0';
X	(void) time(&(entry.ut_time));
X	if (fseek(fp, (long) (sizeof(entry) * position), 0) != -1)   {
X		(void) fwrite(&entry, sizeof(entry), 1, fp);
X	}
X	(void) fclose(fp);
X	return(position);
X}
X
X
X
Xutmp_pos(tty)				/*  like ttyslot  */
X
Xchar	*tty;
X
X{
X	static char	ttys[] = "/etc/ttys";
X
X	FILE	*fp, *fopen();
X	int	position;
X	bool	found;
X	char	temp[TTYS_MAXLEN];
X
X	if ((fp = fopen(ttys, "r")) == NULL)   {
X		return(-1);
X	}
X	found = FALSE;
X	for (position = 1 ; fgets(temp, TTYS_MAXLEN, fp) != NULL ; ++position) {
X		temp[strlen(temp) - 1] = '\0';		/* remove trailing \n */
X		if (strcmp(temp + 2, tty) == 0)   {
X			found = TRUE;
X			break;
X		}
X	}
X	(void) fclose(fp);
X	if (found == FALSE)   {
X		return(-1);
X	}
X	return(position);
X}
XXX_EOF_XXX
if test 3641 -ne "`wc -c < utmp.c`"
then
    echo 'shar: transmission error on "utmp.c"'
fi
chk=`sum utmp.c | awk '{print $1}'`
if test 17023 -ne $chk -a 18791 -ne $chk
then
    echo 'shar: checksum error on "utmp.c"'
fi

-- 
-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
- UUCP:	{allegra,seismo}!rochester!srs!matt	Matt Goheen	 	-
- 	"I am not a number, I am a free man!"	S.R. Systems, Roch, NY	-
-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-

net@tub.UUCP (07/26/87)

> Here is an update for the "screen" program posted several months ago.

I'm sorry to tell you this, but I have submitted a new release of screen to
the moderator of comp.sources.unix three weeks ago; it is certainly not
possible to apply your patches to the new release without modification.
Incidentally, some of your enhancements have already been incorporated into
this release...

[I don't know why screen has not yet appeared in comp.sources.unix;
sometime this week I'm going to write a letter to Rich Salz asking if
he received my submission at all, or if there is some other problem.]

>     patch2:  Fixes a small bug that would crash "screen" when run
> 	     under SunWindows (terminal type = sun).

I have published a patch fixing this problem together with the other
patch; I wonder why you have got only one of them.

> 		1) The ability to explicitly name each window

I had also planned to implement a function to "label" windows; however, I was
not quite sure how screen should obtain the name for a newly created window
(via C-a C-c); I don't like the idea to directly prompt the user for input
(i.e. read from the keyboard), because this causes all other windows to
"hang" until the call to read() terminates.

> 		3) Doesn't redraw the current window if you happen
> 		   to change to the same one (via "^A[0-9]")

The new release of screen doesn't redraw the display upon C-a C-a when
there is only one window.  However, it still doesn't detect C-a <n> when
window <n> is already active...

> 		5) Makes an entry into "/etc/utmp" [...]
> 		   This code is stolen from the "grotwin" package [...]

I don't like this patch very much.  The utmp-code from "grotwin" is somewhat
ugly and it doesn't work on 4.3 BSD systems with the new /etc/ttys format.
The new release of screen contains code to properly handle /etc/utmp on 4.2
and (new-format /etc/ttys) 4.3 systems (using the gettyent(3) functions, if
possible).  It also contains the code that is necessary when you want install
screen as set-uid with owner root (so that it is able to modify /etc/utmp if
it is not writable for world).

    Oliver Laumann, Technical University of Berlin, Germany.
    ...!pyramid!tub!net   or   net@TUB.BITNET

klr@hadron.UUCP (Kurt L. Reisler) (07/27/87)

In article <256@srs.UUCP> matt@srs.UUCP (Matt Goheen) writes:
>Here are some nifty things for "screen" the common man's window package.
>See the README file for details.
>
>						Matt Goheen
>						S.R. Systems
>

>X    patch3:  Various updates from our site.  These include:

Unfortunately, patch3 was received here severely truncated.  If this
was a common occurance around the net, it might be a good idea to
repost it.  If I am an isolated case, let me know and I will locate
a good copy locally.

 Kurt Reisler (703) 359-6100
 ============================================================================
 UNISIG Chairman, DECUS US Chapter                       | Hadron, Inc.
 ..{seismo|sundc|rlgvax|dtix|decuac}!hadron!klr          | 9990 Lee Highway
 Sysop, Fido 109/74  The Bear's Den   (703) 671-0598     | Suite 481
 Sysop, Fido 109/483 The Pot of Gold  (703) 359-6549     | Fairfax, VA 22030
 ============================================================================