diff --git a/src/Makefile.in b/src/Makefile.in
index d4b4afa..03cb638 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -205,8 +205,6 @@ $(SCREEN).tar: .version term.h comm.h tty.c kmapdef.c
 	cd etc; ln * ../dist/$(SCREEN)/etc
 	mkdir dist/$(SCREEN)/utf8encodings
 	cd utf8encodings; ln * ../dist/$(SCREEN)/utf8encodings
-	# sed -e 's/^startup/#startup/' -e 's/^autodetach/#autodetach/' < $(ETCSCREENRC) > dist/$(SCREEN)/etc/etcscreenrc 
-	cp $(HOME)/.screenrc dist/$(SCREEN)/etc/screenrc
 	mkdir dist/$(SCREEN)/doc
 	sed -e 's@/local/emacs@/usr/local@g' < doc/Makefile.in > dist/$(SCREEN)/doc/Makefile.in
 	cd doc; ln FAQ README.DOTSCREEN screen.1 screen.texinfo fdpat.ps make.help window_to_display.ps \
@@ -236,7 +234,7 @@ saber:
 
 config:
 	rm -f config.cache
-	rm -rf autom4te.cache
+	rm -rf autom4te.cache config.log config.status
 	sh ./configure
 
 
diff --git a/src/acls.c b/src/acls.c
index d764023..e639d31 100644
--- a/src/acls.c
+++ b/src/acls.c
@@ -183,7 +183,7 @@ struct acluser **up;
 #endif
   (*up)->u_Esc = DefaultEsc;
   (*up)->u_MetaEsc = DefaultMetaEsc;
-  strncpy((*up)->u_name, name, 20);
+  strncpy((*up)->u_name, name, MAX_USERNAME_LEN);
   (*up)->u_password = NULL;
   if (pass)
     (*up)->u_password = SaveStr(pass);
@@ -319,8 +319,8 @@ struct acluser **up;
     return UserAdd(name, pass, up);
   if (!strcmp(name, "nobody"))		/* he remains without password */
     return -1;
-  strncpy((*up)->u_password, pass ? pass : "", 20);
-  (*up)->u_password[20] = '\0';
+  strncpy((*up)->u_password, pass ? pass : "", MAX_USERNAME_LEN);
+  (*up)->u_password[MAX_USERNAME_LEN] = '\0';
   return 0;
 }
 #endif
diff --git a/src/acls.h b/src/acls.h
index 907e953..0f6a5e5 100644
--- a/src/acls.h
+++ b/src/acls.h
@@ -78,7 +78,7 @@ struct plop
 typedef struct acluser
 {
   struct acluser *u_next;		/* continue the main user list */
-  char u_name[20+1];		/* login name how he showed up */
+  char u_name[MAX_USERNAME_LEN+1];	/* login name how he showed up */
   char *u_password;		/* his password (may be NullStr). */
   int  u_checkpassword;		/* nonzero if this u_password is valid */
   int  u_detachwin;		/* the window where he last detached */
diff --git a/src/attacher.c b/src/attacher.c
index 0712858..eacd9aa 100644
--- a/src/attacher.c
+++ b/src/attacher.c
@@ -593,6 +593,7 @@ Attacher()
 #endif
   for (;;)
     {
+#ifndef DO_NOT_POLL_MASTER
       signal(SIGALRM, AttacherSigAlarm);
       alarm(15);
       pause();
@@ -602,6 +603,9 @@ Attacher()
 	  debug1("attacher: Panic! MasterPid %d does not exist.\n", MasterPid);
 	  AttacherPanic++;
 	}
+#else
+      pause();
+#endif
       if (AttacherPanic)
         {
 	  fcntl(0, F_SETFL, 0);
diff --git a/src/comm.c b/src/comm.c
index aedfe49..82a9e1f 100644
--- a/src/comm.c
+++ b/src/comm.c
@@ -56,6 +56,10 @@ struct comm comms[RC_LAST + 1] =
 #ifdef MULTIUSER
   { "addacl",		ARGS_1234 },
 #endif
+#ifdef TSCREEN
+  { "alias",            ARGS_12|ARGS_ORMORE },
+  { "aliaslist",        ARGS_0 },
+#endif /*TSCREEN*/
   { "allpartial",	NEED_DISPLAY|ARGS_1 },
   { "altscreen",	ARGS_01 },
   { "at",		NEED_DISPLAY|ARGS_2|ARGS_ORMORE },
@@ -103,7 +107,11 @@ struct comm comms[RC_LAST + 1] =
 #endif
   { "blanker",		NEED_DISPLAY|ARGS_0},
 #ifdef BLANKER_PRG
+# ifdef TSCREEN
+  { "blankerprg",	ARGS_01 },
+# else /*!TSCREEN*/
   { "blankerprg",	ARGS_1|ARGS_ORMORE },
+# endif /*TSCREEN*/
 #endif
   { "break",		NEED_FORE|ARGS_01 },
   { "breaktype",	NEED_FORE|ARGS_01 },
@@ -200,11 +208,17 @@ struct comm comms[RC_LAST + 1] =
   { "hardstatus",	ARGS_012 },
   { "height",		ARGS_0123 },
   { "help",		NEED_LAYER|ARGS_02 },
+#ifdef TSCREEN
+  { "hide",		NEED_FORE|ARGS_01 },
+#endif /*TSCREEN*/
 #ifdef COPY_PASTE
   { "history",		NEED_DISPLAY|NEED_FORE|ARGS_0 },
 #endif
   { "hstatus",		NEED_FORE|ARGS_1 },
   { "idle",		ARGS_0|ARGS_ORMORE },
+#ifdef TSCREEN
+  { "if",               ARGS_3|ARGS_ORMORE },
+#endif /*TSCREEN*/
   { "ignorecase",	ARGS_01 },
   { "info",		NEED_LAYER|ARGS_0 },
 #ifdef ENCODINGS
@@ -312,6 +326,10 @@ struct comm comms[RC_LAST + 1] =
   { "time",		ARGS_01 },
   { "title",		NEED_FORE|ARGS_01 },
   { "umask",		ARGS_1|ARGS_ORMORE },
+#ifdef TSCREEN
+  { "unaliasall",       ARGS_0 },
+  { "unbindall",        ARGS_0 },
+#endif /*TSCREEN*/
   { "unsetenv",		ARGS_1 },
 #ifdef UTF8
   { "utf8",		NEED_FORE|ARGS_012 },
diff --git a/src/configure.ac b/src/configure.ac
index cfaf5de..becb454 100644
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -1006,6 +1006,7 @@ sysvr4ptys=1])
 fi
 
 AC_CHECK_FUNCS(getpt)
+AC_CHECK_FUNCS(alphasort scandir)
 
 # check for openpty()
 if test -z "$sysvr4ptys"; then
@@ -1491,6 +1492,11 @@ AC_SEARCH_LIBS(gethostname, nsl)
 
 AC_CHECK_FUNCS(rename fchmod fchown strerror lstat _exit utimes vsnprintf getcwd setlocale strftime)
 
+AC_CHECK_DECL([MAX_USERNAME_LEN],,[
+       AC_DEFINE(MAX_USERNAME_LEN,20,[Length of longest username.])
+])
+
+
 AC_ARG_ENABLE(pam,AS_HELP_STRING([--enable-pam],[enable PAM support]))
 if test "$enable_pam" = "yes"; then
     AC_MSG_CHECKING(for PAM support)
@@ -1625,6 +1631,9 @@ MY_ARG_ENABLE([CHECK_SCREEN_W],[
 	on modern systems which use $COLUMNS or the tty settings instead.
 	])
 
+MY_ARG_ENABLE([TSCREEN],[
+	Enable new tscreen (originally from steve.org.uk) features
+])
 
 
 # 
diff --git a/src/display.c b/src/display.c
index fe3c2f3..a281da5 100644
--- a/src/display.c
+++ b/src/display.c
@@ -59,6 +59,9 @@ static void disp_idle_fn __P((struct event *, char *));
 #ifdef BLANKER_PRG
 static void disp_blanker_fn __P((struct event *, char *));
 #endif
+#ifdef TSCREEN
+static void disp_history_fn __P((struct event *, char *));
+#endif /*TSCREEN*/
 static void WriteLP __P((int, int));
 static void INSERTCHAR __P((int));
 static void RAW_PUTCHAR __P((int));
@@ -74,6 +77,9 @@ extern struct layer *flayer;
 extern struct win *windows, *fore;
 extern struct LayFuncs WinLf;
 
+#ifdef TSCREEN
+extern struct alias *g_aliases_list;
+#endif /*TSCREEN*/
 extern int  use_hardstatus;
 extern int  MsgWait, MsgMinWait;
 extern int  Z0width, Z1width;
@@ -131,6 +137,15 @@ int hardstatusemu = HSTATUS_IGNORE;
 
 int focusminwidth, focusminheight;
 
+#ifdef TSCREEN
+/*
+ * message history.
+ */
+char *msg_history[20] = { NULL };
+int msg_position      = 0;
+
+#endif /*TSCREEN*/
+
 /*
  *  Default layer management
  */
@@ -283,6 +298,12 @@ struct mode *Mode;
   D_blankerev.handler = disp_blanker_fn;
   D_blankerev.fd = -1;
 #endif
+#ifdef TSCREEN
+  D_historyev.type = EV_READ;
+  D_historyev.data = (char *)display;
+  D_historyev.handler = disp_history_fn;
+  D_historyev.fd = -1;
+#endif /*TSCREEN*/
   D_OldMode = *Mode;
   D_status_obuffree = -1;
   Resize_obuf();  /* Allocate memory for buffer */
@@ -353,6 +374,9 @@ FreeDisplay()
   evdeq(&D_readev);
   evdeq(&D_writeev);
   evdeq(&D_blockedev);
+#ifdef TSCREEN
+  evdeq(&D_historyev);
+#endif /*TSCREEN*/
 #ifdef MAPKEYS
   evdeq(&D_mapev);
   if (D_kmaps)
@@ -2649,6 +2673,24 @@ char *msg;
   register char *s, *t;
   register int max;
 
+#ifdef TSCREEN
+  /*
+   * Free current message.
+   */
+  if ( msg_history[ msg_position ] != NULL ) {
+    free( msg_history[ msg_position ] );
+    msg_history[ msg_position ] = NULL;
+  }
+
+  if ( ( (msg_position>0) && (strcmp(msg, msg_history[msg_position-1]) != 0 ) && ( msg[0] != '\0' ) ) ||
+       ( ( msg_position == 0 ) && ( msg != NULL ) && ( msg[0] != '\0'  ) ) )
+    {
+      msg_history[ msg_position ] = strdup( msg );
+      msg_position += 1;
+      if ( msg_position >= ((sizeof(msg_history)/sizeof(msg_history[0]))-1))
+        msg_position = 0;
+    }
+#endif /*TSCREEN*/
   if (!display)
     return;
   
@@ -2748,6 +2790,9 @@ char *msg;
       struct display *olddisplay = display;
       struct layer *oldflayer = flayer;
 
+#ifdef TSCREEN
+      ASSERT(D_obuffree == D_obuflen);
+#endif /*TSCREEN*/
       /* this is copied over from RemoveStatus() */
       D_status = 0;
       GotoPos(0, STATLINE);
@@ -2758,8 +2803,21 @@ char *msg;
 	LaySetCursor();
       display = olddisplay;
       flayer = oldflayer;
+#ifdef TSCREEN
+      D_status_obuflen = D_obuflen;
+      D_status_obuffree = D_obuffree;
+      D_obuffree = D_obuflen = 0;
+#endif /*TSCREEN*/
       D_status = STATUS_ON_WIN;
     }
+#ifdef TSCREEN
+  gettimeofday(&D_status_time, NULL);
+  SetTimeout(&D_statusev, MsgWait);
+  evenq(&D_statusev);
+#ifdef HAVE_BRAILLE
+  RefreshBraille();    /* let user see multiple Msg()s */
+#endif
+#endif /*TSCREEN*/
 }
 
 void
@@ -4265,6 +4323,150 @@ ResetIdle()
     evdeq(&D_idleev);
 }
 
+#ifdef TSCREEN
+
+/**
+ * Dump the recent message history to the console.
+ */
+void ShowHistoryDump()
+{
+  int max = (sizeof(msg_history)/sizeof(msg_history[0]));
+  int cur = 0;
+  int i   = msg_position;
+
+  printf( "Previous Messages\n" );
+  printf( "=================\n\n" );
+
+  /* start at the prev message */
+  i = msg_position-1;
+
+  if ( msg_position < 0 )
+        msg_position = max-1;
+
+  for (cur = 0 ; cur < max; cur +=1 )
+    {
+      if ( (msg_history[i] != NULL) && (msg_history[i][0] != '\0' ) )
+          printf( "%s\n", msg_history[i] );
+
+      i--;
+      if ( i < 0 )
+        i = (max-1);
+    }
+  printf("\n\t\t[Press Any Key To Close]\n");
+}
+
+
+
+
+/**
+ * Open a new window with to display the history.
+ */
+void
+ShowHistory(type)
+char *type;
+{
+  char *m;
+  int pid;
+  int slave = -1;
+  char termname[30];
+#ifndef TIOCSWINSZ
+  char libuf[20], cobuf[20];
+#endif
+  char **np;
+
+  strcpy(termname, "TERM=");
+  strncpy(termname + 5, D_termname, sizeof(termname) - 6);
+  termname[sizeof(termname) - 1] = 0;
+  D_historypid = -1;
+  if ((D_historyev.fd = OpenPTY(&m)) == -1)
+    {
+      Msg(0, "OpenPty failed");
+      return;
+    }
+  switch (pid = (int)fork())
+    {
+    case -1:
+      Msg(errno, "fork");
+      close(D_historyev.fd);
+      D_historyev.fd = -1;
+      return;
+    case 0:
+      displays = 0;
+#ifdef BLANKER_PRG
+      if (setgid(real_gid) || setuid(real_uid))
+        Panic(errno, "setuid/setgid");
+#endif
+      brktty(D_userfd);
+      freetty();
+      close(0);
+      close(1);
+      close(2);
+      closeallfiles(slave);
+      if (open(m, O_RDWR))
+	Panic(errno, "Cannot open %s", m);
+      dup(0);
+      dup(0);
+      if (slave != -1)
+	close(slave);
+      InitPTY(0);
+      fgtty(0);
+      SetTTY(0, &D_OldMode);
+#ifdef BLANKER_PRG
+      np = NewEnv + 3;
+      *np++ = NewEnv[0];
+      *np++ = termname;
+#ifdef TIOCSWINSZ
+      glwz.ws_col = D_width;
+      glwz.ws_row = D_height;
+      (void)ioctl(0, TIOCSWINSZ, (char *)&glwz);
+#else
+      sprintf(libuf, "LINES=%d", D_height);
+      sprintf(cobuf, "COLUMNS=%d", D_width);
+      *np++ = libuf;
+      *np++ = cobuf;
+#endif
+#endif
+#ifdef SIGPIPE
+      signal(SIGPIPE, SIG_DFL);
+#endif
+      display = 0;
+
+      if ( strcmp( type, "history" ) == 0 )
+        ShowHistoryDump();
+      if ( strcmp( type, "alias" ) == 0 )
+        ShowAliasDump();
+    default:
+      break;
+    }
+  D_historypid = pid;
+  evenq(&D_historyev);
+  D_blocked = 4;
+  ClearAll();
+}
+
+
+static void
+disp_history_fn(ev, data)
+struct event *ev;
+char *data;
+{
+  char buf[IOSIZE], *b;
+  int size;
+
+  display = (struct display *)data;
+  size = read(D_historyev.fd, buf, IOSIZE);
+  if (size <= 0)
+  {
+        evdeq(&D_historyev);
+        close(D_historyev.fd);
+        D_historyev.fd = -1;
+        return;
+    }
+  for (b = buf; size; size--)
+    AddChar(*b++);
+}
+
+#endif /*TSCREEN*/
 
 #ifdef BLANKER_PRG
 
diff --git a/src/display.h b/src/display.h
index aaaf6bf..b42fc7c 100644
--- a/src/display.h
+++ b/src/display.h
@@ -226,6 +226,10 @@ struct display
   int   d_blankerpid;
   struct event d_blankerev;
 #endif
+#ifdef TSCREEN
+  int   d_historypid;           /* history display */
+  struct event d_historyev;
+#endif /*TSCREEN*/
 };
 
 #ifdef MULTI
@@ -344,6 +348,10 @@ extern struct display TheDisplay;
 #define D_blankerev	DISPLAY(d_blankerev)
 #define D_blankerpid	DISPLAY(d_blankerpid)
 
+#ifdef TSCREEN
+#define D_historyev    DISPLAY(d_historyev)
+#define D_historypid   DISPLAY(d_historypid)
+#endif /*TSCREEN*/
 
 #define GRAIN 4096	/* Allocation grain size for output buffer */
 #define OBUF_MAX 256	/* default for obuflimit */
diff --git a/src/extern.h b/src/extern.h
index 4332078..4ef6885 100644
--- a/src/extern.h
+++ b/src/extern.h
@@ -78,6 +78,9 @@ extern int   MFindUsedLine __P((struct win *, int, int));
 extern int   StartRc __P((char *, int));
 extern void  FinishRc __P((char *));
 extern void  RcLine __P((char *, int));
+#ifdef TSCREEN
+extern FILE *secpopen __P((char *, char *));
+#endif /*TSCREEN*/
 extern FILE *secfopen __P((char *, char *));
 extern int   secopen __P((char *, int, int));
 extern void  WriteFile __P((struct acluser *, char *, int));
@@ -87,6 +90,7 @@ extern int   printpipe __P((struct win *, char *));
 extern int   readpipe __P((char **));
 extern void  RunBlanker __P((char **));
 extern void  do_source __P((char *));
+extern char *SaveExpandedStr __P((char *path));
 
 /* tty.c */
 extern int   OpenTTY __P((char *, char *));
@@ -141,6 +145,9 @@ extern void  ZmodemPage __P((void));
 #endif
 
 /* window.c */
+#ifdef TSCREEN
+extern int   FindOrMakeWindow __P((struct NewWindow *));
+#endif /*TSCREEN*/
 extern int   MakeWindow __P((struct NewWindow *));
 extern int   RemakeWindow __P((struct win *));
 extern void  FreeWindow __P((struct win *));
@@ -188,6 +195,9 @@ extern int   OpenPTY __P((char **));
 extern void  InitPTY __P((int));
 
 /* process.c */
+#ifdef TSCREEN
+extern char *do_popen( char *);
+#endif /*TSCREEN*/
 extern void  InitKeytab __P((void));
 extern void  ProcessInput __P((char *, int));
 #ifdef MAPKEYS
@@ -205,7 +215,11 @@ extern void  SetEscape __P((struct acluser *, int, int));
 extern void  DoScreen __P((char *, char **));
 extern int   IsNumColon __P((char *, int, char *, int));
 extern void  ShowWindows __P((int));
+#ifdef TSCREEN
+extern char *AddWindows __P((char *, int, int, int, int));
+#else  /*!TSCREEN*/
 extern char *AddWindows __P((char *, int, int, int));
+#endif /*TSCREEN*/
 extern char *AddWindowFlags __P((char *, int, struct win *));
 extern char *AddOtherUsers __P((char *, int, struct win *));
 extern int   WindowByNoN __P((char *));
@@ -217,6 +231,11 @@ extern int   CompileKeys __P((char *, int, unsigned char *));
 extern void  RefreshXtermOSC __P((void));
 #endif
 extern int   ParseSaveStr __P((struct action *act, char **));
+#ifdef TSCREEN
+extern int   ParseSaveExpandedStr __P((struct action *act, char **));
+#else /*!TSCREEN*/
+#define ParseSaveExpandedStr(act, var) ParseSaveStr(act,var)
+#endif /*TSCREEN*/
 extern int   ParseNum __P((struct action *act, int *));
 extern int   ParseSwitch __P((struct action *, int *));
 extern int   ParseAttrColor __P((char *, char *, int));
@@ -242,6 +261,11 @@ extern sigret_t AttacherFinit __P(SIGPROTOARG);
 extern void  SendCmdMessage __P((char *, char *, char **));
 
 /* display.c */
+#ifdef TSCREEN
+extern void  ShowHistory ( char *type );
+extern void ShowHistoryDump();
+extern void ShowAliasDump();
+#endif /*TSCREEN*/
 extern struct display *MakeDisplay __P((char *, char *, char *, int, int, struct mode *));
 extern void  FreeDisplay __P((void));
 extern void  DefProcess __P((char **, int *));
@@ -326,6 +350,9 @@ extern void  LoadLayout __P((struct layout *, struct canvas *));
 extern void  NewLayout __P((char *, int));
 extern void  SaveLayout __P((char *, struct canvas *));
 extern void  ShowLayouts __P((int));
+#ifdef TSCREEN
+extern void RemoveLayout(struct layout *lay) ;
+#endif /*TSCREEN*/
 extern struct layout *FindLayout __P((char *));
 
 /* resize.c */
diff --git a/src/fileio.c b/src/fileio.c
index c9a5eef..d261e2c 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -38,6 +38,9 @@
 #include "config.h" 
 #include "screen.h"
 #include "extern.h"
+#ifdef TSCREEN
+#include <dirent.h>
+#endif /*TSCREEN*/
 
 extern struct display *display, *displays;
 extern struct win *fore;
@@ -60,6 +63,58 @@ static char *findrcfile __P((char *));
 char *rc_name = "";
 int rc_recursion = 0;
 
+/*
+ * tilde expansion for filenames.
+ * NOTE:  Caller frees.
+ */
+char *
+SaveExpandedStr( char *path )
+{
+  if (!path)
+    return;
+  if ( path && *path == '~' )
+    {
+      char filename_tilde_exp[MAXPATHLEN+1];
+      char *slash_position = strchr(path,'/');
+      char *home;
+      if ( slash_position == ++path)
+	{
+	  home = getenv( "HOME" );
+	  if ( !home )
+	    {
+	      Msg(0, "tilde expansion failed");
+	      return;
+	    }
+	}
+      else if (slash_position)
+	{
+	  struct passwd *p;
+	  *slash_position = 0;
+	  p = getpwnam(path);
+	  if (!p)
+	    {
+	      Msg(0, "tilde expansion failed for user %s", path);
+	      return;
+	    }
+	  *slash_position='/';
+	  home=p->pw_dir;
+	}
+      else
+	{
+	  Msg(0, "illegal tilde expression.");
+	  return;
+	}
+      if (strlen(home)+strlen(slash_position) > MAXPATHLEN)
+	{
+	  Msg(0, "tilde expanded path is too long.");
+	  return;
+	}
+      snprintf(filename_tilde_exp, MAXPATHLEN, "%s%s", home, slash_position);
+      return SaveStr(filename_tilde_exp);
+    }
+}
+
+
 static char *
 CatExtra(str1, str2)
 register char *str1, *str2;
@@ -93,49 +148,15 @@ register char *str1, *str2;
   return cp;
 }
 
+
 static char *
 findrcfile(rcfile)
 char *rcfile;
 {
-  char buf[256];
+  char buf[MAXPATHLEN+1];
   char *p;
 
-  /* Tilde prefix support courtesy <hesso@pool.math.tu-berlin.de>,
-   * taken from a Debian patch. */
-  if (rcfile && *rcfile == '~')
-    {
-      static char rcfilename_tilde_exp[MAXPATHLEN+1];
-      char *slash_position = strchr(rcfile, '/');
-      if (slash_position == rcfile+1)
-        {
-          char *home = getenv("HOME");
-          if (!home)
-            {
-              Msg(0, "%s: source: tilde expansion failed", rc_name);
-              return;
-            }
-          snprintf(rcfilename_tilde_exp, MAXPATHLEN, "%s/%s", home, rcfile+2);
-        }
-      else if (slash_position)
-        {
-          struct passwd *p;
-          *slash_position = 0;
-          p = getpwnam(rcfile+1);
-          if (!p)
-            {
-              Msg(0, "%s: source: tilde expansion failed for user %s", rc_name, rcfile+1);
-              return;
-            }
-          snprintf(rcfilename_tilde_exp, MAXPATHLEN, "%s/%s", p->pw_dir, slash_position+1);
-        }
-      else
-        {
-          Msg(0, "%s: source: illegal tilde expression.", rc_name);
-          return;
-        }
-      rcfile = rcfilename_tilde_exp;
-    }
-
+  rcfile=SaveExpandedStr(rcfile);
   if (rcfile)
     {
       char *rcend = rindex(rc_name, '/');
@@ -335,14 +356,157 @@ void
 do_source(rcfilename)
 char *rcfilename;
 {
+#ifdef TSCREEN
+  char filename[MAXPATHLEN+1];
+  struct stat buf;
+#else /*!TSCREEN*/
+#define filename rcfilename
+#endif /*TSCREEN*/
   if (rc_recursion > 10)
     {
       Msg(0, "%s: source: recursion limit reached", rc_name);
       return;
     }
-  rc_recursion++;
-  FinishRc(rcfilename);
-  rc_recursion--;
+#ifdef TSCREEN
+  if (*rcfilename == '~')
+    {
+      rcfilename=SaveExpandedStr(filename);
+      if (rcfilename)
+	{
+	  strncpy(filename,rcfilename,sizeof(filename)-1);
+	  free(rcfilename);
+	}
+    }
+  else
+    {
+        snprintf(filename, MAXPATHLEN, "%s", rcfilename );
+    }
+
+  if ( filename[strlen(filename)-1] == '|' )
+    {
+      filename[strlen(filename)-1] = '\0';
+    }
+
+  /*
+   * OK now "filename" points to the file/dir specified.
+   */
+  if ( stat(filename, &buf) == 0 )
+    {
+      if (  S_ISDIR(buf.st_mode))
+        {
+
+#if HAVE_SCANDIR && HAVE_ALPHASORT
+
+          struct dirent **namelist;
+          int n;
+          int i=0;
+          char fullpath[ PATH_MAX ];
+
+          n = scandir(filename, &namelist, 0, alphasort);
+          if (n < 0)
+            {
+              Msg(0, "%s: source: scandir failed.", filename );
+              return;
+            }
+          else {
+            while(i<n)
+              {
+                struct stat ent;
+
+                /*
+                 * create the full path
+                 */
+                memset( fullpath, '\0', sizeof(fullpath) );
+                snprintf(fullpath, sizeof(fullpath)-1, "%s/%s",
+                         filename, namelist[i]->d_name);
+
+                /*
+                 * If the file is a file and doesn't start with '.' then
+                 * use it.
+                 */
+                if ( ( stat( fullpath, &ent ) == 0 ) &&
+                     ( S_ISREG(ent.st_mode ) ) &&
+                     ( namelist[i]->d_name[0] != '.') )
+                  {
+
+                    /*
+                     * Unless the file ends in "~"
+                     */
+                    int len = strlen( fullpath );
+                    if ( ( len > 0 ) && ( fullpath[len-1] != '~' ) )
+                      do_source( fullpath );
+                  }
+                i++;
+              }
+            while( n-- )
+              {
+                free(namelist[n]);
+              }
+            free(namelist);
+          }
+#else
+          DIR *pDIR;
+          struct dirent *pDirEnt;
+          char fullpath[ PATH_MAX ];
+
+          pDIR = opendir( filename );
+
+          if ( pDIR == NULL )
+            {
+              Msg(0, "%s: source: opendir failed.", filename );
+              return;
+            }
+
+          /* If it is a directory */
+          pDirEnt = readdir( pDIR );
+          while ( pDirEnt != NULL )
+          {
+            struct stat ent;
+
+            /* create full path */
+            memset( fullpath, '\0', sizeof(fullpath) );
+            snprintf(fullpath, sizeof(fullpath)-1, "%s/%s",
+                     filename, pDirEnt->d_name );
+
+            /* if it :
+               1. exists.
+               2. doesn't start with "."
+               3. is a regular file.
+            */
+            if ( ( stat( fullpath, &ent ) == 0 ) &&
+                 ( pDirEnt->d_name[0] != '\0' ) &&
+                 ( S_ISREG(ent.st_mode ) ) )
+              {
+                /* load it, unless it ends in "~". */
+
+                int len = strlen( fullpath );
+                if ( ( len > 0 ) && ( fullpath[len-1] != '~' ) )
+                  do_source( fullpath );
+              }
+
+            pDirEnt = readdir( pDIR );
+          }
+
+          /* Release the open directory */
+          closedir( pDIR );
+#endif
+        }
+      else
+        {
+#endif /*TSCREEN*/
+	  rc_recursion++;
+          FinishRc(filename);
+	  rc_recursion--;
+#ifdef TSCREEN
+	          }
+    }
+  else
+    {
+      Msg(0, "%s: source: not found.", filename );
+      return;
+    }
+
+#endif /*TSCREEN*/
 }
 
 
diff --git a/src/mark.c b/src/mark.c
index be22df7..790536a 100644
--- a/src/mark.c
+++ b/src/mark.c
@@ -150,7 +150,7 @@ nextchar(int *xp, int *yp, int direction, char target, int num)
 {
   int width;  /* width of the current window. */
   int x;      /* x coordinate of the current cursor position. */
-  int step;   /* amount to increment x (+1 or -1) */
+  int step = 1;/* amount to increment x (+1 or -1) */
   int adjust; /* Final adjustment of cursor position. */
   char *displayed_line; /* Line in which search takes place. */
  
@@ -632,7 +632,7 @@ int *inlenp;
 	  revto(cx, cy);
 	break;
 	case ',': {
-	  int search_dir;
+	  int search_dir = 'f';
 	  if (!markdata->f_cmd.target)
 	    break;
 	  if (!rep_cnt)
diff --git a/src/process.c b/src/process.c
index fa3d06c..91d2b29 100644
--- a/src/process.c
+++ b/src/process.c
@@ -164,6 +164,15 @@ static void SelectFin __P((char *, int, char *));
 static void SelectLayoutFin __P((char *, int, char *));
 static struct canvas *FindCanvas __P((int, int));
 
+#ifdef TSCREEN
+/* Alias */
+static void  AddAlias __P((const char *name, const char *val , char **args, int *argl, int count));
+static struct alias * FindAlias __P((const char *name));
+static struct alias * FindAliasnr __P((int));
+static void  DelAlias __P((const char *name, int quiet));
+static int   DoAlias __P((const char *, char **, int *));
+
+#endif /*TSCREEN*/
 
 extern struct layer *flayer;
 extern struct display *display, *displays;
@@ -173,6 +182,9 @@ extern struct layout *layouts, *layout_attach, layout_last_marker;
 extern struct layout *laytab[];
 
 extern char screenterm[], HostName[], version[];
+#ifdef TSCREEN
+extern char *LoginName;
+#endif /*TSCREEN*/
 extern struct NewWindow nwin_undef, nwin_default;
 extern struct LayFuncs WinLf, MarkLf;
 
@@ -231,6 +243,21 @@ int kmap_extn;
 static int maptimeout = 300;
 #endif
 
+#ifdef TSCREEN
+/*
+ * Command aliases.
+ */
+struct alias {
+  int nr;
+  char *name;   /* Name of the alias */
+  int cmdnr;    /* Number of the command this is alias for */
+  char **args;  /* The argument list for the command */
+  int *argl;
+  struct alias *next;
+};
+struct alias *g_aliases_list = NULL;
+#endif /*TSCREEN */
+
 #ifndef MAX_DIGRAPH
 #define MAX_DIGRAPH 512
 #endif
@@ -471,6 +498,227 @@ int *val;
 
 char *noargs[1];
 
+#ifdef TSCREEN
+int
+doSimpleTest( type, arg )
+     char *type;
+     char *arg;
+{
+  struct stat buf;
+  int ret =  0;
+  int result = 0;
+  int invert = 0;
+
+  char *expanded=SaveExpandedStr(arg);
+  ret = stat(expanded , &buf);
+
+  /*
+   * test is to be inverted.
+   */
+  if ( type[0] == '!' )
+    {
+      invert = 1;
+      type += 1;
+    }
+
+  /**
+   * Now the tests themselves.
+   */
+  if ( strcmp( type, "-d" ) == 0 )
+    {
+      /* directory? */
+      if ( S_ISDIR(buf.st_mode))
+        result = 1;
+    }
+  else if ( strcmp( type, "-e" ) == 0 )
+    {
+      /* exists ? */
+      if ( ret == 0 )
+        result = 1;
+    }
+  else if ( strcmp( type, "-a" ) == 0 )
+    {
+      /* alias exists ? */
+      if ( FindAlias( expanded ) != NULL )
+        result = 1;
+    }
+  else if ( strcmp( type, "-f" ) == 0 )
+    {
+      /* regular file ? */
+      if ( S_ISREG(buf.st_mode ) )
+        result = 1;
+    }
+  else if ( strcmp( type, "-x" ) == 0 )
+    {
+      /* executable file ? */
+      if ( ( S_ISREG(buf.st_mode )) && ( isExecutable(buf.st_mode)) )
+        result = 1;
+    }
+  else if ( strcmp( type, "-z" ) == 0 )
+    {
+      int len = strlen( expanded );
+      result = ( len > 0 );
+      Msg(0, "strlen(%s) is %d", expanded, len );
+    }
+  else
+    {
+      Msg(0, "Unknown test type : %s", type );
+    }
+
+  free( expanded );
+
+  if ( invert )
+    result = !result;
+
+  return( result );
+}
+
+
+char *do_popen( char *cmd )
+{
+  int len     = strlen( cmd );
+  char *tmp   = strdup( cmd );
+  char *res   = NULL;
+  FILE * pipe = NULL;
+
+  /* sanity check */
+  if ( len <= 1 )
+    return NULL;
+
+  /* strip trailing ` if prsent */
+  if ( tmp[len-1] == '`' )
+    tmp[len-1] = '\0';
+
+  /* Run the command */
+  pipe = popen(tmp, "r" );
+
+  /* failed, then return the command */
+  if (pipe == NULL )
+      return( tmp );
+
+  /* read the output */
+  while(!feof(pipe) )
+    {
+      char buf[256];
+      memset( buf, '\0', sizeof(buf));
+
+      if( fgets( buf, sizeof(buf)-1, pipe ) != NULL )
+      {
+        int l, i;
+
+        if ( res != NULL )
+        {
+          char *t = strdup( res );
+
+          int newsize = strlen( t ) + strlen( buf ) + 1;
+
+          res = realloc(res, newsize * sizeof(char));
+          sprintf(res, "%s%s", t, buf );
+          free( t );
+        }
+        else
+        {
+          res = malloc((strlen(buf)+1) * sizeof(char));
+          strcpy( res, buf );
+        }
+
+        l = strlen(res);
+        for ( i = 0; i < l ; i++ )
+          {
+            if ( ( res[i] == '\r' ) ||
+                 ( res[i] == '\n' ) )
+              res[i] = '\0';
+          }
+      }
+    }
+
+  /* Close pipe */
+  pclose(pipe);
+
+  if ( res == NULL )
+    return tmp;
+  else
+    free( tmp );
+  return( res );
+}
+
+int
+doComplexTest( test, op1, op2 )
+     char *test;
+     char *op1;
+     char *op2;
+{
+  int result   = 0;
+  int invert   = 0;
+  int free_op1 = 0;
+  int free_op2 = 0;
+
+  /*
+   * test is to be inverted.
+   */
+  if ( test[0] == '!' )
+  {
+    invert = 1;
+    test += 1;
+  }
+
+  if ( ( op1[0] == '`' ) &&
+       ( op1[strlen(op1)-1] == '`' ) )
+    {
+      op1 = do_popen( op1+1 );
+      if ( op1 != NULL )
+        free_op1 = 1;
+    }
+  if ( ( op2[0] == '`' ) &&
+       ( op2[strlen(op2)-1] == '`' ) )
+    {
+
+      op2 = do_popen( op2+1 );
+      if ( op2 != NULL )
+        free_op2 = 1;
+    }
+
+  if ( ( strcmp( test, "=" )  == 0 ) ||
+       ( strcmp( test, "==" ) == 0 ) )
+  {
+    result = ( strcmp( op1, op2 ) == 0 );
+  }
+  else if ( strcmp( test, "!=" ) == 0 )
+  {
+    result = ( strcmp( op1, op2 ) != 0 );
+  }
+  else if ( strcmp( test, "-eq" ) == 0 )
+  {
+    int a = atoi( op1 );
+    int b = atoi( op2 );
+    result = ( a == b );
+  }
+  else if ( strcmp( test, "-ne" ) == 0 )
+  {
+    int a = atoi( op1 );
+    int b = atoi( op2 );
+    result = ( a != b );
+  }
+  else
+  {
+    Msg(0, "Unknown test '%s'", test );
+  }
+
+  if ( invert )
+    result = !result;
+
+  if ( free_op1 )
+    free( op1 );
+  if ( free_op2 )
+    free( op2 );
+
+  return( result );
+}
+
+
+
+#endif /*TSCREEN*/
+
 void
 InitKeytab()
 {
@@ -1121,6 +1369,53 @@ char *data;
     LayProcess(&buf, &len);
 }
 
+#ifdef TSCREEN
+
+void
+HideWindow(p)
+struct win *p;
+{
+  int q;
+  int n = p ? p->w_number : -1;
+  struct win **pp;
+
+  if (!p)
+    {
+      ShowWindows(-1);
+      return;
+    }
+
+  // Valid window?
+  for (q = -1, pp = wtab; pp != wtab + MAXWIN; pp++)
+  {
+    struct win *w = *pp;
+
+    if (w && w->w_number == n)
+    {
+      q = n;
+      break;
+    }
+  }
+  n = q;
+  if (n < 0 || n >= MAXWIN)
+  {
+    ShowWindows(-1);
+    return;
+  }
+  if (p->w_hide)
+    {
+      p->w_hide = 0;
+      Msg(0, "Window %d (%s) unhidden", p->w_number, p->w_title);
+    }
+  else
+    {
+      p->w_hide = 1;
+      Msg(0, "Window %d (%s) is now hidden", p->w_number, p->w_title);
+    }
+}
+
+#endif /*TSCREEN*/
+
 /*ARGSUSED*/
 void
 DoAction(act, key)
@@ -1138,6 +1433,20 @@ int key;
   struct acluser *user;
 
   user = display ? D_user : users;
+#ifdef TSCREEN
+
+  if (nr > RC_LAST)
+    {
+      struct alias *alias = FindAliasnr(nr);
+      if (alias)
+	{
+	  DoAlias(alias->name, act->args, act->argl);
+	  return;
+	}
+      nr = RC_ILLEGAL;
+    }
+
+#endif /*TSCREEN*/
   if (nr == RC_ILLEGAL)
     {
       debug1("key '%c': No action\n", key);
@@ -1176,6 +1485,22 @@ int key;
   msgok = display && !*rc_name;
   switch(nr)
     {
+#ifdef TSCREEN
+    case RC_HIDE:
+      if (!*args || (args[0][0] == '.' && !args[0][1]))
+       {
+	  if (!fore)
+	    {
+	      Msg(0, "hide . needs a window");
+	      break;
+	    }
+	  n = fore->w_number;
+	}
+      else if (ParseWinNum(act, &n) < 0)
+	break;
+      HideWindow(wtab[n]);
+      break;
+#endif /*TSCREEN*/
     case RC_SELECT:
       if (!*args)
         InputSelect();
@@ -1398,6 +1723,32 @@ int key;
 	Msg(0, "zmodem mode is %s", zmodes[zmodem_mode]);
       break;
 #endif
+#ifdef TSCREEN
+    case RC_UNALIASALL:
+      {
+        struct alias *t = g_aliases_list;
+        while( ( t != NULL ) &&
+               ( t->name != NULL ) )
+          {
+            DelAlias( t->name,1 );
+            t = g_aliases_list;
+          }
+      }
+      break;
+    case RC_UNBINDALL:
+      {
+        register unsigned int i;
+
+        for (i = 0; i < sizeof(ktab)/sizeof(*ktab); i++)
+          {
+            ktab[i].nr = RC_ILLEGAL;
+            ktab[i].args = noargs;
+            ktab[i].argl = 0;
+          }
+        Msg(0, "unbound all keys" );
+        break;
+      }
+#endif /*TSCREEN*/
     case RC_ZOMBIE:
       {
         if (!(s = *args))
@@ -1807,7 +2158,11 @@ int key;
       /* FALLTHROUGH */
     case RC_OTHER:
       if (MoreWindows())
+#ifdef TSCREEN
+	SwitchWindow(display && D_other && !D_other->w_hide ? D_other->w_number : NextWindow());
+#else /*!TSCREEN*/
 	SwitchWindow(display && D_other ? D_other->w_number : NextWindow());
+#endif /*TSCREEN*/
       break;
     case RC_META:
       if (user->u_Esc == -1)
@@ -2019,9 +2374,18 @@ int key;
 	}
       break;
     case RC_LASTMSG:
+#ifdef TSCREEN
+      ShowHistory("history");
+#else /*!TSCREEN*/
       if (D_status_lastmsg)
 	Msg(0, "%s", D_status_lastmsg);
+#endif /*TSCREEN*/
+      break;
+#ifdef TSCREEN
+    case RC_ALIASLIST:
+      ShowHistory("alias");
       break;
+#endif /*TSCREEN*/
     case RC_SCREEN:
       DoScreen("key", args);
       break;
@@ -2507,7 +2871,7 @@ int key;
       break;
     case RC_SHELL:
     case RC_DEFSHELL:
-      if (ParseSaveStr(act, &ShellProg) == 0)
+      if (ParseSaveExpandedStr(act, &ShellProg) == 0)
         ShellArgs[0] = ShellProg;
       break;
     case RC_HARDCOPYDIR:
@@ -2526,7 +2890,7 @@ int key;
 		Msg(0, "log flush timeout set to %ds\n", log_flush);
 	      break;
 	    }
-	  if (ParseSaveStr(act, &screenlogfile) || !msgok)
+	  if (ParseSaveExpandedStr(act, &screenlogfile) || !msgok)
 	    break;
 	}
       Msg(0, "logfile is '%s'", screenlogfile);
@@ -2844,6 +3208,14 @@ int key;
 	  Msg(0, "%s: grabbing console %s", rc_name, HostName);
       console_window = n ? fore : 0;
       break;
+#ifdef TSCREEN
+    case RC_ALIAS:
+      if (argc == 1)
+        DelAlias(args[0],0);
+      else
+	AddAlias(args[0], args[1], args+1, argl+1, argc - 1);
+      break;
+#endif /*TSCREEN*/
     case RC_ALLPARTIAL:
       if (ParseOnOff(act, &all_norefresh))
 	break;
@@ -3219,10 +3591,21 @@ int key;
 	    {
 	      if ((i = FindCommnr(args[1])) == RC_ILLEGAL)
 		{
+#ifdef TSCREEN
+		  struct alias *alias = FindAlias(args[1]);
+		  if (!alias)
+		    {
+#endif /*TSCREEN*/
 		  Msg(0, "%s: bind: unknown command '%s'", rc_name, args[1]);
 		  break;
 		}
+#ifdef TSCREEN
+		  i = alias->nr;
+		}
+	      if (i <= RC_LAST && CheckArgNum(i, args + 2) < 0)
+#else /*!TSCREEN*/
 	      if (CheckArgNum(i, args + 2) < 0)
+#endif /*TSCREEN*/
 		break;
 	      ClearAction(&ktabp[n]);
 	      SaveAction(ktabp + n, i, args + 2, argl + 2);
@@ -3231,6 +3614,58 @@ int key;
 	    ClearAction(&ktabp[n]);
 	}
       break;
+#ifdef TSCREEN
+    case RC_IF:
+      {
+        /**
+         * There are two types of test:
+         *
+         * -x foo
+         *
+         * xx -xx bar
+         *
+         * We can spot these by looking for "-" in the correct place.
+         */
+        if ( ( args[0][0] == '-' ) ||
+             ( ( strlen(args[0]) >= 2 ) && ( args[0][0] == '!' ) && ( args[0][1] == '-' ) ) )
+        {
+          char *type = args[0];
+          char *arg  = args[1];
+          if ( doSimpleTest( type, arg ) )
+            {
+              /* test succeeded - run each remaining arg through eval */
+              args = SaveArgs(args);
+              for (i = 2; args[i] ; i++)
+                {
+                  if (args[i][0])
+                    Colonfin(args[i], strlen(args[i]), (char *)0);
+                  free(args[i]);
+                }
+              free(args);
+            }
+        }
+        else
+        {
+          char *op1  = args[0];
+          char *test = args[1];
+          char *op2  = args[2];
+
+          if ( doComplexTest( test, op1, op2 ) )
+          {
+            /* test succeeded - run each remaining arg through eval */
+            args = SaveArgs(args);
+            for (i = 3; args[i] ; i++)
+            {
+              if (args[i][0])
+                Colonfin(args[i], strlen(args[i]), (char *)0);
+              free(args[i]);
+            }
+            free(args);
+          }
+        }
+      }
+      break;
+#endif /*TSCREEN*/
 #ifdef MAPKEYS
     case RC_BINDKEY:
 	{
@@ -3350,10 +3785,21 @@ int key;
 	    {
 	      if ((newnr = FindCommnr(args[1])) == RC_ILLEGAL)
 		{
+#ifdef TSCREEN
+		  struct alias *alias = FindAlias(args[1]);
+		  if (!alias)
+		    {
+#endif /*TSCREEN*/
 		  Msg(0, "%s: bindkey: unknown command '%s'", rc_name, args[1]);
 		  break;
 		}
+#ifdef TSCREEN
+		  newnr = alias->nr;
+		}
+	      if (newnr <= RC_LAST && CheckArgNum(newnr, args + 2) < 0)
+#else /*!TSCREEN*/
 	      if (CheckArgNum(newnr, args + 2) < 0)
+#endif /*TSCREEN*/
 		break;
 	      ClearAction(newact);
 	      SaveAction(newact, newnr, args + 2, argl + 2);
@@ -4094,7 +4540,7 @@ int key;
 	  free(blankerprg);
 	  blankerprg = 0;
 	}
-      if (args[0][0])
+      if ((args) && (*args))
 	blankerprg = SaveArgs(args);
       break;
 #endif
@@ -4393,6 +4839,56 @@ int key;
     }
 }
 
+#ifdef TSCREEN
+static int
+DoAlias(name, args, argl)
+const char *name;
+char **args;
+int *argl;
+{
+  char **mergeds;
+  int *mergedl;
+  int count, i;
+  struct alias *alias = FindAlias(name);
+
+  if (alias == NULL)
+    return 0;
+
+  count = 0;
+  for (; args && args[count]; count++)
+    ;
+  for (i = 0; alias->args && alias->args[i]; i++, count++)
+    ;
+  ++count;
+
+  if ((mergeds = malloc(count * sizeof(char *))) == 0)
+    return 0;
+  if ((mergedl = malloc(count * sizeof(int))) == 0)
+    {
+      free(mergeds);
+      return 0;
+    }
+  for (count = 0; alias->args && alias->args[count]; count++)
+    {
+      mergeds[count] = alias->args[count];
+      mergedl[count] = alias->argl[count];
+    }
+  for (i = 0; args && args[i]; i++, count++)
+    {
+      mergeds[count] = args[i];
+      mergedl[count] = argl[i];
+    }
+  mergeds[count] = 0;
+  mergedl[count] = 0 ;
+
+  DoCommand(mergeds, mergedl);
+
+  free(mergeds);
+  free(mergedl);
+  return 1;
+}
+#endif /*TSCREEN*/
+
 void
 DoCommand(argv, argl) 
 char **argv;
@@ -4400,6 +4896,12 @@ int *argl;
 {
   struct action act;
 
+#ifdef TSCREEN
+    /* Alias? */
+  if (DoAlias(*argv, argv + 1, argl + 1))
+    return;
+#endif /*TSCREEN*/
+
   if ((act.nr = FindCommnr(*argv)) == RC_ILLEGAL)  
     {
       Msg(0, "%s: unknown command '%s'", rc_name, *argv);
@@ -4741,6 +5243,25 @@ char **var;
   return 0;
 }
 
+#ifdef TSCREEN
+int
+ParseSaveExpandedStr(act, var)
+struct action *act;
+char **var;
+{
+  char **args = act->args;
+  if (*args == 0 || args[1])
+    {
+      Msg(0, "%s: %s: one argument required.", rc_name, comms[act->nr].name);
+      return -1;
+    }
+  if (*var)
+    free(*var);
+  *var = SaveExpandedStr(*args);
+  return 0;
+}
+#endif /*TSCREEN*/
+
 int
 ParseNum(act, var)
 struct action *act;
@@ -5195,6 +5716,12 @@ NextWindow()
     {
       if (pp == wtab + MAXWIN)
 	pp = wtab;
+#ifdef TSCREEN
+      struct win *p=*pp;
+      if (p && p->w_hide)
+	continue;
+
+#endif /*TSCREEN*/
       if (*pp)
 	{
 	  if (!fore || group == (*pp)->w_group)
@@ -5217,6 +5744,12 @@ PreviousWindow()
     {
       if (pp == wtab - 1)
 	pp = wtab + MAXWIN - 1;
+#ifdef TSCREEN
+     struct win *p = *pp;
+     if (p && p->w_hide)
+       continue;
+
+#endif /*TSCREEN*/
       if (*pp)
 	{
 	  if (!fore || group == (*pp)->w_group)
@@ -5232,8 +5765,21 @@ static int
 MoreWindows()
 {
   char *m = "No other window.";
+#ifdef TSCREEN
+  struct win **pp, *p;
+  int n = fore ? fore->w_number : -1;
+
+  for (pp = wtab; pp != wtab + MAXWIN; pp++) {
+    p = *pp;
+    if (fore && windows && p && p->w_number != n && p->w_hide == 0)
+#else /*!TSCREEN*/
   if (windows && (fore == 0 || windows->w_next))
+#endif /*TSCREEN*/
     return 1;
+#ifdef TSCREEN
+  }
+
+#endif /*TSCREEN*/
   if (fore == 0)
     {
       Msg(0, "No window available");
@@ -5369,16 +5915,26 @@ int on;
 }
 
 char *
+#ifdef TSCREEN
+AddWindows(buf, len, flags, where, attr)
+#else /*!TSCREEN*/
 AddWindows(buf, len, flags, where)
+#endif /*TSCREEN*/
 char *buf;
 int len;
 int flags;
 int where;
+#ifdef TSCREEN
+int attr;
+#endif /*TSCREEN*/
 {
   register char *s, *ss;
   register struct win **pp, *p;
   register char *cmd;
   int l;
+#ifdef TSCREEN
+  int a;
+#endif /*TSCREEN*/
 
   s = ss = buf;
   if ((flags & 8) && where < 0)
@@ -5409,6 +5965,17 @@ int where;
 	  *s++ = ' ';
 	  *s++ = ' ';
 	}
+#ifdef TSCREEN
+      if ((((flags & 4) && where >= 0 && where < p->w_number) ||
+	  (!(flags & 4) && where >= 0 && p->w_number < where)) &&
+	  (flags & 8) && attr != -1)
+	a = 1;
+      else
+	a = 0;
+      if (a && (p->w_bell == BELL_DONE || p->w_bell == BELL_FOUND))
+	AddWinMsgRend(s, attr);
+      sprintf(s, "%d", p->w_number);
+#endif /*TSCREEN*/
       if (p->w_number == where)
         {
           ss = s;
@@ -5437,7 +6004,11 @@ int where;
       *s++ = ' ';
       strncpy(s, cmd, l);
       s += l;
+#ifdef TSCREEN
+      if (rend != -1 && a && (p->w_bell == BELL_DONE || p->w_bell == BELL_FOUND))
+#else /*!TSCREEN*/
       if (rend != -1)
+#endif /*TSCREEN*/
 	AddWinMsgRend(s, -1);
     }
   *s = 0;
@@ -5472,6 +6043,10 @@ struct win *p;
     *s++ = '@';
   if (p->w_bell == BELL_DONE)
     *s++ = '!';
+#ifdef TSCREEN
+  if (p->w_hide)
+    *s++ = '^';
+#endif /*TSCREEN*/
 #ifdef UTMPOK
   if (p->w_slot != (slot_t) 0 && p->w_slot != (slot_t) -1)
     *s++ = '$';
@@ -5541,7 +6116,11 @@ int where;
     return;
   if (where == -1 && D_fore)
     where = D_fore->w_number;
+#ifdef TSCREEN
+  ss = AddWindows(buf, sizeof(buf), 0, where, -1);
+#else /*!TSCREEN*/
   ss = AddWindows(buf, sizeof(buf), 0, where);
+#endif /*TSCREEN*/
   s = buf + strlen(buf);
   if (ss - buf > D_width / 2)
     {
@@ -5741,6 +6320,65 @@ InputAKA()
     }
 }
 
+#ifdef TSCREEN
+/**
+ * Find possible completions for the given input string, of lenth len.
+ *
+ * Return the count of completions.
+ *
+ * matches will be updated to point to a string of space-separated
+ * matches.
+ *
+ * TODO:  Sort the return value.
+ *
+ */
+int findCompletions( char *input, int len, char **matches )
+{
+  int count         = 0;
+  int max           = RC_LAST;
+  struct alias *cur = g_aliases_list;
+  int i;
+
+  char *result = (char *)malloc( 2048 * sizeof(char));
+  memset(result, '\0', 2048);
+
+  /* test built-in commands. */
+  for ( i = 0; i < max; i++ )
+    {
+      if ( strncmp( input, comms[i].name, len ) == 0 )
+        {
+          if ( result[0] != '\0' )
+            strcat( result, " " );
+
+          strcat( result, comms[i].name );
+          count += 1;
+        }
+    }
+
+  /* now aliases */
+  while( cur != NULL )
+    {
+      if ( strncmp( input, cur->name, len ) == 0 )
+        {
+          if ( result[0] != '\0' )
+            strcat( result, " " );
+
+          strcat( result, cur->name );
+          count += 1;
+        }
+      cur = cur->next;
+    }
+
+  /* need this for the completion to work.  sigh. */
+  strcat(result, " \t" );
+
+  /* *matches = sortString( result , count); */
+  *matches = strdup( result );
+  return count;
+}
+
+#endif /*TSCREEN*/
+
 static void
 Colonfin(buf, len, data)
 char *buf;
@@ -5924,6 +6562,9 @@ void
 DoScreen(fn, av)
 char *fn, **av;
 {
+#ifdef TSCREEN
+  int find = 0;
+#endif /*TSCREEN*/
   struct NewWindow nwin;
   register int num;
   char buf[20];
@@ -5957,6 +6598,11 @@ char *fn, **av;
 	      break;
 	    }
 	  break;
+#ifdef TSCREEN
+        case 'F':
+         find = 1;
+         break;
+#endif /*TSCREEN*/
 	case 't':	/* no more -k */
 	  if (av[0][2])
 	    nwin.aka = &av[0][2];
@@ -6037,7 +6683,12 @@ char *fn, **av;
       if (!nwin.aka)
         nwin.aka = Filename(*av);
     }
-  MakeWindow(&nwin);
+#ifdef TSCREEN
+    if (find)
+    FindOrMakeWindow(&nwin);
+  else
+#endif /*TSCREEN*/
+    MakeWindow(&nwin);
 }
 
 #ifdef COPY_PASTE
@@ -6567,6 +7218,174 @@ char *presel;
   return wi;
 }
 
+#ifdef TSCREEN
+
+
+/**
+ * Add an alias
+ */
+void
+AddAlias(name, value, args, argl, count)
+const char *name;
+const char *value;
+char **args;
+int *argl;
+int count;
+{
+  struct alias *nalias = NULL;
+  static next_command = RC_LAST;
+  int nr;
+
+  /* If we have this alias name already defined then remove it. */
+  if (FindAlias(name) != NULL)
+    DelAlias( name, 1 );
+
+  /* Make sure the alias maps to something */
+  if ((nr = FindCommnr((char *)value)) == RC_ILLEGAL)
+    {
+      struct alias *alias = FindAlias(value);
+      if (!alias)
+	{
+          Msg(0, "%s: could not find command or alias '%s'", rc_name, value);
+	  return;
+	}
+      nr = alias->nr;
+    }
+
+  nalias = (struct alias *)calloc(1, sizeof(struct alias));
+
+  /* store it */
+  nalias->next = NULL;
+  nalias->name = SaveStr(name);
+  nalias->cmdnr = nr;
+  if (count > 0)
+    {
+      nalias->args = SaveArgs(args);
+      nalias->argl = calloc(count + 1, sizeof(int));
+      while (count--)
+	nalias->argl[count] = argl[count];
+    }
+  nalias->nr = ++next_command;
+
+  /* Add to head */
+  nalias->next = g_aliases_list;
+  g_aliases_list = nalias;
+}
+
+
+/**
+ * Find an alias by name.
+ */
+static struct alias *
+FindAlias(name)
+const char *name;
+{
+  struct alias *t = g_aliases_list;
+
+  while(t != NULL)
+    {
+      if ((t->name != NULL) &&
+           (strcmp(t->name, name) == 0))
+        return t;
+
+      t = t->next;
+    }
+
+  return NULL;
+}
+
+/**
+ * Find an alias by number.
+ */
+static struct alias *
+FindAliasnr(nr)
+int nr;
+{
+  struct alias *t;
+  for (t = g_aliases_list; t; t = t->next)
+    {
+      if (t->nr == nr)
+        return t;
+    }
+
+  return NULL;
+}
+
+/**
+ * Delete an alias
+ */
+void
+DelAlias(name, quiet)
+const char *name;
+int quiet;
+{
+  /* Find the previous alias */
+  struct alias *cur  = g_aliases_list;
+  struct alias **pcur = &g_aliases_list;
+
+  while (cur != NULL)
+    {
+      if ((cur->name != NULL) &&
+           (strcmp(cur->name, name) == 0))
+        {
+          struct alias *found = cur;
+          int c;
+
+          /* remove this one from the chain. */
+          *pcur = found->next;
+
+          free(found->name);
+          found->name = NULL;
+	  if (found->args)
+	    {
+	      for (c = 0; found->args[c]; c++)
+		free(found->args[c]);
+	      free(found->args);
+	      free(found->argl);
+	    }
+          free(found);
+
+          if ( !quiet )
+            Msg(0, "alias %s removed", name);
+	  return;
+        }
+      pcur = &cur->next;
+      cur = cur->next;
+    }
+
+  if ( !quiet )
+    Msg(0, "alias %s not found", name);
+}
+
+
+void ShowAliasDump()
+{
+  struct alias *t = g_aliases_list;
+
+  printf( "Alias List\n" );
+  printf( "==========\n\n" );
+
+  while( t != NULL )
+    {
+      int i;
+
+      printf("%s =>", t->name );
+
+      for (i = 0;  t->args[i] != NULL; i++ )
+        {
+          printf( " %s", t->args[i] );
+        }
+      printf("\n");
+      t = t->next;
+    }
+
+  printf("\n\t\t[Press Any Key To Close]\n");
+
+}
+
+
+#endif /*TSCREEN*/
+
 #if 0
 
 /* sorted list of all commands */
diff --git a/src/screen.c b/src/screen.c
index 107c947..d9d4759 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -973,7 +973,7 @@ char **av;
 
   if (home == 0 || *home == '\0')
     home = ppp->pw_dir;
-  if (strlen(LoginName) > 20)
+  if (strlen(LoginName) > MAX_USERNAME_LEN)
     Panic(0, "LoginName too long - sorry.");
 #ifdef MULTIUSER
   if (multi && strlen(multi) > 20)
@@ -1419,7 +1419,7 @@ char **av;
 	  FD_SET(0, &rfd);
 
 	  Msg(0, "Sorry, could not find a PTY or TTY.");
-	  // allow user to exit early by pressing any key.
+	  /* allow user to exit early by pressing any key. */
 	  select(1, &rfd, NULL, NULL, &tv);
 	  Finit(0);
 	  /* NOTREACHED */
@@ -2479,6 +2479,9 @@ int rec;
   int truncper = 0;
   int trunclong = 0;
   struct backtick *bt;
+#ifdef TSCREEN
+  int attrflg = 0, attr = -1;
+#endif /*TSCREEN*/
  
   if (winmsg_numrend >= 0)
     winmsg_numrend = 0;
@@ -2533,6 +2536,10 @@ int rec;
 	num = num * 10 + (*s++ - '0');
       if ((longflg = *s == 'L') != 0)
 	s++;
+#ifdef TSCREEN
+      if ((attrflg = *s == 'B') != 0)
+	s++;
+#endif /*TSCREEN*/
       switch (*s)
 	{
         case '?':
@@ -2705,7 +2712,12 @@ int rec;
 		oldfore = D_fore;
 		D_fore = win;
 	      }
-	    ss = AddWindows(p, l - 1, (*s == 'w' ? 0 : 1) | (longflg ? 0 : 2) | (plusflg ? 4 : 0) | (minusflg ? 8 : 0), win ? win->w_number : -1);
+
+	    ss = AddWindows(p, l - 1, (*s == 'w' ? 0 : 1) | (longflg ? 0 : 2) | (plusflg ? 4 : 0) | (minusflg ? 8 : 0), win ? win->w_number : -1
+#ifdef TSCREEN
+			    , attr
+#endif /*TSCREEN*/
+			    );
 	    if (display)
 	      D_fore = oldfore;
 	  }
@@ -2755,6 +2767,11 @@ int rec;
 		debug1("MakeWinMsg attrcolor %s\n", rbuf);
 	        if (i != 1 || rbuf[0] != '-')
 		  r = ParseAttrColor(rbuf, (char *)0, 0);
+#ifdef TSCREEN
+		if (r != -1 && attrflg)
+		    attr = r;
+		else
+#endif /*TSCREEN*/
 	        if (r != -1 || (i == 1 && rbuf[0] == '-'))
 		  {
 		    winmsg_rend[winmsg_numrend] = r;
diff --git a/src/screen.h b/src/screen.h
index d80f0d5..e4e703a 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -86,6 +86,10 @@
 # define ASSERT(lousy_cpp) do {} while (0)
 #endif
 
+#ifdef TSCREEN
+#  define isExecutable(mode) (mode & (S_IXUSR|S_IXGRP|S_IXOTH))
+
+#endif /*TSCREEN*/
 /* here comes my own Free: jw. */
 #define Free(a) {if ((a) == 0) abort(); else free((void *)(a)); (a)=0;}
 
@@ -201,7 +205,7 @@ struct msg
       create;
       struct
 	{
-	  char auser[20 + 1];	/* username */
+	  char auser[MAX_USERNAME_LEN + 1];	/* username */
 	  int apid;		/* pid of frontend */
 	  int adaptflag;	/* adapt window size? */
 	  int lines, columns;	/* display size */
@@ -215,13 +219,13 @@ struct msg
       attach;
       struct 
 	{
-	  char duser[20 + 1];	/* username */
+	  char duser[MAX_USERNAME_LEN + 1];	/* username */
 	  int dpid;		/* pid of frontend */
 	}
       detach;
       struct 
 	{
-	  char auser[20 + 1];	/* username */
+	  char auser[MAX_USERNAME_LEN + 1];	/* username */
 	  int nargs;
 	  char cmd[MAXPATHLEN];	/* command */
 	  int apid;		/* pid of frontend */
diff --git a/src/window.c b/src/window.c
index 4426f0f..9352a39 100644
--- a/src/window.c
+++ b/src/window.c
@@ -849,6 +849,44 @@ struct NewWindow *newwin;
   return n;
 }
 
+#ifdef TSCREEN
+
+/*
+ * Look up a window via its title. If it's found, it is just fetched to the
+ * foreground. If not, it gets created with the given flags.
+ */
+int
+FindOrMakeWindow(nwin)
+struct NewWindow *nwin;
+{
+  struct win *r = NULL, *p = windows;
+
+  if (!nwin->aka)
+    {
+      Msg(0, "Window lookup impossible without title, creating new.");
+      return MakeWindow(nwin);
+    }
+
+  while (p)
+    {
+      if (strcmp(nwin->aka, p->w_title) == 0)
+       {
+         r = p;
+         break;
+       }
+      p = p->w_next;
+    }
+
+  if (r)
+    SwitchWindow(r->w_number);
+  else
+    return MakeWindow(nwin);
+
+  return 0;
+}
+
+#endif /*TSCREEN*/
+
 /*
  * Resurrect a window from Zombie state.
  * The command vector is therefore stored in the window structure.
diff --git a/src/window.h b/src/window.h
index 6c6ca76..ce307a5 100644
--- a/src/window.h
+++ b/src/window.h
@@ -191,6 +191,9 @@ struct win
   int	 w_SavedCharsetR;
   int	 w_SavedCharsets[4];
 #endif
+#ifdef TSCREEN
+  int    w_hide;
+#endif /*TSCREEN*/
   int	 w_top, w_bot;		/* scrollregion */
   int	 w_wrap;		/* autowrap */
   int	 w_origin;		/* origin mode */
