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 ) ;
+++ /dev/null
-/* 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");
- }
-}
-