home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-05-19 | 54.4 KB | 2,131 lines |
- Newsgroups: comp.sources.misc
- From: iain%anl433.uucp@germany.eu.net (Iain J. Lea)
- Subject: v30i011: tin - threaded full screen newsreader, Part11/14
- Message-ID: <1992May20.172831.29872@sparky.imd.sterling.com>
- X-Md4-Signature: 1b59fca5dabf547e426085c05a927621
- Date: Wed, 20 May 1992 17:28:31 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: iain%anl433.uucp@germany.eu.net (Iain J. Lea)
- Posting-number: Volume 30, Issue 11
- Archive-name: tin/part11
- Environment: BSD, SCO, ISC, SUNOS, SYSVR3, SYSVR4, ULTRIX, XENIX
- Supersedes: tin: Volume 29, Issue 19-30
-
- #! /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: FAQ curses.c init.c open.c
- # Wrapped by kent@sparky on Tue May 19 13:38:05 1992
- 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 11 (of 14)."'
- if test -f 'FAQ' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'FAQ'\"
- else
- echo shar: Extracting \"'FAQ'\" \(14588 characters\)
- sed "s/^X//" >'FAQ' <<'END_OF_FILE'
- X[ NOTE: IGNORE THIS DOCUMENT UNTIL A LATER DATE - IT IS NOT COMPLETE - Iain ]
- X[ THIS DOCUMENT USES THE NN FAQ AS ITS BASE WITH PERMISSION FROM BILL WOHLER]
- X
- XSubject: TIN Frequently Asked Questions (FAQ) with Answers
- XSummary: This document answers Frequently Asked Questions about TIN,
- X a menu-based, point and shoot, USENET news reader.
- XKeywords: FAQ tin news question answer newsrc digest article nntp
- X newsgroup cancel mail signature header netnews usenet kill
- XFollowup-To: poster
- X
- XArchive-name: tin-faq/part01
- XLast-modified: 01/05/92
- X
- X This is a living list of frequently asked questions on the Usenet
- X news reader TIN (Tass & Iain's Newsreader). The point of this is to
- X circulate existing information, and avoid rehashing old answers.
- X Better to build on top than start again. Please read this document
- X before posting to a newsgroup concerning tin.
- X
- X This article is posted monthly. If it has already expired and
- X you're not reading this, you can hope that you saved the last bit of
- X question 3 so that you can get a copy yourself.
- X
- X When someone posts a frequently-asked question, I will point out to
- X them that the answer is here to ensure that everybody gets their
- X question answered fully and to eliminate unnecessary traffic in this
- X newsgroup. Posted answers that are in the FAQ are just as annoying as
- X posted questions that are in the FAQ!
- X
- X Your comments, additions and fixes to this list are welcome: please
- X send them to Iain Lea (iain%anl433.uucp@Germany.EU.net). Complete,
- X accurate and grammatically correct answers are appreciated to reduce
- X the time I have to take to test or edit your answers.
- X
- X
- XFrom: Preface
- XSubject: Table of Contents
- X
- XLegend: + new, - deleted, ! changed
- X
- XIntroductory
- X
- X 1. Why should I use tin?
- X 2. Where can I get tin?
- X 3. What references exist for tin?
- X 4. How should I report bugs?
- X 5. How can I convert from rn to nn?
- X 6. How can I make life simpler when starting nn for the first time?
- X 7. Is there an X interface to tin?
- X
- XBuilding tin
- X
- X 10. What machines does tin run on?
- X
- XUsing tin
- X
- X 20. How do I save files that I can read later with MH, elm, Mail, ...?
- X 21. How come nn doesn't show the Lines count?
- X 22. How can I find all articles having to do with a certain topic?
- X 23. How can I set a different Organization name?
- X 24. Can all non-selected subjects be automatically placed in my kill file?
- X 25. Can I automatically kill articles based on the Newsgroups header?
- X 26. How can I select one article in a thread with auto-select-subject set?
- X 27. Is there a library of macros and other nn features?
- X 28. Can one search for patterns in the entire article from the menu?
- X 29. How can I remove old articles from folders?
- X 30. What's the best way to save multi-part articles?
- X 31. When saving in +a/b/c keeps you from saving in +a/b.
- X 32. Can I use my mailer to send mail?
- X 33. How can I see the original article with the current subject?
- X 34. Can I choose newsgroups as I do articles, ie. with a menu?
- X 35. How can I post prewritten articles with nn?
- X 36. How do I eliminate double signatures?
- X 37. How can I make mail replies go to a different machine?
- X 38. How come more articles get selected than I expect?
- X 39. Any plans for trn-ish thread following?
- X 40. Setting new-group-action to "ask before adding" doesn't work.
- X 41. Why does nn crash when a letter one past the highest letter is selected?
- X 42. Why do articles without a Lines header appear empty?
- X
- XFrom: Preface
- XSubject: Viewing This Article
- X
- X To skip to a particular question numbered xx, use "/^F.*xx" with most
- X pagers. In GNU Emacs type "M-C-s ^F.*xx", (or C-r to search backwards),
- X followed by ESC to end the search.
- X
- X To skip to new or changed questions, use "/^F.*[!+]" with most pagers and
- X "M-C-s ^F.*[!+]" in GNU Emacs.
- X
- X This article is in digest format. Nn may have already broken this
- X message into separate articles; if not, then type "G %". In rn, use
- X ^G to skip sections.
- X
- X To get an overview of just the questions in GNU Emacs, type "M-2 C-x $".
- X Use "C-x $" to display the text again ("M-0 C-l C-x $" ensures that
- X the current cursor location remains on the screen).
- X
- X Contributer's E-Mail addresses can be found at the bottom of this article.
- X
- X
- XFrom: Intro-1
- XSubject: Why should I use tin?
- X
- X tin is a menu based (point and shoot) netnews reader with a complete
- X set of features especially suited to the novice user. Since its first
- X release in Aug 1991 it has started to replace rn and other well-known
- X news readers at many sites.
- X
- X Some of the key features of tin are:
- X
- X * Automatic kill & selection of articles based on subject or author.
- X
- X * Based more on Notes and tass than rn type newreaders.
- X * Full screen, easy to use with on-line help at all levels.
- X * Reads news locally (ie. /usr/spool/news) and/or via NNTP/INN.
- X * Threads on Subject: and/or Archive-name: mail headers.
- X * Four different operating levels:
- X - Group selection level
- X - Thread selection level
- X - Article selection level
- X - Article viewer
- X * Same interface to mail, pipe, print & save articles.
- X * Auto unpacking of multi-part shar & uuencoded articles.
- X * Auto kill & selection of articles based on subject or author.
- X * Batch mode to mail/save new news when user is on holiday.
- X * Builtin NNTP mini-inews & clientlib.c
- X * NNTP extensions XUSER & XINDEX allow central index files.
- X
- X
- XFrom: Intro-2
- XSubject: Where can I get tin?
- X
- X The current version of tin is 1.1 PL3.
- X
- X via anonymous ftp:
- X ftp.Germany.EU.net []
- X pub/news/tin/tin.tar.Z ~250k
- X
- X via mail:
- X Send a note to ftpmail@decwrl.dec.com whose body contains "help"
- X on a line by itself get information on getting ftp sources by
- X mail.
- X
- X
- XFrom: Intro-3 !
- XSubject: What references exist for tin?
- X
- X Usenet:
- X news.software.readers
- X news.software.notes
- X
- X Mailing list:
- X none
- X
- X
- XFrom: Intro-4
- XSubject: How should I report bugs?
- X
- X Either mail them to iain%anl433.uucp@Germany.EU.net and be sure
- X to include the version number as well as what hardware and operating
- X system you are using, or better yet, use the 'B' bug command within tin.
- X
- X
- XFrom: Intro-6
- XSubject: How can I make life simpler when starting tin for the first time?
- X
- X tin -c
- X sysadmin can set interesting groups in LIBDIR/subscriptions
- X Subscribe/unsubscribe from uninteresting groups with sSuU commands at
- X group selection level.
- X
- X
- XFrom: Intro-7
- XSubject: Is there an X interface to tin?
- X
- X No.
- X
- X
- XFrom: Building nn-10
- XSubject: What machines does tin run on?
- X
- X * 386/486 PC & Xenix 2.3.2/SCO SysVR3.2/ISC SysVR3.2/ATT SysVr4.0
- X 386 PC & Minix 386
- X Amdahl & SysVR3
- X * Apollo DN4500 & DomainOS 10.3
- X Apricot VX/FT & SCO 3.2.2
- X Atari STe & Minix 1.5.10.3b
- X Convex C220 & Convex Un*x
- X * Dec 5000/Vax & Ultrix 4.1/4.2
- X DIAB DS90 & D-NIX 5.3
- X * DG Aviion 300 & DG-UX 4.30
- X Harris HCX & CX/UX
- X HP 720/845 & HP-UX 7.0
- X IBM RS/6000 & AIX 3.1.5
- X ICL DRS6000 & SysVR4.0
- X NCR Tower & SysV
- X Powerbook 140 & MacMinix
- X Sequent S81 & PTX 1.3 / Dynix
- X SGI 4D/35 & IRIX 4.0.1
- X * SNI MX300/MX500 & Sinix 5.22/5.23/5.24/5.4
- X * Sony News & NewsOS 4.1
- X * Sun 3/4/IPC/SS1/SS2 & SunOS 4.0.3/4.1/4.1.1
- X * Vax 11/785 & BSD 4.3
- X
- X * donates that the author has compiled & used tin on that machine.
- X
- X
- XFrom: Using nn-22
- XSubject: How can I find all articles having to do with a certain topic?
- X
- X nngrab invokes nn on all articles whose subject or keyword fields
- X contain a desired keyword. This shows one how important it is to
- X use descriptive subjects and keywords when posting articles. For
- X more information, read the manual page.
- X
- X
- XFrom: Using nn-23
- XSubject: How can I set a different Organization name?
- X
- X This header (along with the Reply-To:) are user-specified in the
- X init file. An init file may include the lines:
- X
- X set mail-header Reply-To: steven@Transact.COM;Organization: Transact Software
- X set news-header Reply-To: steven@Transact.COM;Organization: Transact Software
- X
- X You can include any headers that you want in the headers, either in
- X mail or news postings, and they may be different. --Steven M. List
- X
- X A Reply-To header is useful when your system generates either an
- X unwanted or blatantly wrong return address for you. If this header
- X is present, then mailers use it instead of the system generated From
- X header. --Bill Wohler
- X
- X
- XFrom: Using nn-28
- XSubject: Is the Xref: header used to mark crosposted articles read?
- X
- X No. On the TODO list.
- X
- X
- XFrom: Using nn-28
- XSubject: Can one search for patterns in the entire article from the menu?
- X
- X No.
- X
- X
- XFrom: Using nn-29
- XSubject: How can I remove old articles from folders?
- X
- X Just open the folder in the usual way and C(ancel) the articles you
- X want to remove from the folder. When you leave the folder, nn will
- X rewrite the folder with the "cancel"ed articles removed. --Kim Storm
- X
- X
- XFrom: Using nn-30
- XSubject: What's the best way to save multi-part articles?
- X
- X This is VERY easy - all you have to do is to save the articles from
- X the menu, e.g.
- X
- X W(rite) +file.* a b c d... <space>
- X
- X where a b c d... are the articles on the menu you want to save. You
- X can also save the selected articles on the menu with * (only on
- X current page) or + (on all menu pages). --Kim Storm
- X
- X
- XFrom: Using nn-31
- XSubject: When saving in +a/b/c keeps you from saving in +a/b.
- X
- X This happens when default-save-file is $F. Try changing
- X default-save-file to $F/$N (my favorite) to get, for example,
- X +news/software/nn/1022, or $G to put everything in
- X +news.software.nn. Finally, if you really did want the behavior of
- X +$F, a compromise would be to use +$F. (Andrew's favorite) instead
- X (one can use anything other than '.'). --Bill Wohler & Andrew Swann
- X
- X Alternatively, use +$F/$L, to place articles for news.software.nn in
- X the file +/news/software/nn/nn. This has two advantages:
- X 1) You can later read through the folder "nn" and save some of the
- X articles under new folder names having to do with the topic. For
- X example, you might save auto-select topics under +$F/auto-sel,
- X that is, +/news/software/nn/auto-sel.
- X 2) If at a later date, a new newsgroup is added below nn, articles
- X can still be saved under that subgroup since +/news/software/nn is
- X already a directory, not a folder. --Harry Herman
- X
- X
- XFrom: Using nn-33
- XSubject: How can I see the original article with the current subject?
- X
- X While reading an article, use "G RET RET RET". --Bill Wohler
- X
- X
- XFrom: Using nn-35
- XSubject: How can I post prewritten articles with nn?
- X
- X nnpost will construct the header for the posted article, so it
- X requires several arguments to be specified before the article is
- X posted, e.g. a newsgroup name and a subject. If some arguments are
- X missing, nnpost will prompt for the missing arguments.
- X
- X If your pre-written article includes a full header, then you should
- X not use nnpost; instead you should feed the article to "inews -h"
- X directly (which is what nnpost does after building the header from
- X the arguments). --Kim Storm
- X
- X
- XFrom: Using nn-36
- XSubject: How do I eliminate double signatures?
- X
- X Double signatures occur when both nn and inews append your .signature
- X file.
- X
- X If you want inews to append your .signature file, use:
- X
- X unset append-signature-post
- X
- X If you want nn to append your .signature file, you can copy nn's aux
- X file (ie. /usr/local/lib/nn/aux) to your .nn directory and set the
- X mail-script and news-script variables to ~/.nn/aux. In your copy of
- X the aux script, you can either specify a different place for your
- X .signature file (like $HOME/.nn/signature) or you can get fancy: you
- X can use specific .signatures for certain groups, or use the output of
- X a program.
- X
- X
- XFrom: Using nn-37
- XSubject: How can I make mail replies go to a different machine?
- X
- X See "How can I set a different Organization name?"
- X
- X
- XFrom: Using nn-39
- XSubject: Any plans for trn-ish thread following?
- X
- X At the moment, no.
- X
- X
- XFrom: Using nn-42 +
- XSubject: Why do articles without a Lines header appear empty?
- X
- X I discovered that this problem only shows up if you have
- X header-lines set to a string that includes "L". I suspect having
- X the line count patch sets something that makes nn think there is a
- X Lines header and then the header-string is telling it to display the
- X Lines header but there isn't one and things get messed up. --Gary
- X Morris
- X
- X
- XFrom: Appendix
- XSubject: Glossary
- X
- X NNTP Network News Transport Protocol (see RFC 977)
- X
- X
- XFrom: Appendix
- XSubject: Acknowledgements
- X
- XI'd like to thank the following people for providing ideas on the
- Xlayout of this article:
- X
- XJoe Wells <jbw@bigbird.bu.edu> Richard M. Stallman <rms@gnu.ai.mit.edu>
- XDavid Elliott <dce@smsc.sony.com> Tom Christiansen <tchrist@convex.com>
- XEugene N. Miya <eugene@nas.nasa.gov>
- X
- X
- XWe are also grateful to the following individuals that have provided
- Xanswers or other information to make this a better document. The
- Xactual list is undoubtedly larger.
- X
- XF.F. Jacot Guillarmod <ccfj@hippo.ru.ac.za> Mr. Kim F. Storm <storm@texas.dk>
- XSteven M. List <itkin@mrspoc.transact.com> Steven Grady <grady@fx.com>
- XRichard M. Mathews <richard@locus.com> Ian Taylor <ian@airs.com>
- XDave Shaver <shaver@convex.com> Paul Eggert <eggert@twinsun.com>
- XMichael Rawdon <rawdon@rex.cs.tulane.edu> Joerg Napp <napp@uni-paderborn.de>
- XDave Hayes <dave@elxr.jpl.nasa.gov> Gary Morris <garym@telesoft.com>
- XAndrew Swann <swann@imada.ou.dk> Alexis Rosen <alexis@panix.com>
- XDavid B. Thomas <dt@yenta.alb.nm.us> Jeffery Small <jeff@cjsa.wa.com>
- XRichard Reiner <rreiner@nexus.yorku.ca> Max Heffler <max@compaq.com>
- XHarry Herman <herman@corpane.uucp> Luc Rooijakkers <lwj@cs.kun.nl>
- XPaul Bickerstaff <pbickers@tamaluit.phys.uidaho.edu>
- X
- X
- XFrom: Appendix
- XSubject: Warranty
- X
- X[The following statement epitomizes the ridiculous state of
- Xaffairs in America and can be ignored outside of America...]
- X
- XNo Warranty: Because this article is provided free of charge as a
- Xservice to news.software.readers readers, we provide absolutely no
- Xwarranty, to the extent permitted by applicable state law. This
- Xarticle is provided "as is" without warranty of any kind, either
- Xexpressed or implied, including, but not limited to, the implied
- Xwarranties of merchantability and fitness for a particular purpose.
- XShould the information prove defective, you assume the cost of all
- Xnecessary servicing, repair or correction.
- END_OF_FILE
- if test 14588 -ne `wc -c <'FAQ'`; then
- echo shar: \"'FAQ'\" unpacked with wrong size!
- fi
- # end of 'FAQ'
- fi
- if test -f 'curses.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'curses.c'\"
- else
- echo shar: Extracting \"'curses.c'\" \(7985 characters\)
- sed "s/^X//" >'curses.c' <<'END_OF_FILE'
- X/*
- X * Project : tin - a threaded Netnews reader
- X * Module : curses.c
- X * Author : D.Taylor & I.Lea
- X * Created : ??-??-86
- X * Updated : 03-04-92
- X * Notes : This is a screen management library borrowed with permission
- X * from the Elm mail system (a great mailer--I highly recommend
- X * it!).This library was hacked to provide what tin needs.
- X * Copyright : Copyright (c) 1986-92 Dave Taylor & Iain Lea
- X * The Elm Mail System - $Revision: 2.1 $ $State: Exp $
- X */
- X
- X#include <stdio.h>
- X#include <curses.h>
- X#include <sys/errno.h>
- X
- X#define DEFAULT_LINES_ON_TERMINAL 24
- X#define DEFAULT_COLUMNS_ON_TERMINAL 80
- X
- Xint LINES = 23;
- Xint COLS = 80;
- Xint inverse_okay = TRUE;
- Xstatic int _inraw = FALSE; /* are we IN rawmode? */
- X
- X
- X#ifndef INDEX_DAEMON
- X
- X#define BACKSPACE '\b'
- X#define VERY_LONG_STRING 2500
- X
- X#ifdef BSD
- X# ifndef BSD4_1
- X# include <sgtty.h>
- X# else
- X# include <termio.h>
- X# endif
- X#else
- X# ifndef SYSV
- X# ifndef MINIX
- X# ifdef sinix
- X# include <termios.h>
- X# else
- X# include <termio.h>
- X# endif
- X# else
- X# include <sgtty.h>
- X# endif
- X# endif
- X#endif
- X
- X#define TTYIN 0
- X
- X#ifdef SHORTNAMES
- X# define _clearinverse _clrinv
- X# define _cleartoeoln _clrtoeoln
- X# define _cleartoeos _clr2eos
- X#endif
- X
- X#if defined(BSD) || defined(MINIX)
- X# define TCGETA TIOCGETP
- X# define TCSETAW TIOCSETP
- X
- Xstruct sgttyb _raw_tty,
- X _original_tty;
- X#else
- X# ifdef sinix
- X# ifndef TCGETA
- X# define TCGETA STCGETA
- X# endif
- X# ifndef TCSETA
- X# define TCSETAW STCSETAW
- X# endif
- Xstruct termios _raw_tty,
- X _original_tty;
- X# else
- Xstruct termio _raw_tty,
- X _original_tty;
- X# endif
- X#endif
- X
- Xstatic char *_clearscreen, *_moveto, *_cleartoeoln, *_cleartoeos,
- X *_setinverse, *_clearinverse, *_setunderline, *_clearunderline,
- X *_terminalinit, *_terminalend;
- X
- Xstatic int _lines,_columns;
- X
- Xstatic char _terminal[1024]; /* Storage for terminal entry */
- Xstatic char _capabilities[1024]; /* String for cursor motion */
- X
- Xstatic char *ptr = _capabilities; /* for buffering */
- X
- Xint outchar (); /* char output for tputs */
- Xextern char *tgetstr (); /* Get termcap capability */
- Xextern char *tgoto (); /* and the goto stuff */
- X
- X#endif /* INDEX_DAEMON */
- X
- X#include "tin.h"
- X
- X
- Xint InitScreen ()
- X{
- X#ifndef INDEX_DAEMON
- X
- X extern int tgetent(); /* get termcap entry */
- X char termname[40], *p;
- X
- X if ((p = (char *) getenv ("TERM")) == NULL) {
- X fprintf (stderr, "%s: TERM variable must be set to use screen capabilities\n", progname);
- X return (FALSE);
- X }
- X if (strcpy (termname, p) == NULL) {
- X fprintf (stderr,"%s: Can't get TERM variable\n", progname);
- X return (FALSE);
- X }
- X if (tgetent (_terminal, termname) != 1) {
- X fprintf (stderr,"%s: Can't get entry for TERM\n", progname);
- X return (FALSE);
- X }
- X
- X /* load in all those pesky values */
- X _clearscreen = tgetstr ("cl", &ptr);
- X _moveto = tgetstr ("cm", &ptr);
- X _cleartoeoln = tgetstr ("ce", &ptr);
- X _cleartoeos = tgetstr ("cd", &ptr);
- X _lines = tgetnum ("li");
- X _columns = tgetnum ("co");
- X _setinverse = tgetstr ("so", &ptr);
- X _clearinverse = tgetstr ("se", &ptr);
- X _setunderline = tgetstr ("us", &ptr);
- X _clearunderline = tgetstr ("ue", &ptr);
- X _terminalinit = tgetstr ("ti", &ptr);
- X _terminalend = tgetstr ("te", &ptr);
- X
- X InitWin ();
- X
- X if (!_clearscreen) {
- X fprintf (stderr,
- X "%s: Terminal must have clearscreen (cl) capability\n",progname);
- X return (FALSE);
- X }
- X if (!_moveto) {
- X fprintf (stderr,
- X "%s: Terminal must have cursor motion (cm)\n", progname);
- X return (FALSE);
- X }
- X if (!_cleartoeoln) {
- X fprintf (stderr,
- X "%s: Terminal must have clear to end-of-line (ce)\n", progname);
- X return (FALSE);
- X }
- X if (!_cleartoeos) {
- X fprintf (stderr,
- X "%s: Terminal must have clear to end-of-screen (cd)\n", progname);
- X return (FALSE);
- X }
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X if (_lines == -1)
- X _lines = DEFAULT_LINES_ON_TERMINAL;
- X if (_columns == -1)
- X _columns = DEFAULT_COLUMNS_ON_TERMINAL;
- X /* kludge to workaround no inverse */
- X if (_setinverse == 0) {
- X _setinverse = _setunderline;
- X _clearinverse = _clearunderline;
- X if (_setinverse == 0)
- X draw_arrow_mark = 1;
- X }
- X return (TRUE);
- X
- X#else
- X
- X return (FALSE);
- X
- X#endif /* INDEX_DAEMON */
- X}
- X
- X/*
- X * returns the number of lines and columns on the display.
- X */
- X
- Xvoid ScreenSize (num_lines, num_columns)
- X int *num_lines, *num_columns;
- X{
- X#ifndef INDEX_DAEMON
- X
- X if (_lines == 0) _lines = DEFAULT_LINES_ON_TERMINAL;
- X if (_columns == 0) _columns = DEFAULT_COLUMNS_ON_TERMINAL;
- X
- X *num_lines = _lines - 1; /* assume index from zero*/
- X *num_columns = _columns; /* assume index from one */
- X
- X#endif /* INDEX_DAEMON */
- X}
- X
- Xvoid InitWin ()
- X{
- X#ifndef INDEX_DAEMON
- X
- X if (_terminalinit) {
- X tputs (_terminalinit, 1, outchar);
- X fflush (stdout);
- X }
- X
- X#endif /* INDEX_DAEMON */
- X}
- X
- Xvoid EndWin ()
- X{
- X#ifndef INDEX_DAEMON
- X
- X if (_terminalend) {
- X tputs (_terminalend, 1, outchar);
- X fflush (stdout);
- X }
- X
- X#endif /* INDEX_DAEMON */
- X}
- X
- X/*
- X * clear the screen: returns -1 if not capable
- X */
- X
- Xvoid ClearScreen ()
- X{
- X#ifndef INDEX_DAEMON
- X
- X tputs (_clearscreen, 1, outchar);
- X fflush (stdout); /* clear the output buffer */
- X
- X#endif /* INDEX_DAEMON */
- X}
- X
- X/*
- X * move cursor to the specified row column on the screen.
- X * 0,0 is the top left!
- X */
- X
- Xvoid MoveCursor (row, col)
- X int row, col;
- X{
- X#ifndef INDEX_DAEMON
- X
- X char *stuff, *tgoto();
- X
- X stuff = tgoto (_moveto, col, row);
- X tputs (stuff, 1, outchar);
- X fflush (stdout);
- X
- X#endif /* INDEX_DAEMON */
- X}
- X
- X/*
- X * clear to end of line
- X */
- X
- Xvoid CleartoEOLN ()
- X{
- X#ifndef INDEX_DAEMON
- X
- X tputs (_cleartoeoln, 1, outchar);
- X fflush (stdout); /* clear the output buffer */
- X
- X#endif /* INDEX_DAEMON */
- X}
- X
- X/*
- X * clear to end of screen
- X */
- X
- Xvoid CleartoEOS ()
- X{
- X#ifndef INDEX_DAEMON
- X
- X int i;
- X
- X if (_cleartoeos) {
- X tputs (_cleartoeos, 1, outchar);
- X } else {
- X for (i=_lines ; i < _lines ; i++) {
- X MoveCursor (i, 0);
- X CleartoEOLN ();
- X }
- X }
- X fflush (stdout); /* clear the output buffer */
- X
- X#endif /* INDEX_DAEMON */
- X}
- X
- X/*
- X * set inverse video mode
- X */
- X
- Xvoid StartInverse ()
- X{
- X#ifndef INDEX_DAEMON
- X
- X if (_setinverse && inverse_okay)
- X tputs (_setinverse, 1, outchar);
- X fflush (stdout);
- X
- X#endif /* INDEX_DAEMON */
- X}
- X
- X/*
- X * compliment of startinverse
- X */
- X
- Xvoid EndInverse ()
- X{
- X#ifndef INDEX_DAEMON
- X
- X if (_clearinverse && inverse_okay)
- X tputs (_clearinverse, 1, outchar);
- X fflush (stdout);
- X
- X#endif /* INDEX_DAEMON */
- X}
- X
- X/*
- X * returns either 1 or 0, for ON or OFF
- X */
- X
- Xint RawState()
- X{
- X return (_inraw);
- X}
- X
- X/*
- X * state is either TRUE or FALSE, as indicated by call
- X */
- X
- Xvoid Raw(state)
- X int state;
- X{
- X#ifndef INDEX_DAEMON
- X
- X if (state == FALSE && _inraw) {
- X (void) ioctl(TTYIN, TCSETAW, &_original_tty);
- X _inraw = 0;
- X }
- X else if (state == TRUE && ! _inraw) {
- X
- X (void) ioctl(TTYIN, TCGETA, &_original_tty); /** current setting **/
- X
- X (void) ioctl(TTYIN, TCGETA, &_raw_tty); /** again! **/
- X#if defined(BSD) || defined(MINIX)
- X _raw_tty.sg_flags &= ~(ECHO | CRMOD); /* echo off */
- X _raw_tty.sg_flags |= CBREAK; /* raw on */
- X#else
- X _raw_tty.c_lflag &= ~(ICANON | ECHO); /* noecho raw mode */
- X
- X _raw_tty.c_cc[VMIN] = '\01'; /* minimum # of chars to queue */
- X _raw_tty.c_cc[VTIME] = '\0'; /* minimum time to wait for input */
- X#endif
- X
- X (void) ioctl(TTYIN, TCSETAW, &_raw_tty);
- X
- X _inraw = 1;
- X }
- X
- X#endif /* INDEX_DAEMON */
- X}
- X
- X/*
- X * read a character with Raw mode set!
- X */
- X
- Xint ReadCh()
- X{
- X#ifndef INDEX_DAEMON
- X extern int errno;
- X char ch;
- X register int result = 0;
- X
- X#ifdef READ_CHAR_HACK
- X#undef getc
- X while ((result = getc(stdin)) == EOF) {
- X if (feof(stdin))
- X break;
- X
- X if (ferror(stdin) && errno != EINTR)
- X break;
- X
- X clearerr(stdin);
- X }
- X
- X return ((result == EOF) ? EOF : result & 0xFF);
- X#else
- X
- X while ((result = read(0, &ch, 1)) < 0 && errno == EINTR)
- X ; /* spin on signal interrupts */
- X
- X return((result <= 0 ) ? EOF : ch & 0xFF);
- X#endif
- X
- X#endif /* INDEX_DAEMON */
- X}
- X
- X/*
- X * output a character. From tputs... (Note: this CANNOT be a macro!)
- X */
- X
- Xint outchar(c)
- X char c;
- X{
- X fputc (c, stdout);
- X}
- END_OF_FILE
- if test 7985 -ne `wc -c <'curses.c'`; then
- echo shar: \"'curses.c'\" unpacked with wrong size!
- fi
- # end of 'curses.c'
- fi
- if test -f 'init.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'init.c'\"
- else
- echo shar: Extracting \"'init.c'\" \(14261 characters\)
- sed "s/^X//" >'init.c' <<'END_OF_FILE'
- X/*
- X * Project : tin - a threaded Netnews reader
- X * Module : init.c
- X * Author : I.Lea
- X * Created : 01-04-91
- X * Updated : 09-05-92
- X * Notes :
- X * Copyright : (c) Copyright 1991-92 by Iain Lea
- X * You may freely copy or redistribute this software,
- X * so long as there is no profit made from its use, sale
- X * trade or reproduction. You may not change this copy-
- X * right notice, and it must be included in any copy made
- X */
- X
- X#include "tin.h"
- X
- Xchar rcdir[PATH_LEN];
- Xchar rcfile[PATH_LEN];
- Xchar indexdir[PATH_LEN];
- Xchar killfile[PATH_LEN];
- Xchar postfile[PATH_LEN];
- Xchar unthreadfile[PATH_LEN];
- Xchar cvers[LEN];
- Xchar nntp_server[LEN];
- Xchar active_file[PATH_LEN];
- Xchar subscriptions_file[PATH_LEN];
- Xchar homedir[PATH_LEN];
- Xchar userid[LEN];
- Xchar delgroups[LEN];
- Xchar default_maildir[PATH_LEN]; /* mailbox dir where = saves are stored */
- Xchar newsrc[PATH_LEN];
- Xchar newnewsrc[PATH_LEN];
- Xchar add_addr[LEN]; /* address to add to rR reply to author with mail */
- Xchar bug_addr[LEN]; /* address to add send bug reports to */
- Xchar txt_help_bug_report[LEN]; /* address to add send bug reports to */
- Xchar reply_to[LEN]; /* Reply-To: address */
- Xchar my_org[LEN]; /* Organization: */
- Xchar my_distribution[LEN]; /* Distribution: */
- Xchar default_sigfile[PATH_LEN];
- Xchar default_signature[PATH_LEN];
- Xchar default_shell_command[LEN]; /* offers user default choice */
- Xchar killsubj[LEN]; /* contains Subject:'s not to be shown */
- Xchar killfrom[LEN]; /* conatins From:'s not to be shown */
- Xchar page_header[LEN]; /* page header of pgm name and version */
- Xchar default_savedir[PATH_LEN]; /* directory to save articles to */
- Xchar spooldir[PATH_LEN]; /* directory where news is */
- Xchar spooldir_alias[PATH_LEN]; /* alias of spooldir being used */
- Xchar mail_news_user[LEN]; /* mail new news to this user address */
- Xchar mailer[PATH_LEN]; /* mail program */
- Xchar mailbox[PATH_LEN]; /* system mailbox for each user */
- Xchar printer[LEN]; /* printer program specified from tinrc */
- Xchar cmd_line_printer[LEN]; /* printer program specified on cmd line */
- Xchar article[PATH_LEN]; /* ~/.article file */
- Xchar dead_article[PATH_LEN]; /* ~/dead.article file */
- Xchar progname[PATH_LEN]; /* program name */
- Xchar redirect_output[LEN]; /* /dev/null or nothing if -D option */
- X
- Xint xindex_supported = FALSE;
- Xint xuser_supported = FALSE;
- Xint xspooldir_supported = FALSE;
- Xint NOTESLINES; /* set in set_win_size () */
- Xint RIGHT_POS; /* set in set_win_size () */
- Xint MORE_POS; /* set in set_win_size () */
- Xint confirm_action;
- Xint max_subj = 0;
- Xint max_from = 0;
- Xint max_active;
- Xint num_active; /* one past top of active */
- Xint group_top; /* one past top of my_group */
- Xint groupname_len = 0; /* one past top of my_group */
- Xint catchup = FALSE; /* mark all arts read in all subscribed groups */
- Xint update_fork = FALSE; /* update index files by forked tin -u */
- Xint verbose = FALSE; /* update index files only mode */
- Xint start_line_offset; /* used by invoke_editor for line no. */
- Xint inn_nntp_server = FALSE; /* read news via INN NNTP */
- Xint read_news_via_nntp = FALSE; /* read news locally or via NNTP */
- Xint local_index; /* do private indexing? */
- Xint max_art;
- Xint real_gid;
- Xint real_uid;
- Xint real_umask;
- Xint start_editor_offset;
- Xint tin_uid;
- Xint tin_gid;
- Xint top = 0;
- Xint top_base;
- Xint check_any_unread = FALSE;
- Xint notify_new_groups = FALSE;
- Xint start_any_unread = FALSE;
- X
- Xint catchup_read_groups; /* ask if read groups are to be marked read */
- Xint cmd_line; /* batch / interactive mode */
- Xint created_rcdir; /* checks if first time tin is started */
- Xint default_printer; /* set to false if user give a printer with -p switch */
- Xint default_show_author; /* show_author value from 'M' menu in tinrc */
- Xint draw_arrow_mark; /* draw -> or highlighted bar */
- Xint full_page_scroll; /* page half/full screen of articles/groups */
- Xint killed_articles; /* killed / auto-selected hot articles */
- Xint mark_saved_read; /* mark saved article/thread as read */
- Xint num_of_hot_arts;
- Xint num_of_killed_arts;
- Xint num_of_tagged_arts;
- Xint process_id;
- Xint pos_first_unread; /* position cursor at first/last unread article */
- Xint post_proc_type; /* type of post processing to be performed */
- Xint print_header; /* print all of mail header or just Subject: & From lines */
- Xint save_archive_name; /* save thread with name from Archive-name: field */
- Xint mail_news; /* mail all arts to specified user */
- Xint save_news; /* save all arts to savedir structure */
- Xint show_author; /* show Subject & From or only Subject in group menu */
- Xint show_only_unread; /* show only new/unread arts or all arts */
- Xint spooldir_is_active; /* set TRUE if current spooldir is active news feed */
- Xint sort_art_type; /* sort arts[] array by subject,from or date field */
- Xint thread_arts; /* thread/unthread articles for viewing */
- X
- X#ifdef INDEX_DAEMON
- Xint update = TRUE; /* update index files only mode */
- X#else
- Xint update = FALSE; /* update index files only mode */
- X#endif
- X
- Xstruct passwd *myentry;
- X
- X
- X/*
- X * Get users home directory, userid, and a bunch of other stuff!
- X */
- X
- Xvoid init_selfinfo ()
- X{
- X extern char *getlogin ();
- X extern struct passwd *getpwnam ();
- X char nam[LEN];
- X char *p;
- X FILE *fp;
- X struct stat sb;
- X
- X process_id = getpid ();
- X
- X tin_uid = geteuid ();
- X tin_gid = getegid ();
- X real_uid = getuid ();
- X real_gid = getgid ();
- X
- X real_umask = umask (0);
- X umask (real_umask);
- X
- X#ifdef SVR4
- X setlocale (LC_ALL, "");
- X#endif
- X
- X /*
- X * we're setuid, so index in /usr/spool/news even if user root
- X * This is quite essential if non local index files are
- X * to be updated during the night from crontab by root.
- X */
- X if (tin_uid != real_uid) {
- X local_index = FALSE;
- X set_real_uid_gid ();
- X
- X } else { /* index in users home directory ~/.tin/.index */
- X local_index = TRUE;
- X }
- X
- X myentry = (struct passwd *) 0;
- X if ((p = getlogin ()) != (char *) 0) {
- X myentry = getpwnam (p);
- X } else {
- X myentry = getpwuid (getuid ());
- X }
- X
- X strcpy (userid, myentry->pw_name);
- X
- X if ((p = (char *) getenv ("HOME")) != NULL) {
- X strcpy (homedir, p);
- X } else {
- X strcpy (homedir, myentry->pw_dir);
- X }
- X
- X catchup_read_groups = FALSE;
- X confirm_action = TRUE;
- X created_rcdir = FALSE;
- X#ifdef USE_INVERSE_HACK
- X inverse_okay = FALSE;
- X draw_arrow_mark = TRUE;
- X#else
- X draw_arrow_mark = FALSE;
- X#endif
- X default_move_group = 0;
- X#ifdef BSD
- X default_printer = TRUE;
- X#else
- X default_printer = FALSE;
- X#endif
- X default_show_author = SHOW_FROM_NAME;
- X full_page_scroll = TRUE;
- X killed_articles = FALSE;
- X mark_saved_read = TRUE;
- X num_of_hot_arts = 0;
- X num_of_killed_arts = 0;
- X num_of_tagged_arts = 0;
- X post_proc_type = POST_PROC_NONE;
- X pos_first_unread = TRUE;
- X print_header = FALSE;
- X save_archive_name = TRUE;
- X save_news = FALSE;
- X show_only_unread = FALSE;
- X sort_art_type = SORT_BY_DATE_ASCEND;
- X start_editor_offset = TRUE;
- X thread_arts = TRUE;
- X
- X killsubj[0] = '\0';
- X killfrom[0] = '\0';
- X
- X cmd_line_printer[0] = '\0';
- X default_author_search[0] = '\0';
- X default_goto_group[0] = '\0';
- X default_group_search[0] = '\0';
- X default_subject_search[0] = '\0';
- X default_art_search[0] = '\0';
- X default_crosspost_group[0] = '\0';
- X default_mail_address[0] = '\0';
- X default_pipe_command[0] = '\0';
- X default_post_subject[0] = '\0';
- X default_regex_pattern[0] = '\0';
- X default_save_file[0] = '\0';
- X default_shell_command[0] = '\0';
- X nntp_server[0] = '\0';
- X proc_ch_default = 'n';
- X
- X /*
- X * set start spooldir to active newsfeed
- X */
- X strcpy (spooldir_alias, "news");
- X strcpy (spooldir, SPOOLDIR);
- X
- X set_tindir ();
- X
- X sprintf (active_file, "%s/active", LIBDIR);
- X sprintf (article, "%s/.article", homedir);
- X sprintf (dead_article, "%s/dead.article", homedir);
- X sprintf (delgroups, "%s/.delgroups", homedir);
- X sprintf (mailbox, "%s/%s", DEFAULT_MAILBOX, userid);
- X sprintf (default_maildir, "%s/%s", homedir, DEFAULT_MAILDIR);
- X sprintf (default_savedir, "%s/News", homedir);
- X sprintf (default_sigfile, "%s/.Sig", homedir);
- X sprintf (default_signature, "%s/.signature", homedir);
- X sprintf (subscriptions_file, "%s/subscriptions", LIBDIR);
- X
- X strcpy (mailer, get_val ("MAILER", DEFAULT_MAILER));
- X strcpy (printer, DEFAULT_PRINTER);
- X strcpy (spooldir, SPOOLDIR);
- X strcpy (bug_addr, BUG_REPORT_ADDRESS);
- X strcpy (redirect_output, "> /dev/null 2>&1");
- X
- X#ifdef INDEX_DAEMON
- X strcpy (newsrc, active_file); /* so that all groups are indexed */
- X sprintf (indexdir, "%s/.index", spooldir);
- X
- X if (stat (indexdir, &sb) == -1) {
- X mkdir (indexdir, 0777);
- X }
- X#else
- X if (stat (rcdir, &sb) == -1) {
- X created_rcdir = TRUE;
- X mkdir (rcdir, 0755);
- X }
- X if (tin_uid != real_uid) {
- X sprintf (indexdir, "%s/.index", spooldir);
- X
- X set_tin_uid_gid ();
- X if (stat (indexdir, &sb) == -1) {
- X mkdir (indexdir, 0777);
- X }
- X set_real_uid_gid ();
- X } else if (stat (indexdir, &sb) == -1) {
- X mkdir (indexdir, 0755);
- X }
- X if (stat (postfile, &sb) == -1) {
- X if ((fp = fopen (postfile, "w")) != NULL) {
- X fclose (fp);
- X }
- X }
- X if (stat (unthreadfile, &sb) == -1) {
- X if ((fp = fopen (unthreadfile, "w")) != NULL) {
- X fclose (fp);
- X }
- X }
- X
- X read_rcfile ();
- X
- X show_author = default_show_author;
- X
- X#endif /* INDEX_DAEMON */
- X
- X if (stat (active_file, &sb) >= 0)
- X goto got_active;
- X
- X /*
- X * I hate forgetting to define LIBDIR correctly. Guess a couple
- X * of the likely places if it's not where LIBDIR says it is.
- X */
- X
- X strcpy (active_file, "/usr/lib/news/active");
- X if (stat (active_file, &sb) >= 0)
- X goto got_active;
- X
- X strcpy (active_file, "/usr/local/lib/news/active");
- X if (stat (active_file, &sb) >= 0)
- X goto got_active;
- X
- X strcpy (active_file, "/usr/public/lib/news/active");
- X if (stat (active_file, &sb) >= 0)
- X goto got_active;
- X
- X /*
- X * Oh well. Revert to what LIBDIR says it is to produce a useful
- X * error message when read_active_file () fails later.
- X */
- X
- X sprintf (active_file, "%s/active", LIBDIR);
- X
- Xgot_active:
- X
- X /*
- X * check enviroment for ORGANIZATION / NEWSORG
- X */
- X my_org[0] = '\0';
- X#ifdef apollo
- X if ((p = (char *) getenv ("NEWSORG")) != NULL) {
- X#else
- X if ((p = (char *) getenv ("ORGANIZATION")) != NULL) {
- X#endif
- X my_strncpy (my_org, p, sizeof (my_org));
- X goto got_org;
- X }
- X
- X /*
- X * check ~/.tin/organization for organization
- X */
- X sprintf (nam, "%s/organization", rcdir);
- X fp = fopen (nam, "r");
- X
- X /*
- X * check LIBDIR/organization for system wide organization
- X */
- X if (fp == NULL) {
- X sprintf (nam, "%s/organization", LIBDIR);
- X fp = fopen (nam, "r");
- X }
- X
- X if (fp == NULL) {
- X sprintf (nam, "/usr/lib/news/organization");
- X fp = fopen (nam, "r");
- X }
- X
- X if (fp == NULL) {
- X sprintf (nam, "/usr/local/lib/news/organization");
- X fp = fopen (nam, "r");
- X }
- X
- X if (fp == NULL) {
- X sprintf (nam, "/usr/public/lib/news/organization");
- X fp = fopen (nam, "r");
- X }
- X
- X if (fp == NULL) {
- X sprintf (nam, "/etc/organization");
- X fp = fopen (nam, "r");
- X }
- X
- X if (fp != NULL) {
- X if (fgets (my_org, sizeof (my_org), fp) != NULL) {
- X for (p = my_org; *p && *p != '\n'; p++)
- X continue;
- X *p = '\0';
- X }
- X fclose (fp);
- X }
- X
- Xgot_org:;
- X
- X /*
- X * check enviroment for REPLYTO
- X */
- X reply_to[0] = '\0';
- X if ((p = (char *) getenv ("REPLYTO")) != NULL) {
- X my_strncpy (reply_to, p, sizeof (reply_to));
- X goto got_reply;
- X }
- X
- X sprintf (nam, "%s/replyto", rcdir);
- X if ((fp = fopen (nam, "r")) != NULL) {
- X if (fgets (reply_to, sizeof (reply_to), fp) != NULL) {
- X reply_to[strlen (reply_to)-1] = '\0';
- X }
- X fclose (fp);
- X }
- X
- Xgot_reply:;
- X
- X /*
- X * check enviroment for DISTRIBUTION
- X */
- X my_distribution[0] = '\0';
- X if ((p = (char *) getenv ("DISTRIBUTION")) != NULL) {
- X my_strncpy (my_distribution, p, sizeof (my_distribution));
- X }
- X
- X /*
- X * check enviroment for ADD_ADDRESS
- X */
- X add_addr[0] = '\0';
- X if ((p = (char *) getenv ("ADD_ADDRESS")) != NULL) {
- X my_strncpy (add_addr, p, sizeof (add_addr));
- X goto got_add_addr;
- X }
- X
- X sprintf (nam, "%s/add_address", rcdir);
- X if ((fp = fopen (nam, "r")) != NULL) {
- X if (fgets (add_addr, sizeof (add_addr), fp) != NULL) {
- X add_addr[strlen (add_addr)-1] = '\0';
- X }
- X fclose (fp);
- X }
- X
- Xgot_add_addr:;
- X
- X /*
- X * check enviroment for BUG_ADDRESS
- X */
- X if ((p = (char *) getenv ("BUG_ADDRESS")) != NULL) {
- X my_strncpy (bug_addr, p, sizeof (bug_addr));
- X goto got_bug_addr;
- X }
- X
- X sprintf (nam, "%s/bug_address", rcdir);
- X if ((fp = fopen (nam, "r")) != NULL) {
- X if (fgets (bug_addr, sizeof (bug_addr), fp) != NULL) {
- X bug_addr[strlen (bug_addr)-1] = '\0';
- X }
- X fclose (fp);
- X }
- X
- Xgot_bug_addr:;
- X sprintf (txt_help_bug_report, txt_help_bug, bug_addr);
- X}
- X
- X/*
- X * Set up ~/.tin directory & support files depending on where the news
- X * is being read from (ie. active news / CD-ROM spooldir). Note that
- X * any control files which may be specific to a given spooldir (various
- X * CD issues versus live news) should be under the spooldir_alias
- X * subdirectory also.
- X */
- X
- Xvoid set_tindir ()
- X{
- X extern int reread_active_file;
- X struct stat sb;
- X
- X if (strcmp (spooldir_alias, "news") != 0) {
- X sprintf (rcdir, "%s/%s", get_val ("TINDIR", homedir), RCDIR);
- X /*
- X * Create directories
- X */
- X if (stat (rcdir, &sb) == -1) {
- X mkdir (rcdir, 0755);
- X }
- X sprintf (rcdir, "%s/%s", rcdir, spooldir_alias);
- X if (stat (rcdir, &sb) == -1) {
- X created_rcdir = TRUE;
- X mkdir (rcdir, 0755);
- X }
- X /*
- X * Use a separate .newsrc file for every spooldir
- X */
- X sprintf (newsrc, "%s/.newsrc", rcdir);
- X sprintf (newnewsrc, "%s/.newnewsrc", rcdir);
- X
- X spooldir_is_active = FALSE;
- X reread_active_file = FALSE;
- X alarm (0);
- X } else {
- X if (stat (rcdir, &sb) == -1) {
- X mkdir (rcdir, 0755);
- X }
- X sprintf (rcdir, "%s/%s", get_val ("TINDIR", homedir), RCDIR);
- X sprintf (rcfile, "%s/%s", rcdir, RCFILE);
- X sprintf (killfile, "%s/%s", rcdir, KILLFILE);
- X sprintf (postfile, "%s/%s", rcdir, POSTFILE);
- X sprintf (unthreadfile, "%s/%s", rcdir, UNTHREADFILE);
- X sprintf (newsrc, "%s/.newsrc", homedir);
- X sprintf (newnewsrc, "%s/.newnewsrc", homedir);
- X
- X spooldir_is_active = TRUE;
- X reread_active_file = TRUE;
- X }
- X sprintf (indexdir, "%s/%s", rcdir, INDEXDIR);
- X if (stat (indexdir, &sb) == -1) {
- X mkdir (indexdir, 0755);
- X }
- X}
- X
- X
- Xint create_mail_save_dirs ()
- X{
- X int created = FALSE;
- X struct stat sb;
- X
- X if (stat (default_maildir, &sb) == -1) {
- X mkdir (default_maildir, 0755);
- X created = TRUE;
- X }
- X if (stat (default_savedir, &sb) == -1) {
- X mkdir (default_savedir, 0755);
- X created = TRUE;
- X }
- X
- X return (created);
- X}
- END_OF_FILE
- if test 14261 -ne `wc -c <'init.c'`; then
- echo shar: \"'init.c'\" unpacked with wrong size!
- fi
- # end of 'init.c'
- fi
- if test -f 'open.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'open.c'\"
- else
- echo shar: Extracting \"'open.c'\" \(13908 characters\)
- sed "s/^X//" >'open.c' <<'END_OF_FILE'
- X/*
- X * Project : tin - a threaded Netnews reader
- X * Module : open.c
- X * Author : I.Lea & R.Skrenta
- X * Created : 01-04-91
- X * Updated : 12-05-92
- X * Notes : reads news locally (ie. /usr/spool/news) or via NNTP
- X * Copyright : (c) Copyright 1991-92 by Iain Lea & Rich Skrenta
- X * You may freely copy or redistribute this software,
- X * so long as there is no profit made from its use, sale
- X * trade or reproduction. You may not change this copy-
- X * right notice, and it must be included in any copy made
- X */
- X
- X#include "tin.h"
- X#include "nntplib.h"
- X
- X/*
- X * Directory handling code - Hopefully one of these is right for you.
- X */
- X#ifdef BSD
- X# ifdef sinix
- X# include <dir.h>
- X# else
- X# include <sys/dir.h>
- X# endif
- X# define DIR_BUF struct direct
- X# define D_LENGTH d_namlen
- X#endif
- X#ifdef M_XENIX
- X# include <sys/ndir.h>
- X# define DIR_BUF struct direct
- X# define D_LENGTH d_namlen
- X#endif
- X#ifndef DIR_BUF
- X# include <dirent.h>
- X# define DIR_BUF struct dirent
- X# define D_LENGTH d_reclen
- X#endif
- X
- Xint nntp_codeno = 0;
- X
- X#ifdef NNTP_ABLE
- Xint compiled_with_nntp = TRUE; /* used in mail_bug_report() info */
- X#else
- Xint compiled_with_nntp = FALSE;
- X#endif
- X
- X#ifdef NO_POSTING
- Xint can_post = FALSE;
- X#else
- Xint can_post = TRUE;
- X#endif
- X
- Xchar server_name[LEN];
- X
- X
- Xvoid nntp_open ()
- X{
- X#ifdef NNTP_ABLE
- X char *server;
- X int ret;
- X
- X if (read_news_via_nntp) {
- X debug_nntp ("nntp_open", "BEGIN");
- X
- X if (nntp_server[0]) {
- X server = nntp_server;
- X } else {
- X server = getserverbyfile (NNTP_SERVER_FILE);
- X }
- X
- X if (server == (char *) 0) {
- X error_message (txt_cannot_get_nntp_server_name, "");
- X error_message (txt_server_name_in_file_env_var, NNTP_SERVER_FILE);
- X exit(1);
- X }
- X
- X if (update == FALSE) {
- X sprintf (msg, txt_connecting, server);
- X wait_message (msg);
- X }
- X
- X debug_nntp ("nntp_open", server);
- X
- X ret = server_init (server);
- X if (update == FALSE) {
- X fputc ('\n', stdout);
- X }
- X
- X debug_nntp_respcode (ret);
- X
- X switch (ret) {
- X case OK_CANPOST:
- X#ifndef NO_POSTING
- X can_post = TRUE;
- X#endif
- X break;
- X
- X case OK_NOPOST:
- X can_post = FALSE;
- X break;
- X
- X case -1:
- X error_message (txt_failed_to_connect_to_server, server);
- X exit (1);
- X
- X default:
- X sprintf (msg, "%s: %s", progname, nntp_respcode (ret));
- X error_message (msg, "");
- X exit (1);
- X }
- X
- X /*
- X * Find out if NNTP supports my XINDEX & XUSER commands
- X */
- X debug_nntp ("nntp_open", "xindex");
- X put_server ("xindex");
- X if (get_respcode () != ERR_COMMAND) {
- X xindex_supported = TRUE;
- X }
- X debug_nntp ("nntp_open", "xuser");
- X put_server ("xuser");
- X if (get_respcode () != ERR_COMMAND) {
- X xuser_supported = TRUE;
- X }
- X
- X /*
- X * If INN NNTP & XINDEX not supported switch to mode reader
- X */
- X if (! xindex_supported) {
- X debug_nntp ("nntp_open", "mode reader");
- X put_server ("mode reader");
- X if (get_respcode () != ERR_COMMAND) {
- X inn_nntp_server = TRUE;
- X }
- X }
- X }
- X /*
- X * Find out if NNTP supports SPOOLDIR command
- X */
- X get_spooldir ();
- X#endif
- X}
- X
- X
- Xvoid nntp_close ()
- X{
- X#ifdef NNTP_ABLE
- X if (read_news_via_nntp) {
- X debug_nntp ("nntp_close", "END");
- X close_server ();
- X }
- X#endif
- X}
- X
- X
- XFILE *open_active_fp ()
- X{
- X if (read_news_via_nntp) {
- X#ifdef NNTP_ABLE
- X put_server ("list");
- X if (get_respcode () != OK_GROUPS) {
- X debug_nntp ("open_active_fp", "NOT_OK");
- X return (FILE *) 0;
- X }
- X debug_nntp ("open_active_fp", "OK");
- X return nntp_to_fp ();
- X#else
- X return (FILE *) 0;
- X#endif
- X } else {
- X return fopen (active_file, "r");
- X }
- X}
- X
- X
- XFILE *open_subscription_fp ()
- X{
- X if (read_news_via_nntp) {
- X#ifdef NNTP_ABLE
- X put_server ("list subscriptions");
- X if (get_respcode () != OK_GROUPS) {
- X debug_nntp ("open_subscription_fp", "NOT_OK");
- X return (FILE *) 0;
- X }
- X debug_nntp ("open_subscription_fp", "OK");
- X return nntp_to_fp ();
- X#else
- X return (FILE *) 0;
- X#endif
- X } else {
- X return fopen (subscriptions_file, "r");
- X }
- X}
- X
- X
- XFILE *open_index_fp (group_name)
- X char *group_name;
- X{
- X char line[NNTP_STRLEN];
- X extern char index_file[PATH_LEN];
- X
- X find_index_file (group_name);
- X
- X if (read_news_via_nntp && xindex_supported) {
- X sprintf (line, "xindex %s", group_name);
- X debug_nntp ("open_index_fp", line);
- X put_server (line);
- X if (get_respcode () != OK_XINDEX) {
- X debug_nntp ("open_index_fp", "NOT_OK");
- X return (FILE *) 0;
- X }
- X debug_nntp ("open_index_fp", "OK");
- X return nntp_to_fp ();
- X } else {
- X return fopen (index_file, "r");
- X }
- X}
- X
- X
- XFILE *open_art_fp (group_path, art)
- X char *group_path;
- X long art;
- X{
- X char buf[LEN];
- X int respcode;
- X struct stat sb;
- X extern long note_size;
- X
- X if (read_news_via_nntp) {
- X#ifdef NNTP_ABLE
- X sprintf (buf, "article %ld", art);
- X debug_nntp ("open_art_fp", buf);
- X put_server (buf);
- X if ((respcode = get_respcode ()) != OK_ARTICLE) {
- X error_message ("%s", nntp_respcode (respcode));
- X debug_nntp ("open_art_fp", buf);
- X return (FILE *) 0;
- X }
- X
- X debug_nntp ("open_art_fp", "OK");
- X
- X return nntp_to_fp ();
- X#else
- X return (FILE *) 0;
- X#endif
- X } else {
- X sprintf (buf, "%s/%s/%ld", spooldir, group_path, art);
- X
- X if (stat (buf, &sb) < 0) {
- X note_size = 0;
- X } else {
- X note_size = sb.st_size;
- X }
- X return fopen (buf, "r");
- X }
- X}
- X
- X
- XFILE *open_header_fp (group_path, art)
- X char *group_path;
- X long art;
- X{
- X char buf[LEN];
- X
- X if (read_news_via_nntp) {
- X#ifdef NNTP_ABLE
- X sprintf(buf, "head %ld", art);
- X
- X debug_nntp ("open_header_fp", buf);
- X
- X put_server (buf);
- X if (get_respcode () != OK_HEAD) {
- X debug_nntp ("open_header_fp", "NOT_OK_HEAD");
- X return (FILE *) 0;
- X }
- X
- X debug_nntp ("open_header_fp", "OK_HEAD");
- X
- X return nntp_to_fp ();
- X#else
- X return (FILE *) 0;
- X#endif
- X } else {
- X sprintf (buf, "%s/%s/%ld", spooldir, group_path, art);
- X return fopen (buf, "r");
- X }
- X}
- X
- X/*
- X * Longword comparison routine for the qsort()
- X */
- X
- Xint base_comp (p1, p2)
- X char *p1;
- X char *p2;
- X{
- X long *a = (long *) p1;
- X long *b = (long *) p2;
- X
- X if (*a < *b)
- X return -1;
- X if (*a > *b)
- X return 1;
- X return 0;
- X}
- X
- X
- X/*
- X * Read the article numbers existing in a group's spool directory
- X * into base[] and sort them. top_base is one past top.
- X */
- X
- Xvoid setup_base (group, group_path)
- X char *group;
- X char *group_path;
- X{
- X char buf[LEN];
- X#ifdef NNTP_ABLE
- X char line[NNTP_STRLEN];
- X#endif
- X DIR *d;
- X DIR_BUF *e;
- X long art, start, last, dummy, count;
- X
- X top_base = 0;
- X
- X if (read_news_via_nntp) {
- X
- X#ifdef NNTP_ABLE
- X sprintf (buf, "group %s", group);
- X
- X debug_nntp ("setup_base", buf);
- X
- X put_server (buf);
- X
- X if (get_server (line, NNTP_STRLEN) == -1) {
- X error_message (txt_connection_to_server_broken, "");
- X tin_done (1);
- X }
- X
- X if (atoi(line) != OK_GROUP) {
- X debug_nntp ("setup_base", "NOT_OK");
- X return;
- X }
- X
- X debug_nntp ("setup_base", line);
- X
- X sscanf (line,"%ld %ld %ld %ld", &dummy, &count, &start, &last);
- X if (last - count > start) {
- X start = last - count;
- X }
- X
- X while (start <= last) {
- X if (top_base >= max_art) {
- X expand_art();
- X }
- X base[top_base++] = start++;
- X }
- X#else
- X return;
- X#endif
- X } else {
- X sprintf (buf, "%s/%s", spooldir, group_path);
- X
- X if (access (buf, 4) != 0) {
- X return;
- X }
- X
- X d = opendir (buf);
- X if (d != NULL) {
- X while ((e = readdir (d)) != NULL) {
- X art = my_atol (e->d_name, (int) e->D_LENGTH);
- X if (art >= 0) {
- X if (top_base >= max_art)
- X expand_art ();
- X base[top_base++] = art;
- X }
- X }
- X closedir (d);
- X qsort ((char *) base, top_base, sizeof (long), base_comp);
- X }
- X }
- X}
- X
- X/*
- X * get a response code from the server and return it to the caller
- X */
- X
- Xint get_respcode ()
- X{
- X#ifdef NNTP_ABLE
- X char line[NNTP_STRLEN];
- X
- X if (get_server (line, NNTP_STRLEN) == -1) {
- X error_message (txt_connection_to_server_broken, "");
- X tin_done (1);
- X }
- X
- X debug_nntp ("get_respcode", line);
- X
- X return atoi (line);
- X#else
- X return (0);
- X#endif
- X}
- X
- X
- Xint stuff_nntp (fnam)
- X char *fnam;
- X{
- X#ifdef NNTP_ABLE
- X FILE *fp;
- X char line[NNTP_STRLEN];
- X extern char *mktemp ();
- X struct stat sb;
- X extern long note_size;
- X
- X strcpy (fnam, "/tmp/tin_nntpXXXXXX");
- X mktemp (fnam);
- X
- X if ((fp = fopen (fnam, "w")) == (FILE *) 0) {
- X perror_message (txt_stuff_nntp_cannot_open, fnam);
- X return FALSE;
- X }
- X
- X while (1) {
- X if (get_server (line, NNTP_STRLEN) == -1) {
- X error_message (txt_connection_to_server_broken, "");
- X tin_done (1);
- X }
- X
- X debug_nntp ("stuff_nntp", line);
- X
- X if (strcmp (line, ".") == 0)
- X break; /* end of text */
- X strcat (line, "\n");
- X if (line[0] == '.') /* reduce leading .'s */
- X fputs (&line[1], fp);
- X else
- X fputs (line, fp);
- X }
- X fclose (fp);
- X
- X if (stat (fnam, &sb) < 0)
- X note_size = 0;
- X else
- X note_size = sb.st_size;
- X
- X return TRUE;
- X#else
- X return TRUE;
- X#endif
- X}
- X
- X
- XFILE *nntp_to_fp ()
- X{
- X#ifdef NNTP_ABLE
- X char fnam[LEN];
- X FILE *fp = (FILE *) 0;
- X
- X if (! stuff_nntp (fnam)) {
- X debug_nntp ("nntp_to_fp", "! stuff_nntp()");
- X return (FILE *) 0;
- X }
- X
- X if ((fp = fopen (fnam, "r")) == (FILE *) 0) {
- X perror_message (txt_nntp_to_fp_cannot_reopen, fnam);
- X return (FILE *) 0;
- X }
- X
- X unlink (fnam);
- X return fp;
- X#else
- X return (FILE *) 0;
- X#endif
- X}
- X
- X/*
- X * Log user info to local file or NNTP logfile
- X */
- X
- Xvoid log_user ()
- X{
- X char buf[32], *ptr;
- X char line[NNTP_STRLEN];
- X#ifdef LOG_USER
- X FILE *fp;
- X long epoch;
- X#endif
- X extern struct passwd *myentry;
- X
- X my_strncpy (buf, myentry->pw_gecos, sizeof (buf)-1);
- X
- X if (read_news_via_nntp && xuser_supported) {
- X if ((ptr = (char *) strchr(buf, ','))) {
- X *ptr = '\0';
- X }
- X sprintf (line, "xuser %s (%s)", myentry->pw_name, buf);
- X
- X debug_nntp ("log_user", line);
- X put_server (line);
- X } else {
- X#ifdef LOG_USER
- X if ((fp = fopen (LOG_USER_FILE, "a+")) != (FILE *) 0) {
- X time (&epoch);
- X fprintf (fp, "%s%d: %-32s (%-8s) %s", VERSION, PATCHLEVEL,
- X buf, myentry->pw_name, ctime (&epoch));
- X fclose (fp);
- X chmod (LOG_USER_FILE, 0666);
- X }
- X#endif
- X }
- X}
- X
- X/*
- X * NNTP strings for get_respcode()
- X */
- X
- Xchar *nntp_respcode (respcode)
- X int respcode;
- X{
- X#ifdef NNTP_ABLE
- X
- X static char *text;
- X
- X switch (respcode) {
- X case 0:
- X text = "";
- X break;
- X case INF_HELP:
- X text = "100 Help text on way";
- X break;
- X case INF_AUTH:
- X text = "180 Authorization capabilities";
- X break;
- X case INF_DEBUG:
- X text = "199 Debug output";
- X break;
- X case OK_CANPOST:
- X text = "200 Hello; you can post";
- X break;
- X case OK_NOPOST:
- X text = "201 Hello; you can't post";
- X break;
- X case OK_SLAVE:
- X text = "202 Slave status noted";
- X break;
- X case OK_GOODBYE:
- X text = "205 Closing connection";
- X break;
- X case OK_GROUP:
- X text = "211 Group selected";
- X break;
- X case OK_GROUPS:
- X text = "215 Newsgroups follow";
- X break;
- X case OK_XINDEX:
- X text = "218 Group index file follows";
- X break;
- X case OK_ARTICLE:
- X text = "220 Article (head & body) follows";
- X break;
- X case OK_HEAD:
- X text = "221 Head follows";
- X break;
- X case OK_BODY:
- X text = "222 Body follows";
- X break;
- X case OK_NOTEXT:
- X text = "223 No text sent -- stat, next, last";
- X break;
- X case OK_NEWNEWS:
- X text = "230 New articles by message-id follow";
- X break;
- X case OK_NEWGROUPS:
- X text = "231 New newsgroups follow";
- X break;
- X case OK_XFERED:
- X text = "235 Article transferred successfully";
- X break;
- X case OK_POSTED:
- X text = "240 Article posted successfully";
- X break;
- X case OK_AUTHSYS:
- X text = "280 Authorization system ok";
- X break;
- X case OK_AUTH:
- X text = "281 Authorization (user/pass) ok";
- X break;
- X case OK_BIN:
- X text = "282 binary data follows";
- X break;
- X case OK_SPLIST:
- X text = "283 spooldir list follows";
- X break;
- X case OK_SPSWITCH:
- X text = "284 Switching to a different spooldir";
- X break;
- X case OK_SPNOCHANGE:
- X text = "285 Still using same spooldir";
- X break;
- X case OK_SPLDIRCUR:
- X text = "286 Current spooldir";
- X break;
- X case OK_SPLDIRAVL:
- X text = "287 Available spooldir";
- X break;
- X case OK_SPLDIRERR:
- X text = "288 Unavailable spooldir or invalid entry";
- X break;
- X case CONT_XFER:
- X text = "335 Continue to send article";
- X break;
- X case CONT_POST:
- X text = "340 Continue to post article";
- X break;
- X case NEED_AUTHINFO:
- X text = "380 authorization is required";
- X break;
- X case NEED_AUTHDATA:
- X text = "381 <type> authorization data required";
- X break;
- X case ERR_GOODBYE:
- X text = "400 Have to hang up for some reason";
- X break;
- X case ERR_NOGROUP:
- X text = "411 No such newsgroup";
- X break;
- X case ERR_NCING:
- X text = "412 Not currently in newsgroup";
- X break;
- X case ERR_XINDEX:
- X text = "418 No index file for this group";
- X break;
- X case ERR_NOCRNT:
- X text = "420 No current article selected";
- X break;
- X case ERR_NONEXT:
- X text = "421 No next article in this group";
- X break;
- X case ERR_NOPREV:
- X text = "422 No previous article in this group";
- X break;
- X case ERR_NOARTIG:
- X text = "423 No such article in this group";
- X break;
- X case ERR_NOART:
- X text = "430 No such article at all";
- X break;
- X case ERR_GOTIT:
- X text = "435 Already got that article, don't send";
- X break;
- X case ERR_XFERFAIL:
- X text = "436 Transfer failed";
- X break;
- X case ERR_XFERRJCT:
- X text = "437 Article rejected, don't resend";
- X break;
- X case ERR_NOPOST:
- X text = "440 Posting not allowed";
- X break;
- X case ERR_POSTFAIL:
- X text = "441 Posting failed";
- X break;
- X case ERR_NOAUTH:
- X text = "480 authorization required for command";
- X break;
- X case ERR_AUTHSYS:
- X text = "481 Authorization system invalid";
- X break;
- X case ERR_AUTHREJ:
- X text = "482 Authorization data rejected";
- X break;
- X case ERR_INVALIAS:
- X text = "483 Invalid alias on spooldir cmd";
- X break;
- X case ERR_INVNOSPDIR:
- X text = "484 No spooldir file found";
- X break;
- X case ERR_COMMAND:
- X text = "500 Command not recognized";
- X break;
- X case ERR_CMDSYN:
- X text = "501 Command syntax error";
- X break;
- X case ERR_ACCESS:
- X text = "502 Access to server denied";
- X break;
- X case ERR_FAULT:
- X text = "503 Program fault, command not performed";
- X break;
- X case ERR_AUTHBAD:
- X text = "580 Authorization Failed";
- X break;
- X default:
- X text = "Unknown NNTP response code";
- X break;
- X }
- X return (text);
- X#else
- X return ("");
- X#endif
- X}
- END_OF_FILE
- if test 13908 -ne `wc -c <'open.c'`; then
- echo shar: \"'open.c'\" unpacked with wrong size!
- fi
- # end of 'open.c'
- fi
- echo shar: End of archive 11 \(of 14\).
- cp /dev/null ark11isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 14 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-