home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume22 / nn6.4 / part01 next >
Text File  |  1990-06-07  |  54KB  |  2,178 lines

  1. Subject:  v22i036:  NN Newsreader, release 6.4, Part01/21
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: d04fa928 5e29b51a 7500b5b8 47b939e6
  5.  
  6. Submitted-by: "Kim F. Storm" <storm@texas.dk>
  7. Posting-number: Volume 22, Issue 36
  8. Archive-name: nn6.4/part01
  9.  
  10. nn is a menu based (point and shoot) netnews reader with a complete
  11. set of features to satisfy both the expert and the novice user.  Since
  12. its first release in Denmark in 1984 (!), in Europe in 1988, and the
  13. global release in June 1989, it has replaced rn and other well-known
  14. news readers at many sites.
  15.  
  16. Some of the key features of nn are:
  17.  *  It is fast.  It uses a dtabase, so it starts almost equally fast (in a few
  18.     seconds), no matter whether you have 100 or 10000 unread articles!  On
  19.     my system nn uses less than 20 seconds to find all articles on a
  20.     specific subject among 64000 articles in all groups!
  21.  *  Menu-based article selection prior to reading the articles
  22.     with the articles sorted according to subject & posting time!
  23.  *  Release 6.4 uses standard .newsrc, and can leave individual
  24.     articles unread!
  25.  *  Digests are automatically split and presented as ordinary articles!
  26.     You can transparently save and respond to individual subarticles.
  27.  *  Full folder support: read, save, and delete individual articles.
  28.  *  Online help and manual.
  29.  *  Built-in unshar and patch functions.
  30.  *  Built-in uudecode function which will automatically unpack,
  31.     concatenate, and decode multi-part postings.
  32.  *  Easy remapping of keys with advanced macro definition features.
  33.  *  Automatic kill & selection of articles based on subject or author.
  34.  *  Whole classes of news groups can easily be unsubscribed
  35.  *  Related groups can be merged and presented as a single group, e.g.
  36.     comp.emacs and all gnu.emacs groups.
  37.  *  In a distributed environment, the database can be shared among all
  38.     hosts on the network.  Only one daemon is needed on the news server
  39.     for all hosts.  This works in a heterogenous environment as well.
  40.  *  NNTP is also supported (using a local database for speed).
  41.  
  42. #! /bin/sh
  43. # This is a shell archive.  Remove anything before this line, then feed it
  44. # into a shell via "sh file" or similar.  To overwrite existing files,
  45. # type "sh file -c".
  46. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  47. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  48. # Contents:  README MANIFEST conf contrib doc help inews man regexp.h
  49. #   term.c
  50. # Wrapped by storm@texas.dk on Sun May  6 18:19:13 1990
  51. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  52. echo If this archive is complete, you will see the following message:
  53. echo '          "shar: End of archive 1 (of 22)."'
  54. if test -f 'README' -a "${1}" != "-c" ; then 
  55.   echo shar: Will not clobber existing file \"'README'\"
  56. else
  57.   echo shar: Extracting \"'README'\" \(7714 characters\)
  58.   sed "s/^X//" >'README' <<'END_OF_FILE'
  59. X              INTRODUCTION TO NN
  60. X              ------------------
  61. X
  62. X                 RELEASE 6.4
  63. X
  64. X
  65. Xnn is a menu based (point and shoot) netnews reader with a complete
  66. Xset of features to satisfy both the expert and the novice user.  Since
  67. Xits first release in Denmark in 1984 (!), in Europe in 1988, and the
  68. Xglobal release in June 1989, it has replaced rn and other well-known
  69. Xnews readers at many sites.
  70. X
  71. XSome of the key features of nn are:
  72. X
  73. X *  Menu-based article selection prior to reading the articles
  74. X    with the articles sorted according to subject & posting time!
  75. X
  76. X    This significantly reduces the time spent on news reading.
  77. X    No keystorkes are wasted on articles you don't want to read, and
  78. X    only the articles selected on the menu will be read.
  79. X
  80. X *  Release 6.4 uses standard .newsrc, and can leave individual
  81. X    articles unread!
  82. X
  83. X *  Digests are automatically split and presented as ordinary articles!
  84. X    You can transparently save and respond to individual subarticles.
  85. X
  86. X *  Full folder support: read, save, and delete individual articles.
  87. X
  88. X *  Online help and manual.
  89. X
  90. X *  Built-in unshar and patch functions.
  91. X
  92. X *  Built-in uudecode function which will automatically unpack,
  93. X    concatenate, and decode multi-part postings.
  94. X
  95. X *  Easy remapping of keys with advanced macro definition features.
  96. X
  97. X *  Automatic kill & selection of articles based on subject or author.
  98. X
  99. X *  User specified presentation sequence of news groups based on the
  100. X    news group hierarchy.
  101. X
  102. X *  Whole classes of news groups can easily be unsubscribed
  103. X    permanently, e.g. talk.all and all.politics
  104. X
  105. X *  Related groups can be merged and presented as a single group, e.g.
  106. X    comp.emancs and all gnu.emacs groups.
  107. X
  108. X *  Blindingly fast 'search for subject'.  On my Texas S1500 system,
  109. X    nn uses less than 20 seconds to find all articles on a specific
  110. X    subject among 64000 articles in all groups!
  111. X
  112. X *  News collection and presentation is extremely fast, because nn
  113. X    uses its own database on top of the standard news system.
  114. X
  115. X *  In a distributed environment, the database can be shared among all
  116. X    hosts on the network.  Only one daemon is needed on the news server
  117. X    for all hosts.  This works in a heterogenous environment as well.
  118. X
  119. X *  NNTP is also supported (using a local database for speed).
  120. X
  121. XBecause of the database, nn starts almost equally fast (in a few
  122. Xseconds), no matter whether you have 100 or 10000 unread articles!
  123. XThe database takes up some disk space, but dramatically improves speed
  124. Xand functionality.  The amount of disk space consumed is approx. 1Mb
  125. Xper 10000 articles.
  126. X
  127. X
  128. X                 DISTRIBUTION
  129. X                 ------------
  130. X
  131. XThe package is posted as 22 separate shar archives on comp.sources.unix.
  132. XIt is unpacked by applying /bin/sh to each archive in turn.
  133. XEverything is a little more than 1 Mbyte, including documentation.
  134. X
  135. XIt is also available via anonymous ftp from
  136. X
  137. X    host: dkuug.dk (129.142.96.41)
  138. X    File: /pub/nn6.4.tar.Z (compressed tar)
  139. X
  140. X
  141. X                  COPYRIGHT
  142. X                  ---------
  143. X
  144. XCopyright (c) 1989, 1990 by Kim Fabricius Storm.  All rights reserved.
  145. X
  146. XNot derived from licensed software except as stated below.
  147. X
  148. XPermission is granted to anyone to use, modify, and reuse this
  149. Xsoftware for any purpose on any computer system, and to redistribute
  150. Xit freely, subject to the following restrictions:
  151. X
  152. X1. The author is not responsible for the consequences of use of this
  153. X   software, no matter how awful, even if they arise from defects in it.
  154. X
  155. X2. The origin of this software must not be misrepresented, either by
  156. X   explicit claim or by omission.
  157. X
  158. X3. Altered versions must be plainly marked as such, and must not be
  159. X   misrepresented as being the original software.
  160. X
  161. X
  162. XThe following code modules have been incorporated into nn, and the
  163. Xabove copyright notice does not apply to these modules; they include
  164. Xtheir own copyright notices (or have none):
  165. X
  166. Xregexp.c:    Copyright (c) 1986 by University of Toronto.
  167. X         Written by Henry Spencer.
  168. X
  169. Xunshar.c:    No copyright notice.
  170. X        Written by K. Greer, S. Shafer, and M. Mauldin
  171. X
  172. Xdecode.c:    Derived from a modified Berkeley original posted on
  173. X        USENET.
  174. X
  175. Xfullname.c:    Copyright (c) 1986 by Rick Adams.
  176. X        Derived from the Bnews distribution.
  177. X
  178. Xcontrib/*:    Various copyright notices.
  179. X        The software available in the contrib/ directory was sent
  180. X        to me for inclusion in the nn distribution, because
  181. X        the authors think it might be useful to other nn users.
  182. X        I have included it *as is*.
  183. X
  184. Xinews/*:    NNTP 1.5 mini-inews.  Copyrights for NNTP applies.
  185. X        The software in the inews/ directory is a stand-alone
  186. X        version of the NNTP 1.5.7 mini-inews which has been
  187. X        slightly changed to ease configuration when used with nn.
  188. X
  189. XVarious pieces of code which may have their own copyright notices are
  190. Xincluded in the contrib/ and inews/ directories.  This software has been
  191. Xsent to me in the hope that it will be useful to somebody else.  I
  192. Xhave included it in this spirit, but I take no responsibilities for
  193. Xthis software, and I have no intentions to support it.
  194. X
  195. X
  196. X                 INSTALLATION
  197. X                 ------------
  198. X
  199. XThe following files are contained in the `doc' subdirectory:
  200. X
  201. XThe installation procedure is described in the file INSTALLATION.
  202. X
  203. XYou may also find useful information in the files PROBLEMS and NNTP.
  204. X
  205. XThe file NEWS-6.3 describes the major changes from release 6.1 to 6.3.
  206. X
  207. XThe file NEWS-6.4 describes the major changes from release 6.3 to 6.4.
  208. X
  209. X
  210. X             BUG REPORTS and SUGGESTIONS
  211. X             ---------------------------
  212. X
  213. XPlease send bug reports (and fixes) to the following address:
  214. X    nn-bugs@dkuug.dk
  215. X
  216. XYou may also use nn-bugs for suggestions for improvements (missing
  217. Xfeatures in nn are considered to be bugs :-)
  218. X
  219. XThe easiest way to send a bug report is by using the :bug command in nn.
  220. X
  221. X
  222. X              NN HAS ITS OWN NEWS GROUP
  223. X              -------------------------
  224. X
  225. XWe have an unmoderated news group dedicated to nn: news.software.nn
  226. X
  227. XThe news.software.nn group is used for discussion on all subjects
  228. Xrelated to the nn news reader.  This includes, but is not limited to,
  229. Xquestions, answers, ideas, hints, information from the development
  230. Xgroup, patches, etc.
  231. X
  232. XThe news.software.nn group was created in January 1990 after an
  233. Xofficial vote.  It may still be missing on parts of the net, so if you
  234. Xdon't get it please check your news feed, and help propagating the
  235. Xnews group to the entire net.
  236. X
  237. X
  238. X               ACKNOWLEDGEMENTS
  239. X               ----------------
  240. X
  241. XSince the development of nn is now on its fifth year, numerous persons
  242. Xhave contributed to nn with ideas and critisism, have helped me debug
  243. Xthe software by patiently using alpha and beta versions, have provided
  244. Xbug fixes, small and big chunks of code, new configuration files, etc.
  245. X
  246. XMy warm thanks go to Rene Seindal and Wayne Davison for their many
  247. Xcontributions, to Lloyd W. Taylor for his efforts counting the
  248. Xvotes for news.software.nn, and to Paul D. Anderson for running the
  249. Xrelease 6.3 patch server.
  250. X
  251. XI also thank the following persons for their help and contributions:
  252. XPeter Andersen, Jonathan Bayer, Gardner Cohen, Bernie Cosell, P{r
  253. XEmanuelsson, Steven Grady, Miek Grenier, Scott Hankin, Kareth, Mike
  254. XKhaw, Edwin Kremer, Jean-Francois Lamy, Mark Moraes, A. E. Mossberg,
  255. XMark Nagel, Rich Salz, Steve Simmons, Wietse Z. Venema, James A.
  256. XWoods, and Pim Zandbergen.
  257. X
  258. XAnd of course I would like to thank the hundreds of other people who
  259. Xhave reported bugs, given suggestions, provided information, etc.
  260. XForgive me for not listing all your names here, but I hope you
  261. Xunderstand, and that you will continue to contribute your
  262. Xvaluable input to the continued developments.  Let us keep nn in the
  263. Xlead!
  264. X
  265. X
  266. XKim Fabricius Storm
  267. XTexas Instruments A/S, Denmark
  268. X
  269. XEmail: storm@texas.dk
  270. XSnail: Marielundvej 46E, DK-2730 Herlev, Denmark
  271. Xtel:   +45 42 91 7400      fax:   +45 42 91 8400
  272. END_OF_FILE
  273.   if test 7714 -ne `wc -c <'README'`; then
  274.     echo shar: \"'README'\" unpacked with wrong size!
  275.   fi
  276.   # end of 'README'
  277. fi
  278. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  279.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  280. else
  281.   echo shar: Extracting \"'MANIFEST'\" \(10469 characters\)
  282.   sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  283. X   File Name        Archive #    Description
  284. X----------------------------------------------------------
  285. XREADME                     1    Read this file first
  286. XMANIFEST                   1    Packing list
  287. XFILES                     22    Extract file names from MANIFEST
  288. XMakefile                  21    Makefile for building nn
  289. XSPLITNN1                  22    Split nn.1 in four parts.
  290. Xaccount.c                 17    Accounting routines
  291. Xactive.c                  20    Read active file
  292. Xadmin.c                   12    Administration mode (nnadmin)
  293. Xanswer.c                  14    Respond/post/mail code
  294. Xarticles.c                17    Incore article fetching and management
  295. Xarticles.h                21    Header file for article management
  296. Xaux.sh                    10    Auxiliary script for post/mail
  297. Xback_act.sh               22    Backup active file once a day
  298. Xcollect.c                 16    Collect groups and articles in the database
  299. Xconf                       1    Directory for s- and m- files
  300. Xconf/m-3b1g.h             22    For 3b1 (unix-pc) with GCC [no networking].
  301. Xconf/m-att3b.h            22    For AT&T 3b2 (with s-usg3-1.h)
  302. Xconf/m-convex.h           21    For Convex.
  303. Xconf/m-dec3100.h          22    For DECstation 3100 (with s-bsd4-2.h)
  304. Xconf/m-gould.h            22    For Gould PN6000 (with s-bsd4-3.h)
  305. Xconf/m-hp9000.h           22    For HP9000 series 320 and 800 (at least)
  306. Xconf/m-i80286.h           22    For Intel 80286 processors [no network support]
  307. Xconf/m-i80386.h           22    For Intel 80386 processors [no network support]
  308. Xconf/m-m680x0.h           22    For 68000 family processors
  309. Xconf/m-m88000.h           22    For Motorola 88000 risc processors
  310. Xconf/m-mips.h             22    For MIPS processors
  311. Xconf/m-pyramid.h          22    For Pyramid (and Targon 35).
  312. Xconf/m-rt6150.h           22    For IBM 6150
  313. Xconf/m-sgi4D.h            22    For Silicon Graphics 4D series.
  314. Xconf/m-sparc.h            22    For SPARC processors
  315. Xconf/m-sun386i.h          22    For 80386 based SUNs [have network support]
  316. Xconf/m-symmetry.h         22    For Sequent Symmetry.
  317. Xconf/m-template.h         21    Template for new machine files.
  318. Xconf/m-vax.h              22    For VAX family
  319. Xconf/s-3b1g.h             22    For 3b1 (unix-pc) with GCC.
  320. Xconf/s-aix221.h           14    For AIX 2.2.1
  321. Xconf/s-aux1-1.h           22    For A/UX 1.1
  322. Xconf/s-bsd4-2.h           20    For 4.2 BSD and Ultrix systems
  323. Xconf/s-bsd4-3.h           22    For 4.3 BSD systems
  324. Xconf/s-dnix5-2.h          22    For dnix 5.2 on DIAB DS90.
  325. Xconf/s-dnix5-3.h          22    For dnix 5.3 on DIAB DS90.
  326. Xconf/s-dynix3-0.h         22    For Dynix 3.0 on Symmetry.
  327. Xconf/s-fortune.h          19    For Fortune 32:16 [read comments in the file]
  328. Xconf/s-hpux.h              6    For HPUX (series 300)
  329. Xconf/s-hpux2-1.h          22    For HPUX 2.1 (series 800)
  330. Xconf/s-hpux3-0.h          22    For HPUX 3.0 (series 800)
  331. Xconf/s-hpux6-5.h          21    For HPUX 6.5 or newer (series 300)
  332. Xconf/s-pyramid.h          22    For Pyramid (and Targon 35).
  333. Xconf/s-sgi4D.h            21    For IRIX 3.1/3.2 [read comments in the file]
  334. Xconf/s-sunos3.h           22    For SunOS 3
  335. Xconf/s-sunos4-0.h         22    For SunOS 4.0
  336. Xconf/s-sys5-tcap.h        22    For system V using termcap.
  337. Xconf/s-sys5.h             20    For most system V based systems.
  338. Xconf/s-template.h         19    Template for new system files.
  339. Xconf/s-texas1500.h        22    For Texas Instruments System 1500.
  340. Xconf/s-tower32.h          22    For NCR tower
  341. Xconf/s-umipsb.h           19    For Mips w/riscos 4.0 or greater
  342. Xconf/s-uport2-2.h         22    For Microport UNIX V.2
  343. Xconf/s-usg3-1.h           22    For most system V systems (obsolete)
  344. Xconf/s-xenix386.h         21    For xenix386 [termcap version].
  345. Xconf/s-xenix386ds.h       22    For Xenix386 2.3.2 w/development system.
  346. Xconfig.h-dist             17    CONFIGURATION FILE, DISTRIBUTED VERSION
  347. Xcontrib                    1    Directory for contributed software
  348. Xcontrib/aspell            20    Ispell front-end written in perl
  349. Xcontrib/cn                22    Checknews w/multi-column output
  350. Xcontrib/recmail.c         18    Sample recmail program
  351. Xcontrib/recmail.sh        18    Sample recmail script
  352. Xcvt-help.c                22    Convertion utility for help files
  353. Xdata.h                    15    Internal article and group information
  354. Xdb.c                      13    Database access and update routines
  355. Xdb.h                      20    External database format
  356. Xdebug.h                   22    Debugging symbols
  357. Xdecode.c                  17    UUdecode engine
  358. Xdigest.c                  17    Digest splitting
  359. Xdir.c                     19    Directory access
  360. Xdir.h                     22    Include file for directory access
  361. Xdoc                        1    Directory for documentation files
  362. Xdoc/INSTALLATION           9    INSTALLATION AND CONFIGURATION
  363. Xdoc/NEWS-6.3              18    What's new in release 6.3
  364. Xdoc/NEWS-6.4              16    What's new in release 6.4
  365. Xdoc/NNTP                  16    INSTALLATION WITH NNTP or NFS
  366. Xdoc/PROBLEMS              15    KNOWN PROBLEMS AND SOLUTIONS
  367. Xdoc/RELEASE_NOTES         20    Known problems
  368. Xexecute.c                 19    Shell command execution
  369. Xexpire.c                  15    Database expiration
  370. Xfolder.c                  13    Folder menu and file name expansion
  371. Xformat.awk                21    Nroff -man formatter in awk
  372. Xfullname.c                20    Extract full name from /etc/passwd
  373. Xglobal.c                   4    Global routines
  374. Xglobal.h                  19    Global include file
  375. Xgroup.c                   10    Group menu, group overview, and goto-group
  376. Xhelp                       1    Directory for online help files
  377. Xhelp/adm.upgrade1         22    Start-up message 1
  378. Xhelp/adm.upgrade2         22    Start-up message 2
  379. Xhelp/adm.upgrade3         22    Start-up message 3
  380. Xhelp/adm.upgrade4         22    Start-up message 4
  381. Xhelp/adm.welcome          22    New user welcome message
  382. Xhelp/help.attr            22    Help on attributes
  383. Xhelp/help.commands        20    Help on commands
  384. Xhelp/help.extended        21    Help on : commands
  385. Xhelp/help.help            22    Help on help
  386. Xhelp/help.map             21    Help on key mapping
  387. Xhelp/help.menu            21    ? in selection mode
  388. Xhelp/help.more            21    ? in reading mode
  389. Xhelp/help.read            12    Help on reading mode
  390. Xhelp/help.set             22    Help on :set commands
  391. Xhelp/help.show            22    Help on :show commands
  392. Xhelp/help.sort            21    Help on menu ordering
  393. Xhelp/help.variables        2    Help on variables
  394. Xhostname.c                20    Generic gethostname() function
  395. Xinews                      1    Directory for NNTP 1.5.7 mini-inews
  396. Xinews/Makefile            19    mini-inews makefile
  397. Xinews/Manifest            22    mini-inews manifest
  398. Xinews/README              21    mini-inews read me 2nd
  399. Xinews/README.NN           19    mini-inews read me 1st
  400. Xinews/clientlib.c         16    mini-inews source
  401. Xinews/clientlib.h         22    mini-inews source
  402. Xinews/conf.h              20    mini-inews configuration file
  403. Xinews/inews.c             12    mini-inews source
  404. Xinews/nntp.h              20    mini-inews source
  405. Xinews/version.c           22    mini-inews source
  406. Xinit.c                    11    Init file and extended command parsing
  407. Xinit.sample               20    Sample init file
  408. Xinst.sh                   18    Installation script
  409. Xkeymap.c                   6    Key mapping and command names
  410. Xkeymap.h                  19    Key and command names
  411. Xkill.c                    11    Kill compilation and processing
  412. Xmacro.c                   14    Macro compilation and execution
  413. Xman                        1    Directory for user manuals
  414. Xman/nn.1.A                 2    nn manual (for users) - part 1
  415. Xman/nn.1.B                 7    nn manual (for users) - part 2
  416. Xman/nn.1.C                 3    nn manual (for users) - part 3
  417. Xman/nn.1.D                 4    nn manual (for users) - part 4
  418. Xman/nnacct.1m              9    nnacct manual (for sysadm)
  419. Xman/nnadmin.1m             8    nnadmin manual (for sysadm)
  420. Xman/nncheck.1             20    nncheck manual (for users)
  421. Xman/nngoback.1            19    nngoback manual (for users)
  422. Xman/nngrab.1               5    nngrab manual (for users)
  423. Xman/nngrep.1              20    nngrep manual (for users)
  424. Xman/nnmaster.8            13    nnmaster manual (for sysadm)
  425. Xman/nnpost.1              21    nnpost manual (for users)
  426. Xman/nnspew.8              21    nnspew manual (for sysadm)
  427. Xman/nnstats.1m            21    nnstats manual (for sysadm)
  428. Xman/nntidy.1              21    nntidy manual (for users)
  429. Xman/nnusage.1m            21    nnusage manual (for sysadm)
  430. Xmaster.c                   7    Database manager (nnmaster)
  431. Xmatch.c                   20    String/regexp matching
  432. Xmenu.c                     6    Article selection menu
  433. Xmenu.h                    21    Return values from various modes
  434. Xmore.c                     9    Pager (reading mode)
  435. Xnews.c                    18    Parsing of news article headers
  436. Xnews.h                    21    Article header information
  437. Xnewsrc.c                   5    Access and update .newsrc
  438. Xnn.c                      14    nn main program
  439. Xnngrab.sh                 22    Quick subject search
  440. Xnnmail.c                  21    Primitive mailer w/domain addressing
  441. Xnnspew.sh                 22    Subject database generator (for nngrab)
  442. Xnnstats.sh                20    Collection and Expiration reports
  443. Xnntp.c                    10    NNTP interface library
  444. Xnntp.h                    20    NNTP response codes
  445. Xnnusage.sh                22    Usage statistics
  446. Xoptions.c                 19    Option parsing (much better than getopt!)
  447. Xoptions.h                 21    Header file for option parsing
  448. Xpack_date.c               19    Timestamp generation
  449. Xpack_name.c                3    Pack sender names
  450. Xpack_subject.c            21    Pack subject lines
  451. Xpatchlevel.h               8    Patch level and history
  452. Xprefix.c                  16    Generate prefix for scripts.
  453. Xproto.c                   19    Locking and message passing
  454. Xproto.h                   21    Include file for proto routines
  455. Xregexp.c                   8    Regular expression compile and exec
  456. Xregexp.h                   1    Include file for regexp usage
  457. Xreroute.c                 18    Mail address parsing and rewrite
  458. Xroutes.sample             21    Sample configuration file for nnmail
  459. Xsave.c                    15    Article saving, unpacking, etc.
  460. Xsequence.c                 5    Group presentation sequence parser
  461. Xsort.c                    11    Article menu ordering
  462. Xterm.c                     1    Terminal interface library
  463. Xterm.h                    21    Include file for terminal interface
  464. Xunshar.c                  18    Unshar pre-processor
  465. Xupgrade_rc.sh             22    .nn/rc to .newsrc converter
  466. Xusercheck.c               22    Check uid during installation
  467. Xvararg.h                  21    Faked and real varargs.h encapsulation
  468. Xvariable.c                12    Variable management
  469. Xxmakefile                 18    Skeleton for ymakefile
  470. END_OF_FILE
  471.   if test 10469 -ne `wc -c <'MANIFEST'`; then
  472.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  473.   fi
  474.   # end of 'MANIFEST'
  475. fi
  476. if test ! -d 'conf' ; then
  477.     echo shar: Creating directory \"'conf'\"
  478.     mkdir 'conf'
  479. fi
  480. if test ! -d 'contrib' ; then
  481.     echo shar: Creating directory \"'contrib'\"
  482.     mkdir 'contrib'
  483. fi
  484. if test ! -d 'doc' ; then
  485.     echo shar: Creating directory \"'doc'\"
  486.     mkdir 'doc'
  487. fi
  488. if test ! -d 'help' ; then
  489.     echo shar: Creating directory \"'help'\"
  490.     mkdir 'help'
  491. fi
  492. if test ! -d 'inews' ; then
  493.     echo shar: Creating directory \"'inews'\"
  494.     mkdir 'inews'
  495. fi
  496. if test ! -d 'man' ; then
  497.     echo shar: Creating directory \"'man'\"
  498.     mkdir 'man'
  499. fi
  500. if test -f 'regexp.h' -a "${1}" != "-c" ; then 
  501.   echo shar: Will not clobber existing file \"'regexp.h'\"
  502. else
  503.   echo shar: Extracting \"'regexp.h'\" \(731 characters\)
  504.   sed "s/^X//" >'regexp.h' <<'END_OF_FILE'
  505. X/*
  506. X * Definitions etc. for regexp(3) routines.
  507. X *
  508. X * Caveat:  this is V8 regexp(3) [actually, a reimplementation thereof],
  509. X * not the System V one.
  510. X */
  511. X
  512. X#define NSUBEXP  10
  513. Xtypedef struct regexp {
  514. X    char *startp[NSUBEXP];
  515. X    char *endp[NSUBEXP];
  516. X    char regstart;        /* Internal use only. */
  517. X    char reganch;        /* Internal use only. */
  518. X    char *regmust;        /* Internal use only. */
  519. X    int regmlen;        /* Internal use only. */
  520. X    char program[1];    /* Unwarranted chumminess with compiler. */
  521. X} regexp;
  522. X
  523. X
  524. X/*
  525. X * The first byte of the regexp internal "program" is actually this magic
  526. X * number; the start node begins in the second byte.
  527. X */
  528. X#define    MAGIC    0234
  529. X
  530. Xextern regexp *regcomp();
  531. Xextern int regexec();
  532. Xextern void regsub();
  533. Xextern void regerror();
  534. X
  535. END_OF_FILE
  536.   if test 731 -ne `wc -c <'regexp.h'`; then
  537.     echo shar: \"'regexp.h'\" unpacked with wrong size!
  538.   fi
  539.   # end of 'regexp.h'
  540. fi
  541. if test -f 'term.c' -a "${1}" != "-c" ; then 
  542.   echo shar: Will not clobber existing file \"'term.c'\"
  543. else
  544.   echo shar: Extracting \"'term.c'\" \(27619 characters\)
  545.   sed "s/^X//" >'term.c' <<'END_OF_FILE'
  546. X/*
  547. X *    (c) Copyright 1990, Kim Fabricius Storm.  All rights reserved.
  548. X *
  549. X *    Terminal interface.
  550. X */
  551. X
  552. X#include <signal.h>
  553. X#include <errno.h>
  554. X#include "config.h"
  555. X#include "term.h"
  556. X#include "keymap.h"
  557. X
  558. X#ifdef RESIZING
  559. X#include <sys/ioctl.h>            /* for TIOCGWINSZ */
  560. X#ifdef SYSV_RESIZING
  561. X#include <sys/stream.h>
  562. X#include <sys/ptem.h>
  563. X#endif
  564. X
  565. Xint s_resized;
  566. X#endif
  567. X
  568. Xexport char *term_name = NULL;
  569. Xexport int  show_current_time = 1;
  570. Xexport int  conf_dont_sleep = 0;
  571. Xexport int  prompt_length;
  572. Xexport int  terminal_speed;
  573. Xexport int  slow_speed = 1200;
  574. Xexport int  any_message = 0;
  575. Xexport int  flow_control = 1;
  576. Xexport int  use_visible_bell = 1; /* if supported by terminal */
  577. X
  578. Xexport key_type help_key = '?';
  579. Xexport key_type comp1_key = SP;
  580. Xexport key_type comp2_key = TAB;
  581. Xexport key_type erase_key, kill_key;
  582. Xexport key_type delword_key = CONTROL_('W');
  583. X
  584. Xstatic char bell_str[256] = "\007";
  585. X
  586. X#ifdef USE_TERMINFO
  587. X
  588. X#include <curses.h>
  589. X#ifndef auto_left_margin
  590. X#include <term.h>
  591. X#endif
  592. X
  593. X#define HAS_CAP(str) (str && *str)
  594. X
  595. Xextern char *tgoto();        /* some systems don't have this in term.h */
  596. X
  597. X#else
  598. X
  599. X#define USE_TERMCAP
  600. X
  601. Xchar *tgoto();
  602. Xchar PC;
  603. Xchar *BC, *UP;
  604. Xshort ospeed;
  605. X
  606. Xstatic char XBC[64], XUP[64];
  607. Xstatic char enter_ca_mode[64], exit_ca_mode[64];
  608. Xstatic char cursor_home[64];
  609. Xstatic char cursor_address[64];
  610. Xstatic char clear_screen[64];
  611. Xstatic char clr_eol[64];
  612. Xstatic char clr_eos[64];
  613. Xstatic char enter_standout_mode[64], exit_standout_mode[64];
  614. Xstatic char enter_underline_mode[64], exit_underline_mode[64];
  615. Xstatic char key_down[64], key_up[64], key_right[64], key_left[64];
  616. X
  617. Xint  magic_cookie_glitch;    /* magic cookie size */
  618. X
  619. X#define putp(str)    tputs(str, 0, outc)
  620. X
  621. X#define HAS_CAP(str)    (*str)
  622. X
  623. Xstatic outc(c)
  624. X{
  625. X    putchar(c);
  626. X}
  627. X
  628. X#endif    /* USE_TERMCAP */
  629. X
  630. Xint  Lines, Columns;    /* screen size */
  631. Xint  cookie_size;    /* size of magic cookie */
  632. Xint  two_cookies;    /* space needed to enter&exit standout mode */
  633. Xint  STANDOUT;        /* terminal got standout mode */
  634. Xint  WRAP;        /* terminal got automatic margins */
  635. X
  636. X#ifdef HAVE_TERMIO
  637. X
  638. X#define KEY_BURST 50    /* read bursts of 50 chars (or timeout after 100 ms) */
  639. X
  640. X#ifdef USE_TERMCAP
  641. X#include <termio.h>
  642. X#endif
  643. X
  644. X#undef CBREAK
  645. X
  646. Xstatic struct termio norm_tty, raw_tty;
  647. X
  648. X#define    IntrC    norm_tty.c_cc[VINTR]
  649. X#define    EraseC    norm_tty.c_cc[VERASE]
  650. X#define KillC    norm_tty.c_cc[VKILL]
  651. X#define SuspC    CONTROL_('Z')    /* norm_tty.c_cc[SWTCH] */
  652. X
  653. X#else    /* V7/BSD TTY DRIVER */
  654. X
  655. X#include <sgtty.h>
  656. X
  657. Xstatic struct sgttyb norm_tty, raw_tty;
  658. Xstatic struct tchars norm_chars;
  659. X
  660. X#define    IntrC    norm_chars.t_intrc
  661. X#define    EraseC    norm_tty.sg_erase
  662. X#define KillC    norm_tty.sg_kill
  663. X
  664. X#ifdef TIOCGLTC
  665. Xstatic struct     ltchars spec_chars;
  666. X#define SuspC    spec_chars.t_suspc
  667. X#else
  668. X#define    SuspC    CONTROL_('Z')
  669. X#endif
  670. X
  671. X#endif
  672. X
  673. X#ifdef USE_TERMCAP
  674. X
  675. Xopt_cap(cap, buf)
  676. Xchar *cap, *buf;
  677. X{
  678. X    char *tgetstr();
  679. X
  680. X    *buf = NUL;
  681. X    return tgetstr(cap, &buf) != NULL;
  682. X}
  683. X
  684. Xget_cap(cap, buf)
  685. Xchar *cap, *buf;
  686. X{
  687. X    if (!opt_cap(cap, buf))
  688. X    user_error("TERMCAP entry for %s has no '%s' capability",
  689. X           term_name, cap);
  690. X}
  691. X
  692. X#endif  /* USE_TERMCAP */
  693. X
  694. Xstatic int multi_keys = 0;
  695. X
  696. Xstatic struct multi_key {
  697. X    key_type *cur_key;
  698. X    key_type *keys;
  699. X    key_type code;
  700. X} multi_key_list[MULTI_KEYS];
  701. X
  702. Xenter_multi_key(code, keys)
  703. Xint code;
  704. Xkey_type *keys;
  705. X{
  706. X    register i;
  707. X
  708. X    if (strlen((char *)keys) == 1)
  709. X    /* will ignore arrow keys overlaying these keys */
  710. X    if (*keys == NL || *keys == CR ||
  711. X        *keys == erase_key || *keys == kill_key ||
  712. X        *keys == IntrC) return;
  713. X
  714. X    /* lookup code to see if it is already defined... */
  715. X    for (i = 0; i < multi_keys; i++)
  716. X    if (multi_key_list[i].code == (key_type)code)
  717. X        goto replace_key;
  718. X
  719. X    i = multi_keys++;
  720. X
  721. X    /* now i points to matching or empty slot */
  722. X    if (i >= MULTI_KEYS) {
  723. X    /* should never happen */
  724. X    log_entry('E', "too many multi keys");
  725. X    return;
  726. X    }
  727. X
  728. X replace_key:
  729. X
  730. X    multi_key_list[i].keys = keys;
  731. X    multi_key_list[i].code = code;
  732. X}
  733. X
  734. Xdump_multi_keys()
  735. X{
  736. X    register i;
  737. X    register key_type *cp;
  738. X
  739. X    clrdisp();
  740. X    pg_init(0, 1);
  741. X
  742. X    for (i = 0; i < multi_keys; i++) {
  743. X    if (pg_next() < 0) break;
  744. X    printf("%d\t%s\t", i, key_name(multi_key_list[i].code));
  745. X    for (cp = multi_key_list[i].keys; *cp; cp++) {
  746. X        putchar(SP);
  747. X        fputs(key_name(*cp), stdout);
  748. X    }
  749. X    }
  750. X
  751. X    pg_end();
  752. X}
  753. X
  754. X
  755. X#ifdef RESIZING
  756. X
  757. Xsig_type catch_winch()
  758. X{
  759. X    struct winsize winsize;
  760. X
  761. X    (void) signal(SIGWINCH, catch_winch);
  762. X    if (ioctl(0, TIOCGWINSZ, &winsize) >= 0
  763. X    && (winsize.ws_row != Lines || winsize.ws_col != Columns)) {
  764. X    Lines = winsize.ws_row;
  765. X    Columns = winsize.ws_col;
  766. X    s_redraw = 1;
  767. X    s_resized = 1;
  768. X    }
  769. X}
  770. X#endif /* RESIZING */
  771. X
  772. X#ifdef SV_INTERRUPT
  773. X#ifdef NO_SIGINTERRUPT
  774. Xstatic siginterrupt(signo, on)
  775. X{
  776. X  struct sigvec sv;
  777. X  sv.sv_handler = signal (signo, SIG_DFL);
  778. X  sv.sv_mask = 0;
  779. X  sv.sv_flags = on ? SV_INTERRUPT : 0;
  780. X  sigvec (signo, &sv, 0);
  781. X}
  782. X#endif
  783. X#endif
  784. X
  785. Xstatic unsigned sp_table[] = {
  786. X    B9600, 960,
  787. X#ifdef B19200
  788. X    B19200, 1920,
  789. X#else
  790. X#ifdef EXTA
  791. X    EXTA, 1920,
  792. X#endif
  793. X#endif
  794. X#ifdef B38400
  795. X    B38400, 3840,
  796. X#else
  797. X#ifdef EXTB
  798. X    EXTB, 3840,
  799. X#endif
  800. X#endif
  801. X    B1200, 120,
  802. X    B2400, 240,
  803. X    B4800, 480,
  804. X    B300,   30,
  805. X    0,    0
  806. X};
  807. X
  808. Xstatic set_term_speed(sp)
  809. Xregister unsigned long sp;
  810. X{
  811. X    register unsigned *tp;
  812. X
  813. X    for (tp = sp_table; *tp; tp += 2)
  814. X    if (*tp == sp) {
  815. X        terminal_speed = tp[1];
  816. X        return;
  817. X    }
  818. X
  819. X    terminal_speed = 30;
  820. X}
  821. X
  822. Xinit_term()
  823. X{
  824. X#ifdef USE_TERMCAP
  825. X    char tbuf[1024];
  826. X#endif
  827. X
  828. X    if ((term_name = getenv("TERM")) == NULL)
  829. X    user_error("No TERM variable in enviroment");
  830. X
  831. X#ifdef HAVE_TERMIO
  832. X    ioctl(0, TCGETA, &norm_tty);
  833. X#else
  834. X    ioctl(0, TIOCGETP, &norm_tty);
  835. X#endif
  836. X
  837. X#ifdef USE_TERMINFO
  838. X    setupterm((char *)NULL, 1, (int *)NULL);
  839. X    Columns = columns;
  840. X    Lines = lines;
  841. X    cookie_size = magic_cookie_glitch;
  842. X    WRAP = auto_right_margin;
  843. X    if (use_visible_bell && HAS_CAP(flash_screen))
  844. X    strcpy(bell_str, flash_screen);
  845. X    else if (HAS_CAP(bell))
  846. X    strcpy(bell_str, bell);
  847. X    if (! HAS_CAP(cursor_home))
  848. X    cursor_home = copy_str(tgoto(cursor_address, 0, 0));
  849. X#else
  850. X
  851. X    if (tgetent(tbuf, term_name) <= 0)
  852. X    user_error("Unknown terminal type: %s", term_name);
  853. X
  854. X    if (opt_cap("bc", XBC)) BC = XBC;
  855. X    if (opt_cap("up", XUP)) UP = XUP;
  856. X    opt_cap("pc", cursor_address);    /* temp. usage */
  857. X    PC = cursor_address[0];
  858. X
  859. X    get_cap("cm", cursor_address);
  860. X    if (!opt_cap("ho", cursor_home))
  861. X    strcpy(cursor_home, tgoto(cursor_address, 0, 0));
  862. X
  863. X    get_cap("cl", clear_screen);
  864. X    get_cap("ce", clr_eol);
  865. X    opt_cap("cd", clr_eos);
  866. X
  867. X#ifdef RESIZING
  868. X    {
  869. X    struct winsize winsize;
  870. X
  871. X    if (ioctl(0, TIOCGWINSZ, &winsize) >= 0
  872. X        && winsize.ws_row != 0 && winsize.ws_col != 0) {
  873. X        Lines = winsize.ws_row;
  874. X        Columns = winsize.ws_col;
  875. X        (void) signal(SIGWINCH, catch_winch);
  876. X#ifdef SV_INTERRUPT
  877. X        siginterrupt(SIGWINCH, 1);    /* make read from tty interruptable */
  878. X#endif /* SV_INTERRUPT */
  879. X    }
  880. X    }
  881. X    if (Lines == 0 || Columns == 0) {
  882. X#endif /* RESIZING */
  883. X    Lines = tgetnum("li");
  884. X    Columns = tgetnum("co");
  885. X#ifdef RESIZING
  886. X    }
  887. X#endif /* RESIZING */
  888. X
  889. X    opt_cap("so", enter_standout_mode);
  890. X    opt_cap("se", exit_standout_mode);
  891. X
  892. X    opt_cap("us", enter_underline_mode);
  893. X    opt_cap("ue", exit_underline_mode);
  894. X
  895. X    opt_cap("kd", key_down);
  896. X    opt_cap("ku", key_up);
  897. X    opt_cap("kr", key_right);
  898. X    opt_cap("kl", key_left);
  899. X
  900. X    cookie_size = tgetnum("sg");
  901. X
  902. X    WRAP = tgetflag("am");
  903. X
  904. X    opt_cap("ti", enter_ca_mode);
  905. X    opt_cap("te", exit_ca_mode);
  906. X
  907. X    if (!use_visible_bell || !opt_cap("vb", bell_str))
  908. X    if (!opt_cap("bl", bell_str))
  909. X        strcpy(bell_str, "\007");
  910. X
  911. X#endif /* !USE_TERMINFO */
  912. X
  913. X    STANDOUT = HAS_CAP(enter_standout_mode);
  914. X    if (STANDOUT) {
  915. X    if (cookie_size < 0) cookie_size = 0;
  916. X    two_cookies = 2 * cookie_size;
  917. X    } else
  918. X    cookie_size = two_cookies = 0;
  919. X
  920. X
  921. X    raw_tty = norm_tty;
  922. X
  923. X#ifdef HAVE_TERMIO
  924. X    raw_tty.c_iflag &= ~(BRKINT|INLCR|ICRNL|IGNCR);
  925. X    raw_tty.c_iflag |= IGNBRK|IGNPAR|ISTRIP;
  926. X    raw_tty.c_oflag &= ~OPOST;
  927. X    raw_tty.c_lflag &= ~(ISIG|ICANON|XCASE|ECHO|NOFLSH);
  928. X
  929. X    /* read a maximum of 10 characters in one burst; timeout in 1-200 ms */
  930. X    raw_tty.c_cc[VEOF] = KEY_BURST;
  931. X    raw_tty.c_cc[VEOL] = ((raw_tty.c_cflag & CBAUD) > B1200) ? 1 : 2;
  932. X    set_term_speed((unsigned long)(raw_tty.c_cflag & CBAUD));
  933. X#else
  934. X    ioctl(0, TIOCGETC, &norm_chars);
  935. X
  936. X#ifdef TIOCGLTC
  937. X    ioctl(0, TIOCGLTC, &spec_chars);
  938. X#endif
  939. X
  940. X    ospeed = norm_tty.sg_ospeed;
  941. X    set_term_speed((unsigned long)ospeed);
  942. X
  943. X    raw_tty.sg_flags &= ~ECHO;
  944. X#ifdef CBREAK
  945. X#ifdef SV_INTERRUPT            /* make read from tty interruptable */
  946. X    siginterrupt(SIGTSTP, 1);        /* this is necessary to redraw screen */
  947. X#endif
  948. X    raw_tty.sg_flags |= CBREAK;
  949. X#else
  950. X    raw_tty.sg_flags |= RAW;
  951. X#endif
  952. X
  953. X#ifdef SV_INTERRUPT
  954. X    siginterrupt(SIGALRM, 1);        /* make read from tty interruptable */
  955. X#endif
  956. X#endif
  957. X
  958. X    erase_key = (key_type)EraseC;
  959. X    kill_key  = (key_type)KillC;
  960. X
  961. X    if (HAS_CAP(key_down))
  962. X    enter_multi_key(K_down_arrow, (key_type *)key_down);
  963. X    if (HAS_CAP(key_up))
  964. X    enter_multi_key(K_up_arrow, (key_type *)key_up);
  965. X    if (HAS_CAP(key_right))
  966. X    enter_multi_key(K_right_arrow, (key_type *)key_right);
  967. X    if (HAS_CAP(key_left))
  968. X    enter_multi_key(K_left_arrow, (key_type *)key_left);
  969. X
  970. X    visual_on();
  971. X}
  972. X
  973. Xhome()
  974. X{
  975. X    putp(cursor_home);
  976. X}
  977. X
  978. Xstatic int curxy_c = -1, curxy_l, savxy_c = -1, savxy_l;
  979. X
  980. Xsave_xy()
  981. X{
  982. X    savxy_c = curxy_c; savxy_l = curxy_l;
  983. X}
  984. X
  985. Xrestore_xy()
  986. X{
  987. X    if (savxy_c < 0) return;
  988. X    gotoxy(savxy_c, savxy_l); fl;
  989. X}
  990. X
  991. Xgotoxy(c, l)
  992. Xint c, l;
  993. X{
  994. X    curxy_c = c; curxy_l = l;
  995. X    putp(tgoto(cursor_address, c, l));
  996. X}
  997. X
  998. Xclrdisp()
  999. X{
  1000. X#ifdef USE_TERMINFO
  1001. X    putp(clear_screen);        /* tputs is broken on UNISYS I've been told */
  1002. X#else
  1003. X    tputs(clear_screen, Lines, outc);
  1004. X#endif
  1005. X    curxy_c = savxy_c = -1;
  1006. X}
  1007. X
  1008. Xclrline()
  1009. X{
  1010. X    putp(clr_eol);
  1011. X    fl;
  1012. X}
  1013. X
  1014. Xclrpage(lineno)
  1015. Xregister int lineno;
  1016. X{
  1017. X    register int olineno= lineno;
  1018. X
  1019. X    if (HAS_CAP(clr_eos)) {
  1020. X#ifdef USE_TERMINFO
  1021. X    putp(clr_eos);
  1022. X#else
  1023. X    tputs(clr_eos, Lines - lineno, outc);
  1024. X#endif
  1025. X    } else {
  1026. X    clrline();
  1027. X    lineno++;
  1028. X    for (; lineno < Lines; lineno++) {
  1029. X        gotoxy(0, lineno);
  1030. X        putp(clr_eol);
  1031. X    }
  1032. X    gotoxy(0, olineno);
  1033. X    fl;
  1034. X    }
  1035. X}
  1036. X
  1037. Xstatic char so_buf[512], *so_p;
  1038. Xstatic int so_c, so_l, so_b, so_active = 0;
  1039. X
  1040. Xso_gotoxy(c, l, blank)
  1041. X{
  1042. X    if (!STANDOUT && c >= 0) {
  1043. X    if (l >= 0) gotoxy(c, l);
  1044. X    return 0;
  1045. X    }
  1046. X
  1047. X    so_active++;
  1048. X    so_c = c;
  1049. X    so_l = l;
  1050. X    so_b = blank;
  1051. X    so_p = so_buf;
  1052. X    *so_p = NUL;
  1053. X
  1054. X    return 1;    /* not really true if not standout & c < 0 */
  1055. X}
  1056. X
  1057. X/*VARARGS*/
  1058. Xso_printf(va_alist)
  1059. Xva_dcl
  1060. X{
  1061. X    use_vararg;
  1062. X
  1063. X    start_vararg;
  1064. X    so_vprintf(va_args1toN);
  1065. X    end_vararg;
  1066. X}
  1067. X
  1068. Xso_vprintf(va_tail)
  1069. Xva_tdcl
  1070. X{
  1071. X    char *fmt;
  1072. X
  1073. X    fmt = va_arg1(char *);
  1074. X
  1075. X    if (!so_active) {
  1076. X    vprintf(fmt, va_args2toN);
  1077. X    return;
  1078. X    }
  1079. X
  1080. X    vsprintf(so_p, fmt, va_args2toN);
  1081. X    while (*so_p) so_p++;
  1082. X}
  1083. X
  1084. Xso_end()
  1085. X{
  1086. X    int len;
  1087. X
  1088. X    if (!so_active) return;
  1089. X
  1090. X    if (so_l >= 0) {
  1091. X
  1092. X    len = so_p - so_buf + two_cookies;
  1093. X
  1094. X    if (so_c < 0)
  1095. X        so_c = Columns - len - 2;
  1096. X    if (so_c < 0) so_c = 0;
  1097. X
  1098. X    if (len + so_c >= Columns) {
  1099. X        len = Columns - so_c - two_cookies;
  1100. X        so_buf[len] = NUL;
  1101. X    }
  1102. X
  1103. X    if (cookie_size) {
  1104. X        gotoxy(so_c + len - cookie_size, so_l);
  1105. X        putp(exit_standout_mode);
  1106. X    }
  1107. X
  1108. X    gotoxy(so_c, so_l);
  1109. X
  1110. X    }
  1111. X
  1112. X    if ((so_b & 1) && (!STANDOUT || !cookie_size)) putchar(SP);
  1113. X
  1114. X    if (STANDOUT) putp(enter_standout_mode);
  1115. X
  1116. X    fputs(so_buf, stdout);
  1117. X
  1118. X    if (STANDOUT) putp(exit_standout_mode);
  1119. X
  1120. X    if ((so_b & 2) && (!STANDOUT || !cookie_size)) putchar(SP);
  1121. X
  1122. X    so_active = 0;
  1123. X}
  1124. X
  1125. X
  1126. X/*VARARGS*/
  1127. Xso_printxy(va_alist)
  1128. Xva_dcl
  1129. X{
  1130. X    int k, l;
  1131. X    use_vararg;
  1132. X
  1133. X    start_vararg;
  1134. X
  1135. X    k = va_arg1(int);
  1136. X    l = va_arg2(int);
  1137. X
  1138. X    so_gotoxy(k, l, 0);
  1139. X    so_vprintf(va_args3toN);
  1140. X    so_end();
  1141. X
  1142. X    end_vararg;
  1143. X}
  1144. X
  1145. Xunderline(on)
  1146. X{
  1147. X    if (cookie_size) return 0;
  1148. X    if (! HAS_CAP(enter_underline_mode)) return 0;
  1149. X    putp(on ? enter_underline_mode : exit_underline_mode);
  1150. X    return 1;
  1151. X}
  1152. X
  1153. Xhighlight(on)
  1154. X{
  1155. X    if (cookie_size) return 0;
  1156. X    if (! HAS_CAP(enter_standout_mode)) return 0;
  1157. X    putp(on ? enter_standout_mode : exit_standout_mode);
  1158. X    return 1;
  1159. X}
  1160. X
  1161. Xstatic int is_visual = 0;
  1162. Xstatic int is_raw = 0;
  1163. X
  1164. X#ifdef HAVE_TERMIO
  1165. X#define RAW_MODE_ON    ioctl(0, TCSETAF, &raw_tty)
  1166. X#define RAW_MODE_OFF   ioctl(0, TCSETAF, &norm_tty)
  1167. X#else
  1168. X#define RAW_MODE_ON    ioctl(0, TIOCSETP, &raw_tty)
  1169. X#define RAW_MODE_OFF   ioctl(0, TIOCSETP, &norm_tty)
  1170. X#endif
  1171. X
  1172. Xvisual_on()
  1173. X{
  1174. X    if (HAS_CAP(enter_ca_mode)) {
  1175. X    putp(enter_ca_mode);
  1176. X    is_visual = 1;
  1177. X    }
  1178. X}
  1179. X
  1180. Xvisual_off()
  1181. X{
  1182. X    int was_raw = is_raw;
  1183. X
  1184. X    if (term_name == NULL) return 0;
  1185. X
  1186. X    if (is_visual && HAS_CAP(exit_ca_mode)) putp(exit_ca_mode), fl;
  1187. X    is_visual = 0;
  1188. X
  1189. X    is_raw = 1;
  1190. X    unset_raw();
  1191. X
  1192. X    return was_raw;
  1193. X}
  1194. X
  1195. X#ifdef CBREAK
  1196. Xraw()
  1197. X{
  1198. X    if (is_raw == 1)
  1199. X    return;
  1200. X    is_raw = 1;
  1201. X    RAW_MODE_ON;
  1202. X}
  1203. X
  1204. Xno_raw()
  1205. X{
  1206. X    return 0;
  1207. X}
  1208. X
  1209. Xunset_raw()
  1210. X{
  1211. X    if (is_raw == 0)
  1212. X    return 0;
  1213. X    RAW_MODE_OFF;
  1214. X    is_raw = 0;
  1215. X    return 1;
  1216. X}
  1217. X
  1218. X#else /* not CBREAK */
  1219. Xstatic int must_set_raw = 1;
  1220. X
  1221. Xraw()
  1222. X{
  1223. X    if (!flow_control) {
  1224. X    if (!must_set_raw) return;
  1225. X    must_set_raw = 0;
  1226. X    }
  1227. X
  1228. X    if (is_raw) return;
  1229. X
  1230. X    RAW_MODE_ON;
  1231. X
  1232. X    is_raw++;
  1233. X}
  1234. X
  1235. Xno_raw()
  1236. X{
  1237. X    if (!flow_control) return 0;
  1238. X
  1239. X    if (!is_raw) return 0;
  1240. X
  1241. X    RAW_MODE_OFF;
  1242. X
  1243. X    is_raw = 0;
  1244. X
  1245. X    return 1;
  1246. X}
  1247. X
  1248. Xunset_raw()
  1249. X{
  1250. X    int was_raw = is_raw;
  1251. X
  1252. X    if (is_raw) {
  1253. X    RAW_MODE_OFF;
  1254. X    is_raw = 0;
  1255. X    }
  1256. X
  1257. X    if (!flow_control)
  1258. X    must_set_raw = 1;
  1259. X    return was_raw;
  1260. X}
  1261. X
  1262. X#endif /* CBREAK */
  1263. X
  1264. Xstatic int do_flush_input = 0;
  1265. X
  1266. Xflush_input()
  1267. X{
  1268. X#ifdef HAVE_TERMIO
  1269. X    ioctl(0, TCFLSH, 0);
  1270. X    do_flush_input = 1;
  1271. X#else
  1272. X#ifdef FREAD
  1273. X    int arg = FREAD;
  1274. X    ioctl(0, TIOCFLUSH, &arg);
  1275. X#else
  1276. X    ioctl(0, TIOCFLUSH, 0);
  1277. X#endif
  1278. X#endif
  1279. X}
  1280. X
  1281. Xint enable_stop = 1;
  1282. X
  1283. X#ifndef KEY_BURST
  1284. X
  1285. Xstatic int alarm_on = 0;
  1286. X
  1287. Xstatic mk_timeout()
  1288. X{
  1289. X    alarm_on = 0;
  1290. X}
  1291. X
  1292. X#endif
  1293. X
  1294. Xstatic int do_macro_processing = 1;
  1295. X
  1296. Xget_c()
  1297. X{
  1298. X    key_type c;
  1299. X    int any_multi, key_cnt, mc;
  1300. X    register struct multi_key *mk;
  1301. X    register int i;
  1302. X#ifdef KEY_BURST
  1303. X    static char cbuf[KEY_BURST], *cp;
  1304. X    static int n = 0;
  1305. X
  1306. X    if (do_flush_input) {
  1307. X    do_flush_input = 0;
  1308. X    n = 0;
  1309. X    }
  1310. X#else
  1311. X    int n;
  1312. X    key_type first_key;
  1313. X#endif
  1314. X
  1315. X next_key:
  1316. X    if (s_hangup)
  1317. X    return K_interrupt;
  1318. X
  1319. X#ifdef RESIZING
  1320. X    if (s_resized) {
  1321. X    s_resized = 0;
  1322. X    return GETC_COMMAND | K_REDRAW;
  1323. X    }
  1324. X#endif
  1325. X
  1326. X    if (do_macro_processing)
  1327. X    switch (m_getc(&mc)) {
  1328. X     case 0:
  1329. X        break;
  1330. X     case 1:
  1331. X        return mc;
  1332. X     case 2:
  1333. X        return K_interrupt;
  1334. X    }
  1335. X
  1336. X    for (i = multi_keys, mk = multi_key_list; --i >= 0; mk++)
  1337. X    mk->cur_key = mk->keys;
  1338. X    key_cnt = 0;
  1339. X
  1340. X#ifdef KEY_BURST
  1341. X    if (n <= 0) {
  1342. X    n = read(0, cbuf, KEY_BURST);
  1343. X    if (n < 0 && errno != EINTR) s_hangup++;
  1344. X    if (n <= 0) return K_interrupt;
  1345. X    cp = cbuf;
  1346. X    }
  1347. X
  1348. X    while (--n >= 0) {
  1349. X    c = (key_type)*cp++;
  1350. X#else
  1351. X
  1352. X    while ((n = read(0, (char *)&c, 1)) > 0) {
  1353. X    c &= 0177;    /* done by ISTRIP on USG systems */
  1354. X#endif
  1355. X
  1356. X    if (c == CONTROL_('Q') || c == CONTROL_('S'))
  1357. X        continue;
  1358. X
  1359. X    any_multi = 0;
  1360. X    for (i = multi_keys, mk = multi_key_list; --i >= 0; mk++)
  1361. X        if (mk->cur_key) {
  1362. X        if (*(mk->cur_key)++ == c) {
  1363. X            if (*(mk->cur_key) == NUL) {
  1364. X            c = mk->code;
  1365. X            goto got_char;
  1366. X            }
  1367. X            any_multi++;
  1368. X        } else
  1369. X            mk->cur_key = NUL;
  1370. X        }
  1371. X
  1372. X    if (any_multi) {
  1373. X#ifndef KEY_BURST
  1374. X        if (key_cnt == 0) {
  1375. X        first_key = c;
  1376. X        alarm_on = 1;
  1377. X        signal(SIGALRM, mk_timeout);
  1378. X        MICRO_ALARM();
  1379. X        }
  1380. X#endif
  1381. X        key_cnt++;
  1382. X        continue;
  1383. X    }
  1384. X    if (key_cnt == 0)
  1385. X        goto got_char;
  1386. X
  1387. X    ding();
  1388. X    flush_input();
  1389. X    goto next_key;
  1390. X    }
  1391. X
  1392. X#ifdef CBREAK
  1393. X    if (s_redraw) {
  1394. X    s_redraw = 0;
  1395. X    return GETC_COMMAND | K_REDRAW;
  1396. X    }
  1397. X#endif
  1398. X
  1399. X#ifndef KEY_BURST
  1400. X    if (n < 0) {
  1401. X    if (errno != EINTR) s_hangup++;
  1402. X    return K_interrupt;
  1403. X    }
  1404. X#endif
  1405. X
  1406. X#ifdef RESIZING
  1407. X    if (s_resized) {
  1408. X    s_resized = 0;
  1409. X    return GETC_COMMAND | K_REDRAW;
  1410. X    }
  1411. X#endif
  1412. X
  1413. X#ifndef KEY_BURST
  1414. X    if (n < 0 && key_cnt)
  1415. X    c = first_key;
  1416. X#endif
  1417. X
  1418. Xgot_char:
  1419. X
  1420. X#ifndef KEY_BURST
  1421. X    if (alarm_on) {
  1422. X    alarm(0);
  1423. X    alarm_on = 0;
  1424. X    }
  1425. X#endif
  1426. X
  1427. X    c = global_key_map[c];
  1428. X
  1429. X#ifndef CBREAK
  1430. X    if (c == SuspC) {
  1431. X    if (!enable_stop) goto next_key;
  1432. X    if (suspend_nn())
  1433. X        return GETC_COMMAND | K_REDRAW;
  1434. X    else
  1435. X        goto next_key;
  1436. X    }
  1437. X
  1438. X    if (c == IntrC) c = K_interrupt;
  1439. X#endif
  1440. X    return (int)c;
  1441. X}
  1442. X
  1443. X
  1444. X/*
  1445. X * read string with completion, pre-filling, and break on first char
  1446. X *
  1447. X *    dflt        is a string that will be use as default value if the
  1448. X *            space bar is hit as the first character.
  1449. X *
  1450. X *    prefill        pre-fill the buffer with .... and print it
  1451. X *
  1452. X *    break_chars    return immediately if one of these characters
  1453. X *            is entered as the first character.
  1454. X *
  1455. X *    completion     is a function that will fill the buffer with a value
  1456. X *            see the group_completion and file_completion routines
  1457. X *            for examples.
  1458. X */
  1459. X
  1460. Xchar *get_s(dflt, prefill, break_chars, completion)
  1461. Xchar *dflt, *prefill, *break_chars;
  1462. Xfct_type completion;
  1463. X{
  1464. X    static char buf[GET_S_BUFFER];
  1465. X    register char *cp;
  1466. X    register int i, c, lastc;
  1467. X    char *ret_val = buf;
  1468. X    int comp_used, comp_len;
  1469. X    int ostop, max, did_help;
  1470. X    int hit_count;
  1471. X
  1472. X    switch (m_gets(buf)) {
  1473. X     case 0:
  1474. X    break;
  1475. X     case 1:
  1476. X    return buf;
  1477. X     case 2:
  1478. X    return NULL;
  1479. X    }
  1480. X
  1481. X    ostop = enable_stop;
  1482. X    enable_stop = 0;
  1483. X    do_macro_processing = 0;
  1484. X    hit_count = 0;
  1485. X
  1486. X    max = Columns - prompt_length;
  1487. X
  1488. X    if (max >= FILENAME) max = FILENAME-1;
  1489. X
  1490. X    i = comp_len = comp_used = did_help = 0;
  1491. X
  1492. X    if (prefill && prefill[0]) {
  1493. X    while (c = *prefill++) {
  1494. X        if (i == max) break;
  1495. X
  1496. X        putchar(c);
  1497. X        buf[i] = c;
  1498. X        i++;
  1499. X    }
  1500. X    fl;
  1501. X    }
  1502. X
  1503. X    if (dflt && *dflt == NUL)
  1504. X    dflt = NULL;
  1505. X
  1506. X    if (break_chars && *break_chars == NUL)
  1507. X    break_chars = NULL;
  1508. X
  1509. X    c = NUL;
  1510. X    for(;;) {
  1511. X    lastc = c;
  1512. X    c = get_c();
  1513. X    if (c & GETC_COMMAND) continue;
  1514. X
  1515. X     kill_prefill_hack:
  1516. X
  1517. X    hit_count++;
  1518. X
  1519. X    if (i == 0) {
  1520. X        if (c == comp1_key && dflt) {
  1521. X        while ((c = *dflt++) != NUL && i < max) {
  1522. X            putchar(c);
  1523. X            buf[i] = c;
  1524. X            i++;
  1525. X        }
  1526. X        fl;
  1527. X        dflt = NULL;
  1528. X        continue;
  1529. X        }
  1530. X        if (cp = break_chars) {
  1531. X        while (*cp)
  1532. X            if (*cp++ == c) {
  1533. X            buf[0] = c;
  1534. X            buf[1] = NUL;
  1535. X            goto out;
  1536. X            }
  1537. X        }
  1538. X    }
  1539. X
  1540. X    if (completion != NULL_FCT) {
  1541. X        if (comp_used && c == erase_key) {
  1542. X        CALL(completion)(buf, -1);
  1543. X        if (did_help) { clrmsg(i); did_help = 0; }
  1544. X        if (comp_len) {
  1545. X            i -= comp_len;
  1546. X            while (--comp_len >= 0) putchar(BS);
  1547. X            clrline();
  1548. X        }
  1549. X        comp_len = comp_used = 0;
  1550. X        if (lastc == help_key) goto no_completion;
  1551. X        continue;
  1552. X        }
  1553. X
  1554. X        if (c == comp1_key || c == comp2_key || c == help_key) {
  1555. X        if (!comp_used || c == comp2_key ||
  1556. X            (c == help_key && lastc != c)) {
  1557. X            buf[i] = NUL;
  1558. X            if ((comp_used = CALL(completion)(buf, i)) == 0) {
  1559. X            ding();
  1560. X            continue;
  1561. X            }
  1562. X            if (comp_used < 0) {
  1563. X            comp_used = 0;
  1564. X            goto no_completion;
  1565. X            }
  1566. X            comp_len = 0;
  1567. X        }
  1568. X        if (c == help_key) {
  1569. X            if (CALL(completion)((char *)NULL, 1)) {
  1570. X            gotoxy(prompt_length+i, prompt_line); fl;
  1571. X            did_help = 1;
  1572. X            }
  1573. X            continue;
  1574. X        }
  1575. X
  1576. X        if (comp_len) {
  1577. X            i -= comp_len;
  1578. X            while (--comp_len >= 0) putchar(BS);
  1579. X            clrline();
  1580. X            comp_len = 0;
  1581. X        }
  1582. X
  1583. X        switch ( CALL(completion)((char *)NULL, 0) ) {
  1584. X
  1585. X         case 0:    /* no possible completion */
  1586. X            comp_used = 0;
  1587. X            ding();
  1588. X            continue;
  1589. X
  1590. X         case 2:    /* whole new alternative */
  1591. X            while (--i >= 0) putchar(BS);
  1592. X            clrline();
  1593. X            /* fall thru */
  1594. X
  1595. X         case 1:    /* completion */
  1596. X            comp_len = i;
  1597. X            while (c = buf[i]) {
  1598. X            if (i == max) break;
  1599. X            putchar(c);
  1600. X            i++;
  1601. X            }
  1602. X            fl;
  1603. X            comp_len = i - comp_len;
  1604. X            continue;
  1605. X        }
  1606. X        }
  1607. X
  1608. X        if (comp_used) {
  1609. X        CALL(completion)(buf, -1);
  1610. X        if (did_help) clrmsg(i);
  1611. X        comp_len = comp_used = 0;
  1612. X        }
  1613. X    }
  1614. X
  1615. X     no_completion:
  1616. X
  1617. X    if (c == CR || c == NL) {
  1618. X        buf[i] = NUL;
  1619. X        break;
  1620. X    }
  1621. X
  1622. X    if (c == erase_key) {
  1623. X        if (i <= 0) continue;
  1624. X        i--;
  1625. X        putchar(BS);
  1626. X        putchar(' ');
  1627. X        putchar(BS);
  1628. X        fl;
  1629. X        continue;
  1630. X    }
  1631. X
  1632. X    if (c == delword_key) {
  1633. X        if (i <= 0) continue;
  1634. X        buf[i-1] = 'X';
  1635. X        while (i > 0 && isalnum(buf[i-1])) { putchar(BS); i--; }
  1636. X        clrline();
  1637. X        continue;
  1638. X    }
  1639. X
  1640. X    if (c == kill_key) {
  1641. X        while (i > 0) { putchar(BS); i--; }
  1642. X        clrline();
  1643. X        if (hit_count == 1 && dflt) {
  1644. X        c = comp1_key;
  1645. X        goto kill_prefill_hack;
  1646. X        }
  1647. X        continue;
  1648. X    }
  1649. X
  1650. X    if (c == K_interrupt) {
  1651. X        ret_val = NULL;
  1652. X        break;
  1653. X    }
  1654. X
  1655. X    if (!isascii(c) || !isprint(c)) continue;
  1656. X
  1657. X    if (i == max) continue;
  1658. X
  1659. X    if (i > 0 && buf[i-1] == '/' && (c == '/' || c == '+')) {
  1660. X        while (i > 0) { putchar(BS); i--; }
  1661. X        clrline();
  1662. X    }
  1663. X
  1664. X    putchar(c);
  1665. X    fl;
  1666. X
  1667. X    buf[i] = c;
  1668. X    i++;
  1669. X    }
  1670. X out:
  1671. X    enable_stop = ostop;
  1672. X    do_macro_processing = 1;
  1673. X    return ret_val;
  1674. X}
  1675. X
  1676. Xexport int list_offset = 0;
  1677. X
  1678. Xlist_completion(str)
  1679. Xchar *str;
  1680. X{
  1681. X    static int cols, line;
  1682. X
  1683. X    if (str == NULL) {
  1684. X    cols = Columns;
  1685. X    line = prompt_line + 1;
  1686. X
  1687. X    gotoxy(0, line);
  1688. X    clrpage(line);
  1689. X    return 1;
  1690. X    }
  1691. X
  1692. X    str += list_offset;
  1693. X
  1694. X    for (;;) {
  1695. X    cols -= strlen(str);
  1696. X    if (cols >= 0) {
  1697. X        printf("%s%s", str, cols > 0 ? " " : "");
  1698. X        cols--;
  1699. X        return 1;
  1700. X    }
  1701. X    if (line >= Lines - 1) return 0;
  1702. X    line++;
  1703. X    cols = Columns;
  1704. X    gotoxy(0, line);
  1705. X    if (line == Lines - 1) cols--;
  1706. X    }
  1707. X}
  1708. X
  1709. Xyes(must_answer)
  1710. Xint must_answer;
  1711. X{
  1712. X    int c, help = 1, in_macro = 0;
  1713. X
  1714. X    switch (m_yes()) {
  1715. X     case 0:
  1716. X    break;
  1717. X     case 1:
  1718. X    return 0;
  1719. X     case 2:
  1720. X    return 1;
  1721. X     case 3:
  1722. X    do_macro_processing = 0;
  1723. X        in_macro++;
  1724. X    break;
  1725. X    }
  1726. X
  1727. X    for (;;) {
  1728. X    if (!is_raw) {
  1729. X        raw();
  1730. X        c = get_c();
  1731. X        unset_raw();
  1732. X    } else
  1733. X        c = get_c();
  1734. X
  1735. X    if (c == 'y' || c == 'Y') {
  1736. X        c = 1;
  1737. X        break;
  1738. X    }
  1739. X
  1740. X    if (must_answer == 0 && (c == SP || c == CR || c == NL)) {
  1741. X        c = 1;
  1742. X        break;
  1743. X    }
  1744. X
  1745. X    if (c == 'n' || c == 'N') {
  1746. X        c = 0;
  1747. X        break;
  1748. X    }
  1749. X    if (c == K_interrupt) {
  1750. X        c = -1;
  1751. X        break;
  1752. X    }
  1753. X    if (help) {
  1754. X        fputs(" y=YES n=NO", stdout);
  1755. X        prompt_length += 11;
  1756. X        help = 0;
  1757. X    }
  1758. X    }
  1759. X
  1760. X    if (in_macro) {
  1761. X    if (c < 0) m_break();
  1762. X    do_macro_processing = 1;
  1763. X    }
  1764. X
  1765. X    return c;
  1766. X}
  1767. X
  1768. X
  1769. Xding()
  1770. X{
  1771. X    putp(bell_str);
  1772. X    fl;
  1773. X}
  1774. X
  1775. X
  1776. Xdisplay_file(name, modes)
  1777. Xchar *name;
  1778. Xint modes;
  1779. X{
  1780. X    FILE *f;
  1781. X    register c, stand_on;
  1782. X    int linecnt, headln_cnt, hdline, no_conf;
  1783. X    char headline[128];
  1784. X    import char *help_directory;
  1785. X
  1786. X    headline[0] = 0;
  1787. X    hdline = 0;
  1788. X    no_conf = 0;
  1789. X
  1790. X    headln_cnt = -1;
  1791. X
  1792. X    if (modes & CLEAR_DISPLAY) {
  1793. X    gotoxy(0,0);
  1794. X    clrdisp();
  1795. X    }
  1796. X
  1797. X    linecnt = Lines - 1;
  1798. X
  1799. Xchain:
  1800. X
  1801. X    f = open_file(relative(help_directory, name), OPEN_READ);
  1802. X    if (f == NULL)
  1803. X    printf("\r\n\nFile %s is not available\n\n", name);
  1804. X    else {
  1805. X    stand_on = 0;
  1806. X
  1807. X    while ((c = getc(f)) != EOF) {
  1808. X#ifdef HAVE_JOBCONTROL
  1809. X        if (s_redraw) {
  1810. X        no_conf = 1;
  1811. X        break;
  1812. X        }
  1813. X#endif
  1814. X        no_conf = 0;
  1815. X        if (c == '\1') {
  1816. X        if (STANDOUT) {
  1817. X            putp(stand_on ? exit_standout_mode : enter_standout_mode);
  1818. X            stand_on = !stand_on;
  1819. X        }
  1820. X        continue;
  1821. X        }
  1822. X        if (c == '\2') {
  1823. X        headln_cnt = 0;
  1824. X        continue;
  1825. X        }
  1826. X        if (c == '\3') {
  1827. X        headln_cnt = 0;
  1828. X        while ((c = getc(f)) != EOF && c != NL)
  1829. X            headline[headln_cnt++] = c;
  1830. X        headline[headln_cnt++] = NUL;
  1831. X        name = headline;
  1832. X        fclose(f);
  1833. X        goto chain;
  1834. X        }
  1835. X        if (c == '\4') {
  1836. X        printf("%s", version_id);
  1837. X        continue;
  1838. X        }
  1839. X
  1840. X        if (headln_cnt >= 0)
  1841. X        headline[headln_cnt++] = c;
  1842. X
  1843. X        if (hdline) {
  1844. X        puts(headline);
  1845. X        putchar(CR);
  1846. X        hdline = 0;
  1847. X        linecnt--;
  1848. X        }
  1849. X
  1850. X        putchar(c);
  1851. X        if (c == NL) {
  1852. X        putchar(CR);
  1853. X        if (headln_cnt >= 0) {
  1854. X            headline[--headln_cnt] = 0;
  1855. X            headln_cnt = -1;
  1856. X        }
  1857. X        if (--linecnt == 0) {
  1858. X            no_conf = 1;
  1859. X            if (any_key(0) == K_interrupt)
  1860. X            break;
  1861. X            linecnt = Lines - 1;
  1862. X            if (modes & CLEAR_DISPLAY) {
  1863. X            gotoxy(0,0);
  1864. X            clrdisp();
  1865. X            }
  1866. X            hdline = headline[0];
  1867. X        }
  1868. X        }
  1869. X    }
  1870. X
  1871. X    if (stand_on) putp(exit_standout_mode);
  1872. X    fclose(f);
  1873. X    }
  1874. X
  1875. X    prompt_line = Lines-1;    /* move prompt to last line */
  1876. X
  1877. X    if (!no_conf && (modes & CONFIRMATION))
  1878. X    any_key(prompt_line);
  1879. X}
  1880. X
  1881. X
  1882. X/*VARARGS*/
  1883. Xuser_error(va_alist)
  1884. Xva_dcl
  1885. X{
  1886. X    char *fmt;
  1887. X    use_vararg;
  1888. X
  1889. X    unset_raw();
  1890. X    clrdisp();
  1891. X    fl;
  1892. X
  1893. X    start_vararg;
  1894. X    fmt = va_arg1(char *);
  1895. X
  1896. X    vprintf(fmt, va_args2toN);
  1897. X    putchar(NL);
  1898. X
  1899. X    end_vararg;
  1900. X    nn_exit(1);
  1901. X}
  1902. X
  1903. X/*VARARGS*/
  1904. Xmsg(va_alist)
  1905. Xva_dcl
  1906. X{
  1907. X    use_vararg;
  1908. X
  1909. X    start_vararg;
  1910. X    vmsg(va_args1toN);
  1911. X    end_vararg;
  1912. X}
  1913. X
  1914. Xvmsg(va_tail)
  1915. Xva_tdcl
  1916. X{
  1917. X    static char errmsg[512] = "";
  1918. X    char *fmt;
  1919. X
  1920. X    fmt = va_arg1(char *);
  1921. X
  1922. X    if (fmt) vsprintf(errmsg, fmt, va_args2toN);
  1923. X
  1924. X    gotoxy(0, Lines-1);
  1925. X    fputs(errmsg, stdout);
  1926. X    clrline();
  1927. X    any_message = 1;
  1928. X
  1929. X    gotoxy(prompt_length, prompt_line);
  1930. X    fl;
  1931. X}
  1932. X
  1933. Xclrmsg(col)
  1934. Xint col;
  1935. X{
  1936. X    gotoxy(0, prompt_line + 1);
  1937. X    clrpage(prompt_line + 1);
  1938. X    if (col >= 0)
  1939. X    gotoxy(prompt_length + col, prompt_line);
  1940. X    fl;
  1941. X    any_message = 0;
  1942. X}
  1943. X
  1944. X
  1945. X/*VARARGS*/
  1946. Xprompt(va_alist)
  1947. Xva_dcl
  1948. X{
  1949. X    register char *cp;
  1950. X    int stand_on;
  1951. X    char *fmt;
  1952. X    static char cur_p[FILENAME];
  1953. X    static char saved_p[FILENAME];
  1954. X    use_vararg;
  1955. X
  1956. X    start_vararg;
  1957. X
  1958. X    fmt = va_arg1(char *);
  1959. X
  1960. X    if (fmt == P_VERSION) {
  1961. X    gotoxy(0, prompt_line + 1);
  1962. X    printf("Release %s ", version_id);
  1963. X    clrline();
  1964. X    any_message++;
  1965. X
  1966. X    if (prompt_line >= 0)
  1967. X        gotoxy(prompt_length, prompt_line);
  1968. X    goto out;
  1969. X    }
  1970. X
  1971. X    if (fmt == P_SAVE) {
  1972. X    strcpy(saved_p, cur_p);
  1973. X    goto out;
  1974. X    }
  1975. X
  1976. X    if (fmt == P_RESTORE)
  1977. X    strcpy(cur_p, saved_p);
  1978. X
  1979. X    if (prompt_line >= 0)
  1980. X    gotoxy(0, prompt_line);
  1981. X
  1982. X    if (fmt == P_MOVE) {
  1983. X    clrline();
  1984. X    goto out;
  1985. X    }
  1986. X
  1987. X    if (fmt != P_REDRAW && fmt != P_RESTORE)
  1988. X    vsprintf(cur_p, fmt, va_args2toN);
  1989. X
  1990. X    putchar(CR);
  1991. X
  1992. X    for (cp = cur_p, stand_on = 0, prompt_length = 0; *cp; cp++) {
  1993. X    if (*cp == '\1') {
  1994. X        if (cp[1] != '\1') {
  1995. X        if (STANDOUT) {
  1996. X            putp(stand_on ? exit_standout_mode : enter_standout_mode);
  1997. X            stand_on = !stand_on;
  1998. X            prompt_length += cookie_size;
  1999. X        }
  2000. X        continue;
  2001. X        }
  2002. X        cp++;
  2003. X    } else
  2004. X    if (*cp == '\2') {
  2005. X        time_t t, tick_usage();
  2006. X        char   *timestr;
  2007. X
  2008. X        t = tick_usage();
  2009. X
  2010. X        if (show_current_time) {
  2011. X        timestr = ctime(&t) + 11;
  2012. X        timestr[5] = NUL;
  2013. X
  2014. X        printf("-- %s ", timestr);
  2015. X        prompt_length += 9;
  2016. X        }
  2017. X
  2018. X        if (unread_mail(t)) {
  2019. X        printf("Mail ");
  2020. X        prompt_length += 5;
  2021. X        }
  2022. X
  2023. X        continue;
  2024. X    }
  2025. X
  2026. X    putchar(*cp);
  2027. X    prompt_length ++;
  2028. X    }
  2029. X    if (stand_on) {
  2030. X    putp(exit_standout_mode);
  2031. X    prompt_length += cookie_size;
  2032. X    }
  2033. X
  2034. X    clrline();
  2035. X
  2036. X    if (fmt == P_RESTORE)
  2037. X    restore_xy();
  2038. X    else
  2039. X    curxy_c = -1;
  2040. X
  2041. X out:
  2042. X    end_vararg;
  2043. X}
  2044. X
  2045. X
  2046. Xany_key(line)
  2047. Xint line;
  2048. X{
  2049. X    int was_raw, c, dmp;
  2050. X
  2051. X    was_raw = is_raw;
  2052. X    if (!is_raw) raw();
  2053. X    if (line == 0)
  2054. X    line = -1;
  2055. X    else
  2056. X    if (line < 0)
  2057. X        line = Lines + line;
  2058. X
  2059. X    if (line != 10000)
  2060. X    so_printxy(0, line, "Hit any key to continue");
  2061. X
  2062. X    clrline();
  2063. X
  2064. X    dmp = do_macro_processing;
  2065. X    do_macro_processing = 0;
  2066. X    c = get_c();
  2067. X    if (c == 'q' || c == 'Q') c = K_interrupt;
  2068. X    do_macro_processing = dmp;
  2069. X
  2070. X    if (!was_raw) unset_raw();
  2071. X
  2072. X    return c;
  2073. X}
  2074. X
  2075. X
  2076. Xstatic pg_fline, pg_width, pg_maxw, pg_line, pg_col, pg_quit;
  2077. X
  2078. Xpg_init(first_line, cols)
  2079. Xint first_line, cols;
  2080. X{
  2081. X    pg_fline = first_line;
  2082. X    pg_line = pg_fline - 1;
  2083. X    pg_quit = pg_col = 0;
  2084. X    pg_width = Columns / cols;
  2085. X    pg_maxw = pg_width * (cols - 1);
  2086. X}
  2087. X
  2088. Xpg_scroll(n)
  2089. Xint n;
  2090. X{
  2091. X    pg_line += n;
  2092. X    if (pg_line >= (Lines - 1)) {
  2093. X    pg_line = 0;
  2094. X    if (any_key(0) == K_interrupt)
  2095. X        return 1;
  2096. X    putchar(CR);
  2097. X    clrline();
  2098. X    }
  2099. X    return 0;
  2100. X}
  2101. X
  2102. Xpg_next()
  2103. X{
  2104. X    int c;
  2105. X
  2106. X    pg_line++;
  2107. X    if (pg_line < Lines) {
  2108. X    gotoxy(pg_col, pg_line);
  2109. X    if (pg_line == Lines - 1 && pg_col == pg_maxw) {
  2110. X        c = any_key(0);
  2111. X        gotoxy(0, pg_fline);
  2112. X        clrpage(pg_fline);
  2113. X        pg_col = 0;
  2114. X        pg_line = pg_fline;
  2115. X        if (c == K_interrupt) {
  2116. X        pg_quit = 1;
  2117. X        return -1;
  2118. X        }
  2119. X        return 1;
  2120. X    }
  2121. X    } else {
  2122. X    pg_line = pg_fline;
  2123. X    pg_col += pg_width;
  2124. X    gotoxy(pg_col, pg_line);
  2125. X    }
  2126. X    return 0;
  2127. X}
  2128. X
  2129. Xpg_indent(pos)
  2130. Xint pos;
  2131. X{
  2132. X    gotoxy(pg_col + pos, pg_line);
  2133. X}
  2134. X
  2135. Xpg_end()
  2136. X{
  2137. X    if (pg_quit == 0 && pg_next() == 0)
  2138. X    any_key(0);
  2139. X}
  2140. X
  2141. X
  2142. Xuser_delay(ticks)
  2143. Xint ticks;
  2144. X{
  2145. X    if (ticks <= 0 || conf_dont_sleep) {
  2146. X    printf(" <>");
  2147. X    any_key(10000);
  2148. X    } else {
  2149. X    fl;
  2150. X    sleep((unsigned)ticks);
  2151. X    }
  2152. X}
  2153. X
  2154. END_OF_FILE
  2155.   if test 27619 -ne `wc -c <'term.c'`; then
  2156.     echo shar: \"'term.c'\" unpacked with wrong size!
  2157.   fi
  2158.   # end of 'term.c'
  2159. fi
  2160. echo shar: End of archive 1 \(of 22\).
  2161. cp /dev/null ark1isdone
  2162. MISSING=""
  2163. 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
  2164.     if test ! -f ark${I}isdone ; then
  2165.     MISSING="${MISSING} ${I}"
  2166.     fi
  2167. done
  2168. if test "${MISSING}" = "" ; then
  2169.     echo You have unpacked all 22 archives.
  2170.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2171. else
  2172.     echo You still must unpack the following archives:
  2173.     echo "        " ${MISSING}
  2174. fi
  2175. exit 0
  2176.  
  2177. exit 0 # Just in case...
  2178.