v07i052: 2.11 News Source, Part02/09

sources-request at mirror.UUCP sources-request at mirror.UUCP
Fri Nov 7 02:51:39 AEST 1986


Submitted by: seismo!rick (Rick Adams)
Mod.sources: Volume 7, Issue 52
Archive-name: 2.11news/Part12

# To extract, sh this file
#
#	news 2.11 source part 2 of 9
#
if test ! -d src
then
	mkdir src
fi
echo x - src/compress.c 1>&2
sed 's/.//' >src/compress.c <<'*-*-END-of-src/compress.c-*-*'
-#ifdef SCCSID
-static char	*SccsId = "@(#)compress.c	1.12	10/29/86";
-#endif SCCSID
-static char rcs_ident[] = "Based on compress.c,v 4.0 85/07/30 12:50:00 joe Release";
-
-/* 
- * Compress - data compression program 
- */
-#define	min(a,b)	((a>b) ? b : a)
-
-/*
- * machine variants which require cc -Dmachine:  pdp11, z8000, pcxt
- */
-
-/*
- * Set USERMEM to the maximum amount of physical user memory available
- * in bytes.  USERMEM is used to determine the maximum BITS that can be used
- * for compression.
- *
- * SACREDMEM is the amount of physical memory saved for others; compress
- * will hog the rest.
- */
-#ifndef SACREDMEM
-#define SACREDMEM	0
-#endif
-
-#ifndef USERMEM
-# define USERMEM 	450000	/* default user memory */
-#endif
-
-#ifdef interdata		/* (Perkin-Elmer) */
-#define SIGNED_COMPARE_SLOW	/* signed compare is slower than unsigned */
-#endif
-
-#ifdef pdp11
-# define BITS 	12	/* max bits/code for 16-bit machine */
-# define NO_UCHAR	/* also if "unsigned char" functions as signed char */
-# undef USERMEM 
-#endif /* pdp11 */	/* don't forget to compile with -i */
-
-#ifdef z8000
-# define BITS 	12
-# undef vax		/* weird preprocessor */
-# undef USERMEM 
-#endif /* z8000 */
-
-#ifdef pcxt
-# define BITS   12
-# undef USERMEM
-#endif /* pcxt */
-
-#ifdef USERMEM
-# if USERMEM >= (433484+SACREDMEM)
-#  define PBITS	16
-# else
-#  if USERMEM >= (229600+SACREDMEM)
-#   define PBITS	15
-#  else
-#   if USERMEM >= (127536+SACREDMEM)
-#    define PBITS	14
-#   else
-#    if USERMEM >= (73464+SACREDMEM)
-#     define PBITS	13
-#    else
-#     define PBITS	12
-#    endif
-#   endif
-#  endif
-# endif
-# undef USERMEM
-#endif /* USERMEM */
-
-#ifdef PBITS		/* Preferred BITS for this memory size */
-# ifndef BITS
-#  define BITS PBITS
-# endif BITS
-#endif /* PBITS */
-
-#if BITS == 16
-# define HSIZE	69001		/* 95% occupancy */
-#endif
-#if BITS == 15
-# define HSIZE	35023		/* 94% occupancy */
-#endif
-#if BITS == 14
-# define HSIZE	18013		/* 91% occupancy */
-#endif
-#if BITS == 13
-# define HSIZE	9001		/* 91% occupancy */
-#endif
-#if BITS <= 12
-# define HSIZE	5003		/* 80% occupancy */
-#endif
-
-#ifdef M_XENIX			/* Stupid compiler can't handle arrays with */
-# if BITS == 16			/* more than 65535 bytes - so we fake it */
-#  define XENIX_16
-# else
-#  if BITS > 13			/* Code only handles BITS = 12, 13, or 16 */
-#   define BITS	13
-#  endif
-# endif
-#endif
-
-/*
- * a code_int must be able to hold 2**BITS values of type int, and also -1
- */
-#if BITS > 15
-typedef long int	code_int;
-#else
-typedef int		code_int;
-#endif
-
-#ifdef SIGNED_COMPARE_SLOW
-typedef unsigned long int count_int;
-typedef unsigned short int count_short;
-#else
-typedef long int	  count_int;
-#endif
-
-#ifdef NO_UCHAR
- typedef char	char_type;
-#else
- typedef	unsigned char	char_type;
-#endif /* UCHAR */
-char_type magic_header[] = { "\037\235" };	/* 1F 9D */
-
-/* Defines for third byte of header */
-#define BIT_MASK	0x1f
-#define BLOCK_MASK	0x80
-/* Masks 0x40 and 0x20 are free.  I think 0x20 should mean that there is
-   a fourth header byte (for expansion).
-*/
-#define INIT_BITS 9			/* initial number of bits/code */
-
-/*
- * compress.c - File compression ala IEEE Computer, June 1984.
- *
- * Authors:	Spencer W. Thomas	(decvax!harpo!utah-cs!utah-gr!thomas)
- *		Jim McKie		(decvax!mcvax!jim)
- *		Steve Davies		(decvax!vax135!petsd!peora!srd)
- *		Ken Turkowski		(decvax!decwrl!turtlevax!ken)
- *		James A. Woods		(decvax!ihnp4!ames!jaw)
- *		Joe Orost		(decvax!vax135!petsd!joe)
- *
- */
-
-#include <stdio.h>
-#include <ctype.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#define ARGVAL() (*++(*argv) || (--argc && *++argv))
-
-int n_bits;				/* number of bits/code */
-int maxbits = BITS;			/* user settable max # bits/code */
-code_int maxcode;			/* maximum code, given n_bits */
-code_int maxmaxcode = 1L << BITS;	/* should NEVER generate this code */
-#ifdef COMPATIBLE		/* But wrong! */
-# define MAXCODE(n_bits)	(1 << (n_bits) - 1)
-#else
-# define MAXCODE(n_bits)	((1 << (n_bits)) - 1)
-#endif /* COMPATIBLE */
-
-#ifdef XENIX_16
-count_int htab0[8192];
-count_int htab1[8192];
-count_int htab2[8192];
-count_int htab3[8192];
-count_int htab4[8192];
-count_int htab5[8192];
-count_int htab6[8192];
-count_int htab7[8192];
-count_int htab8[HSIZE-65536];
-count_int * htab[9] = {
-	htab0, htab1, htab2, htab3, htab4, htab5, htab6, htab7, htab8 };
-
-#define htabof(i)	(htab[(i) >> 13][(i) & 0x1fff])
-unsigned short code0tab[16384];
-unsigned short code1tab[16384];
-unsigned short code2tab[16384];
-unsigned short code3tab[16384];
-unsigned short code4tab[16384];
-unsigned short * codetab[5] = {
-	code0tab, code1tab, code2tab, code3tab, code4tab };
-
-#define codetabof(i)	(codetab[(i) >> 14][(i) & 0x3fff])
-
-#else	/* Normal machine */
-# ifdef sel
-/* support gould base register problems */
-/*NOBASE*/
-count_int htab [HSIZE];
-unsigned short codetab [HSIZE];
-/*NOBASE*/
-# else /* !gould */
-count_int htab [HSIZE];
-unsigned short codetab [HSIZE];
-# endif /* !gould */
-#define htabof(i)	htab[i]
-#define codetabof(i)	codetab[i]
-#endif	/* !XENIX_16 */
-code_int hsize = HSIZE;			/* for dynamic table sizing */
-count_int fsize;
-
-/*
- * To save much memory, we overlay the table used by compress() with those
- * used by decompress().  The tab_prefix table is the same size and type
- * as the codetab.  The tab_suffix table needs 2**BITS characters.  We
- * get this from the beginning of htab.  The output stack uses the rest
- * of htab, and contains characters.  There is plenty of room for any
- * possible stack (stack used to be 8000 characters).
- */
-
-#define tab_prefixof(i)	codetabof(i)
-#ifdef XENIX_16
-# define tab_suffixof(i)	((char_type *)htab[(i)>>15])[(i) & 0x7fff]
-# define de_stack		((char_type *)(htab2))
-#else	/* Normal machine */
-# define tab_suffixof(i)	((char_type *)(htab))[i]
-# define de_stack		((char_type *)&tab_suffixof(1<<BITS))
-#endif	/* XENIX_16 */
-
-code_int free_ent = 0;			/* first unused entry */
-int exit_stat = 0;
-
-code_int getcode();
-
-Usage() {
-#ifdef DEBUG
-fprintf(stderr,"Usage: compress [-dDVfc] [-b maxbits] [file ...]\n");
-}
-int debug = 0;
-#else
-fprintf(stderr,"Usage: compress [-dfvcV] [-b maxbits] [file ...]\n");
-}
-#endif /* DEBUG */
-int nomagic = 0;	/* Use a 3-byte magic number header, unless old file */
-int zcat_flg = 0;	/* Write output on stdout, suppress messages */
-int quiet = 1;		/* don't tell me about compression */
-
-/*
- * block compression parameters -- after all codes are used up,
- * and compression rate changes, start over.
- */
-int block_compress = BLOCK_MASK;
-int clear_flg = 0;
-long int ratio = 0;
-#define CHECK_GAP 10000	/* ratio check interval */
-count_int checkpoint = CHECK_GAP;
-/*
- * the next two codes should not be changed lightly, as they must not
- * lie within the contiguous general code space.
- */ 
-#define FIRST	257	/* first free entry */
-#define	CLEAR	256	/* table clear output code */
-
-int force = 0;
-char ofname [100];
-#ifdef DEBUG
-int verbose = 0;
-#endif /* DEBUG */
-int (*bgnd_flag)();
-
-int do_decomp = 0;
-
-/*****************************************************************
- * TAG( main )
- *
- * Algorithm from "A Technique for High Performance Data Compression",
- * Terry A. Welch, IEEE Computer Vol 17, No 6 (June 1984), pp 8-19.
- *
- * Usage: compress [-dfvc] [-b bits] [file ...]
- * Inputs:
- *	-d:	    If given, decompression is done instead.
- *
- *      -c:         Write output on stdout, don't remove original.
- *
- *      -b:         Parameter limits the max number of bits/code.
- *
- *	-f:	    Forces output file to be generated, even if one already
- *		    exists, and even if no space is saved by compressing.
- *		    If -f is not used, the user will be prompted if stdin is
- *		    a tty, otherwise, the output file will not be overwritten.
- *
- *      -v:	    Write compression statistics
- *
- * 	file ...:   Files to be compressed.  If none specified, stdin
- *		    is used.
- * Outputs:
- *	file.Z:	    Compressed form of file with same mode, owner, and utimes
- * 	or stdout   (if stdin used as input)
- *
- * Assumptions:
- *	When filenames are given, replaces with the compressed version
- *	(.Z suffix) only if the file decreases in size.
- * Algorithm:
- * 	Modified Lempel-Ziv method (LZW).  Basically finds common
- * substrings and replaces them with a variable size code.  This is
- * deterministic, and can be done on the fly.  Thus, the decompression
- * procedure needs no input table, but tracks the way the table was built.
- */
-
-main( argc, argv )
-register int argc; char **argv;
-{
-    int overwrite = 0;	/* Do not overwrite unless given -f flag */
-    char tempname[100];
-    char **filelist, **fileptr;
-    char *cp, *rindex(), *malloc();
-    struct stat statbuf;
-    extern onintr(), oops();
-
-
-    if ( (bgnd_flag = signal ( SIGINT, SIG_IGN )) != SIG_IGN ) {
-	signal ( SIGINT, onintr );
-	signal ( SIGSEGV, oops );
-    }
-
-#ifdef COMPATIBLE
-    nomagic = 1;	/* Original didn't have a magic number */
-#endif /* COMPATIBLE */
-
-    filelist = fileptr = (char **)(malloc(argc * sizeof(*argv)));
-    *filelist = NULL;
-
-    if((cp = rindex(argv[0], '/')) != 0) {
-	cp++;
-    } else {
-	cp = argv[0];
-    }
-    if(strcmp(cp, "uncompress") == 0) {
-	do_decomp = 1;
-    } else if(strcmp(cp, "zcat") == 0) {
-	do_decomp = 1;
-	zcat_flg = 1;
-    }
-
-#ifdef BSD4_2
-    /* 4.2BSD dependent - take it out if not */
-    setlinebuf( stderr );
-#endif /* BSD4_2 */
-
-    /* Argument Processing
-     * All flags are optional.
-     * -D => debug
-     * -V => print Version; debug verbose
-     * -d => do_decomp
-     * -v => unquiet
-     * -f => force overwrite of output file
-     * -n => no header: useful to uncompress old files
-     * -b maxbits => maxbits.  If -b is specified, then maxbits MUST be
-     *	    given also.
-     * -c => cat all output to stdout
-     * -C => generate output compatible with compress 2.0.
-     * if a string is left, must be an input filename.
-     */
-    for (argc--, argv++; argc > 0; argc--, argv++) {
-	if (**argv == '-') {	/* A flag argument */
-	    while (*++(*argv)) {	/* Process all flags in this arg */
-		switch (**argv) {
-#ifdef DEBUG
-		    case 'D':
-			debug = 1;
-			break;
-		    case 'V':
-			verbose = 1;
-			version();
-			break;
-#else
-		    case 'V':
-			version();
-			break;
-#endif /* DEBUG */
-		    case 'v':
-			quiet = 0;
-			break;
-		    case 'd':
-			do_decomp = 1;
-			break;
-		    case 'f':
-		    case 'F':
-			overwrite = 1;
-			force = 1;
-			break;
-		    case 'n':
-			nomagic = 1;
-			break;
-		    case 'C':
-			block_compress = 0;
-			break;
-		    case 'b':
-			if (!ARGVAL()) {
-			    fprintf(stderr, "Missing maxbits\n");
-			    Usage();
-			    exit(1);
-			}
-			maxbits = atoi(*argv);
-			goto nextarg;
-		    case 'c':
-			zcat_flg = 1;
-			break;
-		    case 'q':
-			quiet = 1;
-			break;
-		    default:
-			fprintf(stderr, "Unknown flag: '%c'; ", **argv);
-			Usage();
-			exit(1);
-		}
-	    }
-	}
-	else {		/* Input file name */
-	    *fileptr++ = *argv;	/* Build input file list */
-	    *fileptr = NULL;
-	    /* process nextarg; */
-	}
-	nextarg: continue;
-    }
-
-    if(maxbits < INIT_BITS) maxbits = INIT_BITS;
-    if (maxbits > BITS) maxbits = BITS;
-    maxmaxcode = 1L << maxbits;
-
-    if (*filelist != NULL) {
-	for (fileptr = filelist; *fileptr; fileptr++) {
-	    exit_stat = 0;
-	    if (do_decomp != 0) {			/* DECOMPRESSION */
-		/* Check for .Z suffix */
-		if (strcmp(*fileptr + strlen(*fileptr) - 2, ".Z") != 0) {
-		    /* No .Z: tack one on */
-		    strcpy(tempname, *fileptr);
-		    strcat(tempname, ".Z");
-		    *fileptr = tempname;
-		}
-		/* Open input file */
-		if ((freopen(*fileptr, "r", stdin)) == NULL) {
-			perror(*fileptr); continue;
-		}
-		/* Check the magic number */
-		if (nomagic == 0) {
-		    if ((getchar() != (magic_header[0] & 0xFF))
-		     || (getchar() != (magic_header[1] & 0xFF))) {
-			fprintf(stderr, "%s: not in compressed format\n",
-			    *fileptr);
-		    continue;
-		    }
-		    maxbits = getchar();	/* set -b from file */
-		    block_compress = maxbits & BLOCK_MASK;
-		    maxbits &= BIT_MASK;
-		    maxmaxcode = 1L << maxbits;
-		    if(maxbits > BITS) {
-			fprintf(stderr,
-			"%s: compressed with %d bits, can only handle %d bits\n",
-			*fileptr, maxbits, BITS);
-			continue;
-		    }
-		}
-		/* Generate output filename */
-		strcpy(ofname, *fileptr);
-		ofname[strlen(*fileptr) - 2] = '\0';  /* Strip off .Z */
-	    } else {					/* COMPRESSION */
-		if (strcmp(*fileptr + strlen(*fileptr) - 2, ".Z") == 0) {
-		    	fprintf(stderr, "%s: already has .Z suffix -- no change\n",
-			    *fileptr);
-		    continue;
-		}
-		/* Open input file */
-		if ((freopen(*fileptr, "r", stdin)) == NULL) {
-		    perror(*fileptr); continue;
-		}
-		stat ( *fileptr, &statbuf );
-		fsize = (long) statbuf.st_size;
-		/*
-		 * tune hash table size for small files -- ad hoc,
-		 * but the sizes match earlier #defines, which
-		 * serve as upper bounds on the number of output codes. 
-		 */
-		hsize = HSIZE;
-		if ( fsize < (1 << 12) )
-		    hsize = min ( 5003, HSIZE );
-		else if ( fsize < (1 << 13) )
-		    hsize = min ( 9001, HSIZE );
-		else if ( fsize < (1 << 14) )
-		    hsize = min ( 18013, HSIZE );
-		else if ( fsize < (1 << 15) )
-		    hsize = min ( 35023, HSIZE );
-		else if ( fsize < 47000 )
-		    hsize = min ( 50021, HSIZE );
-
-		/* Generate output filename */
-		strcpy(ofname, *fileptr);
-#ifndef BSD4_2		/* Short filenames */
-		if ((cp=rindex(ofname,'/')) != NULL)	cp++;
-		else					cp = ofname;
-		if (strlen(cp) > 12) {
-		    fprintf(stderr,"%s: filename too long to tack on .Z\n",cp);
-		    continue;
-		}
-#endif  /* BSD4_2		Long filenames allowed */
-		strcat(ofname, ".Z");
-	    }
-	    /* Check for overwrite of existing file */
-	    if (overwrite == 0 && zcat_flg == 0) {
-		if (stat(ofname, &statbuf) == 0) {
-		    char response[2];
-		    response[0] = 'n';
-		    fprintf(stderr, "%s already exists;", ofname);
-		    if (foreground()) {
-			fprintf(stderr, " do you wish to overwrite %s (y or n)? ",
-			ofname);
-			fflush(stderr);
-			read(2, response, 2);
-			while (response[1] != '\n') {
-			    if (read(2, response+1, 1) < 0) {	/* Ack! */
-				perror("stderr"); break;
-			    }
-			}
-		    }
-		    if (response[0] != 'y') {
-			fprintf(stderr, "\tnot overwritten\n");
-			continue;
-		    }
-		}
-	    }
-	    if(zcat_flg == 0) {		/* Open output file */
-		if (freopen(ofname, "w", stdout) == NULL) {
-		    perror(ofname);
-		    continue;
-		}
-		if(!quiet)
-			fprintf(stderr, "%s: ", *fileptr);
-	    }
-
-	    /* Actually do the compression/decompression */
-	    if (do_decomp == 0)	compress();
-#ifndef DEBUG
-	    else			decompress();
-#else
-	    else if (debug == 0)	decompress();
-	    else			printcodes();
-	    if (verbose)		dump_tab();
-#endif /* DEBUG */
-	    if(zcat_flg == 0) {
-		copystat(*fileptr, ofname);	/* Copy stats */
-		if((exit_stat == 1) || (!quiet))
-			putc('\n', stderr);
-	    }
-	}
-    } else {		/* Standard input */
-	if (do_decomp == 0) {
-		compress();
-#ifdef DEBUG
-		if(verbose)		dump_tab();
-#endif /* DEBUG */
-		if(!quiet)
-			putc('\n', stderr);
-	} else {
-	    /* Check the magic number */
-	    if (nomagic == 0) {
-		if ((getchar()!=(magic_header[0] & 0xFF))
-		 || (getchar()!=(magic_header[1] & 0xFF))) {
-		    fprintf(stderr, "stdin: not in compressed format\n");
-		    exit(1);
-		}
-		maxbits = getchar();	/* set -b from file */
-		block_compress = maxbits & BLOCK_MASK;
-		maxbits &= BIT_MASK;
-		maxmaxcode = 1L << maxbits;
-		fsize = 100000;		/* assume stdin large for USERMEM */
-		if(maxbits > BITS) {
-			fprintf(stderr,
-			"stdin: compressed with %d bits, can only handle %d bits\n",
-			maxbits, BITS);
-			exit(1);
-		}
-	    }
-#ifndef DEBUG
-	    decompress();
-#else
-	    if (debug == 0)	decompress();
-	    else		printcodes();
-	    if (verbose)	dump_tab();
-#endif /* DEBUG */
-	}
-    }
-    exit(exit_stat);
-}
-
-static int offset;
-long int in_count = 1;			/* length of input */
-long int bytes_out;			/* length of compressed output */
-long int out_count = 0;			/* # of codes output (for debugging) */
-
-/*
- * compress stdin to stdout
- *
- * Algorithm:  use open addressing double hashing (no chaining) on the 
- * prefix code / next character combination.  We do a variant of Knuth's
- * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
- * secondary probe.  Here, the modular division first probe is gives way
- * to a faster exclusive-or manipulation.  Also do block compression with
- * an adaptive reset, whereby the code table is cleared when the compression
- * ratio decreases, but after the table fills.  The variable-length output
- * codes are re-sized at this point, and a special CLEAR code is generated
- * for the decompressor.  Late addition:  construct the table according to
- * file size for noticeable speed improvement on small files.  Please direct
- * questions about this implementation to ames!jaw.
- */
-
-compress() {
-    register long fcode;
-    register code_int i = 0;
-    register int c;
-    register code_int ent;
-#ifdef XENIX_16
-    register code_int disp;
-#else	/* Normal machine */
-    register int disp;
-#endif
-    register code_int hsize_reg;
-    register int hshift;
-
-#ifndef COMPATIBLE
-    if (nomagic == 0) {
-	putchar(magic_header[0]); putchar(magic_header[1]);
-	putchar((char)(maxbits | block_compress));
-	if(ferror(stdout))
-		writeerr();
-    }
-#endif /* COMPATIBLE */
-
-    offset = 0;
-    bytes_out = 3;		/* includes 3-byte header mojo */
-    out_count = 0;
-    clear_flg = 0;
-    ratio = 0;
-    in_count = 1;
-    checkpoint = CHECK_GAP;
-    maxcode = MAXCODE(n_bits = INIT_BITS);
-    free_ent = ((block_compress) ? FIRST : 256 );
-
-    ent = getchar ();
-
-    hshift = 0;
-    for ( fcode = (long) hsize;  fcode < 65536L; fcode *= 2L )
-    	hshift++;
-    hshift = 8 - hshift;		/* set hash code range bound */
-
-    hsize_reg = hsize;
-    cl_hash( (count_int) hsize_reg);		/* clear hash table */
-
-#ifdef SIGNED_COMPARE_SLOW
-    while ( (c = getchar()) != (unsigned) EOF ) {
-#else
-    while ( (c = getchar()) != EOF ) {
-#endif
-	in_count++;
-	fcode = (long) (((long) c << maxbits) + ent);
- 	i = (((long)c << hshift) ^ ent);	/* xor hashing */
-
-	if ( htabof (i) == fcode ) {
-	    ent = codetabof (i);
-	    continue;
-	} else if ( (long)htabof (i) < 0 )	/* empty slot */
-	    goto nomatch;
- 	disp = hsize_reg - i;		/* secondary hash (after G. Knott) */
-	if ( i == 0 )
-	    disp = 1;
-probe:
-	if ( (i -= disp) < 0 )
-	    i += hsize_reg;
-
-	if ( htabof (i) == fcode ) {
-	    ent = codetabof (i);
-	    continue;
-	}
-	if ( (long)htabof (i) > 0 ) 
-	    goto probe;
-nomatch:
-	output ( (code_int) ent );
-	out_count++;
- 	ent = c;
-#ifdef SIGNED_COMPARE_SLOW
-	if ( (unsigned) free_ent < (unsigned) maxmaxcode) {
-#else
-	if ( free_ent < maxmaxcode ) {
-#endif
- 	    codetabof (i) = free_ent++;	/* code -> hashtable */
-	    htabof (i) = fcode;
-	}
-	else if ( (count_int)in_count >= checkpoint && block_compress )
-	    cl_block ();
-    }
-    /*
-     * Put out the final code.
-     */
-    output( (code_int)ent );
-    out_count++;
-    output( (code_int)-1 );
-
-    /*
-     * Print out stats on stderr
-     */
-    if(zcat_flg == 0 && !quiet) {
-#ifdef DEBUG
-	fprintf( stderr,
-		"%ld chars in, %ld codes (%ld bytes) out, compression factor: ",
-		in_count, out_count, bytes_out );
-	prratio( stderr, in_count, bytes_out );
-	fprintf( stderr, "\n");
-	fprintf( stderr, "\tCompression as in compact: " );
-	prratio( stderr, in_count-bytes_out, in_count );
-	fprintf( stderr, "\n");
-	fprintf( stderr, "\tLargest code (of last block) was %d (%d bits)\n",
-		free_ent - 1, n_bits );
-#else /* !DEBUG */
-	fprintf( stderr, "Compression: " );
-	prratio( stderr, in_count-bytes_out, in_count );
-#endif /* DEBUG */
-    }
-    if(bytes_out > in_count)	/* exit(2) if no savings */
-	exit_stat = 2;
-    return;
-}
-
-/*****************************************************************
- * TAG( output )
- *
- * Output the given code.
- * Inputs:
- * 	code:	A n_bits-bit integer.  If == -1, then EOF.  This assumes
- *		that n_bits =< (long)wordsize - 1.
- * Outputs:
- * 	Outputs code to the file.
- * Assumptions:
- *	Chars are 8 bits long.
- * Algorithm:
- * 	Maintain a BITS character long buffer (so that 8 codes will
- * fit in it exactly).  Use the VAX insv instruction to insert each
- * code in turn.  When the buffer fills up empty it and start over.
- */
-
-static char buf[BITS];
-
-#ifndef vax
-char_type lmask[9] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
-char_type rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
-#endif /* vax */
-
-output( code )
-code_int  code;
-{
-#ifdef DEBUG
-    static int col = 0;
-#endif /* DEBUG */
-
-    /*
-     * On the VAX, it is important to have the register declarations
-     * in exactly the order given, or the asm will break.
-     */
-    register int r_off = offset, bits= n_bits;
-    register char * bp = buf;
-
-#ifdef DEBUG
-	if ( verbose )
-	    fprintf( stderr, "%5d%c", code,
-		    (col+=6) >= 74 ? (col = 0, '\n') : ' ' );
-#endif /* DEBUG */
-    if ( code >= 0 ) {
-#ifdef vax
-	/* VAX DEPENDENT!! Implementation on other machines is below.
-	 *
-	 * Translation: Insert BITS bits from the argument starting at
-	 * offset bits from the beginning of buf.
-	 */
-	0;	/* Work around for pcc -O bug with asm and if stmt */
-	asm( "insv	4(ap),r11,r10,(r9)" );
-#else /* not a vax */
-/* 
- * byte/bit numbering on the VAX is simulated by the following code
- */
-	/*
-	 * Get to the first byte.
-	 */
-	bp += (r_off >> 3);
-	r_off &= 7;
-	/*
-	 * Since code is always >= 8 bits, only need to mask the first
-	 * hunk on the left.
-	 */
-	*bp = (*bp & rmask[r_off]) | (code << r_off) & lmask[r_off];
-	bp++;
-	bits -= (8 - r_off);
-	code >>= 8 - r_off;
-	/* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
-	if ( bits >= 8 ) {
-	    *bp++ = code;
-	    code >>= 8;
-	    bits -= 8;
-	}
-	/* Last bits. */
-	if(bits)
-	    *bp = code;
-#endif /* vax */
-	offset += n_bits;
-	if ( offset == (n_bits << 3) ) {
-	    bp = buf;
-	    bits = n_bits;
-	    bytes_out += bits;
-	    do
-		putchar(*bp++);
-	    while(--bits);
-	    offset = 0;
-	}
-
-	/*
-	 * If the next entry is going to be too big for the code size,
-	 * then increase it, if possible.
-	 */
-	if ( free_ent > maxcode || (clear_flg > 0))
-	{
-	    /*
-	     * Write the whole buffer, because the input side won't
-	     * discover the size increase until after it has read it.
-	     */
-	    if ( offset > 0 ) {
-		if( fwrite( buf, 1, n_bits, stdout ) != n_bits)
-			writeerr();
-		bytes_out += n_bits;
-	    }
-	    offset = 0;
-
-	    if ( clear_flg ) {
-    	        maxcode = MAXCODE (n_bits = INIT_BITS);
-	        clear_flg = 0;
-	    }
-	    else {
-	    	n_bits++;
-	    	if ( n_bits == maxbits )
-		    maxcode = maxmaxcode;
-	    	else
-		    maxcode = MAXCODE(n_bits);
-	    }
-#ifdef DEBUG
-	    if ( debug ) {
-		fprintf( stderr, "\nChange to %d bits\n", n_bits );
-		col = 0;
-	    }
-#endif /* DEBUG */
-	}
-    } else {
-	/*
-	 * At EOF, write the rest of the buffer.
-	 */
-	if ( offset > 0 )
-	    fwrite( buf, 1, (offset + 7) / 8, stdout );
-	bytes_out += (offset + 7) / 8;
-	offset = 0;
-	fflush( stdout );
-#ifdef DEBUG
-	if ( verbose )
-	    fprintf( stderr, "\n" );
-#endif /* DEBUG */
-	if( ferror( stdout ) )
-		writeerr();
-    }
-}
-
-/*
- * Decompress stdin to stdout.  This routine adapts to the codes in the
- * file building the "string" table on-the-fly; requiring no table to
- * be stored in the compressed file.  The tables used herein are shared
- * with those of the compress() routine.  See the definitions above.
- */
-
-decompress() {
-    register char_type *stackp;
-    register int finchar;
-    register code_int code, oldcode, incode;
-
-    /*
-     * As above, initialize the first 256 entries in the table.
-     */
-    maxcode = MAXCODE(n_bits = INIT_BITS);
-    for ( code = 255; code >= 0; code-- ) {
-	tab_prefixof(code) = 0;
-	tab_suffixof(code) = (char_type)code;
-    }
-    free_ent = ((block_compress) ? FIRST : 256 );
-
-    finchar = oldcode = getcode();
-    if(oldcode == -1)	/* EOF already? */
-	return;			/* Get out of here */
-    putchar( (char)finchar );		/* first code must be 8 bits = char */
-    if(ferror(stdout))		/* Crash if can't write */
-	writeerr();
-    stackp = de_stack;
-
-    while ( (code = getcode()) > -1 ) {
-
-	if ( (code == CLEAR) && block_compress ) {
-	    for ( code = 255; code >= 0; code-- )
-		tab_prefixof(code) = 0;
-	    clear_flg = 1;
-	    free_ent = FIRST - 1;
-	    if ( (code = getcode ()) == -1 )	/* O, untimely death! */
-		break;
-	}
-	incode = code;
-	/*
-	 * Special case for KwKwK string.
-	 */
-	if ( code >= free_ent ) {
-            *stackp++ = finchar;
-	    code = oldcode;
-	}
-
-	/*
-	 * Generate output characters in reverse order
-	 */
-#ifdef SIGNED_COMPARE_SLOW
-	while ( ((unsigned long)code) >= ((unsigned long)256) ) {
-#else
-	while ( code >= 256 ) {
-#endif
-	    *stackp++ = tab_suffixof(code);
-	    code = tab_prefixof(code);
-	}
-	*stackp++ = finchar = tab_suffixof(code);
-
-	/*
-	 * And put them out in forward order
-	 */
-	do
-	    putchar ( *--stackp );
-	while ( stackp > de_stack );
-
-	/*
-	 * Generate the new entry.
-	 */
-	if ( (code=free_ent) < maxmaxcode ) {
-	    tab_prefixof(code) = (unsigned short)oldcode;
-	    tab_suffixof(code) = finchar;
-	    free_ent = code+1;
-	} 
-	/*
-	 * Remember previous code.
-	 */
-	oldcode = incode;
-    }
-    fflush( stdout );
-    if(ferror(stdout))
-	writeerr();
-}
-
-/*****************************************************************
- * TAG( getcode )
- *
- * Read one code from the standard input.  If EOF, return -1.
- * Inputs:
- * 	stdin
- * Outputs:
- * 	code or -1 is returned.
- */
-
-code_int
-getcode() {
-    /*
-     * On the VAX, it is important to have the register declarations
-     * in exactly the order given, or the asm will break.
-     */
-    register code_int code;
-    static int offset = 0, size = 0;
-    static char_type buf[BITS];
-    register int r_off, bits;
-    register char_type *bp = buf;
-
-    if ( clear_flg > 0 || offset >= size || free_ent > maxcode ) {
-	/*
-	 * If the next entry will be too big for the current code
-	 * size, then we must increase the size.  This implies reading
-	 * a new buffer full, too.
-	 */
-	if ( free_ent > maxcode ) {
-	    n_bits++;
-	    if ( n_bits == maxbits )
-		maxcode = maxmaxcode;	/* won't get any bigger now */
-	    else
-		maxcode = MAXCODE(n_bits);
-	}
-	if ( clear_flg > 0) {
-    	    maxcode = MAXCODE (n_bits = INIT_BITS);
-	    clear_flg = 0;
-	}
-	size = fread( buf, 1, n_bits, stdin );
-	if ( size <= 0 )
-	    return -1;			/* end of file */
-	offset = 0;
-	/* Round size down to integral number of codes */
-	size = (size << 3) - (n_bits - 1);
-    }
-    r_off = offset;
-    bits = n_bits;
-#ifdef vax
-    asm( "extzv   r10,r9,(r8),r11" );
-#else /* not a vax */
-	/*
-	 * Get to the first byte.
-	 */
-	bp += (r_off >> 3);
-	r_off &= 7;
-	/* Get first part (low order bits) */
-#ifdef NO_UCHAR
-	code = ((*bp++ >> r_off) & rmask[8 - r_off]) & 0xff;
-#else
-	code = (*bp++ >> r_off);
-#endif /* NO_UCHAR */
-	bits -= (8 - r_off);
-	r_off = 8 - r_off;		/* now, offset into code word */
-	/* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
-	if ( bits >= 8 ) {
-#ifdef NO_UCHAR
-	    code |= (*bp++ & 0xff) << r_off;
-#else
-	    code |= *bp++ << r_off;
-#endif /* NO_UCHAR */
-	    r_off += 8;
-	    bits -= 8;
-	}
-	/* high order bits. */
-	code |= (*bp & rmask[bits]) << r_off;
-#endif /* vax */
-    offset += n_bits;
-
-    return code;
-}
-
-char *
-rindex(s, c)		/* For those who don't have it in libc.a */
-register char *s, c;
-{
-	char *p;
-	for (p = NULL; *s; s++)
-	    if (*s == c)
-		p = s;
-	return(p);
-}
-
-#ifdef DEBUG
-printcodes()
-{
-    /*
-     * Just print out codes from input file.  For debugging.
-     */
-    code_int code;
-    int col = 0, bits;
-
-    bits = n_bits = INIT_BITS;
-    maxcode = MAXCODE(n_bits);
-    free_ent = ((block_compress) ? FIRST : 256 );
-    while ( ( code = getcode() ) >= 0 ) {
-	if ( (code == CLEAR) && block_compress ) {
-   	    free_ent = FIRST - 1;
-   	    clear_flg = 1;
-	}
-	else if ( free_ent < maxmaxcode )
-	    free_ent++;
-	if ( bits != n_bits ) {
-	    fprintf(stderr, "\nChange to %d bits\n", n_bits );
-	    bits = n_bits;
-	    col = 0;
-	}
-	fprintf(stderr, "%5d%c", code, (col+=6) >= 74 ? (col = 0, '\n') : ' ' );
-    }
-    putc( '\n', stderr );
-    exit( 0 );
-}
-
-#ifdef XENIX_16
-code_int stab1[8192] ;
-code_int stab2[8192] ;
-code_int stab3[8192] ;
-code_int stab4[8192] ;
-code_int stab5[8192] ;
-code_int stab6[8192] ;
-code_int stab7[8192] ;
-code_int stab8[8192] ;
-code_int * sorttab[8] = {stab1, stab2, stab3, stab4, stab5, stab6, stab7,
-						 stab8 } ;
-#define stabof(i) (sorttab[(i) >> 13][(i) & 0x1fff]) 
-#else
-code_int sorttab[SSIZE];	/* sorted pointers into htab */
-#define stabof(i) (sorttab[i])
-#endif
-
-dump_tab()	/* dump string table */
-{
-    register int i, first;
-    register ent;
-#define STACK_SIZE	15000
-    int stack_top = STACK_SIZE;
-    register c;
-	unsigned mbshift ;
-
-    if(do_decomp == 0) {	/* compressing */
-	register int flag = 1;
-
-	for(i=0; i<hsize; i++) {	/* build sort pointers */
-		if((long)htabof(i) >= 0) {
-			stabof(codetabof(i)) = i;
-		}
-	}
-	first = block_compress ? FIRST : 256;
-	for(i = first; i < free_ent; i++) {
-		fprintf(stderr, "%5d: \"", i);
-		de_stack[--stack_top] = '\n';
-		de_stack[--stack_top] = '"';
-		stack_top = in_stack((htabof(stabof(i))>>maxbits)&0xff, 
-                                     stack_top);
-/*		for(ent=htabof(stabof(i)) & ((1<<maxbits)-1); */
-		mbshift = ((1 << maxbits) - 1) ;
-		ent = htabof(stabof(i)) & mbshift ;
-		for(;
-		    ent > 256;
-		    /* ent=htabof(stabof(ent)) & ((1<<maxbits)-1)) { */
-		    ent=htabof(stabof(ent)) & mbshift) {
-			stack_top = in_stack(htabof(stabof(ent)) >> maxbits,
-						stack_top);
-		}
-		stack_top = in_stack(ent, stack_top);
-		fwrite( &de_stack[stack_top], 1, STACK_SIZE-stack_top, stderr);
-	   	stack_top = STACK_SIZE;
-	}
-   } else if(!debug) {	/* decompressing */
-
-       for ( i = 0; i < free_ent; i++ ) {
-	   ent = i;
-	   c = tab_suffixof(ent);
-	   if ( isascii(c) && isprint(c) )
-	       fprintf( stderr, "%5d: %5d/'%c'  \"",
-			   ent, tab_prefixof(ent), c );
-	   else
-	       fprintf( stderr, "%5d: %5d/\\%03o \"",
-			   ent, tab_prefixof(ent), c );
-	   de_stack[--stack_top] = '\n';
-	   de_stack[--stack_top] = '"';
-	   for ( ; ent != NULL;
-		   ent = (ent >= FIRST ? tab_prefixof(ent) : NULL) ) {
-	       stack_top = in_stack(tab_suffixof(ent), stack_top);
-	   }
-	   fwrite( &de_stack[stack_top], 1, STACK_SIZE - stack_top, stderr );
-	   stack_top = STACK_SIZE;
-       }
-    }
-}
-
-int
-in_stack(c, stack_top)
-	register c, stack_top;
-{
-	if ( (isascii(c) && isprint(c) && c != '\\') || c == ' ' ) {
-	    de_stack[--stack_top] = c;
-	} else {
-	    switch( c ) {
-	    case '\n': de_stack[--stack_top] = 'n'; break;
-	    case '\t': de_stack[--stack_top] = 't'; break;
-	    case '\b': de_stack[--stack_top] = 'b'; break;
-	    case '\f': de_stack[--stack_top] = 'f'; break;
-	    case '\r': de_stack[--stack_top] = 'r'; break;
-	    case '\\': de_stack[--stack_top] = '\\'; break;
-	    default:
-	 	de_stack[--stack_top] = '0' + c % 8;
-	 	de_stack[--stack_top] = '0' + (c / 8) % 8;
-	 	de_stack[--stack_top] = '0' + c / 64;
-	 	break;
-	    }
-	    de_stack[--stack_top] = '\\';
-	}
-	return stack_top;
-}
-#endif /* DEBUG */
-
-writeerr()
-{
-    perror ( ofname );
-    unlink ( ofname );
-    exit ( 1 );
-}
-
-copystat(ifname, ofname)
-char *ifname, *ofname;
-{
-    struct stat statbuf;
-    int mode;
-    time_t timep[2];
-
-    fclose(stdout);
-    if (stat(ifname, &statbuf)) {		/* Get stat on input file */
-	perror(ifname);
-	return;
-    }
-    if ((statbuf.st_mode & S_IFMT/*0170000*/) != S_IFREG/*0100000*/) {
-	if(quiet)
-	    	fprintf(stderr, "%s: ", ifname);
-	fprintf(stderr, " -- not a regular file: unchanged");
-	exit_stat = 1;
-    } else if (statbuf.st_nlink > 1) {
-	if(quiet)
-	    	fprintf(stderr, "%s: ", ifname);
-	fprintf(stderr, " -- has %d other links: unchanged",
-		statbuf.st_nlink - 1);
-	exit_stat = 1;
-    } else if (exit_stat == 2 && (!force)) { /* No compression: remove file.Z */
-	if(!quiet)
-		fprintf(stderr, " -- file unchanged");
-    } else {			/* ***** Successful Compression ***** */
-	exit_stat = 0;
-	mode = statbuf.st_mode & 07777;
-	if (chmod(ofname, mode))		/* Copy modes */
-	    perror(ofname);
-	chown(ofname, statbuf.st_uid, statbuf.st_gid);	/* Copy ownership */
-	timep[0] = statbuf.st_atime;
-	timep[1] = statbuf.st_mtime;
-	utime(ofname, timep);	/* Update last accessed and modified times */
-	if (unlink(ifname))	/* Remove input file */
-	    perror(ifname);
-	if(!quiet)
-		fprintf(stderr, " -- replaced with %s", ofname);
-	return;		/* Successful return */
-    }
-
-    /* Unsuccessful return -- one of the tests failed */
-    if (unlink(ofname))
-	perror(ofname);
-}
-/*
- * This routine returns 1 if we are running in the foreground and stderr
- * is a tty.
- */
-foreground()
-{
-	if(bgnd_flag) {	/* background? */
-		return(0);
-	} else {			/* foreground */
-		if(isatty(2)) {		/* and stderr is a tty */
-			return(1);
-		} else {
-			return(0);
-		}
-	}
-}
-
-onintr ( )
-{
-    unlink ( ofname );
-    exit ( 1 );
-}
-
-oops ( )	/* wild pointer -- assume bad input */
-{
-    if ( do_decomp == 1 ) 
-    	fprintf ( stderr, "uncompress: corrupt input\n" );
-    unlink ( ofname );
-    exit ( 1 );
-}
-
-cl_block ()		/* table clear for block compress */
-{
-    register long int rat;
-
-    checkpoint = in_count + CHECK_GAP;
-#ifdef DEBUG
-	if ( debug ) {
-    		fprintf ( stderr, "count: %ld, ratio: ", in_count );
-     		prratio ( stderr, in_count, bytes_out );
-		fprintf ( stderr, "\n");
-	}
-#endif /* DEBUG */
-
-    if(in_count > 0x007fffff) {	/* shift will overflow */
-	rat = bytes_out >> 8;
-	if(rat == 0) {		/* Don't divide by zero */
-	    rat = 0x7fffffff;
-	} else {
-	    rat = in_count / rat;
-	}
-    } else {
-	rat = (in_count << 8) / bytes_out;	/* 8 fractional bits */
-    }
-    if ( rat > ratio ) {
-	ratio = rat;
-    } else {
-	ratio = 0;
-#ifdef DEBUG
-	if(verbose)
-		dump_tab();	/* dump string table */
-#endif
- 	cl_hash ( (count_int) hsize );
-	free_ent = FIRST;
-	clear_flg = 1;
-	output ( (code_int) CLEAR );
-#ifdef DEBUG
-	if(debug)
-    		fprintf ( stderr, "clear\n" );
-#endif /* DEBUG */
-    }
-}
-
-cl_hash(hsize)		/* reset code table */
-	register count_int hsize;
-{
-#ifndef XENIX_16	/* Normal machine */
-	register count_int *htab_p = htab+hsize;
-#else
-	register j;
-	register long k = hsize;
-	register count_int *htab_p;
-#endif
-	register long i;
-	register long m1 = -1;
-
-#ifdef XENIX_16
-    for(j=0; j<=8 && k>=0; j++,k-=8192) {
-	i = 8192;
-	if(k < 8192) {
-		i = k;
-	}
-	htab_p = &(htab[j][i]);
-	i -= 16;
-	if(i > 0) {
-#else
-	i = hsize - 16;
-#endif
- 	do {				/* might use Sys V memset(3) here */
-		*(htab_p-16) = m1;
-		*(htab_p-15) = m1;
-		*(htab_p-14) = m1;
-		*(htab_p-13) = m1;
-		*(htab_p-12) = m1;
-		*(htab_p-11) = m1;
-		*(htab_p-10) = m1;
-		*(htab_p-9) = m1;
-		*(htab_p-8) = m1;
-		*(htab_p-7) = m1;
-		*(htab_p-6) = m1;
-		*(htab_p-5) = m1;
-		*(htab_p-4) = m1;
-		*(htab_p-3) = m1;
-		*(htab_p-2) = m1;
-		*(htab_p-1) = m1;
-		htab_p -= 16;
-	} while ((i -= 16) >= 0);
-#ifdef XENIX_16
-	}
-    }
-#endif
-    	for ( i += 16; i > 0; i-- )
-		*--htab_p = m1;
-}
-
-prratio(stream, num, den)
-FILE *stream;
-long int num, den;
-{
-	register int q;			/* Doesn't need to be long */
-
-	if(num > 214748L) {		/* 2147483647/10000 */
-		q = num / (den / 10000L);
-	} else {
-		q = 10000L * num / den;		/* Long calculations, though */
-	}
-	if (q < 0) {
-		putc('-', stream);
-		q = -q;
-	}
-	fprintf(stream, "%d.%02d%%", q / 100, q % 100);
-}
-
-version()
-{
-	fprintf(stderr, "%s\n", rcs_ident);
-	fprintf(stderr, "Options: ");
-#ifdef vax
-	fprintf(stderr, "vax, ");
-#endif
-#ifdef NO_UCHAR
-	fprintf(stderr, "NO_UCHAR, ");
-#endif
-#ifdef SIGNED_COMPARE_SLOW
-	fprintf(stderr, "SIGNED_COMPARE_SLOW, ");
-#endif
-#ifdef XENIX_16
-	fprintf(stderr, "XENIX_16, ");
-#endif
-#ifdef COMPATIBLE
-	fprintf(stderr, "COMPATIBLE, ");
-#endif
-#ifdef DEBUG
-	fprintf(stderr, "DEBUG, ");
-#endif
-#ifdef BSD4_2
-	fprintf(stderr, "BSD4_2, ");
-#endif
-	fprintf(stderr, "BITS = %d\n", BITS);
-}
*-*-END-of-src/compress.c-*-*
echo x - src/virtterm.c 1>&2
sed 's/.//' >src/virtterm.c <<'*-*-END-of-src/virtterm.c-*-*'
-/*
- *  Virtual terminal handler
- *  Written by Kenneth Almquist, AGS Computers  (HO 4C601, X7105).
- *  Modified by Stephen Hemminger, to use TERMCAP (without curses)
- */
-
-#ifdef SCCSID
-static char	*SccsId = "@(#)virtterm.c	1.12	10/29/86";
-#endif /* SCCSID */
-
-/*LINTLIBRARY*/
-
-#include <stdio.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <signal.h>
-#ifdef USG
-#include <termio.h>
-#else /* !USG */
-#include <sgtty.h>
-#endif /* !USG */
-
-/*
- * These values for MAXPLEN and MAXLLEN are used to dimension arrays
- * that hold strings of relative cursor motions.  The actual arrays that
- * are used to hold screen images are malloc'd.
- */
-#define MAXPLEN 90
-#define MAXLLEN 160
-
-#define BOTLINE (ROWS - 1)
-#define DIRTY 01
-
-/* terminal escape sequences from termcap */
-#define HO _tstr[0]		/* home */
-#define CL _tstr[1]		/* clear screen */
-#define CD _tstr[2]		/* clear to end of screen */
-#define CE _tstr[3]		/* clear to end of line */
-#define xUP _tstr[4]		/* up one line */
-#define DO _tstr[5]		/* down one line */
-#define US _tstr[6]		/* underline */
-#define UE _tstr[7]		/* underline end */
-#define BT _tstr[8]		/* backtab */
-#define xBC _tstr[9]		/* backspace */
-#define AL _tstr[10]		/* insert line */
-#define DL _tstr[11]		/* delete line */
-#define CM _tstr[12]		/* cursor move */
-#define CH _tstr[13]		/* cursor horizontal move */
-#define CV _tstr[14]		/* cursor vertical move */
-#define CS _tstr[15]		/* scrolling region */
-#define SF _tstr[16]		/* scroll forwards */
-#define SR _tstr[17]		/* scroll backwards */
-#define TI _tstr[18]		/* start cursor mode */
-#define TE _tstr[19]		/* end cursor mode */
-#define TA _tstr[20]		/* tab char (if not \t) */
-#define CR _tstr[21]		/* carriage return (if not \r) */
-#define xPC _tstr[22]		/* for reading pad character */
-char PC;			/* pad character */
-char *BC, *UP;			/* external variables for tgoto */
-
-static char sname[] = "hoclcdceupdousuebtbcaldlcmchcvcssfsrtitetacrpc";
-char *_tstr[23];
-int     HOlen;			/* length of HO string */
-
-
-/* terminal flags */
-#define BS _tflg[0]		/* can backspace */
-#define AM _tflg[1]		/* has auto margins */
-#define XN _tflg[2]		/* no newline after wrap */
-#define RET !_tflg[3]		/* has carriage return */
-#define NS _tflg[4]		/* has SF (scroll forward) */
-#define PT _tflg[5]		/* has tabs */
-#define XT _tflg[6]		/* tabs are destructive */
-int	GT = 1;			/* tab stops on terminal are set */
-
-static char bname[] = "bsamxnncnsptxt";
-char _tflg[7];
-
-
-extern char *tgoto(), *tgetstr();
-extern char *getenv(), *strcpy();
-
-#define ULINE 0200
-
-/* Constants accessable by user */
-int     hasscroll;		/* scrolling type, 0 == no scrolling */
-int     ROWS;			/* number of lines on screen */
-int     COLS;			/* width of screen */
-
-struct line {
-	char    len;
-	char    flags;
-	char    *l;		/* pointer to actual line text, NO NULL @ end */
-};
-
-int     _row, _col;
-int     _srow, _scol;
-struct line *_virt;		/* what we want the screen to look like */
-struct line *_actual;		/* What it actually looks like */
-int     _uline = 0;
-int     _junked = 1;
-int     _curjunked;
-int     _dir = 1;
-int	_shifttop, _shiftbot;
-int	_shift;
-int	_scratched;
-int     vputc();
-
-/*
- * Tell refresh to shift lines in region upwards count lines.  Count
- * may be negative.  The virtual image is not shifted; this may change
- * later.  The variable _scratched is set to supress all attempts to
- * shift.
- */
-
-ushift(top, bot, count)
-{
-	if (_scratched)
-		return;
-	if (_shift != 0 && (_shifttop != top || _shiftbot != bot)) {
-		_scratched++;
-		return;
-	}
-	_shifttop = top;
-	_shiftbot = bot;
-	_shift += count;
-}
-
-/*
- * generate a beep on the terminal
- */
-beep()
-{
-	vputc('\7');
-}
-
-/*
- * Move to one line below the bottom of the screen.
- */
-botscreen()
-{
-	_amove(BOTLINE, 0);
-	vputc('\n');
-	vflush();
-}
-
-move(row, col)
-{
-	if (row < 0 || row >= ROWS || col < 0 || col >= COLS)
-		return;
-	_row = row;
-	_col = col;
-}
-
-
-
-/*
- * Output string at specified location.
- */
-mvaddstr(row, col, str)
-char *str;
-{
-	move(row, col);
-	addstr(str);
-}
-
-addstr(s)
-char   *s;
-{
-	register char  *p;
-	register struct line   *lp;
-	register int    col = _col;
-
-	lp = &_virt[_row];
-	if (lp->len < col) {
-		p = &lp->l[lp->len];
-		while (lp->len < col) {
-			*p++ = ' ';
-			lp->len++;
-		}
-	}
-	for (p = s; *p != '\0'; p++) {
-		if (*p == '\n') {
-			lp->len = col;
-			lp->flags |= DIRTY;
-			col = 0;
-			if (++_row >= ROWS)
-				_row = 0;
-			lp = &_virt[_row];
-		}
-		else {
-			lp->l[col] = *p;
-			lp->flags |= DIRTY;
-			if (++col >= COLS) {
-				lp->len = COLS;
-				col = 0;
-				if (++_row >= ROWS)
-					_row = 0;
-				lp = &_virt[_row];
-			}
-		}
-	}
-	if (lp->len <= col)
-		lp->len = col;
-	_col = col;
-}
-
-addch(c)
-{
-	register struct line   *lp;
-	register char  *p;
-
-	lp = &_virt[_row];
-	if (lp->len < _col) {
-		p = &lp->l[lp->len];
-		while (lp->len < _col) {
-			*p++ = ' ';
-			lp->len++;
-		}
-	}
-	lp->l[_col] = c;
-	if (lp->len == _col)
-		lp->len++;
-	if (++_col >= COLS) {
-		_col = 0;
-		if (++_row >= ROWS)
-			_row = 0;
-	}
-	lp->flags |= DIRTY;
-}
-
-/*
- * Clear an entire line.
- */
-clrline(row)
-{
-	register struct line   *lp;
-
-	lp = &_virt[row];
-	if (lp->len > 0) {
-		lp->len = 0;
-		lp->flags |= DIRTY;
-	}
-}
-
-erase()
-{
-	register    i;
-
-	for (i = 0; i < ROWS; i++) {
-		_virt[i].len = 0;
-		_virt[i].flags |= DIRTY;
-	}
-}
-
-refresh()
-{
-	register i;
-	register char *p, *q;
-	register int j, len;
-
-	if (checkin())
-		return;
-	i = 1;
-	if (_junked) {
-		_sclear();
-		_junked = 0;
-	} else if (! _scratched) {
-		if (_shift > 0) {
-			_ushift(_shifttop, _shiftbot, _shift);
-		} else if (_shift < 0) {
-			i = _dshift(_shifttop, _shiftbot, -_shift);
-		} else {
-			i = _dir;
-		}
-	}
-	_dir = i;
-	_shift = 0;
-	if (checkin())
-		return;
-	_fixlines();
-	for (i = _dir > 0 ? 0 : BOTLINE; i >= 0 && i < ROWS; i += _dir) {
-		if ((_virt[i].flags & DIRTY) == 0)
-			continue;
-		_ckclrlin(i);		/* decide whether to do a clear line */
-					/* probably should consider cd too  */
-		len = _virt[i].len;
-		if (_actual[i].len < len)
-			len = _actual[i].len;
-		p = _virt[i].l;
-		q = _actual[i].l;
-		for (j = 0; j < len; j++) {
-			if (*p != *q) {
-				/* Inline test for speed */
-				if (i != _srow || j != _scol || _curjunked)
-					_amove(i, j);
-				_aputc(*p);
-				*q = *p;
-			}
-			p++;
-			q++;
-		}
-		len = _virt[i].len;
-		if (_actual[i].len > len) {
-			_clrtoeol(i, len);
-		} else {
-			for (; j < len; j++) {
-				if (*p != ' ') {
-					/* Inline test for speed */
-					if (i != _srow || j != _scol || _curjunked)
-						_amove(i, j);
-					_aputc(*p);
-				}
-				*q++ = *p++;
-			}
-			_actual[i].len = len;
-		}
-		if (checkin())
-			return;
-	}
-	_dir = 1;
-	_amove(_row, _col);
-	vflush();			/* flush output buffer */
-	_scratched = 0;
-}
-
-_dshift(top, bot, count)
-{
-	register    i;
-
-	if (count >= bot - top || hasscroll < 4) {  /* must have CS or AL/DL */
-		_scratched++;
-		return 1;
-	}
-	for (i = bot - count; _actual[i].len == 0; i--)
-		if (i == top)
-			return 1;
-	for (i = top; i <= bot; i++)
-		_virt[i].flags |= DIRTY;
-	for (i = bot; i >= top + count; i--) {
-		/* FIXME, this should be done by recirculating the pointers */
-		register j;
-		j =     _actual[i].len   = _actual[i - count].len;
-		        _actual[i].flags = _actual[i - count].flags;
-		strncpy(_actual[i].l,      _actual[i - count].l, j);
-	}
-	for (; i >= top; i--)
-		_actual[i].len = 0;
-
-	if (hasscroll != 5) {		/* can we define scrolling region, and scroll back */
-		tputs(tgoto(CS, bot, top), 1, vputc);/* define scroll region */
-		_curjunked = 1;
-		_amove(top, 0);
-		for (i = count; --i >= 0;)
-			tputs(SR, 1, vputc);/* scroll back */
-		tputs(tgoto(CS, BOTLINE, 0), 1, vputc);
-		_curjunked = 1;
-	} else {
-		_amove(bot - count + 1, 0);
-		if (CD && bot == BOTLINE)
-			tputs(CD, 1, vputc);
-		else {
-			for (i = count; --i >= 0;)
-				tputs(DL, ROWS - _srow, vputc);
-		}
-		_amove(top, 0);
-		for (i = count; --i >= 0;)
-			tputs(AL, ROWS - _srow, vputc);
-	}
-	return -1;
-}
-
-
-_ushift(top, bot, count)
-{
-	register    i;
-
-	if (count >= bot - top || hasscroll == 0) {
-		_scratched++;
-		return;
-	}
-	for (i = top + count; _actual[i].len == 0; i++)
-		if (i == bot)
-			return;
-	if (hasscroll == 1 || hasscroll == 3) {
-		/* we cheat and shift the entire screen */
-		/* be sure we are shifting more lines into than out of position */
-		if ((bot - top + 1) - count <= ROWS - (bot - top + 1))
-			return;
-		top = 0, bot = BOTLINE;
-	}
-	for (i = top; i <= bot; i++)
-		_virt[i].flags |= DIRTY;
-	for (i = top; i <= bot - count; i++) {
-		/* FIXME, this should be done by recirculating the pointers */
-		register int j;
-		j =     _actual[i].len   = _actual[i + count].len;
-		        _actual[i].flags = _actual[i + count].flags;
-		strncpy(_actual[i].l,      _actual[i + count].l, j);
-	}
-  	for (; i <= bot; i++)
-	for (; i <= bot; i++)
-		_actual[i].len = 0;
-
-	if (hasscroll != 5) {
-		if (top != 0 || bot != BOTLINE) {
-			tputs(tgoto(CS, bot, top), 0, vputc);
-			_curjunked = 1;
-		}
-		_amove(bot, 0);	/* move to bottom */
-		for (i = 0; i < count; i++) {
-			if (SF)		/* scroll forward */
-				tputs(SF, 1, vputc);
-			else
-				vputc('\n');
-		}
-		if (top != 0 || bot != BOTLINE) {
-			tputs(tgoto(CS, BOTLINE, 0), 0, vputc);
-			_curjunked = 1;
-		}
-	} else {
-		_amove(top, 0);
-		for (i = count; --i >= 0;)
-			tputs(DL, ROWS - _srow, vputc);
-		if (bot < BOTLINE) {
-			_amove(bot - count + 1, 0);
-			for (i = count; --i >= 0;)
-				tputs(AL, ROWS - _srow, vputc);
-		}
-	}
-}
-
-_sclear()
-{
-	register struct line   *lp;
-
-	tputs(CL, 0, vputc);
-	_srow = _scol = 0;
-	for (lp = _actual; lp < &_actual[ROWS]; lp++) {
-		lp->len = 0;
-	}
-	for (lp = _virt; lp < &_virt[ROWS]; lp++) {
-		if (lp->len != 0)
-			lp->flags |= DIRTY;
-	}
-}
-
-_clrtoeol(row, col)
-{
-	register struct line *lp = &_actual[row];
-	register i;
-
-	if (CE && lp->len > col + 1) {
-		_amove(row, col);
-		tputs(CE, 1, vputc);
-	} else {
-		for (i = col ; i < lp->len ; i++) {
-			if (lp->l[i] != ' ') {
-				_amove(row, i);
-				_aputc(' ');
-			}
-		}
-	}
-	lp->len = col;
-}
-
-_fixlines()
-{
-	register struct line   *lp;
-	register char  *p;
-	register int    i;
-
-	for (i = 0; i < ROWS; i++) {
-		lp = &_virt[i];
-		if (lp->flags & DIRTY) {
-			for (p = &lp->l[lp->len]; --p >= lp->l && *p == ' ';)
-				;
-			lp->len = (int) (p - lp->l) + 1;
-			if (lp->len == _actual[i].len && strncmp(lp->l, _actual[i].l, lp->len) == 0)
-				lp->flags &= ~DIRTY;
-		}
-	}
-}
-
-
-/*
- * Consider clearing the line before overwriting it.
- * We always clear a line if it has underlined characters in it
- * because these can cause problems.  Otherwise decide whether
- * that will decrease the number of characters to change.  This
- * routine could probably be simplified with no great loss.
- */
-
-_ckclrlin(i)
-{
-	int     eval;
-	int     len;
-	int     first;
-	register struct line   *vp, *ap;
-	register int    j;
-
-	if (!CE)
-		return;
-	ap = &_actual[i];
-	vp = &_virt[i];
-	len = ap->len;
-	eval = -strlen(CE);
-	if (len > vp->len) {
-		len = vp->len;
-		eval = 0;
-	}
-	for (j = 0; j < len && vp->l[j] == ap->l[j]; j++)
-		;
-	if (j == len)
-		return;
-	first = j;
-	while (j < len) {
-		if (vp->l[j] == ' ') {
-			if (ap->l[j] != ' ') {
-				while (++j < len && vp->l[j] == ' ' && ap->l[j] != ' ') {
-					eval++;
-				}
-				if (j == len)
-					eval++;
-				continue;
-			}
-		}
-		else {
-			if (vp->l[j] == ap->l[j]) {
-				while (++j < len && vp->l[j] == ap->l[j]) {
-					eval--;
-				}
-				continue;
-			}
-		}
-		j++;
-	}
-	if (US) {
-		for (j = 0 ; j < ap->len ; j++) {
-			if (ap->l[j] & ULINE) {
-				eval = 999;
-				if (first > j)
-					first = j;
-				break;
-			}
-		}
-	}
-	for (j = first; --j >= 0;)
-		if (vp->l[j] != ' ')
-			break;
-	if (j < 0)
-		first = 0;
-	if (eval > 0) {
-		_amove(i, first);
-		tputs(CE, 0, vputc);
-		_actual[i].len = first;
-	}
-}
-
-
-
-/*
- * Move routine
- * 	first compute direct cursor address string and cost
- *	then relative motion string and cost,
- *	then home then relative and cost
- *	choose smallest and do it.
- *
- *	The plod stuff is to build the strings (with padding) then decide
- */
-static char *plodstr;		/* current location in relmove string */
-
-plodput(c)
-{
-	*plodstr++ = c;
-}
-
-/* FIXME: speedup 1-char horiz moves:  print the char that's there. */
-/* FIXME: avoid funniness if cm works. */
-/* FIXME: Avoid setul(0) if cursor motion OK in standout (XM?) */
-_amove(row, col)
-{
-	char direct[20];
-	char rel[MAXPLEN*10 + MAXLLEN*10];    /* longest move is full screen */
-	char ho[MAXPLEN*10 + MAXLLEN*10];
-	int cost, newcost;
-	register char *movstr;
-
-	if (row == _srow && col == _scol && _curjunked == 0)
-		return;
-	if (_uline)
-		_setul(0);	/* Inline test for speed */
-
-	cost = 999;
-	if (CM) {
-		plodstr = direct;
-		tputs(tgoto(CM, col, row), 0, plodput);
-		cost = plodstr - direct;
-		movstr = direct;
-	}
-	if (_curjunked == 0) {
-		plodstr = rel;
-		if (_vmove(_srow, row) >= 0
-		 && (plodstr - rel) < cost		/* after vmove */
-		 && _hmove(_scol, col, row) >= 0
-		 && (newcost = plodstr - rel) < cost) { /* after both */
-			cost = newcost;
-			movstr = rel;
-		}
-	}
-	if (cost > HOlen) {	/* is it worth calculating */
-		plodstr = ho;
-		tputs(HO, 0, plodput);
-		if (_vmove(0, row) >= 0
-		 && (plodstr - ho) < cost		/* after ho, vmove */
-		 && _hmove(0, col, row) >= 0
-		 && (newcost = plodstr - ho) < cost) {	/* after all three */
-			cost = newcost;
-			movstr = ho;
-		}
-	}
-
-	if (cost < 999)
-		while (--cost >= 0)
-			vputc(*movstr++);
-
-	_srow = row;
-	_scol = col;
-	_curjunked = 0;
-}
-
-_vmove(orow, nrow)
-{
-	char direct[128];
-	char *saveplod = plodstr;
-
-	if (CV) {
-		plodstr = direct;
-		tputs(tgoto(CV, nrow, nrow), 0, plodput);
-		*plodstr = '\0';
-		plodstr = saveplod;
-	}
-	if (orow > nrow) {		/* cursor up */
-		if (! UP)
-			return -1;
-		while (orow > nrow) {
-			tputs(UP, 1, plodput);
-			orow--;
-		}
-	}
-	while (orow < nrow) {		/* cursor down */
-		if (DO)
-			tputs(DO, 1, plodput);
-		else
-			*plodstr++ = '\n';
-		orow++;
-	}
-	if (CV && plodstr - saveplod >= strlen(direct)) {
-		register char *p;
-		plodstr = saveplod;
-		for (p = direct ; *plodstr = *p++ ; plodstr++)
-			;
-	}
-	return 0;
-}
-
-_hmove(ocol, ncol, row)
-{
-	char direct[128];
-	char ret[MAXLLEN*10];
-	char *saveplod = plodstr;
-	char *movstr;
-	int cost, newcost;
-
-	cost = 999;
-	if (CH) {
-		plodstr = direct;
-		tputs(tgoto(CH, ncol, ncol), 0, plodput);
-		cost = plodstr - direct;
-		movstr = direct;
-		plodstr = saveplod;
-	}
-	if (RET && ocol > ncol) {	/* consider doing carriage return */
-		plodstr = ret;
-		if (CR)
-			tputs(CR, 1, plodput);
-		else
-			*plodstr++ = '\r';
-		if (_relhmove(0, ncol, row) >= 0
-		 && (newcost = plodstr - ret) < cost) {
-			cost = newcost;
-			movstr = ret;
-		}
-		plodstr = saveplod;
-	}
-	if (_relhmove(ocol, ncol, row) < 0) {
-		if (cost == 999)
-			return -1;
-		goto copy;
-	}
-	if (plodstr - saveplod > cost) {
-copy:		plodstr = saveplod;
-		while (--cost >= 0)
-			*plodstr++ = *movstr++;
-	}
-	return 0;
-}
-
-_relhmove(ocol, ncol, row)
-{
-	int tab;
-
-	if (ocol < ncol && PT && GT) {	/* tab (nondestructive) */
-		while ((tab = (ocol + 8) & ~07) <= ncol) {
-			if (TA)
-				tputs(TA, 1, plodput);
-			else
-				*plodstr++ = '\t';
-			ocol = tab;
-		}
-		if (tab < COLS && tab - ncol < ncol - ocol) {
-			if (TA)
-				tputs(TA, 1, plodput);
-			else
-				*plodstr++ = '\t';
-			ocol = tab;
-		}
-	} else if (BT && GT && ocol > ncol) {	/* backwards tab */
-		while ((tab = (ocol - 1) &~ 07) >= ncol) {
-			if (BS && tab == ocol - 1) {
-				if (BC)
-					tputs(BC, 1, plodput);
-				else
-					*plodstr++ = '\b';
-			} else
-				tputs(BT, 1, plodput);
-			ocol = tab;
-		}
-		if (ncol - tab + 1 < ocol - ncol) {
-			tputs(BT, 1, plodput);
-			ocol = tab;
-		}
-	}
-	if (ocol > ncol) {			/* cursor left */
-		if (! BS)
-			return -1;
-		while (ocol > ncol) {
-			if (BC != NULL)
-				tputs(BC, 1, plodput);
-			else
-				*plodstr++ = '\b';
-			ocol--;
-		}
-	}
-	if (ocol < ncol) {			/* cursor right */
-		register struct line *lp = &_actual[row];
-		/*
-		 * This code doesn't move over underlined characters properly,
-		 * but in practice this doesn't seem to matter.
-		 */
-		while (ocol < ncol) {
-			if (ocol < lp->len)
-				*plodstr++ = lp->l[ocol];
-			else
-				*plodstr++ = ' ';
-			ocol++;
-		}
-	}
-	return 0;
-}
-
-_aputc(c)
-{
-	if (_uline != (c & ULINE))	/* Inline for speed */
-		_setul(c & ULINE);
-	if (++_scol >= COLS) {
-		if (_srow == ROWS - 1) {
-			/* Don't ever paint last char of last line */
-			_scol--;
-			return;
-		}
-		_curjunked++;		/* Don't assume AM is right */
-	}
-	vputc(c & ~ULINE);
-}
-
-
-_setul(on)
-{
-	if (on) {
-		if (_uline == 0 && US != NULL) {
-			tputs(US, 1, vputc);
-			_uline = ULINE;
-		}
-	}
-	else {
-		if (_uline != 0 && UE != NULL) {
-			tputs(UE, 1, vputc);
-			_uline = 0;
-		}
-	}
-}
-
-/*
- * Initialize termcap strings for later use.
- */
-
-/*
- * Hacks to help with some Tek terminals
- * rad at tek
- */
-int tputs_len;
-countit(c) { tputs_len++; }
-
-initterm()
-{
-	static char tcbuf[1024];	/* termcap buffer */
-	register char  *cp;
-#ifdef USG
-	struct termio tio;
-#else /* !USG */
-	struct sgttyb ttyb;
-#endif /* !USG */
-
-	if ((cp = getenv("TERM")) == NULL)
-		xerror("TERM not set in environment");
-
-	switch (tgetent(tcbuf, cp)) {
-		case 0:
-			xerror("Terminal not found in TERMCAP");
-		case -1:
-			xerror("Can't open /etc/termcap");
-		case 1:
-			break;
-	}
-#ifdef TIOCGWINSZ
-	{
-		struct winsize ws;
-		int winch();
-
-		COLS = ROWS = -1;
-		if(ioctl(1, TIOCGWINSZ, &ws) == 0) {
-			ROWS = ws.ws_row;
-			COLS = ws.ws_col;
-		}
-		if(ROWS <= 0)
-			ROWS = tgetnum("li");
-		if(COLS <= 0)
-			COLS = tgetnum("co");
-		if ((ROWS <= 0) || (COLS <= 0))
-			xerror("Can't get screen size");
-
-		signal(SIGWINCH, winch); /* allow for changing window size */
-	}
-#else /* !TIOCGWINSZ */
-	if ((ROWS = tgetnum("li")) == -1
-		|| (COLS = tgetnum("co")) == -1)
-		xerror("Can't get screen size");
-#endif /* !TIOCGWINSZ */
-	_zap();
-
-	if (CL == NULL)
-		xerror ("No clear screen defined");
-
-	if (HO == NULL && CM == NULL)
-		xerror("No home or cursor addressing");
-	if (HO)
-		HOlen = strlen(HO);
-	else
-		HOlen = 999;
-
-	PC = xPC ? xPC[0] : 0;
-	BC = xBC;
-	UP = xUP;
-	/*
-	 *  _vmove() may be called with a full-screen traverse,
-	 * meaning it will put the UP (along with any padding) into
-	 * the buffer as many as MAXPLEN times.  This means that
-	 * if the UP string would be more than 10 chars long (defined
-	 * in _amove() ), the buffer might be overflowed (assuming
-	 * CH is also large).
-	 * This actually occurs with the Tek4023 termcap, where :up=1000UP:
-	 * is used to fake vi into using :cm instead, due to the fact
-	 * that a 4023 can't do upline relative motion at all.
-	 * -rdoty at tek
-	 */
-	if (UP) {
-		tputs_len = 0;
-		tputs(UP, 1, countit);
-		if (tputs_len > 10 )
-			UP = 0;
-	}
-
-	if (tgetnum("ug") > 0)
-		US = UE = NULL;
-
-	if (XT)				/* Destructive tab code not included */
-		PT = 0;			/* to keep things simple */
-
-#ifdef USG
-	if (ioctl(0, TCGETA, &tio) == 0)
-		GT = tio.c_oflag&TAB3;
-#else /* !USG */
-	if (ioctl(0, TIOCGETP, &ttyb) == 0)
-		GT = ttyb.sg_flags&XTABS;
-#endif /* !USG */
-
-	{
-		char *thelines;
-		int i;
-		char *malloc();
-
-		thelines = malloc(2 * ROWS * COLS);
-		_virt = (struct line *)malloc(2 * ROWS * sizeof (struct line));
-		_actual = _virt + ROWS;
-		for (i = 0; i < ROWS; i++) {
-			_virt[i].len = 0;
-			_virt[i].flags = 0;
-			_actual[i].len = 0;
-			_actual[i].flags = 0;
-			_virt[i].l = thelines;
-			thelines += COLS;
-			_actual[i].l = thelines;
-			thelines += COLS;
-		}
-	}
-
-	/* Select article scrolling algorithm.  We prefer scrolling region
-	   over insert/delete line because it's faster on the HP */
-	hasscroll = 0;
-	if (!NS) {
-		hasscroll = 1;
-		if (SR)
-			hasscroll = 3;
-		if (CS)
-			hasscroll++;
-	}
-	if (AL && DL && hasscroll != 4)
-		hasscroll = 5;
-}
-
-rawterm()
-{
-	if (TI != NULL)
-		tputs(TI, 0, vputc);
-}
-
-cookedterm()
-{
-	if (TE != NULL) {
-		tputs(TE, 0, vputc);
-		vflush();
-	}
-}
-
-/* get strings from termcap */
-_zap()
-{
-	static char tstrbuf[1024];
-	static char *tp;
-	register char  *namp, **sp, *bp;
-
-	tp = tstrbuf;
-	sp = _tstr;
-	for (namp = sname; *namp; namp += 2) {
-		*sp++ = tgetstr(namp, &tp);
-	}
-	bp = _tflg;
-	for (namp = bname; *namp; namp += 2) {
-		*bp++ = tgetflag(namp, &tp);
-	}
-}
-#ifdef TIOCGWINSZ
-/*
- * window changed size -- update ROWS and COLS
- * and then redraw screen
- */
-winch()
-{
-	struct winsize ws;
-	int cols, rows;
-
-	cols = rows = -1;
-	if(ioctl(1, TIOCGWINSZ, &ws) == 0) {
-		rows = ws.ws_row;
-		cols = ws.ws_col;
-	}
-	if (rows == ROWS && cols == COLS) { /* just redraw it if no change */
-		_junked = 1;	/* redraw */
-		updscr();
-		return;
-	}
-
-	if(rows > 0)
-		ROWS = rows;
-	if(cols > 0)
-		COLS = cols;
-
-	if (ROWS > MAXPLEN)
-		ROWS = MAXPLEN;
-	if (COLS > MAXLLEN) {
-		COLS = MAXLLEN;
-		AM = XN = 1;
-	}
-
-	winch_upd();
-}
-#endif TIOCGWINSZ
*-*-END-of-src/virtterm.c-*-*
echo x - src/decode.c 1>&2
sed 's/.//' >src/decode.c <<'*-*-END-of-src/decode.c-*-*'
-#include <stdio.h>
-
-#ifdef SCCSID
-static char	*SccsId = "@(#)decode.c	1.3	5/15/85";
-#endif /* SCCSID */
-
-/*
- * This program is the inverse of encode
- *
- * It collects runs of 12 characters, combines pairs of those
- * to form 6 13 bit numbers, extracts the top bit of each of
- * those to make a 13th 6 bit character, and splits each of
- * the remaining 6 12 bit numbers to form 12 6 bit ones.
- *
- * The strings of 6 bit numbers are collected into groups of
- * 4 and converted into 3 8 bit characters.
- *
- * Now all that would be trivial, if we didn't need to worry
- * about ending all this correctly.  About 1/2 of the following
- * program wouldn't be here if the ending didn't matter....
- */
-
-/*
- * the following pair of characters can never occur as a pair
- * in legal input (since (90 * 91 + 90) > 2^13) - they are
- * noticed at the beginning of a 12 char block, and serve to
- * indicate that this block is the terminator.  The character
- * immediately following is the (expanded) terminator length.
- */
-#define	ENDMARK1	((90*91 + 90) / 91)
-#define	ENDMARK2	((90*91 + 90) % 91)
-
-main()
-{
-	register c;
-	register char *p;
-	register i;
-	register first = 1;
-	register cnt = 0;
-	int errcnt = 0;
-	char b12[12];
-	char c12[12];
-
-	p = b12;
-	i = 12;
-
-	while ((c = getchar()) != EOF) {
-		if (c < ' ' || c >= (' ' + 91)) {
-			if (errcnt++ == 0)
-				fprintf(stderr, "decode: Bad data\n");
-			continue;
-		}
-		if (i == 10 && p[-1] == ENDMARK1 && p[-2] == ENDMARK2) {
-			cnt = c - ' ';
-			i = 12;
-			p -= 2;
-			continue;
-		}
-		*p++ = c - ' ';
-		if (--i == 0) {
-			if (p == &b12[12]) {
-				if (!first)
-					pack12(c12, 12, 0);
-				else
-					first = 0;
-				p = c12;
-			} else {
-				pack12(b12, 12, 0);
-				p = b12;
-			}
-			i = 12;
-		}
-	}
-
-	if (p >= &b12[0] && p < &b12[12]) {
-		if (!first)
-			pack12(c12, 12, i == 12 ? cnt : 0);
-	} else
-		pack12(b12, 12, i == 12 ? cnt : 0);
-
-	if (i != 12) {
-		if (p >= &b12[0] && p < &b12[12])
-			pack12(b12, 12-i, cnt);
-		else
-			pack12(c12, 12-i, cnt);
-	}
-
-	exit(0);
-}
-
-static char b4[4];
-static int cnt = 0;
-
-pack12(p, n, last)
-	register char *p;
-	register n;
-	int last;
-{
-	register i;
-	register char *q;
-	char b13[13];
-
-	{
-		register c;
-		register c13;
-
-		q = b13;
-		c13 = 0;
-
-		for (i = 0; i < n; i += 2) {
-			c = *p++ * 91;
-			c += *p++;
-			c13 <<= 1;
-			if (c & (1 << 12))
-				c13 |= 1;
-			*q++ = (c >> 6) & 0x3f;
-			*q++ = c & 0x3f;
-		}
-		*q++ = c13;
-		if (last)
-			q = &b13[last];
-	}
-
-	p = b13;
-	n = q - p;
-	i = cnt;
-	q = &b4[cnt];
-
-	while (--n > 0) {
-		*q++ = *p++;
-		if (++i == 4) {
-			char b3[3];
-			register char *b = b4;
-
-			/* inline expansion of pack6bit, to save calls ... */
-
-			q = b3;
-			*q++ = (b[0] << 2) | ((b[1] >> 4) & 0x3);
-			*q++ = (b[1] << 4) | ((b[2] >> 2) & 0xf);
-			*q = (b[2] << 6) | (b[3] & 0x3f);
-
-			q = b3;
-			while (--i > 0)
-				putchar(*q++);
-
-			q = b4;
-		}
-	}
-
-	*q++ = *p++;	/* the last octet */
-	++i;
-
-	if (last || i == 4) {
-		pack6bit(b4, i, last);
-		i = 0;
-	}
-
-	cnt = i;
-}
-
-pack6bit(p, n, last)
-	register char *p;
-	register int n;
-	int last;
-{
-	register char *q;
-	register i = 3;
-	char b3[3];
-
-	if (last) {
-		i = p[n-1];
-		if (i >= 3) {
-			fprintf(stderr, "Badly encoded file\n");
-			i = 3;		/* do the best we can */
-		}
-	}
-
-	q = b3;
-	*q++ = (p[0] << 2) | ((p[1] >> 4) & 0x3);
-	*q++ = (p[1] << 4) | ((p[2] >> 2) & 0xf);
-	*q = (p[2] << 6) | (p[3] & 0x3f);
-
-	q = b3;
-
-	while (--i >= 0)
-		putchar(*q++);
-}
*-*-END-of-src/decode.c-*-*
exit



More information about the Mod.sources mailing list