v23i066: Complete reposting of TRN at patchlevel 1, Part07/14
Rich Salz
rsalz at bbn.com
Fri Jan 4 04:54:17 AEST 1991
Submitted-by: Wayne Davison <0004475895 at mcimail.com>
Posting-number: Volume 23, Issue 66
Archive-name: trn/part07
#! /bin/sh
# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix at uunet.uu.net if you want that tool.
# Contents: art.c init.c term.c
# Wrapped by rsalz at litchi.bbn.com on Thu Dec 27 11:34:06 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 7 (of 14)."'
if test -f 'art.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'art.c'\"
else
echo shar: Extracting \"'art.c'\" \(25145 characters\)
sed "s/^X//" >'art.c' <<'END_OF_FILE'
X/* $Header: art.c,v 4.3.3.2 90/08/20 16:05:33 davison Trn $
X *
X * $Log: art.c,v $
X * Revision 4.3.3.2 90/08/20 16:05:33 davison
X * Fixed bug in backpage code.
X *
X * Revision 4.3.3.1 90/06/20 22:35:51 davison
X * Initial Trn Release
X *
X * Revision 4.3.2.3 90/04/21 14:43:27 sob
X * Revised previous patch insure that it does not decrement below zero.
X *
X * Revision 4.3.2.2 90/03/22 23:03:25 sob
X * Fixes provided by Wayne Davison <drivax!davison>
X *
X * Revision 4.3.2.1 89/11/07 23:20:57 sob
X * Bug fixes for NNTP
X *
X * Revision 4.3.1.5 85/09/10 11:07:18 lwall
X * %m not restored on some returns.
X *
X * Revision 4.3.1.4 85/05/23 12:13:31 lwall
X * shouldn't display article that's really a subdirectory.
X *
X * Revision 4.3.1.3 85/05/13 09:29:55 lwall
X * Added CUSTOMLINES option.
X *
X * Revision 4.3.1.2 85/05/10 13:46:07 lwall
X * Fixed header reparse bug on backpage.
X *
X * Revision 4.3.1.1 85/05/10 11:30:56 lwall
X * Branch for patches.
X *
X * Revision 4.3 85/05/01 11:34:51 lwall
X * Baseline for release with 4.3bsd.
X *
X */
X
X#include "EXTERN.h"
X#include "common.h"
X#include "rn.h"
X#include "ngstuff.h"
X#include "ngdata.h"
X#include "head.h"
X#include "cheat.h"
X#include "help.h"
X#include "search.h"
X#include "artio.h"
X#include "ng.h"
X#include "bits.h"
X#include "final.h"
X#include "artstate.h"
X#include "rcstuff.h"
X#include "term.h"
X#include "sw.h"
X#include "util.h"
X#include "backpage.h"
X#include "intrp.h"
X#ifdef USETHREADS
X#include "rthreads.h"
X#endif
X#include "INTERN.h"
X#include "art.h"
X
X/* page_switch() return values */
X
X#define PS_NORM 0
X#define PS_ASK 1
X#define PS_RAISE 2
X#define PS_TOEND 3
X
Xbool special = FALSE; /* is next page special length? */
Xint slines = 0; /* how long to make page when special */
XART_LINE highlight = -1; /* next line to be highlighted */
Xchar *restart = Nullch; /* if nonzero, the place where last */
X /* line left off on line split */
Xchar *blinebeg; /* where in buffer current line began */
XART_POS alinebeg; /* where in file current line began */
X
X#ifdef INNERSEARCH
XART_POS innersearch = 0; /* artpos of end of line we found */
X /* for 'g' command */
XART_LINE isrchline = 0; /* last line to display */
Xbool hide_everything = FALSE;
X /* if set, do not write page now, */
X /* but refresh when done with page */
XCOMPEX gcompex; /* in article search pattern */
X#endif
X
Xbool firstpage; /* is this the 1st page of article? */
X
Xchar art_buf[LBUFLEN]; /* place for article lines */
X
Xvoid
Xart_init()
X{
X ;
X}
X
Xint
Xdo_article()
X{
X register char *s;
X ART_POS artsize; /* size in bytes of article */
X bool hide_this_line = FALSE; /* hidden header line? */
X ART_LINE linenum; /* line # on page, 1 origin */
X#ifdef ULSMARTS
X bool under_lining = FALSE;
X /* are we underlining a word? */
X#endif
X register char *bufptr = art_buf;
X /* pointer to input buffer */
X register int outpos; /* column position of output */
X static char prompt_buf[64]; /* place to hold prompt */
X bool notesfiles = FALSE; /* might there be notesfiles junk? */
X char oldmode = mode;
X
X#ifdef INNERSEARCH
X register int outputok;
X#endif
X
X if (fstat(artfp->_file,&filestat))
X /* get article file stats */
X return DA_CLEAN;
X if ((filestat.st_mode & S_IFMT) != S_IFREG)
X return DA_NORM;
X artsize = filestat.st_size;
X /* from that get article size */
X sprintf(prompt_buf,
X "%%sEnd of article %ld (of %ld)--what next? [%%s]",
X (long)art,(long)lastart); /* format prompt string */
X prompt = prompt_buf;
X int_count = 0; /* interrupt count is 0 */
X firstpage = (topline < 0);
X for (;;) { /* for each page */
X#ifdef USETHREADS
X if (max_tree_lines)
X init_tree(); /* init tree display */
X#endif
X assert(art == openart);
X if (do_fseek) {
X#ifdef ASYNC_PARSE
X parse_maybe(art); /* make sure header is ours */
X#endif
X artpos = vrdary(artline);
X if (artpos < 0)
X artpos = -artpos; /* labs(), anyone? */
X if (firstpage)
X artpos = (ART_POS)0;
X fseek(artfp,artpos,0);
X if (artpos < htype[PAST_HEADER].ht_minpos)
X in_header = SOME_LINE;
X do_fseek = FALSE;
X restart = Nullch;
X }
X linenum = 1;
X if (firstpage) {
X if (firstline) {
X interp(art_buf, (sizeof art_buf), firstline);
X#ifdef USETHREADS
X linenum += tree_puts(art_buf,linenum+topline,0);
X#else
X#ifdef CLEAREOL
X maybe_eol();
X#endif /* CLEAREOL */
X fputs(art_buf,stdout) FLUSH;
X linenum++;
X#endif
X artopen(art); /* rewind article in case interp */
X /* forced a header parse */
X }
X else {
X ART_NUM i;
X
X#ifdef USETHREADS
X if (ThreadedGroup) {
X int sel, unseen;
X
X sel = curr_p_art && (selected_roots[curr_p_art->root] & 1);
X unseen = !was_read(art);
X sprintf(art_buf,"%s%s #%ld",ngname,moderated,(long)art);
X if (selected_root_cnt) {
X i = selected_count - (unseen && sel);
X sprintf(art_buf+strlen(art_buf)," (%ld + %ld more)",
X (long)i,(long)toread[ng] - selected_count
X - unthreaded - (!sel && unseen));
X }
X else if ((i = (ART_NUM)(toread[ng]-unthreaded-unseen)) != 0)
X sprintf(art_buf+strlen(art_buf)," (%ld more)",(long)i);
X linenum += tree_puts(art_buf,linenum+topline,0);
X }
X else
X#endif
X {
X#ifdef CLEAREOL
X maybe_eol();
X#endif /* CLEAREOL */
X printf("Article %ld",(long)art);
X i = (ART_NUM)(toread[ng] - 1 + was_read(art));
X#ifdef DELAYMARK
X if (i || dmcount) {
X printf(" (%ld more",(long)i);
X if (dmcount)
X printf(" + %ld Marked to return)",(long)dmcount);
X putchar(')');
X }
X#else
X if (i)
X printf(" (%ld more)",(long)i);
X#endif
X if (htype[NGS_LINE].ht_flags & HT_HIDE)
X printf(" in %s", ngname);
X fputs(moderated,stdout);
X fputs(":\n",stdout) FLUSH;
X linenum++;
X }
X }
X start_header(art);
X forcelast = FALSE; /* we will have our day in court */
X restart = Nullch;
X artline = 0; /* start counting lines */
X artpos = 0;
X vwtary(artline,artpos); /* remember pos in file */
X }
X for (; /* linenum already set */
X in_header || (
X#ifdef INNERSEARCH
X innersearch ? innermore() :
X#endif
X linenum<(firstpage?initlines:(special?slines:LINES)) );
X linenum++) { /* for each line on page */
X if (int_count) { /* exit via interrupt? */
X putchar('\n') FLUSH; /* get to left margin */
X int_count = 0; /* reset interrupt count */
X mode = oldmode;
X special = FALSE;
X return DA_NORM; /* skip out of loops */
X }
X if (restart) { /* did not finish last line? */
X bufptr = restart; /* then start again here */
X restart = Nullch; /* and reset the flag */
X }
X else { /* not a restart */
X if (fgets(art_buf,LBUFLEN,artfp)==Nullch) {
X /* if all done */
X mode = oldmode;
X special = FALSE;
X return DA_NORM; /* skip out of loops */
X }
X bufptr = art_buf; /* so start at beginning */
X art_buf[LBUFLEN-1] = '\0';
X /* make sure string ends */
X }
X blinebeg = bufptr; /* remember where we began */
X alinebeg = artpos; /* both in buffer and file */
X if (in_header && bufptr == art_buf) {
X hide_this_line =
X parseline(art_buf,do_hiding,hide_this_line);
X#ifdef USETHREADS
X if (!in_header) {
X linenum += finish_tree(linenum+topline);
X }
X#endif
X } else if (notesfiles && do_hiding &&
X bufptr == art_buf && *art_buf == '#' &&
X isupper(art_buf[1]) && art_buf[2] == ':' ) {
X fgets(art_buf,sizeof(art_buf),artfp);
X if (index(art_buf,'!') != Nullch)
X fgets(art_buf,sizeof(art_buf),artfp);
X htype[PAST_HEADER].ht_minpos = ftell(artfp);
X /* exclude notesfiles droppings */
X hide_this_line = TRUE; /* and do not print either */
X notesfiles = FALSE;
X }
X#ifdef CUSTOMLINES
X if (hideline && bufptr == art_buf &&
X execute(&hide_compex,art_buf) )
X hide_this_line = TRUE;
X#endif
X if (in_header && htype[in_header].ht_flags & HT_MAGIC) {
X if (in_header == NGS_LINE) {
X hide_this_line = (index(art_buf,',') == Nullch);
X }
X else if (in_header == EXPIR_LINE) {
X if (!(htype[EXPIR_LINE].ht_flags & HT_HIDE))
X hide_this_line = (strlen(art_buf) < 10);
X }
X else if (in_header == FROM_LINE) {
X if (do_hiding && (s = index(art_buf+6,'(')) != Nullch) {
X strcpy(art_buf+6,s+1);
X if((s = rindex(art_buf+6,')')) != Nullch)
X *s = '\0';
X }
X }
X#ifdef USETHREADS
X else if (in_header == DATE_LINE && curr_p_art && do_hiding) {
X strcpy(art_buf+6,ctime(&curr_p_art->date));
X }
X#endif
X }
X if (in_header == SUBJ_LINE &&
X htype[SUBJ_LINE].ht_flags & HT_MAGIC) {
X /* is this the subject? */
X int length;
X
X length = strlen(art_buf)-1;
X artline++;
X art_buf[length] = '\0'; /* wipe out newline */
X#ifdef NOFIREWORKS
X no_ulfire();
X#endif
X notesfiles =
X (instr(&art_buf[length-10]," - (nf") != Nullch);
X#ifdef USETHREADS
X /* tree_puts(, ,1) underlines subject */
X linenum += tree_puts(art_buf,linenum+topline,1)-1;
X#else
X if (oldsubject) {
X length += 7;
X fputs("(SAME) ",stdout);
X oldsubject = FALSE;
X }
X if (length+UG > COLS) { /* rarely true */
X linenum++;
X vwtary(artline,vrdary(artline-1)+COLS);
X artline++;
X }
X s = art_buf + 8;
X *s++ = '\0'; /* make into 2 strings */
X#ifdef CLEAREOL
X maybe_eol();
X#endif /* CLEAREOL */
X fputs(art_buf,stdout) FLUSH;
X /* print up through : */
X if (!UG)
X putchar(' ');
X underprint(s); /* print subject underlined */
X putchar('\n') FLUSH; /* and finish the line */
X#endif
X }
X else if (hide_this_line && do_hiding) {
X /* do not print line? */
X linenum--; /* compensate for linenum++ */
X if (!in_header)
X hide_this_line = FALSE;
X }
X#ifdef USETHREADS
X else if (in_header) {
X artline++;
X linenum += tree_puts(art_buf,linenum+topline,0)-1;
X }
X#endif
X else { /* just a normal line */
X if (highlight==artline) { /* this line to be highlit? */
X if (marking == STANDOUT) {
X#ifdef NOFIREWORKS
X if (erase_screen)
X no_sofire();
X#endif
X standout();
X }
X else {
X#ifdef NOFIREWORKS
X if (erase_screen)
X no_ulfire();
X#endif
X underline();
X }
X if (*bufptr == '\n')
X putchar(' ');
X }
X#ifdef INNERSEARCH
X outputok = !hide_everything;
X /* get it into register, hopefully */
X#endif
X#ifdef CLEAREOL
X#ifdef INNERSEARCH
X if (outputok)
X#endif
X maybe_eol();
X#endif /* CLEAREOL */
X#ifdef CUSTOMLINES
X if (pagestop && bufptr == art_buf &&
X execute(&page_compex,art_buf) )
X linenum = 32700;
X#endif
X for (outpos = 0; outpos < COLS; ) {
X /* while line has room */
X if (*bufptr >= ' ') { /* normal char? */
X#ifdef ULSMARTS
X if (*bufptr == '_') {
X if (bufptr[1] == '\b') {
X if (!under_lining && highlight!=artline
X#ifdef INNERSEARCH
X && outputok
X#endif
X ) {
X under_lining++;
X if (UG) {
X if (bufptr != buf &&
X bufptr[-1] == ' ') {
X outpos--;
X backspace();
X }
X }
X underline();
X }
X bufptr += 2;
X }
X }
X else {
X if (under_lining) {
X under_lining = 0;
X un_underline();
X if (UG) {
X if (*bufptr == ' ')
X goto skip_put;
X outpos++;
X }
X }
X }
X#endif
X#ifdef INNERSEARCH
X if (outputok)
X#endif
X {
X#ifdef ROTATION
X if (rotate && !in_header
X && isalpha(*bufptr)) {
X if ((*bufptr & 31) <= 13)
X putchar(*bufptr+13);
X else
X putchar(*bufptr-13);
X }
X else
X#endif
X putchar(*bufptr);
X }
X if (*UC && ((highlight==artline && marking == 1)
X#ifdef ULSMARTS
X || under_lining
X#endif
X )) {
X backspace();
X underchar();
X }
X skip_put:
X bufptr++;
X outpos++;
X }
X else if (*bufptr == '\n' || !*bufptr) {
X /* newline? */
X#ifdef ULSMARTS
X if (under_lining) {
X under_lining = 0;
X un_underline();
X }
X#endif
X#ifdef DEBUGGING
X if (debug & DEB_INNERSRCH && outpos < COLS - 6) {
X standout();
X printf("%4d",artline);
X un_standout();
X }
X#endif
X#ifdef INNERSEARCH
X if (outputok)
X#endif
X putchar('\n') FLUSH;
X restart = 0;
X outpos = 1000; /* signal normal \n */
X }
X else if (*bufptr == '\t') { /* tab? */
X#ifdef INNERSEARCH
X if (outputok)
X#endif
X putchar(*bufptr);
X bufptr++;
X outpos += 8 - outpos % 8;
X }
X else if (*bufptr == '\f') { /* form feed? */
X#ifdef INNERSEARCH
X if (outputok)
X#endif
X fputs("^L",stdout);
X if (bufptr == blinebeg && highlight != artline)
X linenum = 32700;
X /* how is that for a magic number? */
X bufptr++;
X outpos += 2;
X }
X else { /* other control char */
X#ifdef INNERSEARCH
X if (outputok)
X#endif
X {
X putchar('^');
X if (highlight == artline && *UC && marking == 1) {
X backspace();
X underchar();
X putchar(*bufptr+64);
X backspace();
X underchar();
X }
X else
X putchar(*bufptr+64);
X }
X bufptr++;
X outpos += 2;
X }
X
X } /* end of column loop */
X
X if (outpos < 1000) {/* did line overflow? */
X restart = bufptr;
X /* restart here next time */
X if (AM) { /* automatic margins on tty? */
X if (!XN && *bufptr == '\n')
X /* need we simulate XN? */
X restart = 0;
X /* skip the newline */
X }
X else { /* cursor just hangs there */
X#ifdef INNERSEARCH
X if (outputok)
X#endif
X putchar('\n') FLUSH;
X /* so move it down ourselves */
X if (*bufptr == '\n')
X restart = 0;
X /* simulate XN if need be */
X }
X#ifdef CLEAREOL
X/* #ifdef INNERSEARCH
X if (outputok)
X#endif
X maybe_eol(); */ /* comment this out for now
X until I am sure it is
X needed*/
X
X#endif /* CLEAREOL */
X }
X
X /* handle normal end of output line formalities */
X
X if (highlight == artline) {
X /* were we highlighting line? */
X if (marking == STANDOUT)
X un_standout();
X else
X un_underline();
X highlight = -1; /* no more we are */
X }
X artline++; /* count the line just printed */
X if (artline - LINES + 1 > topline)
X /* did we just scroll top line off? */
X topline = artline - LINES + 1;
X /* then recompute top line # */
X }
X
X /* determine actual position in file */
X
X if (restart) /* stranded somewhere in the buffer? */
X artpos += restart - blinebeg;
X /* just calculate position */
X else /* no, ftell will do */
X artpos = ftell(artfp);
X /* so do ftell */
X vwtary(artline,artpos); /* remember pos in file */
X } /* end of line loop */
X
X#ifdef INNERSEARCH
X innersearch = 0;
X if (hide_everything) {
X hide_everything = FALSE;
X *buf = Ctl('l');
X goto fake_command;
X }
X#endif
X if (linenum >= 32700)/* did last line have formfeed? */
X vwtary(artline-1,-vrdary(artline-1));
X /* remember by negating pos in file */
X
X special = FALSE; /* end of page, so reset page length */
X firstpage = FALSE; /* and say it is not 1st time thru */
X
X /* extra loop bombout */
X
X if (artpos == artsize) {/* did we just now reach EOF? */
X mode = oldmode;
X return DA_NORM; /* avoid --MORE--(100%) */
X }
X
X/* not done with this article, so pretend we are a pager */
X
Xreask_pager:
X unflush_output(); /* disable any ^O in effect */
X standout(); /* enter standout mode */
X printf("--MORE--(%ld%%)",(long)(artpos*100/artsize));
X un_standout(); /* leave standout mode */
X fflush(stdout);
X/* reinp_pager: /* unused, commented for lint */
X eat_typeahead();
X#ifdef DEBUGGING
X if (debug & DEB_CHECKPOINTING) {
X printf("(%d %d %d)",checkcount,linenum,artline);
X fflush(stdout);
X }
X#endif
X if (checkcount >= docheckwhen &&
X linenum == LINES &&
X (artline > 40 || checkcount >= docheckwhen+10) ) {
X /* while he is reading a whole page */
X /* in an article he is interested in */
X checkcount = 0;
X checkpoint_rc(); /* update .newsrc */
X }
X collect_subjects(); /* loads subject cache until */
X /* input is pending */
X mode = 'p';
X getcmd(buf);
X if (errno) {
X if (LINES < 100 && !int_count)
X *buf = '\f';/* on CONT fake up refresh */
X else {
X *buf = 'q'; /* on INTR or paper just quit */
X }
X }
X carriage_return();
X#ifndef CLEAREOL
X erase_eol(); /* and erase the prompt */
X#else
X if (erase_screen && can_home_clear)
X clear_rest();
X else
X erase_eol(); /* and erase the prompt */
X#endif /* CLEAREOL */
X carriage_return(); /* Resets kernel's tab column counter to 0 */
X fflush(stdout);
X
X fake_command: /* used by innersearch */
X
X /* parse and process pager command */
X
X switch (page_switch()) {
X case PS_ASK: /* reprompt "--MORE--..." */
X goto reask_pager;
X case PS_RAISE: /* reparse on article level */
X mode = oldmode;
X return DA_RAISE;
X case PS_TOEND: /* fast pager loop exit */
X mode = oldmode;
X return DA_TOEND;
X case PS_NORM: /* display more article */
X break;
X }
X } /* end of page loop */
X}
X
X/* process pager commands */
X
Xint
Xpage_switch()
X{
X register char *s;
X
X switch (*buf) {
X case 'd':
X case Ctl('d'): /* half page */
X special = TRUE;
X slines = LINES / 2 + 1;
X if (marking && *blinebeg != '\f'
X#ifdef CUSTOMLINES
X && (!pagestop || blinebeg != art_buf ||
X !execute(&page_compex,blinebeg))
X#endif
X ) {
X up_line();
X highlight = --artline;
X restart = blinebeg;
X artpos = alinebeg;
X }
X return PS_NORM;
X case '!': /* shell escape */
X escapade();
X return PS_ASK;
X#ifdef INNERSEARCH
X case Ctl('i'):
X gline = 3;
X sprintf(cmd_buf,"^[^%c]",*blinebeg);
X compile(&gcompex,cmd_buf,TRUE,TRUE);
X goto caseG;
X case Ctl('g'):
X gline = 3;
X compile(&gcompex,"^Subject:",TRUE,TRUE);
X goto caseG;
X case 'g': /* in-article search */
X if (!finish_command(FALSE))/* get rest of command */
X return PS_ASK;
X s = buf+1;
X if (isspace(*s))
X s++;
X if ((s = compile(&gcompex,s,TRUE,TRUE)) != Nullch) {
X /* compile regular expression */
X printf("\n%s\n",s) FLUSH;
X return PS_ASK;
X }
X carriage_return();
X erase_eol(); /* erase the prompt */
X carriage_return(); /* Resets kernel's tab column counter to 0 */
X /* FALL THROUGH */
X caseG:
X case 'G': {
X /* ART_LINE lines_to_skip = 0; */
X ART_POS start_where;
X
X if (gline < 0 || gline > LINES-2)
X gline = LINES-2;
X#ifdef DEBUGGING
X if (debug & DEB_INNERSRCH)
X printf("Start here? %d >=? %d\n",topline + gline + 1,artline)
X FLUSH;
X#endif
X if (*buf == Ctl('i') || topline+gline+1 >= artline)
X start_where = artpos;
X /* in case we had a line wrap */
X else {
X start_where = vrdary(topline+gline+1);
X if (start_where < 0)
X start_where = -start_where;
X }
X if (start_where < htype[PAST_HEADER].ht_minpos)
X start_where = htype[PAST_HEADER].ht_minpos;
X fseek(artfp,(long)start_where,0);
X innersearch = 0; /* assume not found */
X while (fgets(buf, sizeof buf, artfp) != Nullch) {
X /* lines_to_skip++; NOT USED NOW */
X#ifdef DEBUGGING
X if (debug & DEB_INNERSRCH)
X printf("Test %s",buf) FLUSH;
X#endif
X if (execute(&gcompex,buf) != Nullch) {
X innersearch = ftell(artfp);
X break;
X }
X }
X if (!innersearch) {
X fseek(artfp,artpos,0);
X fputs("(Not found)",stdout) FLUSH;
X return PS_ASK;
X }
X#ifdef DEBUGGING
X if (debug & DEB_INNERSRCH)
X printf("On page? %ld <=? %ld\n",(long)innersearch,(long)artpos)
X FLUSH;
X#endif
X if (innersearch <= artpos) { /* already on page? */
X if (innersearch < artpos) {
X artline = topline+1;
X while (vrdary(artline) < innersearch)
X artline++;
X }
X highlight = artline - 1;
X#ifdef DEBUGGING
X if (debug & DEB_INNERSRCH)
X printf("@ %d\n",highlight) FLUSH;
X#endif
X topline = highlight - gline;
X if (topline < -1)
X topline = -1;
X *buf = '\f'; /* fake up a refresh */
X innersearch = 0;
X return page_switch();
X }
X else { /* who knows how many lines it is? */
X do_fseek = TRUE;
X hide_everything = TRUE;
X }
X return PS_NORM;
X }
X#else
X case 'g': case 'G': case Ctl('g'):
X notincl("g");
X return PS_ASK;
X#endif
X case '\n': /* one line */
X special = TRUE;
X slines = 2;
X return PS_NORM;
X#ifdef ROTATION
X case 'X':
X rotate = !rotate;
X /* FALL THROUGH */
X#endif
X case 'l':
X case '\f': /* refresh screen */
X#ifdef DEBUGGING
X if (debug & DEB_INNERSRCH) {
X printf("Topline = %d",topline) FLUSH;
X gets(buf);
X }
X#endif
X clear();
X carriage_return(); /* Resets kernel's tab column counter to 0 */
X do_fseek = TRUE;
X artline = topline;
X if (artline < 0)
X artline = 0;
X firstpage = (topline < 0);
X return PS_NORM;
X case 'b':
X case '\b':
X case Ctl('b'): { /* back up a page */
X ART_LINE target;
X
X#ifndef CLEAREOL
X clear();
X#else
X if (can_home_clear) /* if we can home do it */
X home_cursor();
X else
X clear();
X
X#endif /* CLEAREOL */
X carriage_return(); /* Resets kernel's tab column counter to 0 */
X do_fseek = TRUE; /* reposition article file */
X target = topline - (LINES - 2);
X artline = topline;
X if (artline >= 0) do {
X artline--;
X } while(artline >= 0 && artline > target && vrdary(artline-1) >= 0);
X topline = artline;
X /* remember top line of screen */
X /* (line # within article file) */
X if (artline < 0)
X artline = 0;
X firstpage = (topline < 0);
X return PS_NORM;
X }
X case 'h': { /* help */
X int cmd;
X
X if ((cmd = help_page()) > 0)
X pushchar(cmd);
X return PS_ASK;
X }
X#ifdef USETHREADS
X case 't': /* output thread data */
X page_line = 1;
X p_art = curr_p_art;
X entire_tree();
X return PS_ASK;
X#endif
X case '\177':
X case '\0': /* treat del,break as 'n' */
X *buf = 'n';
X /* FALL THROUGH */
X case 'k': case 'K':
X#ifdef USETHREADS
X case 'T': case 'J':
X#endif
X case 'n': case 'N': case Ctl('n'):
X case 's': case 'S':
X case 'e':
X case 'u':
X case 'w': case 'W':
X case '|':
X mark_as_read(); /* mark article as read */
X /* FALL THROUGH */
X#ifdef USETHREADS
X case 'U': case ',':
X case '<': case '>':
X case '[': case ']':
X case '{': case '}':
X case '+': case ':':
X#endif
X case '#':
X case '$':
X case '&':
X case '-':
X case '.':
X case '/':
X case '1': case '2': case '3': case '4': case '5':
X case '6': case '7': case '8': case '9':
X case '=':
X case '?':
X case 'c': case 'C':
X#ifdef DEBUGGING
X case 'D':
X#endif
X case 'E':
X case 'f': case 'F':
X case 'j':
X case Ctl('k'):
X case 'm': case 'M':
X case 'p': case 'P': case Ctl('p'):
X case 'Q':
X case 'r': case 'R': case Ctl('r'):
X case 'v':
X case 'Y':
X#ifndef ROTATION
X case 'x': case 'X':
X#endif
X case Ctl('x'):
X case '^':
X
X#ifdef ROTATION
X rotate = FALSE;
X#endif
X reread = FALSE;
X do_hiding = TRUE;
X if (index("nNpP",*buf) == Nullch &&
X index("wWsSe:!&|/?123456789.",*buf) != Nullch) {
X setdfltcmd();
X standout(); /* enter standout mode */
X printf(prompt,mailcall,dfltcmd);
X /* print prompt, whatever it is */
X un_standout(); /* leave standout mode */
X putchar(' ');
X fflush(stdout);
X }
X return PS_RAISE; /* and pretend we were at end */
X#ifdef ROTATION
X case 'x':
X rotate = TRUE;
X /* FALL THROUGH */
X#endif
X case 'y':
X case Ctl('v'):
X /* Leaving it undocumented in case */
X /* I want to steal the key--LAW */
X case ' ': /* continue current article */
X if (erase_screen) { /* -e? */
X#ifndef CLEAREOL
X clear(); /* clear screen */
X#else
X if (can_home_clear) /* if we can home do it */
X home_cursor();
X else
X clear(); /* else clear screen */
X
X#endif /* CLEAREOL */
X if (*blinebeg != '\f'
X#ifdef CUSTOMLINES
X && (!pagestop || blinebeg != art_buf ||
X !execute(&page_compex,blinebeg))
X#endif
X ) {
X restart = blinebeg;
X artline--; /* restart this line */
X artpos = alinebeg;
X if (marking) /* and mark repeated line */
X highlight = artline;
X }
X topline = artline;
X /* and remember top line of screen */
X /* (line # within article file) */
X }
X else if (marking && *blinebeg != '\f'
X#ifdef CUSTOMLINES
X && (!pagestop || blinebeg != art_buf ||
X !execute(&page_compex,blinebeg))
X#endif
X ) {
X /* are we marking repeats? */
X up_line(); /* go up one line */
X highlight = --artline;/* and get ready to highlight */
X restart = blinebeg; /* the old line */
X artpos = alinebeg;
X }
X return PS_NORM;
X case 'q': /* quit this article? */
X do_hiding = TRUE;
X return PS_TOEND;
X default:
X fputs(hforhelp,stdout) FLUSH;
X settle_down();
X return PS_ASK;
X }
X}
X
X#ifdef INNERSEARCH
Xbool
Xinnermore()
X{
X if (artpos < innersearch) { /* not even on page yet? */
X#ifdef DEBUGGING
X if (debug & DEB_INNERSRCH)
X printf("Not on page %ld < %ld\n",(long)artpos,(long)innersearch)
X FLUSH;
X#endif
X return TRUE;
X }
X if (artpos == innersearch) { /* just got onto page? */
X isrchline = artline; /* remember first line after */
X highlight = artline - 1;
X#ifdef DEBUGGING
X if (debug & DEB_INNERSRCH)
X printf("There it is %ld = %ld, %d @ %d\n",(long)artpos,
X (long)innersearch,hide_everything,highlight) FLUSH;
X#endif
X if (hide_everything) { /* forced refresh? */
X topline = highlight - gline;
X if (topline < -1)
X topline = -1;
X return FALSE; /* let refresh do it all */
X }
X }
X#ifdef DEBUGGING
X if (debug & DEB_INNERSRCH)
X printf("Not far enough? %d <? %d + %d\n",artline,isrchline,gline)
X FLUSH;
X#endif
X if (artline < isrchline + gline) {
X return TRUE;
X }
X return FALSE;
X}
X#endif
END_OF_FILE
if test 25145 -ne `wc -c <'art.c'`; then
echo shar: \"'art.c'\" unpacked with wrong size!
fi
# end of 'art.c'
fi
if test -f 'init.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'init.c'\"
else
echo shar: Extracting \"'init.c'\" \(8405 characters\)
sed "s/^X//" >'init.c' <<'END_OF_FILE'
X/* $Header: init.c,v 4.3.3.1 90/06/20 22:37:39 davison Trn $
X *
X * $Log: init.c,v $
X * Revision 4.3.3.1 90/06/20 22:37:39 davison
X * Initial Trn Release
X *
X * Revision 4.3.2.6 90/05/08 22:05:55 sob
X * Added quick startup (-q) flag.
X *
X * Revision 4.3.2.5 90/05/04 23:10:01 sob
X * Fix for exiting "second" rn such that tty will be left in correct state.
X * Provided by glenn at mathcs.emory.edu
X *
X * Revision 4.3.2.4 90/03/22 23:04:32 sob
X * Fixes provided by Wayne Davison <drivax!davison>
X *
X * Revision 4.3.2.3 90/03/17 21:34:04 sob
X * Cleaned up a bit.
X *
X * Revision 4.3.2.2 89/11/08 01:17:48 sob
X * Added changes to insure that this will compile for RN or RRN with no
X * changes to the source code.
X *
X * Revision 4.3.2.1 89/11/06 00:39:14 sob
X * Added RRN support from NNTP 1.5
X *
X * Revision 4.3.1.4 86/09/05 14:24:02 lwall
X * Removed net.announce dependency.
X *
X * Revision 4.3.1.3 85/07/23 18:08:36 lwall
X * Fixed up NOLINEBUF option to work.
X *
X * Revision 4.3.1.2 85/05/21 14:22:46 lwall
X * Sped up "rn -c" by avoiding unnecessary initialization.
X *
X * Revision 4.3.1.1 85/05/10 11:33:39 lwall
X * Branch for patches.
X *
X * Revision 4.3 85/05/01 16:16:13 lwall
X * Baseline for release with 4.3bsd.
X *
X */
X
X#include "EXTERN.h"
X#include "common.h"
X#include "util.h"
X#include "final.h"
X#include "term.h"
X#include "last.h"
X#include "rn.h"
X#include "rcstuff.h"
X#include "ngdata.h"
X#include "only.h"
X#include "intrp.h"
X#include "addng.h"
X#include "sw.h"
X#include "art.h"
X#include "artsrch.h"
X#include "artio.h"
X#include "backpage.h"
X#include "bits.h"
X#include "cheat.h"
X#include "head.h"
X#include "help.h"
X#include "kfile.h"
X#include "ngsrch.h"
X#include "ngstuff.h"
X#include "rcln.h"
X#include "respond.h"
X#ifdef SERVER
X#include "server.h"
X#endif
X#ifdef USETHREADS
X#include "rthreads.h"
X#endif
X#include "ng.h"
X#include "INTERN.h"
X#include "init.h"
X
Xbool
Xinitialize(argc,argv)
Xint argc;
Xchar *argv[];
X{
X char *tcbuf;
X register bool foundany = FALSE;
X long time();
X#ifdef SERVER
X char *server;
X int response;
X#endif
X#ifdef NOLINEBUF
X static char std_out_buf[BUFSIZ]; /* must be static or malloced */
X
X setbuf(stdout, std_out_buf);
X#endif
X
X tcbuf = safemalloc(1024); /* make temp buffer for termcap and */
X /* other initialization stuff */
X
X /* init terminal */
X
X term_init(); /* must precede sw_init() so that */
X /* ospeed is set for baud-rate */
X /* switches. Actually terminal */
X /* mode setting is in term_set() */
X
X /* we have to know rnlib to look up global switches in %X/INIT */
X
X lib = savestr(filexp(LIB));
X rnlib = savestr(filexp(RNLIB));
X
X /* decode switches */
X
X sw_init(argc,argv,&tcbuf); /* must not do % interps! */
X /* (but may mung environment) */
X
X /* init signals, status flags */
X
X final_init();
X
X /* start up file expansion and the % interpreter */
X
X intrp_init(tcbuf);
X
X /* now make sure we have a current working directory */
X
X if (!checkflag)
X cwd_check();
X
X /* now that we know where to save things, cd to news directory */
X
X if (chdir(spool)) {
X printf(nocd,spool) FLUSH;
X finalize(1);
X }
X
X /* if we aren't just checking, turn off echo */
X
X if (!checkflag)
X term_set(tcbuf);
X
X /* get info on last rn run, if any */
X
X if (!checkflag)
X last_init(tcbuf);
X
X free(tcbuf); /* recover 1024 bytes */
X
X /* make sure we are the sole possessors of .newsrc */
X
X if (!checkflag)
X lock_check();
X
X /* check for news news */
X
X if (!checkflag)
X newsnews_check();
X
X#ifdef SERVER
X
X /* open connection to server if appropriate */
X
X server = getserverbyfile(SERVER_FILE);
X if (server == NULL) {
X fprintf(stderr, "Can't get the name of the news server from %s\n",
X SERVER_FILE);
X fprintf(stderr,
X "Either fix this file, or put NNTPSERVER in your environment.\n");
X finalize(1);
X }
X
X response = server_init(server);
X if (response < 0) {
X fprintf(stderr,
X "Couldn't connect to %s news server, try again later.\n",
X server);
X finalize(1);
X }
X
X if (handle_server_response(response, server) < 0)
X finalize(1);
X
X#endif
X
X /* open active file, etc. */
X
X ngdata_init();
X
X /* now read in the .newsrc file */
X
X foundany = rcstuff_init();
X
X /* it looks like we will actually read something, so init everything */
X
X addng_init();
X art_init();
X artio_init();
X artsrch_init();
X backpage_init();
X bits_init();
X cheat_init();
X head_init();
X help_init();
X kfile_init();
X ng_init();
X ngsrch_init();
X ngstuff_init();
X only_init();
X rcln_init();
X respond_init();
X rn_init();
X search_init();
X#ifdef USETHREADS
X thread_init();
X#endif
X util_init();
X
X#ifdef FINDNEWNG
X fstat(actfp->_file,&filestat); /* did active file grow? */
X /*
X * Skip this check if the -q flag was given.
X */
X
X if (!quickstart && filestat.st_size != lastactsiz) {
X long actsiz = filestat.st_size; /* remember new size */
X NG_NUM oldnext = nextrcline; /* remember # lines in newsrc */
X#ifdef FASTNEW
X bool munged = writesoft || !lastactsiz;
X /* bad soft ptrs -> edited active */
X#else
X bool munged = TRUE; /* just assume .newsrc munged */
X#endif
X
X#ifdef VERBOSE
X IF(verbose)
X fputs("\nChecking active list for new newsgroups...\n",stdout)
X FLUSH;
X ELSE
X#endif
X#ifdef TERSE
X fputs("\nNew newsgroups:\n",stdout) FLUSH;
X#endif
X#ifdef FASTNEW
X if (!munged) { /* maybe just do tail of file? */
X fseek(actfp,lastactsiz-1,0);
X fgets(buf,LBUFLEN,actfp);
X munged = (*buf != '\n');
X if (!munged)
X munged = newlist(munged,FALSE);
X }
X#endif
X if (munged) { /* must we scan entire file? */
X fseek(actfp,0L,0); /* rewind active file */
X newlist(munged,FALSE); /* sure hope they use hashing... */
X }
X lastactsiz = actsiz; /* remember for .rnlast */
X if (nextrcline != oldnext) { /* did we add any new groups? */
X foundany = TRUE; /* let main() know */
X starthere = 0; /* and start ng scan from the top */
X }
X }
X#endif
X time(&lasttime); /* remember when we inited-- */
X /* ends up back in .rnlast */
X writelast(); /* in fact, put it there now */
X
X#ifdef FINDNEWNG
X# ifdef ONLY
X if (maxngtodo) /* patterns on command line? */
X foundany |= scanactive();
X# endif
X#endif
X
X return foundany;
X}
X
X/* make sure there is no rn out there already */
X
Xvoid
Xlock_check()
X{
X lockname = savestr(filexp(LOCKNAME));
X if (!checkflag) {
X tmpfp = fopen(lockname,"r");
X if (tmpfp != Nullfp) {
X int processnum;
X
X fgets(buf,LBUFLEN,tmpfp);
X fclose(tmpfp);
X processnum = atoi(buf);
X#ifdef VERBOSE
X IF(verbose)
X printf("You seem to have left an rn running, process %d.\n",
X processnum) FLUSH;
X ELSE
X#endif
X#ifdef TERSE
X printf("Rn left running, #%d.\n", processnum) FLUSH;
X#endif
X if (kill(processnum, SIGEMT)) {
X /* does process not exist? */
X /* (rn ignores SIGEMT) */
X sleep(2);
X#ifdef VERBOSE
X IF(verbose)
X fputs("\n\
XThat process does not seem to exist anymore. The count of read articles\n\
Xmay be incorrect in the last newsgroup accessed by that other (defunct)\n\
Xprocess.\n\n",stdout) FLUSH;
X ELSE
X#endif
X#ifdef TERSE
X fputs("\nProcess crashed.\n",stdout) FLUSH;
X#endif
X if (*lastngname) {
X#ifdef VERBOSE
X IF(verbose)
X printf("(The last newsgroup accessed was %s.)\n\n",
X lastngname) FLUSH;
X ELSE
X#endif
X#ifdef TERSE
X printf("(In %s.)\n\n",lastngname) FLUSH;
X#endif
X }
X get_anything();
X putchar('\n') FLUSH;
X }
X else {
X#ifdef VERBOSE
X IF(verbose)
X fputs("\n\
XYou may not have two copies of rn running simultaneously. Goodbye.\n\
X",stdout) FLUSH;
X ELSE
X#endif
X#ifdef TERSE
X fputs("\nCan't start another.\n",stdout) FLUSH;
X#endif
X if (bizarre)
X resetty();
X exit(0);
X }
X }
X tmpfp = fopen(lockname,"w");
X if (tmpfp == Nullfp) {
X printf(cantcreate,lockname) FLUSH;
X sig_catcher(0);
X }
X fprintf(tmpfp,"%d\n",getpid());
X fclose(tmpfp);
X }
X}
X
Xvoid
Xnewsnews_check()
X{
X char *newsnewsname = filexp(NEWSNEWSNAME);
X
X if ((tmpfp = fopen(newsnewsname,"r")) != Nullfp) {
X fstat(tmpfp->_file,&filestat);
X if (filestat.st_mtime > lasttime) {
X while (fgets(buf,sizeof(buf),tmpfp) != Nullch)
X fputs(buf,stdout) FLUSH;
X get_anything();
X putchar('\n') FLUSH;
X }
X fclose(tmpfp);
X }
X}
END_OF_FILE
if test 8405 -ne `wc -c <'init.c'`; then
echo shar: \"'init.c'\" unpacked with wrong size!
fi
# end of 'init.c'
fi
if test -f 'term.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'term.c'\"
else
echo shar: Extracting \"'term.c'\" \(25423 characters\)
sed "s/^X//" >'term.c' <<'END_OF_FILE'
X/* $Header: term.c,v 4.3.3.1 90/07/28 18:09:09 davison Trn $
X *
X * $Log: term.c,v $
X * Revision 4.3.3.1 90/07/28 18:09:09 davison
X * Initial Trn Release
X *
X * Revision 4.3.2.7 90/04/21 16:54:29 sob
X * Installed patches provided by SCO for SCO Xenix
X *
X * Revision 4.3.2.6 90/04/13 23:48:17 sob
X * Modifications provided by Gene Hackney for 3b2.
X *
X * Revision 4.3.2.5 90/04/06 20:35:08 sob
X * Added fixes for SCO Xenix sent by ronald at robobar.co.uk.
X *
X * Revision 4.3.2.4 90/03/22 23:05:38 sob
X * Fixes provided by Wayne Davison <drivax!davison>
X *
X * Revision 4.3.2.3 89/11/28 01:51:58 sob
X * Now handles SIGWINCH correctly.
X *
X * Revision 4.3.2.2 89/11/27 01:31:34 sob
X * Altered NNTP code per ideas suggested by Bela Lubkin
X * <filbo at gorn.santa-cruz.ca.us>
X *
X * Revision 4.3.2.1 89/11/06 01:02:12 sob
X * Added RRN support from NNTP 1.5
X *
X * Revision 4.3.1.3 85/09/10 11:05:23 lwall
X * Improved %m in in_char().
X *
X * Revision 4.3.1.2 85/05/16 16:45:35 lwall
X * Forced \r to \n on input.
X * Fix for terminfo braindamage regarding bc emulation.
X *
X * Revision 4.3.1.1 85/05/10 11:41:03 lwall
X * Branch for patches.
X *
X * Revision 4.3 85/05/01 11:51:10 lwall
X * Baseline for release with 4.3bsd.
X *
X */
X
X#include "EXTERN.h"
X#include "common.h"
X#include "util.h"
X#include "final.h"
X#include "help.h"
X#include "cheat.h"
X#include "intrp.h"
X#include "INTERN.h"
X#include "term.h"
X
X#ifdef SYS_PTEM
X#include <sys/stream.h>
X#include <sys/ptem.h>
X#endif
X
Xchar ERASECH; /* rubout character */
Xchar KILLCH; /* line delete character */
Xchar tcarea[TCSIZE]; /* area for "compiled" termcap strings */
X
X#ifdef USETHREADS
Xint upcost;
X#endif
X
X/* guarantee capability pointer != Nullch */
X/* (I believe terminfo will ignore the &tmpaddr argument.) */
X
X#define Tgetstr(key) ((tmpstr = tgetstr(key,&tmpaddr)) ? tmpstr : nullstr)
X
X#ifdef PUSHBACK
Xstruct keymap {
X char km_type[128];
X union km_union {
X struct keymap *km_km;
X char *km_str;
X } km_ptr[128];
X};
X
X#define KM_NOTHIN 0
X#define KM_STRING 1
X#define KM_KEYMAP 2
X#define KM_BOGUS 3
X
X#define KM_TMASK 3
X#define KM_GSHIFT 4
X#define KM_GMASK 7
X
Xtypedef struct keymap KEYMAP;
X
XKEYMAP *topmap INIT(Null(KEYMAP*));
X
Xvoid mac_init();
XKEYMAP *newkeymap();
Xvoid show_keymap();
Xvoid pushstring();
X#endif
X
Xvoid line_col_calcs();
X
X/* terminal initialization */
X
Xvoid
Xterm_init()
X{
X savetty(); /* remember current tty state */
X
X#ifdef TERMIO
X ospeed = _tty.c_cflag & CBAUD; /* for tputs() */
X ERASECH = _tty.c_cc[VERASE]; /* for finish_command() */
X KILLCH = _tty.c_cc[VKILL]; /* for finish_command() */
X#else
X ospeed = _tty.sg_ospeed; /* for tputs() */
X ERASECH = _tty.sg_erase; /* for finish_command() */
X KILLCH = _tty.sg_kill; /* for finish_command() */
X#endif
X
X /* The following could be a table but I can't be sure that there isn't */
X /* some degree of sparsity out there in the world. */
X
X switch (ospeed) { /* 1 second of padding */
X#ifdef BEXTA
X case BEXTA: just_a_sec = 1920; break;
X#else
X#ifdef B19200
X case B19200: just_a_sec = 1920; break;
X#endif
X#endif
X case B9600: just_a_sec = 960; break;
X case B4800: just_a_sec = 480; break;
X case B2400: just_a_sec = 240; break;
X case B1800: just_a_sec = 180; break;
X case B1200: just_a_sec = 120; break;
X case B600: just_a_sec = 60; break;
X case B300: just_a_sec = 30; break;
X /* do I really have to type the rest of this??? */
X case B200: just_a_sec = 20; break;
X case B150: just_a_sec = 15; break;
X case B134: just_a_sec = 13; break;
X case B110: just_a_sec = 11; break;
X case B75: just_a_sec = 8; break;
X case B50: just_a_sec = 5; break;
X default: just_a_sec = 960; break;
X /* if we are running detached I */
X } /* don't want to know about it! */
X}
X
X/* set terminal characteristics */
X
Xvoid
Xterm_set(tcbuf)
Xchar *tcbuf; /* temp area for "uncompiled" termcap entry */
X{
X char *tmpaddr; /* must not be register */
X register char *tmpstr;
X char *tgetstr();
X char *s;
X int status;
X#ifdef TIOCGWINSZ
X#ifdef u3b2
Xstruct winsize {
X unsigned short ws_row; /* rows, in characters*/
X unsigned short ws_col; /* columns, in character */
X unsigned short ws_xpixel; /* horizontal size, pixels */
X unsigned short ws_ypixel; /* vertical size, pixels */
X};
X#endif
X struct winsize winsize;
X#endif
X
X#ifdef PENDING
X#if ! defined (FIONREAD) && ! defined (RDCHK)
X /* do no delay reads on something that always gets closed on exit */
X
X devtty = open("/dev/tty",0);
X if (devtty < 0) {
X printf(cantopen,"/dev/tty") FLUSH;
X finalize(1);
X }
X fcntl(devtty,F_SETFL,O_NDELAY);
X#endif
X#endif
X
X /* get all that good termcap stuff */
X
X#ifdef HAVETERMLIB
X status = tgetent(tcbuf,getenv("TERM")); /* get termcap entry */
X if (status < 1) {
X#ifdef VERBOSE
X printf("No termcap %s found.\n", status ? "file" : "entry") FLUSH;
X#else
X fputs("Termcap botch\n",stdout) FLUSH;
X#endif
X finalize(1);
X }
X tmpaddr = tcarea; /* set up strange tgetstr pointer */
X s = Tgetstr("pc"); /* get pad character */
X PC = *s; /* get it where tputs wants it */
X if (!tgetflag("bs")) { /* is backspace not used? */
X BC = Tgetstr("bc"); /* find out what is */
X if (BC == nullstr) /* terminfo grok's 'bs' but not 'bc' */
X BC = Tgetstr("le");
X } else
X BC = "\b"; /* make a backspace handy */
X UP = Tgetstr("up"); /* move up a line */
X if (!*UP) /* no UP string? */
X marking = 0; /* disable any marking */
X if (muck_up_clear) /* this is for weird HPs */
X CL = "\n\n\n\n";
X else
X CL = Tgetstr("cl"); /* get clear string */
X CE = Tgetstr("ce"); /* clear to end of line string */
X#if defined(CLEAREOL) || defined(USETHREADS)
X HO = Tgetstr("ho"); /* home cursor if no CM */
X CM = Tgetstr("cm"); /* cursor motion */
X if (*CM || *HO)
X can_home = TRUE;
X#endif
X#ifdef CLEAREOL
X CD = Tgetstr("cd"); /* clear to end of display */
X if (!*CE || !*CD || !can_home) /* can we CE, CD, and home? */
X can_home_clear = FALSE; /* no, so disable use of clear eol */
X#endif /* CLEAREOL */
X#ifdef USETHREADS
X upcost = strlen(UP);
X#endif
X SO = Tgetstr("so"); /* begin standout */
X SE = Tgetstr("se"); /* end standout */
X if ((SG = tgetnum("sg"))<0)
X SG = 0; /* blanks left by SG, SE */
X US = Tgetstr("us"); /* start underline */
X UE = Tgetstr("ue"); /* end underline */
X if ((UG = tgetnum("ug"))<0)
X UG = 0; /* blanks left by US, UE */
X if (*US)
X UC = nullstr; /* UC must not be NULL */
X else
X UC = Tgetstr("uc"); /* underline a character */
X if (!*US && !*UC) { /* no underline mode? */
X US = SO; /* substitute standout mode */
X UE = SE;
X UG = SG;
X }
X LINES = tgetnum("li"); /* lines per page */
X COLS = tgetnum("co"); /* columns on page */
X
X#ifdef TIOCGWINSZ
X { struct winsize ws;
X if (ioctl(0, TIOCGWINSZ, &ws) >= 0 && ws.ws_row > 0 && ws.ws_col > 0) {
X LINES = ws.ws_row;
X COLS = ws.ws_col;
X }
X }
X#endif
X
X AM = tgetflag("am"); /* terminal wraps automatically? */
X XN = tgetflag("xn"); /* then eats next newline? */
X VB = Tgetstr("vb");
X if (!*VB)
X VB = "\007";
X CR = Tgetstr("cr");
X if (!*CR) {
X if (tgetflag("nc") && *UP) {
X CR = safemalloc((MEM_SIZE)strlen(UP)+2);
X sprintf(CR,"%s\r",UP);
X }
X else
X CR = "\r";
X }
X#ifdef TIOCGWINSZ
X if (ioctl(1, TIOCGWINSZ, &winsize)>=0) {
X if (winsize.ws_row>0) LINES=winsize.ws_row;
X if (winsize.ws_col>0) COLS=winsize.ws_col;
X }
X#endif
X#else
X ?????? /* Roll your own... */
X#endif
X line_col_calcs();
X noecho(); /* turn off echo */
X crmode(); /* enter cbreak mode */
X
X#ifdef PUSHBACK
X mac_init(tcbuf);
X#endif
X}
X
X#ifdef PUSHBACK
Xvoid
Xmac_init(tcbuf)
Xchar *tcbuf;
X{
X char tmpbuf[1024];
X
X tmpfp = fopen(filexp(getval("RNMACRO",RNMACRO)),"r");
X if (tmpfp != Nullfp) {
X while (fgets(tcbuf,1024,tmpfp) != Nullch) {
X mac_line(tcbuf,tmpbuf,(sizeof tmpbuf));
X }
X fclose(tmpfp);
X }
X}
X
Xvoid
Xmac_line(line,tmpbuf,tbsize)
Xchar *line;
Xchar *tmpbuf;
Xint tbsize;
X{
X register char *s, *m;
X register KEYMAP *curmap;
X register int ch;
X register int garbage = 0;
X static char override[] = "\nkeymap overrides string\n";
X
X if (topmap == Null(KEYMAP*))
X topmap = newkeymap();
X if (*line == '#' || *line == '\n')
X return;
X if (line[ch = strlen(line)-1] == '\n')
X line[ch] = '\0';
X m = dointerp(tmpbuf,tbsize,line," \t");
X if (!*m)
X return;
X while (*m == ' ' || *m == '\t') m++;
X for (s=tmpbuf,curmap=topmap; *s; s++) {
X ch = *s & 0177;
X if (s[1] == '+' && isdigit(s[2])) {
X s += 2;
X garbage = (*s & KM_GMASK) << KM_GSHIFT;
X }
X else
X garbage = 0;
X if (s[1]) {
X if ((curmap->km_type[ch] & KM_TMASK) == KM_STRING) {
X fputs(override,stdout) FLUSH;
X free(curmap->km_ptr[ch].km_str);
X curmap->km_ptr[ch].km_str = Nullch;
X }
X curmap->km_type[ch] = KM_KEYMAP + garbage;
X if (curmap->km_ptr[ch].km_km == Null(KEYMAP*))
X curmap->km_ptr[ch].km_km = newkeymap();
X curmap = curmap->km_ptr[ch].km_km;
X }
X else {
X if ((curmap->km_type[ch] & KM_TMASK) == KM_KEYMAP)
X fputs(override,stdout) FLUSH;
X else {
X curmap->km_type[ch] = KM_STRING + garbage;
X curmap->km_ptr[ch].km_str = savestr(m);
X }
X }
X }
X}
X
XKEYMAP*
Xnewkeymap()
X{
X register int i;
X register KEYMAP *map;
X
X#ifndef lint
X map = (KEYMAP*)safemalloc(sizeof(KEYMAP));
X#else
X map = Null(KEYMAP*);
X#endif /* lint */
X for (i=127; i>=0; --i) {
X map->km_ptr[i].km_km = Null(KEYMAP*);
X map->km_type[i] = KM_NOTHIN;
X }
X return map;
X}
X
Xvoid
Xshow_macros()
X{
X char prebuf[64];
X
X if (topmap != Null(KEYMAP*)) {
X print_lines("Macros:\n",STANDOUT);
X *prebuf = '\0';
X show_keymap(topmap,prebuf);
X }
X else {
X print_lines("No macros defined.\n", NOMARKING);
X }
X}
X
Xvoid
Xshow_keymap(curmap,prefix)
Xregister KEYMAP *curmap;
Xchar *prefix;
X{
X register int i;
X register char *next = prefix + strlen(prefix);
X register int kt;
X
X for (i=0; i<128; i++) {
X if (kt = curmap->km_type[i]) {
X if (i < ' ')
X sprintf(next,"^%c",i+64);
X else if (i == ' ')
X strcpy(next,"\\040");
X else if (i == 127)
X strcpy(next,"^?");
X else
X sprintf(next,"%c",i);
X if ((kt >> KM_GSHIFT) & KM_GMASK) {
X sprintf(cmd_buf,"+%d", (kt >> KM_GSHIFT) & KM_GMASK);
X strcat(next,cmd_buf);
X }
X switch (kt & KM_TMASK) {
X case KM_NOTHIN:
X sprintf(cmd_buf,"%s %c\n",prefix,i);
X print_lines(cmd_buf,NOMARKING);
X break;
X case KM_KEYMAP:
X show_keymap(curmap->km_ptr[(char)i].km_km, prefix);
X break;
X case KM_STRING:
X sprintf(cmd_buf,"%s %s\n",prefix,curmap->km_ptr[i].km_str);
X print_lines(cmd_buf,NOMARKING);
X break;
X case KM_BOGUS:
X sprintf(cmd_buf,"%s BOGUS\n",prefix);
X print_lines(cmd_buf,STANDOUT);
X break;
X }
X }
X }
X}
X
X#endif
X
X/* routine to pass to tputs */
X
Xchar
Xputchr(ch)
Xregister char ch;
X{
X putchar(ch);
X#ifdef lint
X ch = Null(char);
X ch = ch;
X#endif
X return((char) 0);
X}
X
X/* input the 2nd and succeeding characters of a multi-character command */
X/* returns TRUE if command finished, FALSE if they rubbed out first character */
X
Xbool
Xfinish_command(donewline)
Xint donewline;
X{
X register char *s;
X register bool quoteone = FALSE;
X
X s = buf;
X if (s[1] != FINISHCMD) /* someone faking up a command? */
X return TRUE;
X do {
X top:
X if ((unsigned char)*s < ' ') {
X putchar('^');
X putchar(*s | 64);
X }
X else if (*s == '\177') {
X putchar('^');
X putchar('?');
X }
X else
X putchar(*s); /* echo previous character */
X s++;
Xre_read:
X fflush(stdout);
X getcmd(s);
X if (quoteone) {
X quoteone = FALSE;
X continue;
X }
X if (errno || *s == Ctl('l')) {
X *s = Ctl('r'); /* force rewrite on CONT */
X }
X if (*s == '\033') { /* substitution desired? */
X#ifdef ESCSUBS
X char tmpbuf[4], *cpybuf;
X
X tmpbuf[0] = '%';
X read_tty(&tmpbuf[1],1);
X#ifdef RAWONLY
X tmpbuf[1] &= 0177;
X#endif
X tmpbuf[2] = '\0';
X if (tmpbuf[1] == 'h') {
X (void) help_subs();
X *s = '\0';
X reprint();
X goto re_read;
X }
X else if (tmpbuf[1] == '\033') {
X *s = '\0';
X cpybuf = savestr(buf);
X interp(buf, (sizeof buf), cpybuf);
X free(cpybuf);
X s = buf + strlen(buf);
X reprint();
X goto re_read;
X }
X else {
X interp(s,(sizeof buf) - (s-buf),tmpbuf);
X fputs(s,stdout);
X s += strlen(s);
X }
X goto re_read;
X#else
X notincl("^[");
X *s = '\0';
X reprint();
X goto re_read;
X#endif
X }
X else if (*s == ERASECH) { /* they want to rubout a char? */
X rubout();
X s--; /* discount the char rubbed out */
X if ((unsigned char)*s < ' ' || *s == '\177')
X rubout();
X if (s == buf) { /* entire string gone? */
X fflush(stdout); /* return to single char command mode */
X return FALSE;
X }
X else
X goto re_read;
X }
X else if (*s == KILLCH) { /* wipe out the whole line? */
X while (s-- != buf) { /* emulate that many ERASEs */
X rubout();
X if ((unsigned char)*s < ' ' || *s == '\177')
X rubout();
X }
X fflush(stdout);
X return FALSE; /* return to single char mode */
X }
X#ifdef WORDERASE
X else if (*s == Ctl('w')) { /* wipe out one word? */
X *s-- = ' ';
X while (!isspace(*s) || isspace(s[1])) {
X rubout();
X if (s-- == buf) {
X fflush(stdout);
X return FALSE; /* return to single char mode */
X }
X if ((unsigned char)*s < ' ' || *s == '\177')
X rubout();
X }
X s++;
X goto re_read;
X }
X#endif
X else if (*s == Ctl('r')) {
X *s = '\0';
X reprint();
X goto re_read;
X }
X else if (*s == Ctl('v')) {
X putchar('^');
X backspace();
X fflush(stdout);
X getcmd(s);
X goto top;
X }
X else if (*s == '\\') {
X quoteone = TRUE;
X }
X } while (*s != '\n'); /* till a newline (not echoed) */
X *s = '\0'; /* terminate the string nicely */
X if (donewline)
X putchar('\n') FLUSH;
X return TRUE; /* say we succeeded */
X}
X
X/* discard any characters typed ahead */
X
Xvoid
Xeat_typeahead()
X{
X#ifdef PUSHBACK
X if (!typeahead && nextin==nextout) /* cancel only keyboard stuff */
X#else
X if (!typeahead)
X#endif
X {
X#ifdef PENDING
X while (input_pending())
X read_tty(buf,sizeof(buf));
X#else /* this is probably v7 */
X ioctl(_tty_ch,TIOCSETP,&_tty);
X#endif
X }
X}
X
Xvoid
Xsettle_down()
X{
X dingaling();
X fflush(stdout);
X sleep(1);
X#ifdef PUSHBACK
X nextout = nextin; /* empty circlebuf */
X#endif
X eat_typeahead();
X}
X
X#ifdef PUSHBACK
X/* read a character from the terminal, with multi-character pushback */
X
Xint
Xread_tty(addr,size)
Xchar *addr;
Xint size;
X{
X if (nextout != nextin) {
X *addr = circlebuf[nextout++];
X nextout %= PUSHSIZE;
X return 1;
X }
X else {
X size = read(0,addr,size);
X#ifdef RAWONLY
X *addr &= 0177;
X#endif
X return size;
X }
X}
X
X#ifdef PENDING
X#if ! defined (FIONREAD) && ! defined (RDCHK)
Xint
Xcircfill()
X{
X register int Howmany = read(devtty,circlebuf+nextin,1);
X
X if (Howmany) {
X nextin += Howmany;
X nextin %= PUSHSIZE;
X }
X return Howmany;
X}
X#endif /* PENDING */
X#endif /* FIONREAD */
X
Xvoid
Xpushchar(c)
Xchar c;
X{
X nextout--;
X if (nextout < 0)
X nextout = PUSHSIZE - 1;
X if (nextout == nextin) {
X fputs("\npushback buffer overflow\n",stdout) FLUSH;
X sig_catcher(0);
X }
X circlebuf[nextout] = c;
X}
X
X#else /* PUSHBACK */
X#ifndef read_tty
X/* read a character from the terminal, with hacks for O_NDELAY reads */
X
Xint
Xread_tty(addr,size)
Xchar *addr;
Xint size;
X{
X if (is_input) {
X *addr = pending_ch;
X is_input = FALSE;
X return 1;
X }
X else {
X size = read(0,addr,size);
X#ifdef RAWONLY
X *addr &= 0177;
X#endif
X return size;
X }
X}
X#endif /* read_tty */
X#endif /* PUSHBACK */
X
X/* print an underlined string, one way or another */
X
Xvoid
Xunderprint(s)
Xregister char *s;
X{
X assert(UC);
X if (*UC) { /* char by char underline? */
X while (*s) {
X if ((unsigned char)*s < ' ') {
X putchar('^');
X backspace();/* back up over it */
X underchar();/* and do the underline */
X putchar(*s+64);
X backspace();/* back up over it */
X underchar();/* and do the underline */
X }
X else {
X putchar(*s);
X backspace();/* back up over it */
X underchar();/* and do the underline */
X }
X s++;
X }
X }
X else { /* start and stop underline */
X underline(); /* start underlining */
X while (*s) {
X if ((unsigned char)*s < ' ') {
X putchar('^');
X putchar(*s+64);
X }
X else
X putchar(*s);
X s++;
X }
X un_underline(); /* stop underlining */
X }
X}
X
X/* keep screen from flashing strangely on magic cookie terminals */
X
X#ifdef NOFIREWORKS
Xvoid
Xno_sofire()
X{
X if (*UP && *SE) { /* should we disable fireworks? */
X putchar('\n');
X un_standout();
X up_line();
X carriage_return();
X }
X}
X
Xvoid
Xno_ulfire()
X{
X if (*UP && *US) { /* should we disable fireworks? */
X putchar('\n');
X un_underline();
X up_line();
X carriage_return();
X }
X}
X#endif
X
X/* get a character into a buffer */
X
Xvoid
Xgetcmd(whatbuf)
Xregister char *whatbuf;
X{
X#ifdef PUSHBACK
X register KEYMAP *curmap;
X register int i;
X bool no_macros;
X int times = 0; /* loop detector */
X char scrchar;
X
Xtryagain:
X curmap = topmap;
X no_macros = (whatbuf != buf && nextin == nextout);
X#endif
X for (;;) {
X int_count = 0;
X errno = 0;
X if (read_tty(whatbuf,1) < 0)
X if (!errno)
X errno = EINTR;
X else {
X perror(readerr);
X sig_catcher(0);
X }
X#ifdef PUSHBACK
X if (*whatbuf & 0200 || no_macros) {
X *whatbuf &= 0177;
X goto got_canonical;
X }
X if (curmap == Null(KEYMAP*))
X goto got_canonical;
X for (i = (curmap->km_type[*whatbuf] >> KM_GSHIFT) & KM_GMASK; i; --i){
X read_tty(&scrchar,1);
X }
X switch (curmap->km_type[*whatbuf] & KM_TMASK) {
X case KM_NOTHIN: /* no entry? */
X if (curmap == topmap) /* unmapped canonical */
X goto got_canonical;
X settle_down();
X goto tryagain;
X case KM_KEYMAP: /* another keymap? */
X curmap = curmap->km_ptr[*whatbuf].km_km;
X assert(curmap != Null(KEYMAP*));
X break;
X case KM_STRING: /* a string? */
X pushstring(curmap->km_ptr[*whatbuf].km_str);
X if (++times > 20) { /* loop? */
X fputs("\nmacro loop?\n",stdout);
X settle_down();
X }
X no_macros = FALSE;
X goto tryagain;
X }
X#else
X#ifdef RAWONLY
X *whatbuf &= 0177;
X#endif
X break;
X#endif
X }
X
Xgot_canonical:
X#ifndef TERMIO
X if (*whatbuf == '\r')
X *whatbuf = '\n';
X#endif
X if (whatbuf == buf)
X whatbuf[1] = FINISHCMD; /* tell finish_command to work */
X}
X
X#ifdef PUSHBACK
Xvoid
Xpushstring(str)
Xchar *str;
X{
X register int i;
X char tmpbuf[PUSHSIZE];
X register char *s = tmpbuf;
X
X assert(str != Nullch);
X interp(s,PUSHSIZE,str);
X for (i = strlen(s)-1; i >= 0; --i) {
X s[i] ^= 0200;
X pushchar(s[i]);
X }
X}
X#endif
X
Xint
Xget_anything()
X{
X char tmpbuf[2];
X
Xreask_anything:
X unflush_output(); /* disable any ^O in effect */
X standout();
X#ifdef VERBOSE
X IF(verbose)
X fputs("[Type space to continue] ",stdout);
X ELSE
X#endif
X#ifdef TERSE
X fputs("[MORE] ",stdout);
X#endif
X un_standout();
X fflush(stdout);
X eat_typeahead();
X if (int_count) {
X return -1;
X }
X collect_subjects(); /* loads subject cache until */
X /* input is pending */
X getcmd(tmpbuf);
X if (errno || *tmpbuf == '\f') {
X putchar('\n') FLUSH; /* if return from stop signal */
X goto reask_anything; /* give them a prompt again */
X }
X if (*tmpbuf == 'h') {
X#ifdef VERBOSE
X IF(verbose)
X fputs("\nType q to quit or space to continue.\n",stdout) FLUSH;
X ELSE
X#endif
X#ifdef TERSE
X fputs("\nq to quit, space to continue.\n",stdout) FLUSH;
X#endif
X goto reask_anything;
X }
X else if (*tmpbuf != ' ' && *tmpbuf != '\n') {
X carriage_return();
X erase_eol(); /* erase the prompt */
X carriage_return();
X return *tmpbuf == 'q' ? -1 : *tmpbuf;
X }
X if (*tmpbuf == '\n') {
X page_line = LINES - 1;
X carriage_return();
X erase_eol();
X carriage_return();
X }
X else {
X page_line = 1;
X if (erase_screen) /* -e? */
X clear(); /* clear screen */
X else {
X carriage_return();
X erase_eol(); /* erase the prompt */
X carriage_return();
X }
X }
X return 0;
X}
X
X#ifdef USETHREADS
Xint
Xpause_getcmd()
X{
X unflush_output(); /* disable any ^O in effect */
X standout();
X#ifdef VERBOSE
X IF(verbose)
X fputs("[Type space or a command] ",stdout);
X ELSE
X#endif
X#ifdef TERSE
X fputs("[CMD] ",stdout);
X#endif
X un_standout();
X fflush(stdout);
X eat_typeahead();
X if (int_count) {
X return -1;
X }
X getcmd(buf);
X if (errno || *buf == '\f') {
X return 0; /* if return from stop signal */
X }
X else if (*buf != ' ') {
X carriage_return();
X erase_eol(); /* erase the prompt */
X carriage_return();
X return *buf;
X }
X return 0;
X}
X#endif
X
Xvoid
Xin_char(prompt, newmode)
Xchar *prompt;
Xchar newmode;
X{
X char oldmode = mode;
X
Xreask_in_char:
X unflush_output(); /* disable any ^O in effect */
X fputs(prompt,stdout);
X fflush(stdout);
X eat_typeahead();
X mode = newmode;
X getcmd(buf);
X if (errno || *buf == '\f') {
X putchar('\n') FLUSH; /* if return from stop signal */
X goto reask_in_char; /* give them a prompt again */
X }
X mode = oldmode;
X}
X
Xint
Xprint_lines(what_to_print,hilite)
Xchar *what_to_print;
Xint hilite;
X{
X register char *s;
X register int i;
X
X if (page_line < 0) /* they do not want to see this? */
X return -1;
X for (s=what_to_print; *s; ) {
X if (page_line >= LINES || int_count) {
X if (i = -1, int_count || (i = get_anything())) {
X page_line = -1; /* disable further print_lines */
X return i;
X }
X }
X page_line++;
X if (hilite == STANDOUT) {
X#ifdef NOFIREWORKS
X if (erase_screen)
X no_sofire();
X#endif
X standout();
X }
X else if (hilite == UNDERLINE) {
X#ifdef NOFIREWORKS
X if (erase_screen)
X no_ulfire();
X#endif
X underline();
X }
X for (i=0; i<COLS; i++) {
X if (!*s)
X break;
X if ((unsigned char)*s >= ' ')
X putchar(*s);
X else if (*s == '\t') {
X putchar(*s);
X i = ((i+8) & ~7) - 1;
X }
X else if (*s == '\n') {
X i = 32000;
X }
X else {
X i++;
X putchar('^');
X putchar(*s + 64);
X }
X s++;
X }
X if (i) {
X if (hilite == STANDOUT)
X un_standout();
X else if (hilite == UNDERLINE)
X un_underline();
X if (AM && i == COLS)
X fflush(stdout);
X else
X putchar('\n') FLUSH;
X }
X }
X return 0;
X}
X
Xvoid
Xpage_init()
X{
X page_line = 1;
X if (erase_screen)
X clear();
X else
X putchar('\n') FLUSH;
X}
X
Xvoid
Xpad(num)
Xint num;
X{
X register int i;
X
X for (i = num; i; --i)
X putchar(PC);
X fflush(stdout);
X}
X
X/* echo the command just typed */
X
X#ifdef VERIFY
Xvoid
Xprintcmd()
X{
X if (verify && buf[1] == FINISHCMD) {
X if ((unsigned char)*buf < ' ') {
X putchar('^');
X putchar(*buf | 64);
X backspace();
X backspace();
X }
X else {
X putchar(*buf);
X backspace();
X }
X fflush(stdout);
X }
X}
X#endif
X
Xvoid
Xrubout()
X{
X backspace(); /* do the old backspace, */
X putchar(' '); /* space, */
X backspace(); /* backspace trick */
X}
X
Xvoid
Xreprint()
X{
X register char *s;
X
X fputs("^R\n",stdout) FLUSH;
X for (s = buf; *s; s++) {
X if ((unsigned char)*s < ' ') {
X putchar('^');
X putchar(*s | 64);
X }
X else
X putchar(*s);
X }
X}
X
X#if defined(CLEAREOL) || defined(USETHREADS)
Xvoid
Xhome_cursor()
X{
X char *tgoto();
X
X if (!*HO) { /* no home sequence? */
X if (!*CM) { /* no cursor motion either? */
X fputs ("\n\n\n", stdout);
X return; /* forget it. */
X }
X tputs (tgoto (CM, 0, 0), 1, putchr); /* go to home via CM */
X return;
X }
X else { /* we have home sequence */
X tputs (HO, 1, putchr); /* home via HO */
X }
X}
X#endif
X
X#ifdef USETHREADS
Xvoid
Xgoto_line(from,to) /* assumes caller is already at beginning of line */
Xint from,to;
X{
X char *tgoto(), *str;
X int cmcost;
X
X if (from == to) {
X return;
X }
X if (*CM) {
X cmcost = strlen(str = tgoto(CM,0,to));
X } else {
X cmcost = 9999;
X }
X if (to > from) {
X go_down:
X if (to - from <= cmcost) {
X while(from++ < to) {
X putchar('\n');
X }
X return;
X }
X } else if(*UP) {
X if ((from - to) * upcost <= cmcost) {
X while(from-- > to) {
X tputs(UP,1,putchr);
X }
X return;
X }
X } else if (cmcost == 9999) {
X home_cursor();
X from = 0;
X goto go_down;
X }
X tputs(str,1,putchr);
X}
X#endif
X
X
Xvoid
Xline_col_calcs()
X{
X if (LINES > 0) { /* is this a crt? */
X if ((!initlines) || (!initlines_specified))
X /* no -i or unreasonable value for initlines */
X if (ospeed >= B9600) /* whole page at >= 9600 baud */
X initlines = LINES;
X else if (ospeed >= B4800)/* 16 lines at 4800 */
X initlines = 16;
X else /* otherwise just header */
X initlines = 8;
X }
X else { /* not a crt */
X LINES = 30000; /* so don't page */
X CL = "\n\n"; /* put a couple of lines between */
X if ((!initlines) || (!initlines_specified))
X /* make initlines reasonable */
X initlines = 8;
X }
X if (COLS <= 0)
X COLS = 80;
X}
X
X
X#ifdef SIGWINCH
Xint
Xwinch_catcher()
X{
X /* Come here if window size change signal received */
X#ifdef TIOCGWINSZ
X struct winsize ws;
X
X if (ioctl(0, TIOCGWINSZ, &ws) >= 0 && ws.ws_row > 0 && ws.ws_col > 0) {
X LINES = ws.ws_row;
X COLS = ws.ws_col;
X line_col_calcs();
X }
X#else
X ???????
X /* Well, if SIGWINCH is defined, but TIOCGWINSZ isn't, there's */
X /* almost certainly something wrong. Figure it out for yourself, */
X /* because I don't know now to deal :-) */
X#endif
X}
X#endif
END_OF_FILE
if test 25423 -ne `wc -c <'term.c'`; then
echo shar: \"'term.c'\" unpacked with wrong size!
fi
# end of 'term.c'
fi
echo shar: End of archive 7 \(of 14\).
cp /dev/null ark7isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 14 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still must unpack the following archives:
echo " " ${MISSING}
fi
exit 0
exit 0 # Just in case...
--
Please send comp.sources.unix-related mail to rsalz at uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.
More information about the Comp.sources.unix
mailing list