Merge branch 'master' of ssh://erxz.com/~/git_repo/stem
Uri Guttman [Wed, 23 Sep 2009 06:57:52 +0000 (02:57 -0400)]
Conflicts:
MANIFEST

.gitignore
Build.PL
BuildStem.pm
MANIFEST.SKIP
extras/ssfe.1 [deleted file]
extras/ssfe.c [deleted file]
notes/srs_notes.txt
srs_notes.txt [deleted file]

index 6af5e59..7b00c40 100644 (file)
@@ -38,3 +38,6 @@ slides
 stem2pod
 test
 
+# other random stuff
+*.BACKUP
+*.orig
index 702ee1a..2939b17 100644 (file)
--- a/Build.PL
+++ b/Build.PL
@@ -5,146 +5,178 @@ use warnings ;
 
 use Config ;
 use File::Spec ;
-use BuildStem ;
 use Data::Dumper ;
 
-# I wonder if I should add the ability to put the Docs and Design etc
-# directories in apropriate spots, like 
-# /usr/local/share/stem (site) or /usr/share/stem (vendor)
-
-my %requires ;
+use BuildStem ;
 
-my $version_from = File::Spec->catfile( File::Spec->curdir, 'lib', 'Stem.pm' );
+my $version_from = File::Spec->catfile( 
+    File::Spec->curdir, 'lib', 'Stem.pm' 
+);
 
 my $build = BuildStem->new(
-#my $build = $class->new(
-       module_name             => 'Stem',
-       dist_version_from       => $version_from,
-       requires                => \%requires,
-       dist_abstract           => 'ABSTRACT GOES HERE',
-       license                 => 'gpl',
-       dynamic_config          => 1,
-       recursive_test_files    => 1,
-       create_makefile_pl      => 'passthrough'
+    module_name                 => 'Stem',
+    dist_version_from   => $version_from,
+    requires            => {
+      YAML        => 0,
+    },
+    dist_abstract       => 
+        'An asynchronous message passing framework for Perl',
+    license             => 'gpl',
+    dynamic_config      => 1,
+    recursive_test_files => 1,
+    needs_compiler       => 0,
+    recommends           => {
+       DBI    => 0,
+        Event  => 0,
+    },
+    create_makefile_pl  => 'passthrough'
 );
 
 
 
-$build->is_unixish() || die "Stem currently only installs properly on *nix-like platforms.\n";
+$build->is_unixish() or 
+  die "Stem currently only installs properly on *nix-like platforms.\n";
 
-### this will come in handy for some refactoring...
-## $build->config( 'install_base' )
 
-print <<'EOT';
+### ask about the config path and where to install bundled config files
 
-Stem comes with a utility called 'run_stem' which takes care of things
-like initalizing Stem with a configuration file and controlling it's
-operation via various parameters you can pass in as environment
-variables or command line arguments.
+print <<'EOT';
 
-Stem configuration files are used to create and initialize Stem Cells
-(objects). run_stem can search a path list for config files, so you
-can set that list of directories here.
+Stem configuration files are used to create and initialize Stem Cells.
+An included program called 'run_stem' will search a default path for 
+a specified config file and use it to get everything going. You can see
+this in action if you check out Stem's demo scripts.
 
 Note that you can easily override this path with either a shell environment
-variable or on the command line of run_stem. See the documentation on
-run_stem for how so do this.
-
-The last directory in the list is where the standard and demo Stem
-configuration files will be installed.
+variable or a command line agrument. See the documentation on run_stem for 
+how to do this.
 
 EOT
 
-my $conf_path = $build->prompt(
-       "Please enter a list of directory paths separated by ':'\n",
+$build->config_data( 
+    conf_path => scalar $build->prompt(
+        "Please enter a list of directory paths separated by ':'\n",
        '.:~/.stem/conf:/usr/local/stem/conf'
+    )
 );
-$build->config_data(conf_path => $conf_path);
 
 
+print <<'EOT';
 
-print "\n\nChecking to see if you have a good C compiler...\n\n" ;
-if ( $build->have_c_compiler() ) {
-       print <<'EOT';
+Where would you like to install the config files bundled with Stem?
+If you specify a directory not already in the path above, it will be
+appended. If this directory does not exist, it will be created.
 
+EOT
 
-ssfe (Split Screen Front End) is a compiled program optionally used by
-the Stem demonstration scripts that provides a full screen interface
-with command line editing and history. It is not required to run Stem
-but it makes the demonstrations easier to work with and they look much
-nicer. To use ssfe add the '-s' option when you run any demonstration
-script. You can also use ssfe for your own programs. If you build ssfe
-it will be installed in the demo/ directory. You may copy it to a place
-in your $PATH is you wish.
+$build->config_data( 
+    conf_dir => scalar $build->prompt(
+        "Please enter a directory path:\n",
+       '/usr/local/stem/conf'
+    )
+);
 
-EOT
-       my $build_ssfe = $build->y_n("Do you want to  build ssfe?\n", 'y');
-       $build->config_data(build_ssfe => $build_ssfe);
+### add the conf_dir to the conf_path, if necessary
+{
+    my $conf_path = $build->config_data( 'conf_path' );
+    my $conf_dir  = $build->config_data( 'conf_dir' );
+    if ( $conf_path =~ /(^|:)\Q$conf_dir\E(:|$)/ ) {
+        $build->config_data( conf_path => "$conf_path:$conf_dir" );
+    }
 }
 
 
+
+### ask about building the demo scripts
 print <<'EOT';
 
 Stem comes with a variety of demos to show how to get started and do some
-basic things. If you wish, they can be configured to run locally out of the 
-demo/ directory.
+basic things. If you wish to try them they will be available in the demo/
+directory after you run ./Build. In any case, they will not be installed 
+to the system, even after you install the rest of Stem.
 
 EOT
-my $build_demos = $build->y_n("\nDo you want to build the demos?\n",'y');
-$build->config_data(build_demos => $build_demos);
-if ( $build_demos ) {
 
-       # Check for telnet
+$build->config_data(
+    build_demos => scalar $build->y_n(
+        "Do you want to build the demos?\n", 'y'
+    )
+);
+
+
+if ( $build->config_data( 'build_demos' ) ) {
+
+
+       ### Try to find telnet
        my $telnet_path = $build->find_binary( 'telnet' ) || '' ;
        while ( ! -x $telnet_path && ! $build->_is_unattended() ) {
                print <<'EOT';
 
-telnet was not found on this system. you can't run the demo programs
-without telnet.  Make sure you enter a valid path to telnet or some other
-terminal emulator.
-
-NOTE: If you don't have an telnet, you can still run the demo scripts
-by hand. Run a *_demo script and see what telnet commands it
-issues. The run those telnet commands using your telnet or another
-similar program.
+telnet was not found on this system. the demo programs won't run properly
+without telnet. Please enter a valid path to telnet, or a single <space> 
+to give up trying.
 
 EOT
                $telnet_path = $build->prompt(
                          "Enter the path to telnet "
                        . "(or another compatible telnet client)",
-            '/usr/bin/telnet'
+                                             '/usr/bin/telnet'
                ) ;
+               last if $telnet_path =~ s/^\w+$//;
        }
-       $build->config_data( telnet_path => $telnet_path ) ;
+       $build->config_data( telnet_path => $telnet_path || undef ) ;
+
+
 
 
-       # Check for xterm
+       # Try to find xterm
        my $xterm_path = $build->find_binary( 'xterm' ) || '' ;
        while ( ! -x $xterm_path && ! $build->_is_unattended() ) {
-               print <<'EOT';
+           print <<'EOT';
+
+xterm was not found on this system. the demo programs won't run properly
+without xterm.  Please enter a valid path to xterm or a single <space> to
+give up trying.
+
+EOT
+           $xterm_path = $build->prompt(
+               "Enter the path to xterm "
+             . "(or another compatible terminal emulator)",
+             '/usr/bin/xterm'
+           ) ;
+           last if $xterm_path =~ s/^\w+$//;
+       }
+       $build->config_data( xterm_path => $xterm_path || undef ) ;
 
 
-xterm was not found on this system. you can't run the demo programs
-without xterm.  Make sure you enter a valid path to xterm or some other
-terminal emulator.
+    ### Only build ssfe if we have a working C compiler
+    if ( $build->have_c_compiler() ) {
+        print <<'EOT';
 
-NOTE: If you don't have an xterm, you can still run the demo scripts
-by hand. Run a *_demo script and see what commands it issues. Take the
-part after the -e and run that command in its own terminal window.
+ssfe (Split Screen Front End) is a compiled program optionally used by
+the Stem demonstration scripts that provides a full screen interface
+with command line editing and history. It is not required to run Stem
+but it makes the demonstrations easier to work with and they look much
+nicer. To use ssfe add the '-s' option when you run any demonstration
+script. You can also use ssfe for your own programs. If you build ssfe
+it will be installed in the demo/ directory. You may copy it to a place
+in your $PATH is you wish.
 
 EOT
-               $xterm_path = $build->prompt(
-                         "Enter the path to xterm "
-                       . "(or another compatible terminal emulator)",
-            '/usr/bin/xterm'
-               ) ;
+       $build->config_data(
+           build_ssfe => scalar $build->y_n(
+                "Do you want to build ssfe for the demos?\n", 'y'
+            )
+        );
+    }
 }
-       $build->config_data( xterm_path => $xterm_path ) ;
 
-}
 
 
 
+### NOTE: find out whether or not each of the following 
+### config_data settings are actually being *used* for anything
+
 my $script_dest = $build->install_destination('script') ;
 my $run_stem_path = File::Spec->catfile( $script_dest, 'run_stem' ) ;
 $build->config_data( run_stem_path => $run_stem_path ) ;
index 2f9f771..9899ae6 100644 (file)
@@ -35,7 +35,7 @@ sub build_ssfe {
     print "Compiling ssfe\n";
     system( "cd extras; tar xzf sirc-2.211.tar.gz; cp sirc-2.211/ssfe.c ../demo" );
     system( "cc -o demo/ssfe demo/ssfe.c -ltermcap 2>/dev/null" );
-    $self->add_to_cleanup(qw(demo/ssfe demo/ssfe.c ));
+    $self->add_to_cleanup(qw(demo/ssfe demo/ssfe.c extras/sirc-2.211 ));
 }
 
 
index 7408d6d..e504f66 100644 (file)
 # Temp, old and emacs backup files.
 ~$
 \.old$
-^#.*#$
+\B#.*#$
 ^\.#
 \.*.swp$
 
 # other stuff we dont want in the dist tarball
 ^notes/
-
+^*.orig
+^*.BACKUP
diff --git a/extras/ssfe.1 b/extras/ssfe.1
deleted file mode 100644 (file)
index c71ff35..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-.TH SSFE 1 "" "Roger Espel Llima"
-.SH NAME
-ssfe \- split-screen front-end
-.SH SYNOPSIS
-.B ssfe
-[options] program-name [program-options]
-.SH DESCRIPTION
-.B ssfe
-runs a line-oriented program in the background, and provides a full
-screen interface for it.  The bottom line of the screen is the input
-line, which you can edit using emacs-like keys; above that is the
-status bar, and the scrolling area with the program's output.
-.PP
-You can configure 
-.B ssfe
-to reprint or not your own input lines, to use prompts, and to do word-wrap
-on the program's output.
-.PP
-.B ssfe
-also understands a little protocol to communicate with the program it is
-running, which can be used to change the contents of the status line,
-to set ssfe's modes and to prompt for input.
-.SH OPTIONS
-.TP
-.BR "-raw"
-Disables word-wrap and handling of control characters.  In this mode, ssfe
-will not attempt keep track of the cursor's position.
-.TP
-.BR "-cooked"
-Enables word-wrap, and prints control characters using inverse-video;  this
-is the default mode.
-.TP
-.BR "-irc"
-Same as -cooked, but also interprets Ctrl-B, Ctrl-V and Ctrl-_ with the
-IRC convention (toggles for bold, inverse, underlined, respectively).
-.TP
-.BR "-hold"
-Sets hold-mode.  In hold mode, 
-.B ssfe
-will stop after each screenful, and wait for the user to hit TAB.
-.TP
-.BR "-beep"
-In cooked or IRC mode, enables beeps.  When beeps are disabled, the
-character Ctrl-G is displayed as an inverse-video G.
-.TP
-.BR "-flow"
-Enables flow-control with ^S and ^Q.  
-.B ssfe
-normally disables those, but some terminals require them to operate properly.
-.TP
-.BR "-print"
-Enables printing of your own commands back in the scrolling area.
-.TP
-.BR "-prompt \fI<prompt>\fR"
-Sets a prompt for the user input line.  The default prompt is none, or
-``> '' if -print is specified.
-
-.SH ARGUMENTS
-.TP
-.BR "program [options]"
-Names the program that 
-.B ssfe
-should run.
-
-.SH KEYS
-.B ssfe 
-understands these keys (^ means Control):
-.TP
-.BR "^\e"
-Interrupt ssfe and whatever program it's running, and exit back to the unix
-prompt.
-.TP
-.BR "^a"
-Go to the beginning of the line.
-.TP
-.BR "^b, left arrow"
-Move left a letter.
-.TP
-.BR "^c"
-Interrupt: ignored by the front-end, can be used to interrupt connecting to a
-server, with sirc.
-.TP
-.BR "^d"
-Delete the character under the cursor.
-.TP
-.BR "^e"
-Go to the end of the line.
-.TP
-.BR "^f, right arrow"
-Move right a letter.
-.TP
-.BR "^h, DEL"
-Erase the previous character.
-.TP
-.BR "^i, TAB"
-Go to next /msg in msg history.
-.TP
-.BR "^j, ^m, Enter"
-.TP
-.BR "^k"
-Erase from the cursor to the end of the line.
-.TP
-.BR "^l"
-Redisplay the status bar and the command line.
-.TP
-.BR "^n, down arrow"
-Go to the next line in command-line history.
-.TP
-.BR "^o"
-With sirc, type the last msg you got on the command line
-.TP
-.BR "^p, up arrow"
-Go to the previous line in command-line history.
-.TP
-.BR "^t"
-With sirc, switch to the next channel you're on.
-.TP
-.BR "^u"
-Erase command-line.
-.TP 
-.BR "^v"
-Insert the next character literally, even if it's a ^something.
-.TP
-.BR "^x b"
-Toggle beep on or off (off by default).
-.TP
-.BR "^x c"
-Exit the front end, back to the unix prompt.
-.TP
-.BR "^x h"
-Toggle hold mode.
-.TP
-.BR "^x i"
-Toggle irc-mode (^b^v^_ handling) on and off.
-.TP
-.BR "^y"
-Yank the current line in the history without sending it.
-.TP
-.BR "^z"
-Suspend ssfe and sirc and go back to the unix prompt - you come back with 'fg'.
-
-.SH COPYING
-.B ssfe
-is free software. You can redistribute it and/or modify it under the GNU
-General Public License as published by the Free Software Foundation.  See
-the file LICENSE for details.
-
-.SH SEE ALSO
-.BR sirc (1)
-
-.SH ENVIRONMENT VARIABLES
-.TP
-.BR TERM 
-sets the terminal type.  The terminal needs to be able to set a scrolling
-zone for ssfe to work.
-
-.SH BUGS
-None known, please report to the author.
-
-.SH AUTHOR
-.B sirc
-was written by Roger Espel Llima <roger.espel.llima@pobox.com>. 
-
diff --git a/extras/ssfe.c b/extras/ssfe.c
deleted file mode 100644 (file)
index b37f1dc..0000000
+++ /dev/null
@@ -1,1314 +0,0 @@
-/* An ircII-like split-screen front end
-   Copyright (C) 1995 Roger Espel Llima
-
-   Started: 17 Feb 95 by orabidoo <roger.espel.llima@ens.fr>
-   Latest modification: 7 June 97
-
-   To compile: gcc ssfe.c -o ssfe -ltermcap
-
-   If it doesn't work, try gcc ssfe.c -o ssfe -lcurses
-   or try cc, acc or c89 instead of gcc, or -lncurses.
-
-   Use: ssfe [options] program arguments
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation. See the file LICENSE for details.
-*/
-
-#include <sys/time.h>
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <signal.h>
-#include <errno.h>
-
-#ifdef USE_SGTTY
-#include <sgtty.h>
-#else
-#include <termios.h>
-#endif
-
-#include <sys/ioctl.h>
-
-#ifdef _AIX
-#include <sys/select.h>
-#endif
-
-#define BUF_SIZE 512
-#define MAX_COLS 512
-
-unsigned char *statusline;
-int ystatus, yinput;     /* line number of the status line, input line */
-
-int ttyfd;
-#ifdef TIOCGWINSZ
-struct winsize wsz;
-#endif
-
-#ifdef USE_SGTTY
-struct sgttyb term, term0;
-struct tchars tch, tch0;
-struct ltchars lch, lch0;
-#else
-struct termios term, term0;
-#endif
-
-int pid, mypid;
-int i;
-int cols, lines;
-int readfd, writefd, errfd;
-
-unsigned char *t, *w;
-unsigned char tmpstr[BUF_SIZE], extrainput[BUF_SIZE+20], readbuf[2*BUF_SIZE],
-             *input, *writebuf, o_buffer[BUF_SIZE];
-int bold=0, inv=0, under=0, wherex=0, wherey=0, donl=0;
-int hold_mode=0, hold_lines=0, ctrlx=0, beep=0, flow=0;
-
-unsigned char defprompt[]="> ",
-        nullstring[]="",
-        *prompt;
-int plen=0, specialprompt=0, modified=1, no_echo=0;
-
-#define MAX_TAB_LINES 20
-struct tabinfo {
-  unsigned char string[BUF_SIZE];
-  struct tabinfo *prev, *next;
-};
-int tablines=0;
-struct tabinfo *curtabt=NULL, *curtabr=NULL, *oldest=NULL;
-
-#define MAX_HIST_LINES 50
-struct histinfo {
-  unsigned char string[BUF_SIZE+20];
-  int len, plen;
-  struct histinfo *prev, *next;
-};
-int histlines=0;
-struct histinfo *histcurrent=NULL, *histoldest=NULL;
-
-char ctrl_t[128] = "/next\n";
-
-unsigned char id[]="`#ssfe#", *inid=id, protcmd[BUF_SIZE], *wpc=protcmd;
-int idstatus=0;  /* 0 looking for/in the word, 1 in the arguments */
-#define ID_BACK "@ssfe@"
-
-int rc, rrc, inputcursor, inputlast, inputofs, inarrow=0, quote=0;
-int cursorwhere;     /* 0 = up, 1 = down, 2 = undef */
-int dispmode=1; /* 0=raw, 1=wordwrap, 2=process ^b^v^_ */
-int printmode=0;
-int cutline=0;
-
-char *termtype, termcap[1024], *tc, capabilities[2048];
-char *t_cm, *t_cl, *t_mr, *t_md, *t_me, *t_cs, *t_ce, *t_us;
-int ansi_cs = 0;
-
-fd_set ready, result;
-extern int errno;
-
-#ifdef __GNUC__
-extern unsigned char *tgoto(unsigned char *cm, int col, int line);
-#else
-extern unsigned char *tgoto();
-#endif
-
-#ifdef __GNUC__
-int myputchar(int c) {
-#else
-int myputchar(c) {
-#endif
-  unsigned char cc=(unsigned char)c;
-  return(write(1, &cc, 1));
-}
-
-#ifdef __GNUC__
-int addchar(int c) {
-#else
-int addchar(c) {
-#endif
-  (*w++)=(unsigned char)c;
-}
-
-#ifdef __GNUC__
-void putcap(unsigned char *s) {
-#else
-void putcap(s)
-unsigned char *s; {
-#endif
-  tputs(s, 0, myputchar);
-}
-
-#ifdef __GNUC__
-int do_cs(int y1, int y2) {
-#else
-int do_cs(y1, y2) {
-#endif
-  static char temp[16];
-  if (ansi_cs) {
-    sprintf(temp, "\e[%d;%dr", y1, y2);
-    write(1, temp, strlen(temp));
-  } else putcap((char *)tgoto(t_cs, y2-1, y1-1));
-}
-
-#ifdef __GNUC__
-void writecap(unsigned char *s) {
-#else
-void writecap(s)
-unsigned char *s; {
-#endif
-  tputs(s, 0, addchar);
-}
-
-#ifdef __GNUC__
-void gotoxy(int x, int y) {
-#else
-void gotoxy(x, y) {
-#endif
-/* left upper = 0, 0 */
-  putcap(tgoto(t_cm, x, y));
-}
-
-#define clearscreen() (putcap(t_cl))
-#define cleareol() (putcap(t_ce))
-#define fullscroll() (do_cs(0, 0))
-#define winscroll() (do_cs(1, lines-2))
-#define setbold() (putcap(t_md))
-#define setunder() (putcap(t_us))
-#define setinv() (putcap(t_mr))
-#define normal() (putcap(t_me))
-
-#ifdef __GNUC__
-void ofsredisplay(int x);
-void inschar(unsigned char t);
-void dokbdchar(unsigned char t);
-#else
-void ofsredisplay();
-void inschar();
-void dokbdchar();
-#endif
-void displaystatus();
-
-#ifdef __GNUC__
-void cleanupexit(int n, unsigned char *error) {
-#else
-void cleanupexit(n, error)
-int n;
-unsigned char *error; {
-#endif
-  normal();
-  fullscroll();
-  gotoxy(0, lines-1);
-  cleareol();
-#ifdef USE_SGTTY
-  ioctl(ttyfd, TIOCSETP, &term0);
-  ioctl(ttyfd, TIOCSETC, &tch0);
-  ioctl(ttyfd, TIOCSLTC, &lch0);
-#else
-  tcsetattr(ttyfd, TCSADRAIN, &term0);
-#endif
-  close(ttyfd);
-  if (error!=NULL)
-    fprintf(stderr, "%s\n", error);
-  exit(n);
-}
-
-void allsigs();
-
-void interrupted() {
-  cleanupexit(1, "interrupted");
-}
-
-void sigpipe() {
-  cleanupexit(1, "program died");
-}
-
-void sigcont() {
-  allsigs();
-#ifdef USE_SGTTY
-  ioctl(ttyfd, TIOCSETP, &term);
-  ioctl(ttyfd, TIOCSETC, &tch);
-  ioctl(ttyfd, TIOCSLTC, &lch);
-#else
-  tcsetattr(ttyfd, TCSANOW, &term);
-#endif
-  wherex=0;
-  wherey=ystatus-1;
-  displaystatus();
-  ofsredisplay(0);
-}
-
-void suspend() {
-  normal();
-  fullscroll();
-  gotoxy(0, ystatus);
-  cleareol();
-#ifdef USE_SGTTY
-  ioctl(ttyfd, TIOCSETP, &term0);
-  ioctl(ttyfd, TIOCSETC, &tch0);
-  ioctl(ttyfd, TIOCSLTC, &lch0);
-#else
-  tcsetattr(ttyfd, TCSANOW, &term0);
-#endif
-  kill(pid, SIGCONT);
-  signal(SIGTSTP, SIG_DFL);
-  signal(SIGCONT, sigcont);
-  kill(mypid, SIGTSTP);
-}
-
-void sigwinch() {
-#ifdef TIOCGWINSZ
-  signal(SIGWINCH, sigwinch);
-  if (ioctl(ttyfd, TIOCGWINSZ, &wsz)>=0 && wsz.ws_row>0 && wsz.ws_col>0) {
-    lines=wsz.ws_row;
-    cols=wsz.ws_col;
-    cursorwhere=2;
-    ystatus=lines-2;
-    yinput=lines-1;
-    wherex=0;
-    wherey=ystatus-1;
-    displaystatus();
-    if (inputlast>cols-8) {
-      inputcursor=cols-9;
-      inputofs=inputlast-cols+9;
-    } else {
-      inputofs=0;
-      inputcursor=inputlast;
-    }
-    ofsredisplay(0);
-  }
-#endif
-}
-
-void allsigs() {
-  signal(SIGHUP, interrupted);
-  signal(SIGINT, interrupted);
-  signal(SIGQUIT, SIG_IGN);
-  signal(SIGPIPE, sigpipe);
-  signal(SIGTSTP, suspend);
-  signal(SIGCONT, sigcont);
-#ifdef TIOCGWINSZ
-  signal(SIGWINCH, sigwinch);
-#endif
-}
-
-#ifdef __GNUC__
-void setstatus(unsigned char *title) {
-#else
-void setstatus(title)
-unsigned char *title; {
-#endif
-  unsigned char *t=title;
-  for (;*t;t++) if (*t<' ') (*t)+='@';
-  memset(statusline, ' ', MAX_COLS-1);
-  memcpy(statusline, title, strlen(title)<MAX_COLS ? strlen(title) : MAX_COLS);
-}
-
-void displaystatus() {
-  normal();
-  fullscroll();
-  gotoxy(0, ystatus);
-  setinv();
-  write(1, statusline, cols-1);
-  if (hold_mode) {
-    gotoxy(cols-4, ystatus);
-    write(1, "(h)", 3);
-  }
-  cursorwhere=2;
-  normal();
-  cleareol();
-}
-
-#ifdef __GNUC__
-int casecmp(unsigned char *s, unsigned char *t) {
-#else
-int casecmp(s, t)
-unsigned char *s, *t; {
-#endif
-  while (((*s>='a' && *s<='z')?(*s)-32:*s)==
-         ((*t>='a' && *t<='z')?(*t)-32:*t)) {
-    if (*s=='\0') return 1;
-    s++; t++;
-  }
-  return 0;
-}
-
-#ifdef __GNUC__
-void addtab(unsigned char *line) {
-#else
-void addtab(line)
-unsigned char *line; {
-#endif
-  struct tabinfo *nt;
-
-  nt=oldest;
-  if (tablines) do {
-    if (casecmp(nt->string, line)) {
-      strcpy(nt->string, line);
-      if (nt==oldest) oldest=nt->prev;
-      else {
-       nt->prev->next=nt->next;
-       nt->next->prev=nt->prev;
-       nt->prev=oldest;
-       nt->next=oldest->next;
-       oldest->next=nt;
-       nt->next->prev=nt;
-      }
-      curtabt=oldest->next;
-      curtabr=oldest;
-      return;
-    }
-    nt=nt->next;
-  } while (nt!=oldest);
-
-  if (!tablines) {
-    nt=(struct tabinfo *)malloc(sizeof (struct tabinfo));
-    nt->prev=nt->next=curtabt=curtabr=oldest=nt;
-    tablines++;
-  } else if (tablines<MAX_TAB_LINES) {
-    nt=(struct tabinfo *)malloc(sizeof (struct tabinfo));
-    nt->prev=oldest;
-    nt->next=oldest->next;
-    oldest->next=nt;
-    nt->next->prev=nt;
-    tablines++;
-  } else {
-    nt=oldest;
-    oldest=nt->prev;
-  }
-  strcpy(nt->string, line);
-  oldest=nt->prev;
-  curtabt=oldest->next;
-  curtabr=oldest;
-}
-
-void doprotcommand() {
-  unsigned char *tmp;
-
-  switch (protcmd[0]) {
-    case 'i' : dispmode=2;     /* set irc mode, ack */
-              bold=inv=under=0;
-              write(writefd, "@ssfe@i\n", 8);
-              break;
-    case 'c' : dispmode=1;     /* set cooked mode, ack */
-              write(writefd, "@ssfe@c\n", 8);
-              break;
-    case 's' : setstatus(protcmd+1); /* set status */
-              displaystatus();
-              break;
-    case 'T' : strncpy(ctrl_t, protcmd+1, 127); /* set ^t's text */
-              ctrl_t[126] = '\0';
-              strcat(ctrl_t, "\n");
-              break;
-    case 't' : addtab(protcmd+1); /* add tabkey entry */
-              break;
-    case 'l' : fullscroll(); /* clear screen */
-              normal();
-              clearscreen();
-              bold=inv=under=wherex=wherey=donl=0;
-              displaystatus();
-              ofsredisplay(0);
-              break;
-
-    case 'P' : no_echo = 1;                /* password prompt */
-    case 'p' : if (strlen(protcmd+1)<=8) {  /* prompt something */
-                fullscroll();
-                if (!specialprompt) {
-                  histcurrent->len=inputlast;
-                  histcurrent->plen=plen;
-                }
-                input=extrainput;
-                strcpy(input, protcmd+1);
-                plen=strlen(input);
-                inputofs=0;
-                modified=specialprompt=1;
-                inputlast=inputcursor=plen;
-                ofsredisplay(0);
-              }
-              break;
-    case 'n' : if (cursorwhere!=1) { /* type text */
-                normal();
-                fullscroll();
-                gotoxy(inputcursor, yinput);
-                cursorwhere=1;
-              }
-              for (tmp=protcmd+1; *tmp; tmp++) {
-                inschar(*tmp);
-              }
-              break;
-    case 'o' : strcpy(o_buffer, protcmd+1);
-              break;
-  }
-}
-
-void newline() {
-  unsigned char t;
-  hold_lines++;
-  if (hold_mode && hold_lines>lines-4) {
-    normal();
-    fullscroll();
-    gotoxy(cols-4, ystatus);
-    setinv();
-    write(1, "(H)", 3);
-    while(1) {
-      read(0, &t, 1);
-      if (t==9) break;
-      dokbdchar(t);
-    }
-    normal();
-    fullscroll();
-    gotoxy(cols-4, ystatus);
-    setinv();
-    write(1, "(h)", 3);
-    hold_lines=0;
-    normal();
-    winscroll();
-    gotoxy(cols-1, wherey);
-    if (bold) setbold();
-    if (under) setunder();
-    if (inv) setinv();
-  }
-}
-
-#ifdef __GNUC__
-void formatter(unsigned char *readbuf, int rc) {
-#else
-void formatter(readbuf, rc)
-unsigned char *readbuf;
-int rc; {
-#endif
-
-  unsigned char t, *r, *lwr, *lww;
-  int lwrc, lwbold, lwunder, lwinv, lwx;
-
-  if (cursorwhere!=0) {
-    winscroll();
-    gotoxy(wherex, wherey);
-    cursorwhere=0;
-  }
-  if (donl) {
-    newline();
-    write(1, "\r\n", 2);
-    normal();
-    wherex=0;
-    bold=inv=under=lwbold=lwinv=lwunder=0;
-    if (wherey<ystatus-1) wherey++;
-  } else if (dispmode>1) {
-    if (bold) setbold();
-    if (under) setunder();
-    if (inv) setinv();
-    lwbold=bold;
-    lwinv=inv;
-    lwunder=under;
-  }
-  if (rc && readbuf[rc-1]=='\n') {
-    rc--;
-    donl=1; cutline=0;
-  } else {
-    donl=0;
-    if (dispmode==0) cutline=1;
-  }
-  if (dispmode==0) {
-    if (rc) write(1, readbuf, rc);
-    normal();
-    return;
-  }
-  lww=w=writebuf;
-  lwr=r=readbuf;
-  lwrc=rc;
-  lwx=wherex;
-  while(rc-->0) {
-    t=(*r++);
-    if (t=='\r') continue;
-    if (wherex>cols-2 || (t==9 && wherex>(cols-2)&0xfff8)) {
-      if (t==' ' || t==9) ;
-      else if (lww>writebuf+cols/2) {
-       wherex=lwx; r=lwr; w=lww; rc=lwrc;
-       bold=lwbold; inv=lwinv; under=lwunder; wherex=lwx;
-      } else {
-       rc++; r--;
-      }
-      write(1, writebuf, w-writebuf);
-      newline();
-      write(1, "\r\n           ", 13);
-      w=writebuf;
-      lwr=r; lww=w; lwrc=rc;
-      lwbold=bold; lwinv=inv; lwunder=under;
-      lwx=wherex=11;
-      if (wherey<ystatus-1) wherey++;
-      rc--; t=(*r++);
-    }
-    if (t=='\n') {
-      if (w!=writebuf) write(1, writebuf, w-writebuf);
-      newline();
-      write(1, "\r\n", 2);
-      normal();
-      w=writebuf;
-      lwr=r; lww=w; lwrc=rc;
-      lwbold=bold=lwinv=inv=lwunder=under=lwx=wherex=0;
-      if (wherey<ystatus-1) wherey++;
-    } else if (dispmode>1 &&
-               ((t==2 && bold) || (t==22 && inv) || (t==31 && under))) {
-      writecap(t_me);
-      bold=under=inv=0;
-    } else if (dispmode>1 && t==2) {
-      writecap(t_md);
-      bold=1;
-    } else if (dispmode>1 && t==22) {
-      writecap(t_mr);
-      inv=1;
-    } else if (dispmode>1 && t==31) {
-      writecap(t_us);
-      under=1;
-    } else if (dispmode>1 && t==15) {
-      if (bold || inv || under) writecap(t_me);
-      bold=under=inv=0;
-    } else if (t==9) {
-      (*w++)=t;
-      wherex=(wherex & 0xfff8)+8;
-    } else if (t<' ' && (t!=7 || !beep)) {
-      wherex++;
-      if (inv) {
-       writecap(t_me);
-       (*w++)=(t+'@');
-      } else {
-       writecap(t_mr);
-       (*w++)=(t+'@');
-       writecap(t_me);
-      }
-      if (bold) writecap(t_md);
-      if (inv) writecap(t_mr);
-      if (under) writecap(t_us);
-    } else {
-      if (t!=7) wherex++;
-      (*w++)=t;
-    }
-    if (t==' ' || t==9) {
-      lwr=r; lww=w; lwrc=rc;
-      lwbold=bold; lwinv=inv; lwunder=under;
-      lwx=wherex;
-    }
-  }
-  if (w!=writebuf) write(1, writebuf, w-writebuf);
-}
-
-#ifdef __GNUC__
-void doprogramline(unsigned char *readbuf, int rc) {
-#else
-void doprogramline(readbuf, rc)
-unsigned char *readbuf;
-int rc; {
-#endif
-
-  unsigned char *w, *r, *r2, t;
-  if (dispmode==0) {
-    formatter(readbuf, rc);
-    return;
-  }
-  w=r=readbuf;
-  while(rc-->0) {
-    t=(*r++);
-    if (idstatus==0)
-      if (*inid=='\0') {
-       idstatus=1;
-       wpc=protcmd;
-       inid=id;
-      } else if (*inid==t && (inid!=id || r==(readbuf+1) || *(r-2)=='\n')) {
-       inid++;
-       (*wpc++)=t;
-      } else {
-        r2=protcmd;
-        while (r2!=wpc) (*w++)=(*r2++);
-       (*w++)=t;
-       wpc=protcmd;
-       inid=id;
-      }
-    if (idstatus==1)
-      if (t=='\n')  {
-        *wpc='\0';
-        doprotcommand();
-       inid=id;
-       wpc=protcmd;
-       idstatus=0;
-      } else (*wpc++)=t;
-  }
-  if (w!=readbuf) formatter(readbuf, w-readbuf);
-}
-
-#ifdef __GNUC__
-void write1(unsigned char t, int pos) {
-#else
-void write1(t, pos)
-unsigned char t;
-int pos; {
-#endif
-  if (no_echo && pos>=plen) {
-    write(1, "*", 1);
-  } else if (t>=' ')
-      write(1, &t, 1);
-  else {
-      setinv();
-      t+='@';
-      write(1, &t, 1);
-      normal();
-  }
-}
-
-#ifdef __GNUC__
-void ofsredisplay(int x) {
-#else
-void ofsredisplay(x) {
-#endif
-/* redisplays starting at x */
-  unsigned char *w;
-  int i;
-  gotoxy(x, yinput);
-  if (inputlast-inputofs>=x) {
-    i=((inputlast-inputofs>cols-1 ? cols-1-x : inputlast-inputofs-x));
-    for (w=input+inputofs+x; i--; w++) write1(*w, w-input);
-  }
-  cleareol();
-  gotoxy(inputcursor, yinput);
-  cursorwhere=1;
-}
-
-#ifdef __GNUC__
-void delempty(struct histinfo *leavealone) {
-#else
-void delempty(leavealone)
-struct histinfo *leavealone; {
-#endif
-  struct histinfo *h, *h2;
-  int cont=0;
-  h=histoldest;
-  do {
-    cont=0;
-    if ((h->len<=h->plen) && (h!=leavealone)) {
-      histlines--;
-      h->next->prev=h->prev;
-      h->prev->next=h->next;
-      h2=h->prev;
-      free(h);
-      if (h==histoldest) {
-        histoldest=h2;
-       cont=1;
-      }
-      h=h2;
-    } else h=h->prev;
-  } while ((h!=histoldest || cont) && histlines>0);
-  if (!histlines) {
-    histoldest=NULL;
-    return;
-  }
-}
-
-struct histinfo *makenew() {
-  struct histinfo *nh;
-  if (!histlines) {
-    nh=(struct histinfo *)malloc(sizeof (struct histinfo));
-    nh->prev=nh->next=histoldest=nh;
-    histlines++;
-  } else if (histlines<MAX_HIST_LINES) {
-    nh=(struct histinfo *)malloc(sizeof (struct histinfo));
-    nh->prev=histoldest;
-    nh->next=histoldest->next;
-    histoldest->next=nh;
-    nh->next->prev=nh;
-    histlines++;
-  } else {
-    nh=histoldest;
-    histoldest=nh->prev;
-  }
-  return nh;
-}
-
-#ifdef __GNUC__
-void sendline(int yank) {
-#else
-void sendline(yank) {
-#endif
-  if (!specialprompt) {
-    histcurrent->len=inputlast;
-    histcurrent->plen=plen;
-  }
-  if (!yank) {
-    input[inputlast]='\n';
-    if (printmode) formatter(input, inputlast+1);
-    if (write(writefd, input+plen, inputlast+1-plen)<inputlast+1-plen)
-      cleanupexit(1, "write error");
-  }
-  input[inputlast]='\0';
-  delempty(NULL);
-  histcurrent=makenew();
-  input=histcurrent->string;
-  strcpy(input, prompt);
-  plen=strlen(prompt);
-  inputofs=specialprompt=0;
-  modified=1;
-  inputcursor=inputlast=plen;
-  ofsredisplay(0);
-  no_echo=0;
-}
-
-void modify() {
-  struct histinfo *h;
-  if (!modified) {
-    if (inputlast>plen) {
-      h=histcurrent;
-      delempty(h);
-      histcurrent=makenew();
-      strcpy(histcurrent->string, h->string);
-      input=histcurrent->string;
-    }
-    modified=1;
-  }
-}
-
-void fixpos() {
-  if (inputcursor<8 && inputofs>0) {
-    inputofs-=cols-16;
-    inputcursor+=cols-16;
-    if (inputofs<0) {
-      inputcursor+=inputofs;
-      inputofs=0;
-    }
-    ofsredisplay(0);
-  } else if (inputcursor>cols-8) {
-    inputofs+=cols-16;
-    inputcursor-=cols-16;
-    ofsredisplay(0);
-  }
-}
-
-void reshow() {
-  if (inputlast>cols-8) {
-    inputcursor=cols-9;
-    inputofs=inputlast-cols+9;
-  } else {
-    inputofs=0;
-    inputcursor=inputlast;
-  }
-  ofsredisplay(0);
-}
-
-#ifdef __GNUC__
-void inschar(unsigned char t) {
-#else
-void inschar(t)
-unsigned char t; {
-#endif
-
-  unsigned char *tmp;
-
-  if (inputlast<BUF_SIZE-4) {
-    modify();
-    if (inputofs+inputcursor==inputlast) {
-      write1(t, inputlast);
-      input[inputlast++]=t;
-      input[inputlast]='\0';
-      inputcursor++;
-    } else {
-      tmp=input+inputlast;
-      while (tmp>=input+inputofs+inputcursor)
-       *(tmp+1)=(*tmp--);
-      input[inputofs+(inputcursor++)]=t;
-      inputlast++;
-      ofsredisplay(inputcursor-1);
-    }
-    fixpos();
-  }
-}
-
-#ifdef __GNUC__
-void dokbdchar(unsigned char t) {
-#else
-void dokbdchar(t)
-unsigned char t; {
-#endif
-
-  unsigned char *tmp;
-
-  if (inarrow==1) {
-    if (t=='[' || t=='O') {
-      inarrow++;
-      return;
-    }
-    inarrow=0;
-  } else if (inarrow==2) {
-    inarrow=0;
-    if (t=='D') t=2;
-    else if (t=='C') t=6;
-    else if (t=='A') t=16;
-    else if (t=='B') t=14;
-    else return;
-  }
-  if (ctrlx && !quote) {
-    ctrlx=0;
-    t|=0x20;
-    if (dispmode>0 && ((t=='h' && !hold_mode) || t=='y')) {
-      hold_mode=1;
-      hold_lines=0;
-      if (cursorwhere!=1) fullscroll();
-      cursorwhere=2;
-      normal();
-      gotoxy(cols-4, ystatus);
-      setinv();
-      write(1, "(h)", 3);
-      normal();
-    } else if (dispmode>0 && ((t=='h' && hold_mode) || t=='n')) {
-      hold_mode=0;
-      if (cursorwhere!=1) fullscroll();
-      cursorwhere=2;
-      normal();
-      gotoxy(cols-4, ystatus);
-      setinv();
-      write(1, "   ", 3);
-      normal();
-    } else if (dispmode>0 && t=='i') {
-      dispmode=3-dispmode;
-      bold=inv=under=0;
-    } else if (dispmode>0 && t=='b') {
-      beep=!beep;
-    } else if (t=='c') cleanupexit(1, "exiting");
-    return;
-  }
-  if (cutline) donl=1;
-  if (cursorwhere!=1) {
-    normal();
-    fullscroll();
-    gotoxy(inputcursor, yinput);
-    cursorwhere=1;
-  }
-  if (t==24 && !quote) {
-    ctrlx=1;
-    return;
-  } else ctrlx=0;
-  if (t==27 && !quote) {
-    inarrow=1;
-  } else if ((t==10 || t==13) && !quote) {  /* return, newline */
-    sendline(0);
-    if (tablines) {
-      curtabr=oldest;
-      curtabt=oldest->next;
-    }
-  } else if (t==25 && !quote) {          /* ^y */
-    if (!specialprompt) {
-      sendline(1);
-      if (tablines) {
-       curtabr=oldest;
-       curtabt=oldest->next;
-      }
-    }
-  } else if (t==21 && !quote) {   /* ^u */
-    modify();
-    input[plen]='\0';
-    inputcursor=inputlast=plen;
-    inputofs=0;
-    ofsredisplay(0);
-  } else if ((t==8 || t==0x7f) && !quote) {  /* ^h, ^? */
-    if (inputcursor>plen) {
-      modify();
-      tmp=input+inputcursor+inputofs;
-      while (tmp<input+inputlast)
-       *(tmp-1)=(*tmp++);
-      input[--inputlast]='\0';
-      gotoxy(--inputcursor, yinput);
-      ofsredisplay(inputcursor);
-      fixpos();
-    }
-  } else if (t==4 && !quote) {  /* ^d */
-    if (inputcursor+inputofs<inputlast) {
-      modify();
-      tmp=input+inputcursor+inputofs+1;
-      while (tmp<input+inputlast)
-       *(tmp-1)=(*tmp++);
-      input[--inputlast]='\0';
-      gotoxy(inputcursor, yinput);
-      ofsredisplay(inputcursor);
-    }
-  } else if (t==11 && !quote) {  /* ^k */
-    if (inputcursor+inputofs<inputlast) {
-      modify();
-      input[inputlast=inputofs+inputcursor]='\0';
-      ofsredisplay(inputcursor);
-    }
-  } else if (t==2 && !quote) {  /* ^b */
-    if (inputcursor>0 && (inputcursor>plen || inputofs>0)) {
-      gotoxy(--inputcursor, yinput);
-      fixpos();
-    }
-  } else if (t==6 && !quote) {  /* ^f */
-    if (inputcursor+inputofs<inputlast) {
-      gotoxy(++inputcursor, yinput);
-      fixpos();
-    }
-  } else if (t==1 && !quote) { /* ^a */
-    if (inputcursor+inputofs>plen) {
-      if (inputofs==0)
-       gotoxy((inputcursor=plen), yinput);
-      else {
-       inputofs=0;
-       inputcursor=plen;
-       ofsredisplay(0);
-      }
-    }
-  } else if (t==5 && !quote) { /* ^e */
-    if (inputcursor+inputofs<inputlast) {
-      if (inputlast-inputofs<cols-3) {
-       gotoxy((inputcursor=inputlast-inputofs), yinput);
-      } else if (inputlast>cols-8) {
-       inputcursor=cols-9;
-       inputofs=inputlast-cols+9;
-       ofsredisplay(0);
-      } else {
-       inputofs=0;
-       inputcursor=inputlast;
-       ofsredisplay(0);
-      }
-    }
-  } else if (t==12 && !quote) { /* ^l */
-    displaystatus();
-    ofsredisplay(0);
-  } else if (t==9 && !quote) { /* TAB */
-    if (tablines) {
-      modify();
-      strcpy(input+plen, curtabt->string);
-      curtabr=curtabt->prev;
-      curtabt=curtabt->next;
-      inputlast=strlen(input);
-      reshow();
-    }
-  } else if (t==18 && !quote) { /* ^r */
-    if (tablines) {
-      modify();
-      strcpy(input+plen, curtabr->string);
-      curtabt=curtabr->next;
-      curtabr=curtabr->prev;
-      inputlast=strlen(input);
-      reshow();
-    }
-  } else if (t==16 && !quote) { /* ^p */
-    if (histlines>1 && !specialprompt) {
-      histcurrent->plen=plen;
-      histcurrent->len=inputlast;
-      histcurrent=histcurrent->next;
-      plen=histcurrent->plen;
-      inputlast=histcurrent->len;
-      input=histcurrent->string;
-      modified=0;
-      reshow();
-    }
-  } else if (t==14 && !quote) { /* ^n */
-    if (histlines>1 && !specialprompt) {
-      histcurrent->plen=plen;
-      histcurrent->len=inputlast;
-      histcurrent=histcurrent->prev;
-      plen=histcurrent->plen;
-      inputlast=histcurrent->len;
-      input=histcurrent->string;
-      modified=0;
-      reshow();
-    }
-  } else if (t==15 &&!quote) { /* ^o */
-    if (strlen(o_buffer)) modify();
-    for (tmp=o_buffer; *tmp; tmp++) inschar(*tmp);
-  } else if (t==20 && !quote) { /* ^t */
-    write(writefd, ctrl_t, strlen(ctrl_t));
-  } else if (t==22 && !quote) { /* ^v */
-    quote++;
-    return;
-#ifdef CONTROL_W
-  } else if (t==23 && !quote) { /* ^w */
-    fullscroll();
-    normal();
-    clearscreen();
-    bold=inv=under=wherex=wherey=donl=0;
-    displaystatus();
-    ofsredisplay(0);
-#endif
-  } else inschar(t);
-  quote=0;
-}
-
-#ifdef __GNUC__
-void barf(unsigned char *m) {
-#else
-void barf(m)
-unsigned char *m; {
-#endif
-  fprintf(stderr, "%s\n", m);
-  exit(1);
-}
-
-char *myname;
-
-void use() {
-  fprintf(stderr, "Use: %s [options] program [program's options]\n", myname);
-  fprintf(stderr, "Options are:\n");
-  fprintf(stderr, "   -raw, -cooked, -irc  : set display mode\n");
-  fprintf(stderr, "   -print               : print your input lines\n");
-  fprintf(stderr, "   -prompt <prompt>     : specify a command-line prompt\n");
-  fprintf(stderr, "   -hold                : pause after each full screen (for cooked/irc mode)\n");
-  fprintf(stderr, "   -beep                : let beeps through (for cooked/irc mode)\n");
-  fprintf(stderr, "   -flow                : leave ^S/^Q alone for flow control\n");
-  exit(1);
-}
-
-#ifdef __GNUC__
-int main(int argc, char *argv[]) {
-#else
-int main(argc, argv)
-int argc;
-char *argv[]; {
-#endif
-
-  char *vr;
-  int pfds0[2], pfds1[2], pfds2[2];
-
-  myname=(*argv);
-  prompt=nullstring;
-  while (argc>1) {
-    if (strcmp(argv[1], "-raw")==0) {
-      dispmode=0;
-      argv++; argc--;
-    } else if (strcmp(argv[1], "-cooked")==0) {
-      dispmode=1;
-      argv++; argc--;
-    } else if (strcmp(argv[1], "-irc")==0) {
-      dispmode=2;
-      argv++; argc--;
-    } else if (strcmp(argv[1], "-hold")==0) {
-      hold_mode=1;
-      argv++; argc--;
-    } else if (strcmp(argv[1], "-print")==0) {
-      argv++; argc--;
-      if (prompt==nullstring) prompt=defprompt;
-      printmode=1;
-    } else if (strcmp(argv[1], "-beep")==0) {
-      beep=1;
-      argv++; argc--;
-    } else if (strcmp(argv[1], "-flow")==0) {
-      flow=1;
-      argv++; argc--;
-    } else if (strcmp(argv[1], "-prompt")==0) {
-      if (argc>2) prompt=(unsigned char *)argv[2];
-      if (strlen(prompt)>8) barf("Prompt too long");
-      argv+=2; argc-=2;
-    } else break;
-  }
-  if (argc<2) use();
-  if (!isatty(0)) barf("I can only run on a tty, sorry");
-  if ((termtype=getenv("TERM"))==NULL) barf("No terminal type set");
-  if (tgetent(termcap, termtype)<1) barf("No termcap info for your terminal");
-  tc=capabilities;
-  if ((t_cm=(char *)tgetstr("cm", &tc))==NULL)
-    barf("Can't find a way to move the cursor around with your terminal");
-  if ((t_cl=(char *)tgetstr("cl", &tc))==NULL)
-    barf("Can't find a way to clear the screen with your terminal");
-  if ((t_ce=(char *)tgetstr("ce", &tc))==NULL)
-    barf("Can't find a way to clear to end of line with your terminal");
-  if ((t_cs=(char *)tgetstr("cs", &tc))==NULL) {
-    if (strncmp(termtype, "xterm", 5)==0 || strncmp(termtype, "vt100", 5)==0)
-      ansi_cs=1;
-    else
-      barf("Can't find a way to set the scrolling region with your terminal");
-  }
-  if ((t_me=(char *)tgetstr("me", &tc))!=NULL) {
-    if ((t_mr=(char *)tgetstr("mr", &tc))==NULL) t_mr=t_me;
-    if ((t_md=(char *)tgetstr("md", &tc))==NULL) t_md=t_me;
-    if ((t_us=(char *)tgetstr("us", &tc))==NULL) t_us=t_me;
-  } else if ((t_me=(char *)tgetstr("se", &tc))!=NULL &&
-            (t_mr=(char *)tgetstr("so", &tc))!=NULL) {
-    t_md=t_mr;
-    t_us=tc;
-    (*tc++)='\0';
-  } else {
-    t_me=t_md=t_mr=t_us=tc;
-    (*tc++)='\0';
-  }
-
-/*
-  if ((ttyfd=open("/dev/tty", O_RDWR))<0 &&
-      (ttyfd=open("/dev/tty", O_RDONLY))<0) barf("Can't open terminal!");
-    */
-    ttyfd = 0;
-
-#ifdef TIOCGWINSZ
-  if (ioctl(ttyfd, TIOCGWINSZ, &wsz)<0 || wsz.ws_row<1 || wsz.ws_col<1) {
-#endif
-    lines=((vr=getenv("LINES"))?atoi(vr):0);
-    cols=((vr=getenv("COLUMNS"))?atoi(vr):0);
-    if (lines<1 || cols<1) {
-      if ((lines=tgetnum("li"))<1 || (cols=tgetnum("co"))<1) {
-       lines=24; cols=80;
-      }
-    }
-#ifdef TIOCGWINSZ
-  } else {
-    lines=wsz.ws_row;
-    cols=wsz.ws_col;
-  }
-#endif
-
-  if (pipe(pfds0)<0 || pipe(pfds1)<0 || pipe(pfds2)<0) {
-    perror("pipe");
-    exit(1);
-  }
-  mypid=getpid();
-  switch (pid=fork()) {
-    case -1:
-      perror("fork");
-      exit(1);
-    case 0:
-      if (pfds0[0]!=0) dup2(pfds0[0], 0);
-      if (pfds1[1]!=1) dup2(pfds1[1], 1);
-      if (pfds2[1]!=2) dup2(pfds2[1], 2);
-      if (pfds0[0]>2) close(pfds0[0]);
-      if (pfds0[1]>2) close(pfds0[1]);
-      if (pfds1[0]>2) close(pfds1[0]);
-      if (pfds1[1]>2) close(pfds1[1]);
-      if (pfds2[0]>2) close(pfds2[0]);
-      if (pfds2[1]>2) close(pfds2[1]);
-      /* okay we can read from 0 and write to 1 and 2, now.. it seems */
-      execvp(argv[1], argv+1);
-      perror("exec");
-      sleep(1);
-      exit(1);
-    default:
-      close(pfds0[0]);
-      close(pfds1[1]);
-      close(pfds2[1]);
-      readfd=pfds1[0];
-      writefd=pfds0[1];
-      errfd=pfds2[0];
-  }
-
-#ifdef USE_SGTTY
-
-  if (ioctl(ttyfd, TIOCGETP, &term)<0 || ioctl(ttyfd, TIOCGETC, &tch)<0 ||
-      ioctl(ttyfd, TIOCGLTC, &lch)<0) {
-    perror("sgtty get ioctl");
-    exit(1);
-  }
-  term0=term;
-  tch0=tch;
-  lch0=lch;
-  term.sg_flags|=CBREAK;
-  term.sg_flags&= ~ECHO & ~CRMOD;
-
-  memset(&tch, -1, sizeof(tch));
-  memset(&lch, -1, sizeof(lch));
-  tch.t_intrc=(char)28;
-  tch.t_quitc=(char)3;
-  if (flow) {
-    tch.t_startc=(char)17;
-    tch.t_stopc=(char)19;
-  }
-  lch.t_suspc=(char)26;
-
-  if (ioctl(ttyfd, TIOCSETP, &term)<0 || ioctl(ttyfd, TIOCSETC, &tch)<0 ||
-      ioctl(ttyfd, TIOCSLTC, &lch)<0) {
-    perror("sgtty set ioctl");
-    exit(1);
-  }
-
-#else
-  if (tcgetattr(ttyfd, &term)<0) {
-    perror("tcgetattr");
-    exit(1);
-  }
-  term0=term;
-
-  term.c_lflag &= ~ECHO & ~ICANON;
-  term.c_cc[VTIME]=(char)0;
-  term.c_cc[VMIN]=(char)1;
-  if (!flow) {
-    term.c_cc[VSTOP]=(char)0;
-    term.c_cc[VSTART]=(char)0;
-  }
-  term.c_cc[VQUIT]=(char)3;
-  term.c_cc[VINTR]=(char)28; /* reverse ^c and ^\ */
-  term.c_cc[VSUSP]=(char)26;
-#ifdef VREPRINT
-  term.c_cc[VREPRINT]=(char)0;
-#endif
-#ifdef VDISCARD
-  term.c_cc[VDISCARD]=(char)0;
-#endif
-#ifdef VLNEXT
-  term.c_cc[VLNEXT]=(char)0;
-#endif
-#ifdef VDSUSP
-  term.c_cc[VDSUSP]=(char)0;
-#endif
-
-  if (tcsetattr(ttyfd, TCSANOW, &term)<0) {
-    perror("tcsetattr");
-    exit(1);
-  }
-#endif
-
-  allsigs();
-
-  ystatus=lines-2;
-  yinput=lines-1;
-
-  if (lines>255) barf("Screen too big");
-  if (ystatus<=2 || cols<20) barf("Screen too small");
-
-  statusline=(unsigned char *)malloc(MAX_COLS);
-  writebuf=(unsigned char *)malloc(20*BUF_SIZE);
-  strcpy(tmpstr, " ");
-  for (i=1; i<argc; i++)
-    if (strlen(tmpstr)+strlen(argv[i])<cols-1) {
-      strcat(tmpstr, argv[i]);
-      strcat(tmpstr, " ");
-    }
-  setstatus(tmpstr);
-
-  if (dispmode==0) wherey=ystatus-1;
-  clearscreen();
-  displaystatus();
-
-  histoldest=histcurrent=(struct histinfo *)malloc(sizeof (struct histinfo));
-  input=histcurrent->string;
-  histcurrent->prev=histcurrent->next=histcurrent;
-  histlines=1;
-  plen=strlen(prompt);
-  inputlast=inputcursor=plen;
-  strcpy(input, prompt);
-  ofsredisplay(0);
-  *protcmd='\0';
-  *o_buffer='\0';
-  cursorwhere=1;
-
-  FD_ZERO(&ready);
-  FD_SET(ttyfd, &ready);
-  FD_SET(readfd, &ready);
-  FD_SET(errfd, &ready);
-
-  while(1) {
-    result=ready;
-    if (select(64, &result, NULL, NULL, NULL)<=0)
-      if (errno==EINTR) continue;
-      else cleanupexit(1, "select error");
-
-    if (FD_ISSET(readfd, &result))
-      if ((rc=read(readfd, readbuf, BUF_SIZE))>0)
-        doprogramline(readbuf, rc);
-      else
-        cleanupexit(1, "program terminated");
-    if (FD_ISSET(errfd, &result))
-      if ((rc=read(errfd, readbuf, BUF_SIZE))>0)
-        doprogramline(readbuf, rc);
-      else
-        cleanupexit(1, "program terminated");
-    if (FD_ISSET(ttyfd, &result))
-      if ((rrc=read(0, readbuf, BUF_SIZE))>0)
-        for (t=readbuf; rrc>0; rrc--) dokbdchar(*(t++));
-      else
-       cleanupexit(1, "read error from keyboard");
-  }
-}
-
index 7b3e6c3..525d64a 100644 (file)
@@ -4,3 +4,15 @@ Odd sort of behavior... when dumping \%:: with Data::Dumper in Stem/Conf.pm
 the program just "freezes"...
 
 
+
+# A simple script to (naievely) figure out the non-core dependencies in Stem:
+# this for example, looks for anything not core in perl 5.008001
+
+egrep -hR '^use ' ./lib/ | 
+  sed 's/[^a-zA-Z0-9_: ]//' | 
+  egrep -v 'use (Stem|[0-9]+)' | 
+  sort -u | 
+  cut -d ' ' -f 2 | 
+  perl -MModule::CoreList -M5.010 \
+    -ne 'chomp; say unless exists $Module::CoreList::version{"5.008001"}{$_}'
+
diff --git a/srs_notes.txt b/srs_notes.txt
deleted file mode 100644 (file)
index 7b3e6c3..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-Odd sort of behavior... when dumping \%:: with Data::Dumper in Stem/Conf.pm
-(insert a print @ line 234)
-
-the program just "freezes"...
-
-