home *** CD-ROM | disk | FTP | other *** search
- Subject: v22i036: NN Newsreader, release 6.4, Part01/21
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: d04fa928 5e29b51a 7500b5b8 47b939e6
-
- Submitted-by: "Kim F. Storm" <storm@texas.dk>
- Posting-number: Volume 22, Issue 36
- Archive-name: nn6.4/part01
-
- nn is a menu based (point and shoot) netnews reader with a complete
- set of features to satisfy both the expert and the novice user. Since
- its first release in Denmark in 1984 (!), in Europe in 1988, and the
- global release in June 1989, it has replaced rn and other well-known
- news readers at many sites.
-
- Some of the key features of nn are:
- * It is fast. It uses a dtabase, so it starts almost equally fast (in a few
- seconds), no matter whether you have 100 or 10000 unread articles! On
- my system nn uses less than 20 seconds to find all articles on a
- specific subject among 64000 articles in all groups!
- * Menu-based article selection prior to reading the articles
- with the articles sorted according to subject & posting time!
- * Release 6.4 uses standard .newsrc, and can leave individual
- articles unread!
- * Digests are automatically split and presented as ordinary articles!
- You can transparently save and respond to individual subarticles.
- * Full folder support: read, save, and delete individual articles.
- * Online help and manual.
- * Built-in unshar and patch functions.
- * Built-in uudecode function which will automatically unpack,
- concatenate, and decode multi-part postings.
- * Easy remapping of keys with advanced macro definition features.
- * Automatic kill & selection of articles based on subject or author.
- * Whole classes of news groups can easily be unsubscribed
- * Related groups can be merged and presented as a single group, e.g.
- comp.emacs and all gnu.emacs groups.
- * In a distributed environment, the database can be shared among all
- hosts on the network. Only one daemon is needed on the news server
- for all hosts. This works in a heterogenous environment as well.
- * NNTP is also supported (using a local database for speed).
-
- #! /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@uunet.uu.net if you want that tool.
- # Contents: README MANIFEST conf contrib doc help inews man regexp.h
- # term.c
- # Wrapped by storm@texas.dk on Sun May 6 18:19:13 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 1 (of 22)."'
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(7714 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- X INTRODUCTION TO NN
- X ------------------
- X
- X RELEASE 6.4
- X
- X
- Xnn is a menu based (point and shoot) netnews reader with a complete
- Xset of features to satisfy both the expert and the novice user. Since
- Xits first release in Denmark in 1984 (!), in Europe in 1988, and the
- Xglobal release in June 1989, it has replaced rn and other well-known
- Xnews readers at many sites.
- X
- XSome of the key features of nn are:
- X
- X * Menu-based article selection prior to reading the articles
- X with the articles sorted according to subject & posting time!
- X
- X This significantly reduces the time spent on news reading.
- X No keystorkes are wasted on articles you don't want to read, and
- X only the articles selected on the menu will be read.
- X
- X * Release 6.4 uses standard .newsrc, and can leave individual
- X articles unread!
- X
- X * Digests are automatically split and presented as ordinary articles!
- X You can transparently save and respond to individual subarticles.
- X
- X * Full folder support: read, save, and delete individual articles.
- X
- X * Online help and manual.
- X
- X * Built-in unshar and patch functions.
- X
- X * Built-in uudecode function which will automatically unpack,
- X concatenate, and decode multi-part postings.
- X
- X * Easy remapping of keys with advanced macro definition features.
- X
- X * Automatic kill & selection of articles based on subject or author.
- X
- X * User specified presentation sequence of news groups based on the
- X news group hierarchy.
- X
- X * Whole classes of news groups can easily be unsubscribed
- X permanently, e.g. talk.all and all.politics
- X
- X * Related groups can be merged and presented as a single group, e.g.
- X comp.emancs and all gnu.emacs groups.
- X
- X * Blindingly fast 'search for subject'. On my Texas S1500 system,
- X nn uses less than 20 seconds to find all articles on a specific
- X subject among 64000 articles in all groups!
- X
- X * News collection and presentation is extremely fast, because nn
- X uses its own database on top of the standard news system.
- X
- X * In a distributed environment, the database can be shared among all
- X hosts on the network. Only one daemon is needed on the news server
- X for all hosts. This works in a heterogenous environment as well.
- X
- X * NNTP is also supported (using a local database for speed).
- X
- XBecause of the database, nn starts almost equally fast (in a few
- Xseconds), no matter whether you have 100 or 10000 unread articles!
- XThe database takes up some disk space, but dramatically improves speed
- Xand functionality. The amount of disk space consumed is approx. 1Mb
- Xper 10000 articles.
- X
- X
- X DISTRIBUTION
- X ------------
- X
- XThe package is posted as 22 separate shar archives on comp.sources.unix.
- XIt is unpacked by applying /bin/sh to each archive in turn.
- XEverything is a little more than 1 Mbyte, including documentation.
- X
- XIt is also available via anonymous ftp from
- X
- X host: dkuug.dk (129.142.96.41)
- X File: /pub/nn6.4.tar.Z (compressed tar)
- X
- X
- X COPYRIGHT
- X ---------
- X
- XCopyright (c) 1989, 1990 by Kim Fabricius Storm. All rights reserved.
- X
- XNot derived from licensed software except as stated below.
- X
- XPermission is granted to anyone to use, modify, and reuse this
- Xsoftware for any purpose on any computer system, and to redistribute
- Xit freely, subject to the following restrictions:
- X
- X1. The author is not responsible for the consequences of use of this
- X software, no matter how awful, even if they arise from defects in it.
- X
- X2. The origin of this software must not be misrepresented, either by
- X explicit claim or by omission.
- X
- X3. Altered versions must be plainly marked as such, and must not be
- X misrepresented as being the original software.
- X
- X
- XThe following code modules have been incorporated into nn, and the
- Xabove copyright notice does not apply to these modules; they include
- Xtheir own copyright notices (or have none):
- X
- Xregexp.c: Copyright (c) 1986 by University of Toronto.
- X Written by Henry Spencer.
- X
- Xunshar.c: No copyright notice.
- X Written by K. Greer, S. Shafer, and M. Mauldin
- X
- Xdecode.c: Derived from a modified Berkeley original posted on
- X USENET.
- X
- Xfullname.c: Copyright (c) 1986 by Rick Adams.
- X Derived from the Bnews distribution.
- X
- Xcontrib/*: Various copyright notices.
- X The software available in the contrib/ directory was sent
- X to me for inclusion in the nn distribution, because
- X the authors think it might be useful to other nn users.
- X I have included it *as is*.
- X
- Xinews/*: NNTP 1.5 mini-inews. Copyrights for NNTP applies.
- X The software in the inews/ directory is a stand-alone
- X version of the NNTP 1.5.7 mini-inews which has been
- X slightly changed to ease configuration when used with nn.
- X
- XVarious pieces of code which may have their own copyright notices are
- Xincluded in the contrib/ and inews/ directories. This software has been
- Xsent to me in the hope that it will be useful to somebody else. I
- Xhave included it in this spirit, but I take no responsibilities for
- Xthis software, and I have no intentions to support it.
- X
- X
- X INSTALLATION
- X ------------
- X
- XThe following files are contained in the `doc' subdirectory:
- X
- XThe installation procedure is described in the file INSTALLATION.
- X
- XYou may also find useful information in the files PROBLEMS and NNTP.
- X
- XThe file NEWS-6.3 describes the major changes from release 6.1 to 6.3.
- X
- XThe file NEWS-6.4 describes the major changes from release 6.3 to 6.4.
- X
- X
- X BUG REPORTS and SUGGESTIONS
- X ---------------------------
- X
- XPlease send bug reports (and fixes) to the following address:
- X nn-bugs@dkuug.dk
- X
- XYou may also use nn-bugs for suggestions for improvements (missing
- Xfeatures in nn are considered to be bugs :-)
- X
- XThe easiest way to send a bug report is by using the :bug command in nn.
- X
- X
- X NN HAS ITS OWN NEWS GROUP
- X -------------------------
- X
- XWe have an unmoderated news group dedicated to nn: news.software.nn
- X
- XThe news.software.nn group is used for discussion on all subjects
- Xrelated to the nn news reader. This includes, but is not limited to,
- Xquestions, answers, ideas, hints, information from the development
- Xgroup, patches, etc.
- X
- XThe news.software.nn group was created in January 1990 after an
- Xofficial vote. It may still be missing on parts of the net, so if you
- Xdon't get it please check your news feed, and help propagating the
- Xnews group to the entire net.
- X
- X
- X ACKNOWLEDGEMENTS
- X ----------------
- X
- XSince the development of nn is now on its fifth year, numerous persons
- Xhave contributed to nn with ideas and critisism, have helped me debug
- Xthe software by patiently using alpha and beta versions, have provided
- Xbug fixes, small and big chunks of code, new configuration files, etc.
- X
- XMy warm thanks go to Rene Seindal and Wayne Davison for their many
- Xcontributions, to Lloyd W. Taylor for his efforts counting the
- Xvotes for news.software.nn, and to Paul D. Anderson for running the
- Xrelease 6.3 patch server.
- X
- XI also thank the following persons for their help and contributions:
- XPeter Andersen, Jonathan Bayer, Gardner Cohen, Bernie Cosell, P{r
- XEmanuelsson, Steven Grady, Miek Grenier, Scott Hankin, Kareth, Mike
- XKhaw, Edwin Kremer, Jean-Francois Lamy, Mark Moraes, A. E. Mossberg,
- XMark Nagel, Rich Salz, Steve Simmons, Wietse Z. Venema, James A.
- XWoods, and Pim Zandbergen.
- X
- XAnd of course I would like to thank the hundreds of other people who
- Xhave reported bugs, given suggestions, provided information, etc.
- XForgive me for not listing all your names here, but I hope you
- Xunderstand, and that you will continue to contribute your
- Xvaluable input to the continued developments. Let us keep nn in the
- Xlead!
- X
- X
- XKim Fabricius Storm
- XTexas Instruments A/S, Denmark
- X
- XEmail: storm@texas.dk
- XSnail: Marielundvej 46E, DK-2730 Herlev, Denmark
- Xtel: +45 42 91 7400 fax: +45 42 91 8400
- END_OF_FILE
- if test 7714 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'MANIFEST' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'MANIFEST'\"
- else
- echo shar: Extracting \"'MANIFEST'\" \(10469 characters\)
- sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
- X File Name Archive # Description
- X----------------------------------------------------------
- XREADME 1 Read this file first
- XMANIFEST 1 Packing list
- XFILES 22 Extract file names from MANIFEST
- XMakefile 21 Makefile for building nn
- XSPLITNN1 22 Split nn.1 in four parts.
- Xaccount.c 17 Accounting routines
- Xactive.c 20 Read active file
- Xadmin.c 12 Administration mode (nnadmin)
- Xanswer.c 14 Respond/post/mail code
- Xarticles.c 17 Incore article fetching and management
- Xarticles.h 21 Header file for article management
- Xaux.sh 10 Auxiliary script for post/mail
- Xback_act.sh 22 Backup active file once a day
- Xcollect.c 16 Collect groups and articles in the database
- Xconf 1 Directory for s- and m- files
- Xconf/m-3b1g.h 22 For 3b1 (unix-pc) with GCC [no networking].
- Xconf/m-att3b.h 22 For AT&T 3b2 (with s-usg3-1.h)
- Xconf/m-convex.h 21 For Convex.
- Xconf/m-dec3100.h 22 For DECstation 3100 (with s-bsd4-2.h)
- Xconf/m-gould.h 22 For Gould PN6000 (with s-bsd4-3.h)
- Xconf/m-hp9000.h 22 For HP9000 series 320 and 800 (at least)
- Xconf/m-i80286.h 22 For Intel 80286 processors [no network support]
- Xconf/m-i80386.h 22 For Intel 80386 processors [no network support]
- Xconf/m-m680x0.h 22 For 68000 family processors
- Xconf/m-m88000.h 22 For Motorola 88000 risc processors
- Xconf/m-mips.h 22 For MIPS processors
- Xconf/m-pyramid.h 22 For Pyramid (and Targon 35).
- Xconf/m-rt6150.h 22 For IBM 6150
- Xconf/m-sgi4D.h 22 For Silicon Graphics 4D series.
- Xconf/m-sparc.h 22 For SPARC processors
- Xconf/m-sun386i.h 22 For 80386 based SUNs [have network support]
- Xconf/m-symmetry.h 22 For Sequent Symmetry.
- Xconf/m-template.h 21 Template for new machine files.
- Xconf/m-vax.h 22 For VAX family
- Xconf/s-3b1g.h 22 For 3b1 (unix-pc) with GCC.
- Xconf/s-aix221.h 14 For AIX 2.2.1
- Xconf/s-aux1-1.h 22 For A/UX 1.1
- Xconf/s-bsd4-2.h 20 For 4.2 BSD and Ultrix systems
- Xconf/s-bsd4-3.h 22 For 4.3 BSD systems
- Xconf/s-dnix5-2.h 22 For dnix 5.2 on DIAB DS90.
- Xconf/s-dnix5-3.h 22 For dnix 5.3 on DIAB DS90.
- Xconf/s-dynix3-0.h 22 For Dynix 3.0 on Symmetry.
- Xconf/s-fortune.h 19 For Fortune 32:16 [read comments in the file]
- Xconf/s-hpux.h 6 For HPUX (series 300)
- Xconf/s-hpux2-1.h 22 For HPUX 2.1 (series 800)
- Xconf/s-hpux3-0.h 22 For HPUX 3.0 (series 800)
- Xconf/s-hpux6-5.h 21 For HPUX 6.5 or newer (series 300)
- Xconf/s-pyramid.h 22 For Pyramid (and Targon 35).
- Xconf/s-sgi4D.h 21 For IRIX 3.1/3.2 [read comments in the file]
- Xconf/s-sunos3.h 22 For SunOS 3
- Xconf/s-sunos4-0.h 22 For SunOS 4.0
- Xconf/s-sys5-tcap.h 22 For system V using termcap.
- Xconf/s-sys5.h 20 For most system V based systems.
- Xconf/s-template.h 19 Template for new system files.
- Xconf/s-texas1500.h 22 For Texas Instruments System 1500.
- Xconf/s-tower32.h 22 For NCR tower
- Xconf/s-umipsb.h 19 For Mips w/riscos 4.0 or greater
- Xconf/s-uport2-2.h 22 For Microport UNIX V.2
- Xconf/s-usg3-1.h 22 For most system V systems (obsolete)
- Xconf/s-xenix386.h 21 For xenix386 [termcap version].
- Xconf/s-xenix386ds.h 22 For Xenix386 2.3.2 w/development system.
- Xconfig.h-dist 17 CONFIGURATION FILE, DISTRIBUTED VERSION
- Xcontrib 1 Directory for contributed software
- Xcontrib/aspell 20 Ispell front-end written in perl
- Xcontrib/cn 22 Checknews w/multi-column output
- Xcontrib/recmail.c 18 Sample recmail program
- Xcontrib/recmail.sh 18 Sample recmail script
- Xcvt-help.c 22 Convertion utility for help files
- Xdata.h 15 Internal article and group information
- Xdb.c 13 Database access and update routines
- Xdb.h 20 External database format
- Xdebug.h 22 Debugging symbols
- Xdecode.c 17 UUdecode engine
- Xdigest.c 17 Digest splitting
- Xdir.c 19 Directory access
- Xdir.h 22 Include file for directory access
- Xdoc 1 Directory for documentation files
- Xdoc/INSTALLATION 9 INSTALLATION AND CONFIGURATION
- Xdoc/NEWS-6.3 18 What's new in release 6.3
- Xdoc/NEWS-6.4 16 What's new in release 6.4
- Xdoc/NNTP 16 INSTALLATION WITH NNTP or NFS
- Xdoc/PROBLEMS 15 KNOWN PROBLEMS AND SOLUTIONS
- Xdoc/RELEASE_NOTES 20 Known problems
- Xexecute.c 19 Shell command execution
- Xexpire.c 15 Database expiration
- Xfolder.c 13 Folder menu and file name expansion
- Xformat.awk 21 Nroff -man formatter in awk
- Xfullname.c 20 Extract full name from /etc/passwd
- Xglobal.c 4 Global routines
- Xglobal.h 19 Global include file
- Xgroup.c 10 Group menu, group overview, and goto-group
- Xhelp 1 Directory for online help files
- Xhelp/adm.upgrade1 22 Start-up message 1
- Xhelp/adm.upgrade2 22 Start-up message 2
- Xhelp/adm.upgrade3 22 Start-up message 3
- Xhelp/adm.upgrade4 22 Start-up message 4
- Xhelp/adm.welcome 22 New user welcome message
- Xhelp/help.attr 22 Help on attributes
- Xhelp/help.commands 20 Help on commands
- Xhelp/help.extended 21 Help on : commands
- Xhelp/help.help 22 Help on help
- Xhelp/help.map 21 Help on key mapping
- Xhelp/help.menu 21 ? in selection mode
- Xhelp/help.more 21 ? in reading mode
- Xhelp/help.read 12 Help on reading mode
- Xhelp/help.set 22 Help on :set commands
- Xhelp/help.show 22 Help on :show commands
- Xhelp/help.sort 21 Help on menu ordering
- Xhelp/help.variables 2 Help on variables
- Xhostname.c 20 Generic gethostname() function
- Xinews 1 Directory for NNTP 1.5.7 mini-inews
- Xinews/Makefile 19 mini-inews makefile
- Xinews/Manifest 22 mini-inews manifest
- Xinews/README 21 mini-inews read me 2nd
- Xinews/README.NN 19 mini-inews read me 1st
- Xinews/clientlib.c 16 mini-inews source
- Xinews/clientlib.h 22 mini-inews source
- Xinews/conf.h 20 mini-inews configuration file
- Xinews/inews.c 12 mini-inews source
- Xinews/nntp.h 20 mini-inews source
- Xinews/version.c 22 mini-inews source
- Xinit.c 11 Init file and extended command parsing
- Xinit.sample 20 Sample init file
- Xinst.sh 18 Installation script
- Xkeymap.c 6 Key mapping and command names
- Xkeymap.h 19 Key and command names
- Xkill.c 11 Kill compilation and processing
- Xmacro.c 14 Macro compilation and execution
- Xman 1 Directory for user manuals
- Xman/nn.1.A 2 nn manual (for users) - part 1
- Xman/nn.1.B 7 nn manual (for users) - part 2
- Xman/nn.1.C 3 nn manual (for users) - part 3
- Xman/nn.1.D 4 nn manual (for users) - part 4
- Xman/nnacct.1m 9 nnacct manual (for sysadm)
- Xman/nnadmin.1m 8 nnadmin manual (for sysadm)
- Xman/nncheck.1 20 nncheck manual (for users)
- Xman/nngoback.1 19 nngoback manual (for users)
- Xman/nngrab.1 5 nngrab manual (for users)
- Xman/nngrep.1 20 nngrep manual (for users)
- Xman/nnmaster.8 13 nnmaster manual (for sysadm)
- Xman/nnpost.1 21 nnpost manual (for users)
- Xman/nnspew.8 21 nnspew manual (for sysadm)
- Xman/nnstats.1m 21 nnstats manual (for sysadm)
- Xman/nntidy.1 21 nntidy manual (for users)
- Xman/nnusage.1m 21 nnusage manual (for sysadm)
- Xmaster.c 7 Database manager (nnmaster)
- Xmatch.c 20 String/regexp matching
- Xmenu.c 6 Article selection menu
- Xmenu.h 21 Return values from various modes
- Xmore.c 9 Pager (reading mode)
- Xnews.c 18 Parsing of news article headers
- Xnews.h 21 Article header information
- Xnewsrc.c 5 Access and update .newsrc
- Xnn.c 14 nn main program
- Xnngrab.sh 22 Quick subject search
- Xnnmail.c 21 Primitive mailer w/domain addressing
- Xnnspew.sh 22 Subject database generator (for nngrab)
- Xnnstats.sh 20 Collection and Expiration reports
- Xnntp.c 10 NNTP interface library
- Xnntp.h 20 NNTP response codes
- Xnnusage.sh 22 Usage statistics
- Xoptions.c 19 Option parsing (much better than getopt!)
- Xoptions.h 21 Header file for option parsing
- Xpack_date.c 19 Timestamp generation
- Xpack_name.c 3 Pack sender names
- Xpack_subject.c 21 Pack subject lines
- Xpatchlevel.h 8 Patch level and history
- Xprefix.c 16 Generate prefix for scripts.
- Xproto.c 19 Locking and message passing
- Xproto.h 21 Include file for proto routines
- Xregexp.c 8 Regular expression compile and exec
- Xregexp.h 1 Include file for regexp usage
- Xreroute.c 18 Mail address parsing and rewrite
- Xroutes.sample 21 Sample configuration file for nnmail
- Xsave.c 15 Article saving, unpacking, etc.
- Xsequence.c 5 Group presentation sequence parser
- Xsort.c 11 Article menu ordering
- Xterm.c 1 Terminal interface library
- Xterm.h 21 Include file for terminal interface
- Xunshar.c 18 Unshar pre-processor
- Xupgrade_rc.sh 22 .nn/rc to .newsrc converter
- Xusercheck.c 22 Check uid during installation
- Xvararg.h 21 Faked and real varargs.h encapsulation
- Xvariable.c 12 Variable management
- Xxmakefile 18 Skeleton for ymakefile
- END_OF_FILE
- if test 10469 -ne `wc -c <'MANIFEST'`; then
- echo shar: \"'MANIFEST'\" unpacked with wrong size!
- fi
- # end of 'MANIFEST'
- fi
- if test ! -d 'conf' ; then
- echo shar: Creating directory \"'conf'\"
- mkdir 'conf'
- fi
- if test ! -d 'contrib' ; then
- echo shar: Creating directory \"'contrib'\"
- mkdir 'contrib'
- fi
- if test ! -d 'doc' ; then
- echo shar: Creating directory \"'doc'\"
- mkdir 'doc'
- fi
- if test ! -d 'help' ; then
- echo shar: Creating directory \"'help'\"
- mkdir 'help'
- fi
- if test ! -d 'inews' ; then
- echo shar: Creating directory \"'inews'\"
- mkdir 'inews'
- fi
- if test ! -d 'man' ; then
- echo shar: Creating directory \"'man'\"
- mkdir 'man'
- fi
- if test -f 'regexp.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'regexp.h'\"
- else
- echo shar: Extracting \"'regexp.h'\" \(731 characters\)
- sed "s/^X//" >'regexp.h' <<'END_OF_FILE'
- X/*
- X * Definitions etc. for regexp(3) routines.
- X *
- X * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof],
- X * not the System V one.
- X */
- X
- X#define NSUBEXP 10
- Xtypedef struct regexp {
- X char *startp[NSUBEXP];
- X char *endp[NSUBEXP];
- X char regstart; /* Internal use only. */
- X char reganch; /* Internal use only. */
- X char *regmust; /* Internal use only. */
- X int regmlen; /* Internal use only. */
- X char program[1]; /* Unwarranted chumminess with compiler. */
- X} regexp;
- X
- X
- X/*
- X * The first byte of the regexp internal "program" is actually this magic
- X * number; the start node begins in the second byte.
- X */
- X#define MAGIC 0234
- X
- Xextern regexp *regcomp();
- Xextern int regexec();
- Xextern void regsub();
- Xextern void regerror();
- X
- END_OF_FILE
- if test 731 -ne `wc -c <'regexp.h'`; then
- echo shar: \"'regexp.h'\" unpacked with wrong size!
- fi
- # end of 'regexp.h'
- 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'\" \(27619 characters\)
- sed "s/^X//" >'term.c' <<'END_OF_FILE'
- X/*
- X * (c) Copyright 1990, Kim Fabricius Storm. All rights reserved.
- X *
- X * Terminal interface.
- X */
- X
- X#include <signal.h>
- X#include <errno.h>
- X#include "config.h"
- X#include "term.h"
- X#include "keymap.h"
- X
- X#ifdef RESIZING
- X#include <sys/ioctl.h> /* for TIOCGWINSZ */
- X#ifdef SYSV_RESIZING
- X#include <sys/stream.h>
- X#include <sys/ptem.h>
- X#endif
- X
- Xint s_resized;
- X#endif
- X
- Xexport char *term_name = NULL;
- Xexport int show_current_time = 1;
- Xexport int conf_dont_sleep = 0;
- Xexport int prompt_length;
- Xexport int terminal_speed;
- Xexport int slow_speed = 1200;
- Xexport int any_message = 0;
- Xexport int flow_control = 1;
- Xexport int use_visible_bell = 1; /* if supported by terminal */
- X
- Xexport key_type help_key = '?';
- Xexport key_type comp1_key = SP;
- Xexport key_type comp2_key = TAB;
- Xexport key_type erase_key, kill_key;
- Xexport key_type delword_key = CONTROL_('W');
- X
- Xstatic char bell_str[256] = "\007";
- X
- X#ifdef USE_TERMINFO
- X
- X#include <curses.h>
- X#ifndef auto_left_margin
- X#include <term.h>
- X#endif
- X
- X#define HAS_CAP(str) (str && *str)
- X
- Xextern char *tgoto(); /* some systems don't have this in term.h */
- X
- X#else
- X
- X#define USE_TERMCAP
- X
- Xchar *tgoto();
- Xchar PC;
- Xchar *BC, *UP;
- Xshort ospeed;
- X
- Xstatic char XBC[64], XUP[64];
- Xstatic char enter_ca_mode[64], exit_ca_mode[64];
- Xstatic char cursor_home[64];
- Xstatic char cursor_address[64];
- Xstatic char clear_screen[64];
- Xstatic char clr_eol[64];
- Xstatic char clr_eos[64];
- Xstatic char enter_standout_mode[64], exit_standout_mode[64];
- Xstatic char enter_underline_mode[64], exit_underline_mode[64];
- Xstatic char key_down[64], key_up[64], key_right[64], key_left[64];
- X
- Xint magic_cookie_glitch; /* magic cookie size */
- X
- X#define putp(str) tputs(str, 0, outc)
- X
- X#define HAS_CAP(str) (*str)
- X
- Xstatic outc(c)
- X{
- X putchar(c);
- X}
- X
- X#endif /* USE_TERMCAP */
- X
- Xint Lines, Columns; /* screen size */
- Xint cookie_size; /* size of magic cookie */
- Xint two_cookies; /* space needed to enter&exit standout mode */
- Xint STANDOUT; /* terminal got standout mode */
- Xint WRAP; /* terminal got automatic margins */
- X
- X#ifdef HAVE_TERMIO
- X
- X#define KEY_BURST 50 /* read bursts of 50 chars (or timeout after 100 ms) */
- X
- X#ifdef USE_TERMCAP
- X#include <termio.h>
- X#endif
- X
- X#undef CBREAK
- X
- Xstatic struct termio norm_tty, raw_tty;
- X
- X#define IntrC norm_tty.c_cc[VINTR]
- X#define EraseC norm_tty.c_cc[VERASE]
- X#define KillC norm_tty.c_cc[VKILL]
- X#define SuspC CONTROL_('Z') /* norm_tty.c_cc[SWTCH] */
- X
- X#else /* V7/BSD TTY DRIVER */
- X
- X#include <sgtty.h>
- X
- Xstatic struct sgttyb norm_tty, raw_tty;
- Xstatic struct tchars norm_chars;
- X
- X#define IntrC norm_chars.t_intrc
- X#define EraseC norm_tty.sg_erase
- X#define KillC norm_tty.sg_kill
- X
- X#ifdef TIOCGLTC
- Xstatic struct ltchars spec_chars;
- X#define SuspC spec_chars.t_suspc
- X#else
- X#define SuspC CONTROL_('Z')
- X#endif
- X
- X#endif
- X
- X#ifdef USE_TERMCAP
- X
- Xopt_cap(cap, buf)
- Xchar *cap, *buf;
- X{
- X char *tgetstr();
- X
- X *buf = NUL;
- X return tgetstr(cap, &buf) != NULL;
- X}
- X
- Xget_cap(cap, buf)
- Xchar *cap, *buf;
- X{
- X if (!opt_cap(cap, buf))
- X user_error("TERMCAP entry for %s has no '%s' capability",
- X term_name, cap);
- X}
- X
- X#endif /* USE_TERMCAP */
- X
- Xstatic int multi_keys = 0;
- X
- Xstatic struct multi_key {
- X key_type *cur_key;
- X key_type *keys;
- X key_type code;
- X} multi_key_list[MULTI_KEYS];
- X
- Xenter_multi_key(code, keys)
- Xint code;
- Xkey_type *keys;
- X{
- X register i;
- X
- X if (strlen((char *)keys) == 1)
- X /* will ignore arrow keys overlaying these keys */
- X if (*keys == NL || *keys == CR ||
- X *keys == erase_key || *keys == kill_key ||
- X *keys == IntrC) return;
- X
- X /* lookup code to see if it is already defined... */
- X for (i = 0; i < multi_keys; i++)
- X if (multi_key_list[i].code == (key_type)code)
- X goto replace_key;
- X
- X i = multi_keys++;
- X
- X /* now i points to matching or empty slot */
- X if (i >= MULTI_KEYS) {
- X /* should never happen */
- X log_entry('E', "too many multi keys");
- X return;
- X }
- X
- X replace_key:
- X
- X multi_key_list[i].keys = keys;
- X multi_key_list[i].code = code;
- X}
- X
- Xdump_multi_keys()
- X{
- X register i;
- X register key_type *cp;
- X
- X clrdisp();
- X pg_init(0, 1);
- X
- X for (i = 0; i < multi_keys; i++) {
- X if (pg_next() < 0) break;
- X printf("%d\t%s\t", i, key_name(multi_key_list[i].code));
- X for (cp = multi_key_list[i].keys; *cp; cp++) {
- X putchar(SP);
- X fputs(key_name(*cp), stdout);
- X }
- X }
- X
- X pg_end();
- X}
- X
- X
- X#ifdef RESIZING
- X
- Xsig_type catch_winch()
- X{
- X struct winsize winsize;
- X
- X (void) signal(SIGWINCH, catch_winch);
- X if (ioctl(0, TIOCGWINSZ, &winsize) >= 0
- X && (winsize.ws_row != Lines || winsize.ws_col != Columns)) {
- X Lines = winsize.ws_row;
- X Columns = winsize.ws_col;
- X s_redraw = 1;
- X s_resized = 1;
- X }
- X}
- X#endif /* RESIZING */
- X
- X#ifdef SV_INTERRUPT
- X#ifdef NO_SIGINTERRUPT
- Xstatic siginterrupt(signo, on)
- X{
- X struct sigvec sv;
- X sv.sv_handler = signal (signo, SIG_DFL);
- X sv.sv_mask = 0;
- X sv.sv_flags = on ? SV_INTERRUPT : 0;
- X sigvec (signo, &sv, 0);
- X}
- X#endif
- X#endif
- X
- Xstatic unsigned sp_table[] = {
- X B9600, 960,
- X#ifdef B19200
- X B19200, 1920,
- X#else
- X#ifdef EXTA
- X EXTA, 1920,
- X#endif
- X#endif
- X#ifdef B38400
- X B38400, 3840,
- X#else
- X#ifdef EXTB
- X EXTB, 3840,
- X#endif
- X#endif
- X B1200, 120,
- X B2400, 240,
- X B4800, 480,
- X B300, 30,
- X 0, 0
- X};
- X
- Xstatic set_term_speed(sp)
- Xregister unsigned long sp;
- X{
- X register unsigned *tp;
- X
- X for (tp = sp_table; *tp; tp += 2)
- X if (*tp == sp) {
- X terminal_speed = tp[1];
- X return;
- X }
- X
- X terminal_speed = 30;
- X}
- X
- Xinit_term()
- X{
- X#ifdef USE_TERMCAP
- X char tbuf[1024];
- X#endif
- X
- X if ((term_name = getenv("TERM")) == NULL)
- X user_error("No TERM variable in enviroment");
- X
- X#ifdef HAVE_TERMIO
- X ioctl(0, TCGETA, &norm_tty);
- X#else
- X ioctl(0, TIOCGETP, &norm_tty);
- X#endif
- X
- X#ifdef USE_TERMINFO
- X setupterm((char *)NULL, 1, (int *)NULL);
- X Columns = columns;
- X Lines = lines;
- X cookie_size = magic_cookie_glitch;
- X WRAP = auto_right_margin;
- X if (use_visible_bell && HAS_CAP(flash_screen))
- X strcpy(bell_str, flash_screen);
- X else if (HAS_CAP(bell))
- X strcpy(bell_str, bell);
- X if (! HAS_CAP(cursor_home))
- X cursor_home = copy_str(tgoto(cursor_address, 0, 0));
- X#else
- X
- X if (tgetent(tbuf, term_name) <= 0)
- X user_error("Unknown terminal type: %s", term_name);
- X
- X if (opt_cap("bc", XBC)) BC = XBC;
- X if (opt_cap("up", XUP)) UP = XUP;
- X opt_cap("pc", cursor_address); /* temp. usage */
- X PC = cursor_address[0];
- X
- X get_cap("cm", cursor_address);
- X if (!opt_cap("ho", cursor_home))
- X strcpy(cursor_home, tgoto(cursor_address, 0, 0));
- X
- X get_cap("cl", clear_screen);
- X get_cap("ce", clr_eol);
- X opt_cap("cd", clr_eos);
- X
- X#ifdef RESIZING
- X {
- X struct winsize winsize;
- X
- X if (ioctl(0, TIOCGWINSZ, &winsize) >= 0
- X && winsize.ws_row != 0 && winsize.ws_col != 0) {
- X Lines = winsize.ws_row;
- X Columns = winsize.ws_col;
- X (void) signal(SIGWINCH, catch_winch);
- X#ifdef SV_INTERRUPT
- X siginterrupt(SIGWINCH, 1); /* make read from tty interruptable */
- X#endif /* SV_INTERRUPT */
- X }
- X }
- X if (Lines == 0 || Columns == 0) {
- X#endif /* RESIZING */
- X Lines = tgetnum("li");
- X Columns = tgetnum("co");
- X#ifdef RESIZING
- X }
- X#endif /* RESIZING */
- X
- X opt_cap("so", enter_standout_mode);
- X opt_cap("se", exit_standout_mode);
- X
- X opt_cap("us", enter_underline_mode);
- X opt_cap("ue", exit_underline_mode);
- X
- X opt_cap("kd", key_down);
- X opt_cap("ku", key_up);
- X opt_cap("kr", key_right);
- X opt_cap("kl", key_left);
- X
- X cookie_size = tgetnum("sg");
- X
- X WRAP = tgetflag("am");
- X
- X opt_cap("ti", enter_ca_mode);
- X opt_cap("te", exit_ca_mode);
- X
- X if (!use_visible_bell || !opt_cap("vb", bell_str))
- X if (!opt_cap("bl", bell_str))
- X strcpy(bell_str, "\007");
- X
- X#endif /* !USE_TERMINFO */
- X
- X STANDOUT = HAS_CAP(enter_standout_mode);
- X if (STANDOUT) {
- X if (cookie_size < 0) cookie_size = 0;
- X two_cookies = 2 * cookie_size;
- X } else
- X cookie_size = two_cookies = 0;
- X
- X
- X raw_tty = norm_tty;
- X
- X#ifdef HAVE_TERMIO
- X raw_tty.c_iflag &= ~(BRKINT|INLCR|ICRNL|IGNCR);
- X raw_tty.c_iflag |= IGNBRK|IGNPAR|ISTRIP;
- X raw_tty.c_oflag &= ~OPOST;
- X raw_tty.c_lflag &= ~(ISIG|ICANON|XCASE|ECHO|NOFLSH);
- X
- X /* read a maximum of 10 characters in one burst; timeout in 1-200 ms */
- X raw_tty.c_cc[VEOF] = KEY_BURST;
- X raw_tty.c_cc[VEOL] = ((raw_tty.c_cflag & CBAUD) > B1200) ? 1 : 2;
- X set_term_speed((unsigned long)(raw_tty.c_cflag & CBAUD));
- X#else
- X ioctl(0, TIOCGETC, &norm_chars);
- X
- X#ifdef TIOCGLTC
- X ioctl(0, TIOCGLTC, &spec_chars);
- X#endif
- X
- X ospeed = norm_tty.sg_ospeed;
- X set_term_speed((unsigned long)ospeed);
- X
- X raw_tty.sg_flags &= ~ECHO;
- X#ifdef CBREAK
- X#ifdef SV_INTERRUPT /* make read from tty interruptable */
- X siginterrupt(SIGTSTP, 1); /* this is necessary to redraw screen */
- X#endif
- X raw_tty.sg_flags |= CBREAK;
- X#else
- X raw_tty.sg_flags |= RAW;
- X#endif
- X
- X#ifdef SV_INTERRUPT
- X siginterrupt(SIGALRM, 1); /* make read from tty interruptable */
- X#endif
- X#endif
- X
- X erase_key = (key_type)EraseC;
- X kill_key = (key_type)KillC;
- X
- X if (HAS_CAP(key_down))
- X enter_multi_key(K_down_arrow, (key_type *)key_down);
- X if (HAS_CAP(key_up))
- X enter_multi_key(K_up_arrow, (key_type *)key_up);
- X if (HAS_CAP(key_right))
- X enter_multi_key(K_right_arrow, (key_type *)key_right);
- X if (HAS_CAP(key_left))
- X enter_multi_key(K_left_arrow, (key_type *)key_left);
- X
- X visual_on();
- X}
- X
- Xhome()
- X{
- X putp(cursor_home);
- X}
- X
- Xstatic int curxy_c = -1, curxy_l, savxy_c = -1, savxy_l;
- X
- Xsave_xy()
- X{
- X savxy_c = curxy_c; savxy_l = curxy_l;
- X}
- X
- Xrestore_xy()
- X{
- X if (savxy_c < 0) return;
- X gotoxy(savxy_c, savxy_l); fl;
- X}
- X
- Xgotoxy(c, l)
- Xint c, l;
- X{
- X curxy_c = c; curxy_l = l;
- X putp(tgoto(cursor_address, c, l));
- X}
- X
- Xclrdisp()
- X{
- X#ifdef USE_TERMINFO
- X putp(clear_screen); /* tputs is broken on UNISYS I've been told */
- X#else
- X tputs(clear_screen, Lines, outc);
- X#endif
- X curxy_c = savxy_c = -1;
- X}
- X
- Xclrline()
- X{
- X putp(clr_eol);
- X fl;
- X}
- X
- Xclrpage(lineno)
- Xregister int lineno;
- X{
- X register int olineno= lineno;
- X
- X if (HAS_CAP(clr_eos)) {
- X#ifdef USE_TERMINFO
- X putp(clr_eos);
- X#else
- X tputs(clr_eos, Lines - lineno, outc);
- X#endif
- X } else {
- X clrline();
- X lineno++;
- X for (; lineno < Lines; lineno++) {
- X gotoxy(0, lineno);
- X putp(clr_eol);
- X }
- X gotoxy(0, olineno);
- X fl;
- X }
- X}
- X
- Xstatic char so_buf[512], *so_p;
- Xstatic int so_c, so_l, so_b, so_active = 0;
- X
- Xso_gotoxy(c, l, blank)
- X{
- X if (!STANDOUT && c >= 0) {
- X if (l >= 0) gotoxy(c, l);
- X return 0;
- X }
- X
- X so_active++;
- X so_c = c;
- X so_l = l;
- X so_b = blank;
- X so_p = so_buf;
- X *so_p = NUL;
- X
- X return 1; /* not really true if not standout & c < 0 */
- X}
- X
- X/*VARARGS*/
- Xso_printf(va_alist)
- Xva_dcl
- X{
- X use_vararg;
- X
- X start_vararg;
- X so_vprintf(va_args1toN);
- X end_vararg;
- X}
- X
- Xso_vprintf(va_tail)
- Xva_tdcl
- X{
- X char *fmt;
- X
- X fmt = va_arg1(char *);
- X
- X if (!so_active) {
- X vprintf(fmt, va_args2toN);
- X return;
- X }
- X
- X vsprintf(so_p, fmt, va_args2toN);
- X while (*so_p) so_p++;
- X}
- X
- Xso_end()
- X{
- X int len;
- X
- X if (!so_active) return;
- X
- X if (so_l >= 0) {
- X
- X len = so_p - so_buf + two_cookies;
- X
- X if (so_c < 0)
- X so_c = Columns - len - 2;
- X if (so_c < 0) so_c = 0;
- X
- X if (len + so_c >= Columns) {
- X len = Columns - so_c - two_cookies;
- X so_buf[len] = NUL;
- X }
- X
- X if (cookie_size) {
- X gotoxy(so_c + len - cookie_size, so_l);
- X putp(exit_standout_mode);
- X }
- X
- X gotoxy(so_c, so_l);
- X
- X }
- X
- X if ((so_b & 1) && (!STANDOUT || !cookie_size)) putchar(SP);
- X
- X if (STANDOUT) putp(enter_standout_mode);
- X
- X fputs(so_buf, stdout);
- X
- X if (STANDOUT) putp(exit_standout_mode);
- X
- X if ((so_b & 2) && (!STANDOUT || !cookie_size)) putchar(SP);
- X
- X so_active = 0;
- X}
- X
- X
- X/*VARARGS*/
- Xso_printxy(va_alist)
- Xva_dcl
- X{
- X int k, l;
- X use_vararg;
- X
- X start_vararg;
- X
- X k = va_arg1(int);
- X l = va_arg2(int);
- X
- X so_gotoxy(k, l, 0);
- X so_vprintf(va_args3toN);
- X so_end();
- X
- X end_vararg;
- X}
- X
- Xunderline(on)
- X{
- X if (cookie_size) return 0;
- X if (! HAS_CAP(enter_underline_mode)) return 0;
- X putp(on ? enter_underline_mode : exit_underline_mode);
- X return 1;
- X}
- X
- Xhighlight(on)
- X{
- X if (cookie_size) return 0;
- X if (! HAS_CAP(enter_standout_mode)) return 0;
- X putp(on ? enter_standout_mode : exit_standout_mode);
- X return 1;
- X}
- X
- Xstatic int is_visual = 0;
- Xstatic int is_raw = 0;
- X
- X#ifdef HAVE_TERMIO
- X#define RAW_MODE_ON ioctl(0, TCSETAF, &raw_tty)
- X#define RAW_MODE_OFF ioctl(0, TCSETAF, &norm_tty)
- X#else
- X#define RAW_MODE_ON ioctl(0, TIOCSETP, &raw_tty)
- X#define RAW_MODE_OFF ioctl(0, TIOCSETP, &norm_tty)
- X#endif
- X
- Xvisual_on()
- X{
- X if (HAS_CAP(enter_ca_mode)) {
- X putp(enter_ca_mode);
- X is_visual = 1;
- X }
- X}
- X
- Xvisual_off()
- X{
- X int was_raw = is_raw;
- X
- X if (term_name == NULL) return 0;
- X
- X if (is_visual && HAS_CAP(exit_ca_mode)) putp(exit_ca_mode), fl;
- X is_visual = 0;
- X
- X is_raw = 1;
- X unset_raw();
- X
- X return was_raw;
- X}
- X
- X#ifdef CBREAK
- Xraw()
- X{
- X if (is_raw == 1)
- X return;
- X is_raw = 1;
- X RAW_MODE_ON;
- X}
- X
- Xno_raw()
- X{
- X return 0;
- X}
- X
- Xunset_raw()
- X{
- X if (is_raw == 0)
- X return 0;
- X RAW_MODE_OFF;
- X is_raw = 0;
- X return 1;
- X}
- X
- X#else /* not CBREAK */
- Xstatic int must_set_raw = 1;
- X
- Xraw()
- X{
- X if (!flow_control) {
- X if (!must_set_raw) return;
- X must_set_raw = 0;
- X }
- X
- X if (is_raw) return;
- X
- X RAW_MODE_ON;
- X
- X is_raw++;
- X}
- X
- Xno_raw()
- X{
- X if (!flow_control) return 0;
- X
- X if (!is_raw) return 0;
- X
- X RAW_MODE_OFF;
- X
- X is_raw = 0;
- X
- X return 1;
- X}
- X
- Xunset_raw()
- X{
- X int was_raw = is_raw;
- X
- X if (is_raw) {
- X RAW_MODE_OFF;
- X is_raw = 0;
- X }
- X
- X if (!flow_control)
- X must_set_raw = 1;
- X return was_raw;
- X}
- X
- X#endif /* CBREAK */
- X
- Xstatic int do_flush_input = 0;
- X
- Xflush_input()
- X{
- X#ifdef HAVE_TERMIO
- X ioctl(0, TCFLSH, 0);
- X do_flush_input = 1;
- X#else
- X#ifdef FREAD
- X int arg = FREAD;
- X ioctl(0, TIOCFLUSH, &arg);
- X#else
- X ioctl(0, TIOCFLUSH, 0);
- X#endif
- X#endif
- X}
- X
- Xint enable_stop = 1;
- X
- X#ifndef KEY_BURST
- X
- Xstatic int alarm_on = 0;
- X
- Xstatic mk_timeout()
- X{
- X alarm_on = 0;
- X}
- X
- X#endif
- X
- Xstatic int do_macro_processing = 1;
- X
- Xget_c()
- X{
- X key_type c;
- X int any_multi, key_cnt, mc;
- X register struct multi_key *mk;
- X register int i;
- X#ifdef KEY_BURST
- X static char cbuf[KEY_BURST], *cp;
- X static int n = 0;
- X
- X if (do_flush_input) {
- X do_flush_input = 0;
- X n = 0;
- X }
- X#else
- X int n;
- X key_type first_key;
- X#endif
- X
- X next_key:
- X if (s_hangup)
- X return K_interrupt;
- X
- X#ifdef RESIZING
- X if (s_resized) {
- X s_resized = 0;
- X return GETC_COMMAND | K_REDRAW;
- X }
- X#endif
- X
- X if (do_macro_processing)
- X switch (m_getc(&mc)) {
- X case 0:
- X break;
- X case 1:
- X return mc;
- X case 2:
- X return K_interrupt;
- X }
- X
- X for (i = multi_keys, mk = multi_key_list; --i >= 0; mk++)
- X mk->cur_key = mk->keys;
- X key_cnt = 0;
- X
- X#ifdef KEY_BURST
- X if (n <= 0) {
- X n = read(0, cbuf, KEY_BURST);
- X if (n < 0 && errno != EINTR) s_hangup++;
- X if (n <= 0) return K_interrupt;
- X cp = cbuf;
- X }
- X
- X while (--n >= 0) {
- X c = (key_type)*cp++;
- X#else
- X
- X while ((n = read(0, (char *)&c, 1)) > 0) {
- X c &= 0177; /* done by ISTRIP on USG systems */
- X#endif
- X
- X if (c == CONTROL_('Q') || c == CONTROL_('S'))
- X continue;
- X
- X any_multi = 0;
- X for (i = multi_keys, mk = multi_key_list; --i >= 0; mk++)
- X if (mk->cur_key) {
- X if (*(mk->cur_key)++ == c) {
- X if (*(mk->cur_key) == NUL) {
- X c = mk->code;
- X goto got_char;
- X }
- X any_multi++;
- X } else
- X mk->cur_key = NUL;
- X }
- X
- X if (any_multi) {
- X#ifndef KEY_BURST
- X if (key_cnt == 0) {
- X first_key = c;
- X alarm_on = 1;
- X signal(SIGALRM, mk_timeout);
- X MICRO_ALARM();
- X }
- X#endif
- X key_cnt++;
- X continue;
- X }
- X if (key_cnt == 0)
- X goto got_char;
- X
- X ding();
- X flush_input();
- X goto next_key;
- X }
- X
- X#ifdef CBREAK
- X if (s_redraw) {
- X s_redraw = 0;
- X return GETC_COMMAND | K_REDRAW;
- X }
- X#endif
- X
- X#ifndef KEY_BURST
- X if (n < 0) {
- X if (errno != EINTR) s_hangup++;
- X return K_interrupt;
- X }
- X#endif
- X
- X#ifdef RESIZING
- X if (s_resized) {
- X s_resized = 0;
- X return GETC_COMMAND | K_REDRAW;
- X }
- X#endif
- X
- X#ifndef KEY_BURST
- X if (n < 0 && key_cnt)
- X c = first_key;
- X#endif
- X
- Xgot_char:
- X
- X#ifndef KEY_BURST
- X if (alarm_on) {
- X alarm(0);
- X alarm_on = 0;
- X }
- X#endif
- X
- X c = global_key_map[c];
- X
- X#ifndef CBREAK
- X if (c == SuspC) {
- X if (!enable_stop) goto next_key;
- X if (suspend_nn())
- X return GETC_COMMAND | K_REDRAW;
- X else
- X goto next_key;
- X }
- X
- X if (c == IntrC) c = K_interrupt;
- X#endif
- X return (int)c;
- X}
- X
- X
- X/*
- X * read string with completion, pre-filling, and break on first char
- X *
- X * dflt is a string that will be use as default value if the
- X * space bar is hit as the first character.
- X *
- X * prefill pre-fill the buffer with .... and print it
- X *
- X * break_chars return immediately if one of these characters
- X * is entered as the first character.
- X *
- X * completion is a function that will fill the buffer with a value
- X * see the group_completion and file_completion routines
- X * for examples.
- X */
- X
- Xchar *get_s(dflt, prefill, break_chars, completion)
- Xchar *dflt, *prefill, *break_chars;
- Xfct_type completion;
- X{
- X static char buf[GET_S_BUFFER];
- X register char *cp;
- X register int i, c, lastc;
- X char *ret_val = buf;
- X int comp_used, comp_len;
- X int ostop, max, did_help;
- X int hit_count;
- X
- X switch (m_gets(buf)) {
- X case 0:
- X break;
- X case 1:
- X return buf;
- X case 2:
- X return NULL;
- X }
- X
- X ostop = enable_stop;
- X enable_stop = 0;
- X do_macro_processing = 0;
- X hit_count = 0;
- X
- X max = Columns - prompt_length;
- X
- X if (max >= FILENAME) max = FILENAME-1;
- X
- X i = comp_len = comp_used = did_help = 0;
- X
- X if (prefill && prefill[0]) {
- X while (c = *prefill++) {
- X if (i == max) break;
- X
- X putchar(c);
- X buf[i] = c;
- X i++;
- X }
- X fl;
- X }
- X
- X if (dflt && *dflt == NUL)
- X dflt = NULL;
- X
- X if (break_chars && *break_chars == NUL)
- X break_chars = NULL;
- X
- X c = NUL;
- X for(;;) {
- X lastc = c;
- X c = get_c();
- X if (c & GETC_COMMAND) continue;
- X
- X kill_prefill_hack:
- X
- X hit_count++;
- X
- X if (i == 0) {
- X if (c == comp1_key && dflt) {
- X while ((c = *dflt++) != NUL && i < max) {
- X putchar(c);
- X buf[i] = c;
- X i++;
- X }
- X fl;
- X dflt = NULL;
- X continue;
- X }
- X if (cp = break_chars) {
- X while (*cp)
- X if (*cp++ == c) {
- X buf[0] = c;
- X buf[1] = NUL;
- X goto out;
- X }
- X }
- X }
- X
- X if (completion != NULL_FCT) {
- X if (comp_used && c == erase_key) {
- X CALL(completion)(buf, -1);
- X if (did_help) { clrmsg(i); did_help = 0; }
- X if (comp_len) {
- X i -= comp_len;
- X while (--comp_len >= 0) putchar(BS);
- X clrline();
- X }
- X comp_len = comp_used = 0;
- X if (lastc == help_key) goto no_completion;
- X continue;
- X }
- X
- X if (c == comp1_key || c == comp2_key || c == help_key) {
- X if (!comp_used || c == comp2_key ||
- X (c == help_key && lastc != c)) {
- X buf[i] = NUL;
- X if ((comp_used = CALL(completion)(buf, i)) == 0) {
- X ding();
- X continue;
- X }
- X if (comp_used < 0) {
- X comp_used = 0;
- X goto no_completion;
- X }
- X comp_len = 0;
- X }
- X if (c == help_key) {
- X if (CALL(completion)((char *)NULL, 1)) {
- X gotoxy(prompt_length+i, prompt_line); fl;
- X did_help = 1;
- X }
- X continue;
- X }
- X
- X if (comp_len) {
- X i -= comp_len;
- X while (--comp_len >= 0) putchar(BS);
- X clrline();
- X comp_len = 0;
- X }
- X
- X switch ( CALL(completion)((char *)NULL, 0) ) {
- X
- X case 0: /* no possible completion */
- X comp_used = 0;
- X ding();
- X continue;
- X
- X case 2: /* whole new alternative */
- X while (--i >= 0) putchar(BS);
- X clrline();
- X /* fall thru */
- X
- X case 1: /* completion */
- X comp_len = i;
- X while (c = buf[i]) {
- X if (i == max) break;
- X putchar(c);
- X i++;
- X }
- X fl;
- X comp_len = i - comp_len;
- X continue;
- X }
- X }
- X
- X if (comp_used) {
- X CALL(completion)(buf, -1);
- X if (did_help) clrmsg(i);
- X comp_len = comp_used = 0;
- X }
- X }
- X
- X no_completion:
- X
- X if (c == CR || c == NL) {
- X buf[i] = NUL;
- X break;
- X }
- X
- X if (c == erase_key) {
- X if (i <= 0) continue;
- X i--;
- X putchar(BS);
- X putchar(' ');
- X putchar(BS);
- X fl;
- X continue;
- X }
- X
- X if (c == delword_key) {
- X if (i <= 0) continue;
- X buf[i-1] = 'X';
- X while (i > 0 && isalnum(buf[i-1])) { putchar(BS); i--; }
- X clrline();
- X continue;
- X }
- X
- X if (c == kill_key) {
- X while (i > 0) { putchar(BS); i--; }
- X clrline();
- X if (hit_count == 1 && dflt) {
- X c = comp1_key;
- X goto kill_prefill_hack;
- X }
- X continue;
- X }
- X
- X if (c == K_interrupt) {
- X ret_val = NULL;
- X break;
- X }
- X
- X if (!isascii(c) || !isprint(c)) continue;
- X
- X if (i == max) continue;
- X
- X if (i > 0 && buf[i-1] == '/' && (c == '/' || c == '+')) {
- X while (i > 0) { putchar(BS); i--; }
- X clrline();
- X }
- X
- X putchar(c);
- X fl;
- X
- X buf[i] = c;
- X i++;
- X }
- X out:
- X enable_stop = ostop;
- X do_macro_processing = 1;
- X return ret_val;
- X}
- X
- Xexport int list_offset = 0;
- X
- Xlist_completion(str)
- Xchar *str;
- X{
- X static int cols, line;
- X
- X if (str == NULL) {
- X cols = Columns;
- X line = prompt_line + 1;
- X
- X gotoxy(0, line);
- X clrpage(line);
- X return 1;
- X }
- X
- X str += list_offset;
- X
- X for (;;) {
- X cols -= strlen(str);
- X if (cols >= 0) {
- X printf("%s%s", str, cols > 0 ? " " : "");
- X cols--;
- X return 1;
- X }
- X if (line >= Lines - 1) return 0;
- X line++;
- X cols = Columns;
- X gotoxy(0, line);
- X if (line == Lines - 1) cols--;
- X }
- X}
- X
- Xyes(must_answer)
- Xint must_answer;
- X{
- X int c, help = 1, in_macro = 0;
- X
- X switch (m_yes()) {
- X case 0:
- X break;
- X case 1:
- X return 0;
- X case 2:
- X return 1;
- X case 3:
- X do_macro_processing = 0;
- X in_macro++;
- X break;
- X }
- X
- X for (;;) {
- X if (!is_raw) {
- X raw();
- X c = get_c();
- X unset_raw();
- X } else
- X c = get_c();
- X
- X if (c == 'y' || c == 'Y') {
- X c = 1;
- X break;
- X }
- X
- X if (must_answer == 0 && (c == SP || c == CR || c == NL)) {
- X c = 1;
- X break;
- X }
- X
- X if (c == 'n' || c == 'N') {
- X c = 0;
- X break;
- X }
- X if (c == K_interrupt) {
- X c = -1;
- X break;
- X }
- X if (help) {
- X fputs(" y=YES n=NO", stdout);
- X prompt_length += 11;
- X help = 0;
- X }
- X }
- X
- X if (in_macro) {
- X if (c < 0) m_break();
- X do_macro_processing = 1;
- X }
- X
- X return c;
- X}
- X
- X
- Xding()
- X{
- X putp(bell_str);
- X fl;
- X}
- X
- X
- Xdisplay_file(name, modes)
- Xchar *name;
- Xint modes;
- X{
- X FILE *f;
- X register c, stand_on;
- X int linecnt, headln_cnt, hdline, no_conf;
- X char headline[128];
- X import char *help_directory;
- X
- X headline[0] = 0;
- X hdline = 0;
- X no_conf = 0;
- X
- X headln_cnt = -1;
- X
- X if (modes & CLEAR_DISPLAY) {
- X gotoxy(0,0);
- X clrdisp();
- X }
- X
- X linecnt = Lines - 1;
- X
- Xchain:
- X
- X f = open_file(relative(help_directory, name), OPEN_READ);
- X if (f == NULL)
- X printf("\r\n\nFile %s is not available\n\n", name);
- X else {
- X stand_on = 0;
- X
- X while ((c = getc(f)) != EOF) {
- X#ifdef HAVE_JOBCONTROL
- X if (s_redraw) {
- X no_conf = 1;
- X break;
- X }
- X#endif
- X no_conf = 0;
- X if (c == '\1') {
- X if (STANDOUT) {
- X putp(stand_on ? exit_standout_mode : enter_standout_mode);
- X stand_on = !stand_on;
- X }
- X continue;
- X }
- X if (c == '\2') {
- X headln_cnt = 0;
- X continue;
- X }
- X if (c == '\3') {
- X headln_cnt = 0;
- X while ((c = getc(f)) != EOF && c != NL)
- X headline[headln_cnt++] = c;
- X headline[headln_cnt++] = NUL;
- X name = headline;
- X fclose(f);
- X goto chain;
- X }
- X if (c == '\4') {
- X printf("%s", version_id);
- X continue;
- X }
- X
- X if (headln_cnt >= 0)
- X headline[headln_cnt++] = c;
- X
- X if (hdline) {
- X puts(headline);
- X putchar(CR);
- X hdline = 0;
- X linecnt--;
- X }
- X
- X putchar(c);
- X if (c == NL) {
- X putchar(CR);
- X if (headln_cnt >= 0) {
- X headline[--headln_cnt] = 0;
- X headln_cnt = -1;
- X }
- X if (--linecnt == 0) {
- X no_conf = 1;
- X if (any_key(0) == K_interrupt)
- X break;
- X linecnt = Lines - 1;
- X if (modes & CLEAR_DISPLAY) {
- X gotoxy(0,0);
- X clrdisp();
- X }
- X hdline = headline[0];
- X }
- X }
- X }
- X
- X if (stand_on) putp(exit_standout_mode);
- X fclose(f);
- X }
- X
- X prompt_line = Lines-1; /* move prompt to last line */
- X
- X if (!no_conf && (modes & CONFIRMATION))
- X any_key(prompt_line);
- X}
- X
- X
- X/*VARARGS*/
- Xuser_error(va_alist)
- Xva_dcl
- X{
- X char *fmt;
- X use_vararg;
- X
- X unset_raw();
- X clrdisp();
- X fl;
- X
- X start_vararg;
- X fmt = va_arg1(char *);
- X
- X vprintf(fmt, va_args2toN);
- X putchar(NL);
- X
- X end_vararg;
- X nn_exit(1);
- X}
- X
- X/*VARARGS*/
- Xmsg(va_alist)
- Xva_dcl
- X{
- X use_vararg;
- X
- X start_vararg;
- X vmsg(va_args1toN);
- X end_vararg;
- X}
- X
- Xvmsg(va_tail)
- Xva_tdcl
- X{
- X static char errmsg[512] = "";
- X char *fmt;
- X
- X fmt = va_arg1(char *);
- X
- X if (fmt) vsprintf(errmsg, fmt, va_args2toN);
- X
- X gotoxy(0, Lines-1);
- X fputs(errmsg, stdout);
- X clrline();
- X any_message = 1;
- X
- X gotoxy(prompt_length, prompt_line);
- X fl;
- X}
- X
- Xclrmsg(col)
- Xint col;
- X{
- X gotoxy(0, prompt_line + 1);
- X clrpage(prompt_line + 1);
- X if (col >= 0)
- X gotoxy(prompt_length + col, prompt_line);
- X fl;
- X any_message = 0;
- X}
- X
- X
- X/*VARARGS*/
- Xprompt(va_alist)
- Xva_dcl
- X{
- X register char *cp;
- X int stand_on;
- X char *fmt;
- X static char cur_p[FILENAME];
- X static char saved_p[FILENAME];
- X use_vararg;
- X
- X start_vararg;
- X
- X fmt = va_arg1(char *);
- X
- X if (fmt == P_VERSION) {
- X gotoxy(0, prompt_line + 1);
- X printf("Release %s ", version_id);
- X clrline();
- X any_message++;
- X
- X if (prompt_line >= 0)
- X gotoxy(prompt_length, prompt_line);
- X goto out;
- X }
- X
- X if (fmt == P_SAVE) {
- X strcpy(saved_p, cur_p);
- X goto out;
- X }
- X
- X if (fmt == P_RESTORE)
- X strcpy(cur_p, saved_p);
- X
- X if (prompt_line >= 0)
- X gotoxy(0, prompt_line);
- X
- X if (fmt == P_MOVE) {
- X clrline();
- X goto out;
- X }
- X
- X if (fmt != P_REDRAW && fmt != P_RESTORE)
- X vsprintf(cur_p, fmt, va_args2toN);
- X
- X putchar(CR);
- X
- X for (cp = cur_p, stand_on = 0, prompt_length = 0; *cp; cp++) {
- X if (*cp == '\1') {
- X if (cp[1] != '\1') {
- X if (STANDOUT) {
- X putp(stand_on ? exit_standout_mode : enter_standout_mode);
- X stand_on = !stand_on;
- X prompt_length += cookie_size;
- X }
- X continue;
- X }
- X cp++;
- X } else
- X if (*cp == '\2') {
- X time_t t, tick_usage();
- X char *timestr;
- X
- X t = tick_usage();
- X
- X if (show_current_time) {
- X timestr = ctime(&t) + 11;
- X timestr[5] = NUL;
- X
- X printf("-- %s ", timestr);
- X prompt_length += 9;
- X }
- X
- X if (unread_mail(t)) {
- X printf("Mail ");
- X prompt_length += 5;
- X }
- X
- X continue;
- X }
- X
- X putchar(*cp);
- X prompt_length ++;
- X }
- X if (stand_on) {
- X putp(exit_standout_mode);
- X prompt_length += cookie_size;
- X }
- X
- X clrline();
- X
- X if (fmt == P_RESTORE)
- X restore_xy();
- X else
- X curxy_c = -1;
- X
- X out:
- X end_vararg;
- X}
- X
- X
- Xany_key(line)
- Xint line;
- X{
- X int was_raw, c, dmp;
- X
- X was_raw = is_raw;
- X if (!is_raw) raw();
- X if (line == 0)
- X line = -1;
- X else
- X if (line < 0)
- X line = Lines + line;
- X
- X if (line != 10000)
- X so_printxy(0, line, "Hit any key to continue");
- X
- X clrline();
- X
- X dmp = do_macro_processing;
- X do_macro_processing = 0;
- X c = get_c();
- X if (c == 'q' || c == 'Q') c = K_interrupt;
- X do_macro_processing = dmp;
- X
- X if (!was_raw) unset_raw();
- X
- X return c;
- X}
- X
- X
- Xstatic pg_fline, pg_width, pg_maxw, pg_line, pg_col, pg_quit;
- X
- Xpg_init(first_line, cols)
- Xint first_line, cols;
- X{
- X pg_fline = first_line;
- X pg_line = pg_fline - 1;
- X pg_quit = pg_col = 0;
- X pg_width = Columns / cols;
- X pg_maxw = pg_width * (cols - 1);
- X}
- X
- Xpg_scroll(n)
- Xint n;
- X{
- X pg_line += n;
- X if (pg_line >= (Lines - 1)) {
- X pg_line = 0;
- X if (any_key(0) == K_interrupt)
- X return 1;
- X putchar(CR);
- X clrline();
- X }
- X return 0;
- X}
- X
- Xpg_next()
- X{
- X int c;
- X
- X pg_line++;
- X if (pg_line < Lines) {
- X gotoxy(pg_col, pg_line);
- X if (pg_line == Lines - 1 && pg_col == pg_maxw) {
- X c = any_key(0);
- X gotoxy(0, pg_fline);
- X clrpage(pg_fline);
- X pg_col = 0;
- X pg_line = pg_fline;
- X if (c == K_interrupt) {
- X pg_quit = 1;
- X return -1;
- X }
- X return 1;
- X }
- X } else {
- X pg_line = pg_fline;
- X pg_col += pg_width;
- X gotoxy(pg_col, pg_line);
- X }
- X return 0;
- X}
- X
- Xpg_indent(pos)
- Xint pos;
- X{
- X gotoxy(pg_col + pos, pg_line);
- X}
- X
- Xpg_end()
- X{
- X if (pg_quit == 0 && pg_next() == 0)
- X any_key(0);
- X}
- X
- X
- Xuser_delay(ticks)
- Xint ticks;
- X{
- X if (ticks <= 0 || conf_dont_sleep) {
- X printf(" <>");
- X any_key(10000);
- X } else {
- X fl;
- X sleep((unsigned)ticks);
- X }
- X}
- X
- END_OF_FILE
- if test 27619 -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 1 \(of 22\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 22 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...
-