[comp.sources.unix] v19i071: NN, a Usenet news reader, Part10/15

rsalz@uunet.uu.net (Rich Salz) (06/27/89)

Submitted-by: storm@texas.dk (Kim F. Storm)
Posting-number: Volume 19, Issue 71
Archive-name: nn/part10

#!/bin/sh
# this is part 10 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file nn.1 continued
#
CurArch=10
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
     exit 1; fi
( read Scheck
  if test "$Scheck" != $CurArch
  then echo "Please unpack part $Scheck next!"
       exit 1;
  else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file nn.1"
sed 's/^X//' << 'NO_NEWS_IS_GOOD_NEWS' >> nn.1
Xa total of 32 different macros.
X.LP
XTo define macro number \fIM\fP, the following construction is used
X(the line breaks are mandatory):
X.nf
X	\fBdefine\fP \fIM\fP
X		\fIbody\fP
X	\fBend\fP
X.fi
X.LP
XThe \fIbody\fP consists of a sequence of \fItokens\fP separated by
Xwhite space (blanks or newlines).  However, certain \fItokens\fP 
Xcontinue to the end of the current line.  
X.LP
XThe following \fItokens\fP may occur in the macro \fIbody\fP:
X.TP
X.I Comments
XEmpty lines and text following a # character (preceded by white space)
Xis ignored.
X.TP
X.I Command Names
XAny command name listed in the key mapping section can be included in
Xa macro causing that command to be invoked when the macro is executed.
X.TP
X.I Extended Commands
XAll the extended commands which can be executed through the 
X.B command
Xcommand (normally bound to the : key) can also be executed in a macro.
XAn extended command starts with a colon (:) and continues to the
Xend of the current line.  Example:
X.br
X	:show groups total
X.TP
X.I Key Strokes
XA key stroke (which is normally mapped into a command depending on the
Xcurrent mode) is specified as a key name enclosed in single quotes.
XExamples (A-key, left arrow key, RETURN key):
X.br
X	'A'  'left'  '^M'
X.TP
X.I Strings
XInput to commands prompting for a string, e.g. a file name, can be
Xspecified in a macro as a double quoted string.  Example (save without
Xprompting for a file name):
X.br
X	\fBsave-short\fP "+$G"
X.TP
X.I Conditionals
XConditionals may occur anywhere in a macro; a conditional is evaluated
Xwhen the macro is executed, and if the condition is false \fIthe rest
Xof the current line is ignored\fP.  The following conditionals are available:
X.nf
X	\fB?menu\fP	True in menu mode
X	\fB?show\fP	True in reading mode
X	\fB?folder\fP	True when looking at a folder
X	\fB?group\fP	True when looking at a news group
X	\fB?yes\fP	Query user, true if answer is yes
X	\fB?no\fP	Query user, true if answer is no
X.fi
XExample (stop macro execution if user rejects to continue):
X.br
X	\fBprompt\fP "continue? " \fB?no break\fP
X.sp 0.5v
XIn addition to these conditionals, it is possible to test the current
Xvalue of boolean and integer variables using the following form:
X.br
X	\fB?\fP\fIvariable\fP\fB=\fP\fIvalue\fP
X.br
XThis conditional will be true (1) if the variable is an integer variable
Xwhose current value is the one specified, or (2) if the variable is a
Xboolean variable which is either \fBon\fP or \fBoff\fP.  Examples:
X.nf
X	?layout=3 :set layout 1
X	?monitor=on  break
X	?sort=off :sort age
X.fi
X.TP
X.B break
XTerminate macro execution completely.  This includes nested macros.
XExample (stop if looking at a folder):
X.br
X	\fB?folder\fP \fBbreak\fP
X.TP
X.B return
XTerminate execution of current macro.  If the current macro is called
Xfrom another macro, execution of that macro continues immediately.
X.TP
X.B input
XQuery the user for a key stroke or a string, for example a file name.
XExample (prompt the user for a file name in the usual way):
X.br
X	\fBsave-short\fP \fBinput\fP
X.TP
X.B yes
XConfirm unconditionally \fIif\fP a command requires confirmation.  It
Xis ignored if the command does not require confirmation.  Example
X(confirm creation of new files):
X.br
X	\fBsave-short\fP "+$G" \fByes\fP
X.TP
X.B no
XTerminate execution of current macro \fIif\fP a command requires
Xconfirmation; otherwise ignore it.  If neither \fByes\fP nor \fBno\fP
Xis specified when a command requires confirmation, the user must
Xanswer the question as usual \- if the user confirms the action
Xexecution continues normally; otherwise the execution of the current
Xmacro is terminated.  Example (do not create new files):
X.br
X	\fBsave-short\fP "+$L/misc" \fBno\fP
X.TP
X\fBprompt\fP \fIstring\fP
XPrint the \fIstring\fP in the prompt line (highlighted).  The string
Xmust be enclosed in double quotes.  Example:
X.br
X	\fBprompt\fP "Enter recipient name"
X.TP
X\fBecho\fP \fIstring\fP
XDisplay the \fIstring\fP in the prompt line for a short period.  Example:
X.br
X	?show \fBecho\fP "Cannot be used in reading mode" break
X.TP
X\fBmacro\fP \fIM\fP
XInvoke macro number \fIM\fP.  The maximum macro nesting level is five
X(also catches macro loops).
X.LP
XI use the following macro to quickly save all the selected files in a
Xfile whose name is entered as usual.  It also works in reading mode
X(saving just the current article).
X.nf
X	\fBdefine\fP 1
X		:unset save-report
X		save-short input yes
X		?menu '+'
X		:set save-report
X	\fBend\fP
X.fi
X.SH THE INIT FILES
XThe
X.I init
Xfiles are used to customize \fInn\fP's behaviour to your personal taste.
X\fINn\fP uses two init files \- a system-wide init file located in the
Xlibrary directory, and a private init file located in the user's
X\&\fI.nn\fP directory.  The private init file is read after the global
Xinit file to allow the user to change the default setup.
X.LP
XThe init file may contain the following types of commands (and data):
X.TP
X.B Comments
XEmpty lines and lines with a # character as the first non-blank
Xcharacter are ignored.
X.TP
X.B Variable settings
XYou can 
X.B set
X(or 
X.BR unset )
Xall the variables described earlier to change
Xnn's behaviour permanently.  The 
X.B set
Xand
X.B unset
Xcommands you can use in the init file have exactly the same format as
Xthe 
X.B :set
Xand
X.B :unset
Xcommands described earlier (except that the : prefix is omitted.)
X.TP
X.B Key mappings
XYou can use all the versions of the
X.B map
Xcommand in the init file.
X.TP
X.B Macro Definitions
XYou can define sequences of commands and key strokes using the
X\fBdefine\fP...\fBend\fP construction,
Xwhich can then be
Xbound to single keys with the
X.B map
Xcommand.
X.TP
X.B Load terminal specific files
XYou can load a terminal specific file using the
X.sp 0.5v
X	\fBload\fP \fIfile\fP
X.sp 0.5v
XThe character
X.B @
Xin the 
X.I file
Xwill be replaced by the terminal type defined in the TERM environment
Xvariable.  \fInn\fP silently ingores the
X.B load
Xcommand if the file does not exist (so you don't have to have a
Xspecific init file for terminals which does not require remapping).
XIf the file is not specified by an absolute pathname, it must reside
Xin your ~/.nn directory.  Examples:
X.nf
X	# load local customizations
X	load /usr/lib/nninit
X	# load personal terminal specific customizations
X	load init.@
X.fi
X.TP
X.B Change working directory of nn
XYou can use the
X.B cd
Xcommand to change the working directory whenever you enter \fInn\fP.
XExample:
X.nf
X	# Use folder directory as working directory inside \fInn\fP
X	cd ~/News
X.fi
X.TP
X.B The news group presentation sequence
XThe 
X.I last
Xpart of the init file may specify the sequence in which you want the
Xnews groups to be presented.  This part starts with the command
X.B sequence
Xand continues to the end of the init file.
X.LP
XBoth init files may contain a presentation sequence.  In this case,
Xthe global sequence is \fIappended\fP to the private sequence.
X.SH GROUP PRESENTATION SEQUENCE
XNews groups are normally presented in the sequence defined in the
Xsystem-wide 
X.B init
Xfile in \fInn\fP's library directory.
X.LP
XYou can personalize the presentation sequence
Xby specifying an alternative sequence in the private
X.I init
Xfile.
XThe sequence in the private init file is used
X.I before
Xthe global presentation sequence, and need only
Xdescribe the deviations from the default presentation sequence.
X.LP
XThe presentation sequence must start with the word
X.br
X	\fBsequence\fP
X.br
Xfollowed by a list of the news group names in the order you want them
Xto be presented.  
XThe group names must be separated by white space.
XThe sequence list must be the \fIlast\fP part of the
Xinit file (the parsing of commands from the init file stops when the
Xword \fBsequence\fP is encountered).
X.LP
XYou may use a full group name like "comp.unix.questions", or just the
Xname of a main group or subgroup, e.g. "comp" or "comp.unix".
XHowever, if "comp" precedes "comp.unix.questions" in the list, this
Xsubgroup will be placed in the normal alphabetic sequence during the
Xcollection of all the "comp" groups.
X.LP
XGroups which are not explicitly mentioned in any of the sequence files
Xwill be placed after the mentioned groups, unless `!!' is used and it
Xhas not been disabled (as described below).
X.LP
XEach group name may be followed by a file or folder name (must start
Xwith either of / . ~ or +) which will specify the default save file
Xfor that group (and its subgroups).  A single "+" following the group
Xname is an abbreviation for the last save file name used.
X.LP
XWhen an article is saved, the default save name will be used as the
Xinitial contents of the file name prompt for further editing.  It
Xtherefore does not need to be be a complete file name (unless you use
Xthe quick save mode).
X.LP
XThe following meta notation can be used in a sequence file:
X.TP
Xgroup.name
XAppend the group (and its subgroups) to the presentation sequence list.
X.TP
X\&! group.name
XCompletely ignore the group (and its subgroups)
Xunless they are already in the presentation sequence (i.e. has been
Xexplicitly mentioned earlier in the sequence).
X.TP
X\&!!
XStop building the presentation sequence.  This eliminates all groups
Xthat are not already in the presentation sequence.
X.TP
X\fBNEW\fP
XThis is a pseudo group name which matches all new groups; you could place
Xthis symbol early in your presentation sequence to see new groups `out
Xof sequence' (to attract your attention to them).
X.TP
X\&< group.name
XPlace the group (and its subgroups) at the beginning of the
Xpresentation sequence.
X.TP
X\&> group.name
XPlace the group (and its subgroups) after all other groups that are
Xand will be entered into the presentation sequence.
X.TP
X\&@
XDisable the `!!' command.  This can be included in the personal
Xpresentation sequence if the global 
X.B sequence
Xfile contains a !! entry (see example 1 below).
X.LP
X.sp 0.5v
X.B Example 1:
XIn a company where ordinary users only should read the local
Xnews groups, and ignore the rest (including new news groups which are
Xotherwise always subscribed to initially), can use the following
Xglobal presentation sequence:
X.sp 0.5v
X.nf
X	general
X	follow
X	!local.test
X	local
X	!!
X.fi
X.sp 0.5v
XThe "expert" users in the company must put the 
X.B @
Xcommand somewhere
Xin their private sequence to avoid losing news groups which they have
Xnot explicitly mentioned in their init file.
X.sp
X.B Example 2:
XThis is the global sequence for systems with
Xheavy news addicts who setup their own sequences anyway.
X.nf
X.sp 0.5v
X	# all must read the general news first
X	< general
X.sp 0.5v
X	# test is test, and junk is junk, 
X	# so it is placed at the very end
X	> test 
X	> .test	
X	> junk
X.sp 0.5v
X	# this is the standard sequence which everybody may
X	# change to their own liking
X	local	# our local groups
X	dk	# the Danish groups
X	eunet.general # to present it before eunet.followup
X	eunet	# the other European groups 
X	comp	# the serious groups
X	news	# news on news
X	sci	# other serious groups
X	rec	# not really that important (don't quote me)
X	misc	# well, it must be somewhere
X.sp 0.5v
X	# the groups that are not listed above goes here
X.sp 0.5v
X.fi
XNotice the use of comments in the sequence where they are allowed at
Xthe end of non-empty lines as well.
X.sp
X.B Example 3:
XMy own presentation sequence (in the init file) simply
Xlists my favourite groups and the corresponding default save files:
X.nf
X.sp 0.5v
X   \fBsequence\fP
X	rec.music.synth +synth/
X	comp.emacs +emacs/misc
X	gnu.emacs +
X	NEW  # show new groups here
X	comp.risks +risks
X	news.admin
X	eunet.sources +src/unix/
X	comp.sources +src/$L/
X	comp.sys.ti +ti/$L
X.sp 0.5v
X.fi
XThe presentation sequence is not used when \fInn\fP is called with one or
Xmore news group names on the command line; it is thus possible to read
Xignored groups (on explicit request) wihtout changing the init file.
X(Of course, you can also use the
X.B G
Xcommand to read ignored groups).
X.SH THE NN RECORD FILE
XThe directory ~/.nn contains all the files that are related to
X\fInn\fP.  Besides the init file, most of these files are maintained
Xautomatically by \fInn\fP, and the most 
Ximportant is the
X.B rc
Xfile which contains a record of which articles have been read in which
Xgroups, and which groups have been unsubscribed to.  (This is the
Xequivalent of the .newsrc file used by other news reader programs; the
X\&.newsrc file is not supported in the present release of \fInn\fP.)
X.LP
XNormally, you will not need to change this file, because you can use
Xthe \fBU\fP command to unsubscribe and resubscribe to news groups, and
Xthe
X.IR nngoback (1)
Xprogram is available to `turn back' the rc file one or more days.
X.LP
XEach line in the rc file has the following format:
X.br
X.sp 0.5v
X	+ 000000 news.group.name
X.sp 0.5v
X.br
XThe "+" indicates that you subscribe to the news group.  A "!" instead
Xof the "+" indicates that you have unsubscribed to the group.  The
Xsix digits are the number of the last article you have read in the
Xgroup, and the rest of the line is the name of the news group.
X.LP
XThe order of the lines in the rc file is not important, and
Xentries for new newsgroups are automatically appended to the file
X(with subscription, unless you immediately unsubscribe to them).
X.SH ENVIRONMENT
XThe following environment variables are used by \fInn\fP:
X.LP
X.BR EDITOR .
XThe editor invoked when editing replies, follow-ups, and composing
Xmail.  \fInn\fP knows about the following editors:
X.BR vi (1),
X.BR ded (1),
X.B GNU
X.BR emacs (1),
Xand
X.B Micro
X.BR emacs (1),
Xand will try to position the cursor on the first line following the
Xheader, i.e. after the blank line which must not be deleted!  If an
Xarticle has been included, the cursor is placed on the first line of
Xthe included text (to allow you to delete sections easily).
X.LP
X.BR SHELL .
XThis is the shell which is spawned if the system cannot suspend
X\fInn\fP, and it will be used to execute the shell escapes.
X.LP
X.BR TERM .
XThe terminal type.
X.SH AUTHOR
XKim F. Storm, Texas Instruments A/S, Denmark
X.br
XE-mail: storm@texas.dk  (but see the addresses below)
X.LP
XThe NNTP support was designed and implemented by
XRen\o'\(aae' Seindal, Institute of Datalogy, University of Copenhagen, Denmark,
Xwho also ported \fInn\fP to BSD 4.3 and SunOS 4.0.
X.SH FILES
X.DT
X.nr tW \w'~/.nn/KILL.COMP'
X.nr tX \w'/usr/lib/terminfo/*'
X.if \n(tWu>\n(tXu .nr tX \n(tWu
X.ta \n(tWu+3m
X~/.nn/rc	The record of read articles.
X.br
X~/.nn/rc.bak	Copy of rc file saved on entry to \fInn\fP.
X.br
X~/.nn/init	Personal configuration and presentation sequence.
X.br
X~/.nn/kill	The automatic kills and selections.
X.br
X~/.nn/KILL.COMP	The compiled kill file.
X.br
X$lib/init	System-wide setup and presentation sequence.
X.br
X$lib/aux	The response edit and send script.
X.br
X$lib/routes	Mapping rules for mail addresses (on non-domain systems).
X.br
X$db/*	The news data base.
X.br
X/etc/termcap	Terminal data base [BSD].
X.br
X/usr/lib/terminfo/*	Terminal data base [SysV].
X.br
X/usr/lib/nntp-server	Name of remote nntp server.
X.sp 0.5v
X.DT
XThe name $lib and $db are the directories used for the auxiliary files
Xand the news data base respectively.  Their name and location is
Xdefined at compile time.  Common choices are /usr/local/lib/nn or
X/usr/lib/news/nn for $lib and /usr/spool/nn or /usr/spool/news/.nn for
X$db.
X.SH SEE ALSO
XOther netnews documentation.
X.br
Xnncheck(1), nngoback(1), nngrep(1), nntidy(1)
X.br
Xnnadmin(1M), nnquery(1M), nnusage(1M), nnmaster(8)
X.SH MAILING LISTS
XBugs and fixes, suggestions, ideas, critique, etc. can be sent to
Xthe following address:
X.br
X	nn-bugs@dkuug.dk
X.LP
XWe have created a moderated mailing list for news about \fInn\fP.  The
Xmoderator is Ren\o'\(aae' Seindal, seindal@diku.dk.  Send
Xyour contributions to the address:
X.br
X	nn-info@dkuug.dk
X.LP
XYou are welcome to join the nn-info mailing list, just send your
Xname and E-mail address to the following address:
X.br
X	nn-info-request@dkuug.dk
X.LP
XIf these addresses fail, you may want to know that dkuug.dk is the
Xdanish EUnet backbone, so if you can reach uunet or mcvax, you can
Xalso reach us (e.g. using ...!uunet!dkuug.dk!nn-info).
NO_NEWS_IS_GOOD_NEWS
echo "File nn.1 is complete"
chmod 0644 nn.1 || echo "restore of nn.1 fails"
set `wc -c nn.1`;Sum=$1
if test "$Sum" != "93389"
then echo original size 93389, current size $Sum;fi
echo "x - extracting nn.c (Text)"
sed 's/^X//' << 'NO_NEWS_IS_GOOD_NEWS' > nn.c &&
X/*
X *	The User Interface main program
X */
X
X#include "config.h"
X#include "menu.h"
X#include "term.h"
X#include "keymap.h"
X#include "options.h"
X
Xstatic int
X    dont_read_init_file = 0,
X    prompt_for_group = 0;
X
Xstatic char
X    *match_subject = NULL;
X
Xexport int
X    article_limit = -1,
X    also_read_articles = 0,
X    do_kill_handling = 1,
X    group_name_args = 0,
X    merged_menu = 0,
X    silent = 0,
X    Debug = 0;
X
Ximport int 
X    keep_rc_backup, no_update,		 			/* rc.c */
X    preview_window, fmt_linenum, fmt_rptsubj,			/* menu.c */
X    show_article_date, first_page_lines,			/* more.c */
X    dont_split_digests, dont_sort_articles,			/* group.c */
X    dont_sort_folders,						/* folder.c */
X    show_current_time, conf_dont_sleep;				/* term.c */
X
XOption_Description(nn_options) {
X    'a', Int_Option(article_limit),
X    'B', Bool_Option(keep_rc_backup),
X    'd', Bool_Option(dont_split_digests),
X    'f', Bool_Option(dont_sort_folders),
X    'g', Bool_Option(prompt_for_group),
X    'I', Bool_Option(dont_read_init_file),
X    'k', Bool_Option(do_kill_handling),
X    'l', Int_Option(first_page_lines),
X    'L', Int_Option_Optional(fmt_linenum, 3),
X    'm', Bool_Option(merged_menu),
X    'N', Bool_Option(no_update),
X    'q', Bool_Option(dont_sort_articles),
X    'Q', Bool_Option(silent),
X    's', String_Option(match_subject),
X    'S', Bool_Option(fmt_rptsubj),
X    'T', Bool_Option(show_current_time),
X    'w', Int_Option_Optional(preview_window, 5),
X    'W', Bool_Option(conf_dont_sleep),
X    'x', Int_Option_Optional(also_read_articles, -1),
X    'Z', Int_Option(Debug),
X    '\0',
X};
X
X
Xstatic int
X    report_number_of_articles = 0,
X    report_group_names = 0;
Xstatic char
X    *check_message_format = NULL;
X
XOption_Description(check_options) {
X    'Q', Bool_Option(silent),
X    'r', Bool_Option(report_number_of_articles),
X    'f', String_Option(check_message_format),
X    't', Bool_Option(report_group_names),
X    '\0',
X};
X
X
X/* program name == argv[0] without path */
X
Xchar *pname;
X
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X    extern long unread_articles;
X    extern char *program_name();
X    int emacs_slave_mode = 0, check_news = 0, enter_admin_mode = 0;
X
X    pname = program_name(argv);
X    if (strcmp(pname, "nnadmin") == 0)
X	enter_admin_mode = 1;
X    else
X    if (strcmp(pname, "nnemacs") == 0)
X	emacs_slave_mode = 1;
X    else
X    if (strcmp(pname, "nncheck") == 0) {
X	keep_rc_backup = 0;    
X	check_news = 1;
X    }
X    
X    if (!check_news && !emacs_slave_mode && (!enter_admin_mode || argc == 1))
X	if (!isatty(0)) {
X	    fprintf(stderr, "Input is not a tty\n");
X	    nn_exit(1);
X	}
X    
X    init_global(0);
X    init_key_map();
X    init_execute();
X    init_macro();
X    
X#ifdef NNTP
X    nntp_check();
X#endif
X    if (enter_admin_mode) {
X	if (argc == 1) {
X	    init_term();
X	    visit_init_file();
X	}
X	open_master(OPEN_READ);
X	visit_active_file();
X	admin_mode(argv[1]);
X	nn_exit(0);
X    }
X
X    if (check_news)
X	parse_options(argc, argv, (char *)NULL, check_options, "");	
X    else
X    if (!emacs_slave_mode) {
X	init_term();
X
X	if (argc < 2 || strncmp(argv[1], "-I", 2))
X	    visit_init_file();
X
X	group_name_args =
X	    parse_options(argc, argv, (char *)NULL,
X			  nn_options, " [group | [+]folder]...");
X
X	if (!silent)
X	    print_version("Release %R.%V.%P #%U,  Kim F. Storm, 1989\n\n");
X    }
X
X    open_master(OPEN_READ);
X    
X    if (also_read_articles) {
X	if (article_limit < 0) 
X	    article_limit = also_read_articles;
X	do_kill_handling = 0;
X	no_update++;
X    }
X    
X    if (match_subject) {
X	if (*match_subject != '/') init_quick_match(match_subject);
X	no_update++;
X	do_kill_handling = 0;
X    }
X
X    if (merged_menu) {
X	no_update++;
X    }
X    
X    if (!no_update && group_name_args > 0)
X	no_update = only_folder_args(argv + 1);
X    
X    visit_rc_file();
X
X    count_unread_articles(report_group_names);
X
X    if (emacs_slave_mode)
X	prt_unread("%U %G\n");
X    
X    if (check_news) {
X	if (check_message_format) {
X	    if (unread_articles || !silent)
X		prt_unread(check_message_format);
X	} else    
X	if (report_number_of_articles) {
X	    prt_unread("%U");
X	    nn_exit(0);
X	} else
X	if (!silent) {
X	    if (unread_articles || report_number_of_articles)
X		prt_unread("There %i %u in %g\n");
X	    else 
X		prt_unread((char *)NULL);
X	}
X
X	nn_exit( unread_articles ? 0 : 99 );
X    }
X	
X    if (unread_articles == 0 &&
X	group_name_args == 0 &&
X	!also_read_articles &&
X	!prompt_for_group) {
X	if (!silent) prt_unread((char *)NULL);
X	nn_exit(0);
X    }
X
X    if (do_kill_handling)
X	do_kill_handling = init_kill();
X    
X    if (group_name_args > 0)
X	named_group_sequence(argv + 1);
X    else
X	normal_group_sequence();
X
X    if (emacs_slave_mode) {
X	emacs_mode();
X	goto out;
X    }
X
X    if (prompt_for_group) {
X	raw();
X	current_group = NULL;
X	prompt_line = Lines - 1;
X	goto_group(K_GOTO_GROUP, (article_header *)NULL);
X	no_raw();
X	clrdisp();
X	goto out;
X    }
X    if (!no_update && article_limit == 0) {
X	char answer[50];
X
X	prt_unread("\nCatch-up on %u ? (all) (i)nteractive ");
X	fl;
X	if (gets(answer)) {
X	    if (strncmp(answer, "all", 3) == 0) {
X		printf("\nUPDATING rc FILE....");
X		fl;
X		read_news(-1);
X		printf("DONE\n");
X		goto out;
X	    }
X	    if (*answer == 'i') {
X		read_news(1);
X		goto out;
X	    }
X	}
X	printf("\nNO UPDATE\n");
X	goto out;
X    }
X
X    if (merged_menu) {
X	merge_and_read(match_subject, do_kill_handling);
X	clrdisp();
X    } else
X    if (read_news(0)) {
X	clrdisp();
X    } else {
X	gotoxy(0,Lines-1);
X	if (group_name_args == 0)
X	    printf("No News\n");
X	else
X	    printf("\r\n");
X    }
X    
X#ifdef STATISTICS    
X    log_usage();
X#endif    
X
X    if (!also_read_articles && unread_articles > 0 && !silent && group_name_args == 0)
X	prt_unread("There %i still %u in %g\n\n\r");
X        
X out:
X    
X    nn_exit(0);
X    /*NOTREACHED*/
X}
X
X/* 
X * nn_exit() --- called whenever a program exits.
X */
X 
Xnn_exit(n)
X{
X    static int loop = 0;
X    
X    if (loop) exit(n);
X    loop++;
X    
X#ifdef NNTP
X    nntp_cleanup();
X#endif /* NNTP */
X    close_master();
X    close_rc();
X    
X    exit(n);
X}
X
Xexport group_header *jump_to_group = NULL;
X
Xstatic read_news(mode)
X{
X    register group_header *cur, *prev, *tmp;
X    int menu_cmd;
X    int must_clear = 0, did_jump = 0;
X    extern int menu();
X
X    prev = group_sequence;
X
X    cur = group_sequence;
X	
X    while (cur != NULL || did_jump) {
X	if (s_hangup) break;
X	
X	if (cur == NULL) {
X	    did_jump = 0;
X	    cur = group_sequence;
X	    continue;
X	}
X	
X	if (!also_read_articles)
X	    if (cur->last_article >= cur->last_l_article) {
X		cur = cur->next_group;
X		continue;
X	    }
X	
X	if (mode) {
X	    if (mode > 0) {
X		char answer[50];
X		printf("Update %s (%ld)? ", 
X		       cur->group_name,
X		       (long)(cur->last_l_article - cur->last_article));
X		fl;
X		if (gets(answer) == NULL || s_keyboard) {
X		    putchar(NL);
X		    printf("Update rest? ");
X		    fl;
X		    if (gets(answer) == NULL || *answer != 'y')
X			return 0;
X		    mode = -1;
X		    *answer = 'y';
X		}
X		if (*answer == '?') {
X		    printf("Enter (y)es to update current group\n");
X		    continue; /* redo current group */
X		}
X		if (*answer != 'y') {
X		    cur = cur->next_group;
X		    continue;
X		}
X	    }
X	    update_rc(cur);
X	    continue;
X	}
X	
X	free_memory();
X	
X	if (cur->group_flag & G_FOLDER) {
X	    menu_cmd = folder_menu(cur->group_name);
X	    if (menu_cmd == ME_NO_REDRAW) {
X		menu_cmd = ME_NO_ARTICLES;
X		cur->last_l_article = 0;
X	    }
X	} else
X	    menu_cmd = group_menu(cur, -1, 
X				  match_subject, do_kill_handling, menu);
X
X	if (menu_cmd != ME_NO_ARTICLES)
X	    must_clear++;
X	
X	switch (menu_cmd) {
X	    
X	 case ME_PREV:
X	    tmp = cur;
X	    cur = prev;
X	    prev = tmp;
X	    cur->last_article = cur->first_article;
X	    continue;
X	    
X	 case ME_READ:
X	    cur->last_article = cur->last_l_article;
X	    /* fall thru */
X	    
X	 case ME_NEXT:
X	    prev = cur;
X	    /* fall thru */
X	    
X	 case ME_NO_ARTICLES:
X	    cur = cur->next_group;
X	    continue;
X	    
X	 case ME_QUIT:
X	    if (jump_to_group) {
X		prev = cur;
X		cur = jump_to_group;
X		jump_to_group = NULL;
X		did_jump = 1;
X		continue;
X	    }
X	    
X	    return must_clear;
X	}	
X    }
X    return must_clear;
X}
X
X
X
Xexport char *mail_box = NULL;
X
Xunread_mail(t)
Xtime_t t;
X{
X    struct stat st;
X    static time_t next = 0;
X    static int any = 0;
X    
X    if (next > t) return any;
X    
X    next = t + 60;
X    any = 0;
X    
X    if (mail_box == NULL ||
X	stat(mail_box, &st) != 0 ||
X	st.st_size == 0 || 
X	st.st_mtime < st.st_atime) return 0;
X    
X    any = 1;
X    
X    return 1;
X}
X
X#ifdef STATISTICS
Xstatic time_t usage_time = 0;
X
Xtick_usage(end_t, start_t)
Xtime_t *end_t, *start_t;
X{
X    time_t temp_t;
X    static time_t last_t = 0;
X    
X    if (end_t == NULL) end_t = &temp_t;
X    
X    time(end_t);
X    
X    if (start_t == 0) {
X	/* 
X	 * We ignore delays > 2 minutes because the user has probably
X	 * just left the terminal inside nn and done something else
X	 */
X	if ((last_t + 120) > *end_t) 
X	    usage_time += *end_t - last_t;
X    } else 
X	usage_time += (*end_t - *start_t)/60;
X    
X    last_t = *end_t;
X}
X
Xlog_usage()
X{
X    usage_time /= 60;
X
X    if (usage_time < STATISTICS) return; /* don't log short sessions */
X    
X    log_entry('U', "USAGE %d.%02d", usage_time/60, usage_time%60);
X}
X#endif
X
X#ifdef MALLOC_TEST
Xstatic int in_calloc = 0;
X
Xchar *malloc(n)
Xunsigned int n;
X{
X    char *p, *sbrk();
X    
X    if (p = sbrk(n + 3))
X	while ( ((int)p) & 3) p++;
X    
X    if (!in_calloc)
X	printf("MALLOC(%u) => %lx\n", n, (long)p);
X    
X    return p;
X}
X
Xchar *calloc(n, s)
Xunsigned n, s;
X{
X    char *p;
X    
X    in_calloc = 1;
X    p = malloc(n*s);
X    in_calloc = 0;
X    
X    printf("CALLOC(%u,%u) => %lx\n", n, s, (long)p);
X
X    return p;
X}
X
Xfree(p)
Xchar *p;
X{
X    printf("FREE(%lx)\n", p);
X}
X
Xchar *realloc()
X{
X    printf("REALLOC\n");
X}
X
X#endif /* MALLOC_TEST */
X
X/* this will go into emacs_mode.c when it is completed someday */
X
Xemacs_mode()
X{
X    printf("EMACS MODE IS NOT SUPPORTED YET.\n");
X}
NO_NEWS_IS_GOOD_NEWS
chmod 0644 nn.c || echo "restore of nn.c fails"
set `wc -c nn.c`;Sum=$1
if test "$Sum" != "9858"
then echo original size 9858, current size $Sum;fi
echo "x - extracting nnadmin.1m (Text)"
sed 's/^X//' << 'NO_NEWS_IS_GOOD_NEWS' > nnadmin.1m &&
X.TH NNADMIN 1M "Release 6.3"
X.\" (c) Copyright 1988, Kim F. Storm
X.UC 4
X.SH NAME
Xnnadmin \- nn database administration
X.SH SYNOPSIS
X.B nnadmin
X[ 
X.I commands
X]
X.SH DESCRIPTION
X.I nnadmin
Xis a control program for the \fInnmaster\fP(1M) daemon which is
Xresponsible for building and maintaining the database used by the
X\fInn\fP(1) news reader.
X.LP
X\fInnadmin\fP allows you to display extracts from the log file,
Xdisplay the "raw" contents of the database, make consistency checks on
Xthe database, instruct the running \fInnmaster\fP to expire one or
Xmore groups, alter the options of the running \fInnmaster\fP, and much
Xmore.
X.LP
X\fInnadmin\fP runs in two modes: interactive and non-interactive.
X.LP
XIn interactive mode, simple one line menus are used to show the
Xavailable operations which are then selected by typing the letter
Xassociated with the command (normally the first letter in the command
Xname).
X.LP
XIn non-interactive mode, the
X.I commands
Xargument will be used as a series of key-strokes which are interpreted
Xexactly as if they were typed in from the keyboard in interactive
Xmode.  For example, to stop the \fInnmaster\fP, the following
Xinvokation of nnadmin can be used:
X.br
X	\fInnadmin\fP MK
X.br
Xwhich will select the (M)aster submenu from the main menu, and then
Xthe (K)ill entry from the submenu.
X.LP
XIn non-interactive mode, the menus are not displayed and the commands
Xare not echoed!  \fInnadmin\fP will exit when there are no more
Xkey-strokes to be read from the 
X.I commands
Xargument.  It is not possible to specify a group name in the 
X.I commands
Xargument, so the functionalities of \fInnadmin\fP that relates to
Xspecific groups are only available in interactive mode.
X.LP
XYou can also invoke an interactive \fInnadmin\fP using the 
X.B :admin
Xcommand in \fInn\fP.  The only operation which is not available is the
XValidation command, because it whould disturb the normal operation of
X\fInn\fP.
X.SH MAIN MENU
XFrom the main menu (identified by the 
X.B ADMIN
Xprompt) you can select the following operations:
X.TP
X.B C)onf
X.br
XShow current configuration parameters such as directories, files,
Xprograms, network usage, etc.
X.TP
X.B E)xpire
X.br
XSend a request to the \fInnmaster\fP daemon to run expire on all
Xgroups in the database.  This is equal to the Init operation when
Xthe \fInnmaster\fP is started with the \-E option.
X.TP
X.B G)roups
X.br
XEnter the GROUP submenu.
X.TP
X.B I)nit
X.br
XSend a request to the \fInnmaster\fP daemon to recollect all
Xgroups in the database.  
X.TP
X.B L)ogs
X.br
XEnter the LOG submenu.
X.TP
X.B M)aster
X.br
XEnter the MASTER submenu.
X.TP
X.B Q)uit
X.br
XQuit \fInnadmin\fP.
X.TP
X.B S)tat
X.br
XPrint general statistics about the database.  See the section on
XDatabase Statistics below.
X.TP
X.B U)pdate
X.br
XUpdate the incore copy of the database master index.
X.TP
X.B V)alidate
X.br
XMake a thorough consistency check on the database.  If inconsistencies
Xare found in a group, you will be asked whether a request should be
Xsent to the \fInnmaster\fP daemon to recollect the group (in
Xnon-interactive mode, requests will be sent automatically for all
Xcorrupted groups).
X.TP
X.B W)akeup
X.br
XSend a wakeup signal to the \fInnmaster\fP daemon to have it receive
Xmessages sent to it, perform the required actions, and then collect
Xarticles as necessary.
X.TP
X.B Z (silent validation)
X.br
XThis operation is identical to the Validate operation, expect that no
Xoutput is produced during the consistency check; this operation is
Xused by the \fInnmaster\fP to execute the \-C option.
X.SH THE MASTER MENU
XThe master menu (identified by the
X.B MASTER
Xprompt) provides access to overall database information, and to send
Xcontrol messages to the \fInnmaster\fP daemon.
X.TP
X.B A)ll
X.br
XPrint the master index entry for all groups in the database.
X.TP
X.B E)mpty
X.br
XPrint the master index entry for the empty groups in the database.
X.TP
X.B F)iles
X.br
XPrint a listing (using 
X.IR ls (1))
Xof all the data and index files in the database.
X.TP
X.B G)roup
X.br
XPrint the master index entry for a single group identified by its
Xinternal group number.
X.TP
X.B K)ill 
X.br
XStop the \fInnmaster\fP when it has finished its current task.
X.TP
X.B N)on-empty
X.br
XPrint the master index entry for the non-empty groups in the database.
X.TP
X.B O)ptions
X.br
XChange the runtime options of the running \fInnmaster\fP daemon.
XCurrently, only the value of the \-r and \-e options can be modified.
X.TP
X.B S)tat
X.br
XPrint general statistics about the database.  See the section on
XDatabase Statistics below.
X.TP
X.B T)race
X.br
XTurn the trace option \-t on or off in the running \fInnmaster\fP.
X.SH THE LOG MENU
XThe log menu (identified by the
X.B LOG
Xprompt) enables you the extract specific entries from the log file,
Xand to truncate the log file.
X.LP
XThe entries in the log file share the following format:
X.sp 0.5v
X	<class>: <date> <time> (<user>): <message>
X.sp 0.5v
Xwhere <class> identifies the message class, the <date> and <time>
Xspecify when the entry was made, the <user> specifies who created the
Xentry (the letter "M" denote the \fInnmaster\fP), and the <message> is
Xthe text of the entry.
X.LP
XTo extract the log file entries of a specific class, simply enter the
Xletter identifying the class:
X.TP
X.B A - admin to master communication
X.br
XThis class of messages are related to the sending of messages from an
X\fInnadmin\fP program to the \fInnmaster\fP daemon.
X.TP
X.B C - collection statistics
X.br
XStatistics about collection of new articles.  The message has the format:
X.br
X	Collect: \fInnn\fP art, \fIppp\fP gr, \fIttt\fP s
X.br
Xmeaning that 
X.I nnn
Xarticles in
X.I ppp
Xgroups were collected in
X.I ttt
Xseconds (real time).
X.TP
X.B E - fatal errors
X.br
XFatal errors encountered during operation.  These errors require
Xmanual intervention to be fixed (some of the fatal errors occur if
Xthing that "cannot happen" happens anyway, and may indicate a bug
Xin the software).
X.TP
X.B M - nnmaster messages.
X.br
XMaster start/stop messages.
X.TP
X.B N - NNTP related messages
X.br
XVarious messages related to the NNTP part of the nnmaster, mostly
Xabout lost connections and failed attempts to connect to the NNTP
Xserver.  These messages should only appear if you use NNTP, and your
XNNTP server is down for some reason. 
X.TP
X.B R - reports
X.br
XNon-fatal error which enables the \fInnmaster\fP to continue
Xoperation, but may prevent a user to run \fInn\fP (file access
Xproblems).  Reported problems should be checked.  The most common
Xreport message will probably be 
X.br
X	some.group: no directory
X.br
Xwhich indicates that the spool directory for that group has
Xdisappeared (most likely because it has been rmgroup'ed).
X.TP
X.B T - trace output
X.br
XMessages produced as a result of using the \-t option on the
X\fInnmaster\fP.  This is primarily for debugging purposes.
X.TP
X.B U - usage statistics
X.br
XIf \fInn\fP is compiled with the STATISTICS option enabled, an entry
Xwill be made in the log file every time a user has spent more than
Xfive minutes on news reading.  The message will have the following format:
X.br
X	USAGE \fIhours.minutes\fP
X.br
XSince it is possible to
Xsuspend
X\fInn\fP, or leave the terminal while \fInn\fP is active, \fInn\fP
Xtries to be intelligent when it calculates the usage time so it will
Xreflect the actual time spent on news reading.  The usage statistics
Xcan be summarized using the \fInnusage\fP(1M) program.
X.TP
X.B V - validation errors
X.br
XWhen inconsistencies are detected in the database during validation,
Xan entry for each corrupted group will be entered in the log file.
X.TP
X.B X - expire statistics
X.br
XMessages similar to the Collect statistics reporting the result of
Xrunning expire on the database.
X.LP
XTo extract a specific entry class, 
X.IR grep (1)
Xis used, so it may take a while on a large log file.
X.LP
XThere are also a few special operations on the log file:
X.TP
X.B G)roup
X.br
XExtract the entries which refers to a specified group.
X.TP
X.B (1-9) tail
X.br
XInvoke
X.IR tail (1)
Xto extract the last 10-90 entries in the log file.
X.TP
X.B (.) all
X.br
XDisplay the complete log file.
X.TP
X.B (@) clean
X.br
XMove the Log file to Log.old, and create a new empty Log file.  If you
Xwant to clean out the old log file as well, simply repeat the clean
Xoperation (this will result in an empty Log.old file.)
X.SH THE GROUP MENU
XWhen you enter the group menu (identified by the
X.B GROUP
Xprompt), \fInnadmin\fP will prompt you for the name of a news group,
Xwhich you can enter with the usual completion feature described in the
X\fInn\fP(1) manual.  You can then perform the following operations on
Xthe specified group:
X.TP
X.B C)lear_flag
X.br
XClear a group specific flag.  See the section on group flags below.
X.TP
X.B D)ata
X.br
XDump the contents of the data file containing the extracted article
Xheaders for the group.
X.TP
X.B E)xpire
X.br
XRequest the \fInnmaster\fP to run expire on the group.
X.TP
X.B F)iles
X.br
XList the files (using
X.IR ls (1))
Xcontaining the index and data for the group.
X.TP
X.B G)roup
X.br
XSwitch to another group.
X.TP
X.B H)eader
X.br
XDump the master index entry for the group.
X.TP
X.B R)ecollect
X.br
XRequest the \fInnmaster\fP to recollect all articles in the group.
X.TP
X.B S)et_flag
X.br
XSet a group specific flag.  See the section on group flags below.
X.SH INDIVIDUAL GROUP FLAGS
XYou can set and clear the following flags for individual groups to
Xcontrol the future behaviour of \fInnmaster\fP on that group.
X.TP
X.B A)lways_digest
X.br
XNormally, \fInnmaster\fP will only attempt to split digests into
Xindividual articles if it can easily recognize an article as a digest.
XThis requires that the word "digest" appears somewhere in the subject
Xline, and that one of the first few lines in the body of the article
Xloosely matches the subject.  A few news groups frequently receives
Xdigests which break one or both of these requirements.  To have
X\fInnmaster\fP split these digests into individual articles anyway,
Xyou can turn on the "always digest" flag on these news groups.
XThis will instruct \fInnmaster\fP to treat 
X.I all
Xarticles in the group as digests (naturally, articles which are then
Xfound not to contain other articles are still treated as normal articles.)
X.TP
X.B C)ontrol
X.br
XThis is a special flag for the control group.  It indicates that the
X"Newsgroups:" field in the article header cannot be trusted (it does
Xnot specify the groups to which the article has been posted.)
X.TP
X.B D)irectory missing
X.br
XThis flag indicates that the spool directory for the news group cannot
Xbe found (the group has probably been removed with 
X.IR rmgroup (1M)).
XIt is set automatically be the \fInnmaster\fP if it cannot
Xaccess the directory.  When the flag is set, \fInnmaster\fP completely
Xignores the group, so it can be used to disable news collection in
Xspecific groups.  If you recreate the group or the directory
Xmanually, you must also clear this flag to have the \fInnmaster\fP
Xrecognize the group again.
X.TP
X.B M)oderated
X.br
XIndicates that the group is moderated.  This flag is normally
Xinitialized automatically from the active file, and it should not be
Xchanged lightly.
X.TP
X.B N)ever_digest
X.br
XThis is the opposite of the "always digest" flag; when set, the
X\fInnmaster\fP will never attempt to split any articles in that group
Xinto subarticles.
X.LP
XNotice that these flags will be reset to their default value if you
Xreinitialize the database using \fInnmaster\fP \-I.
X.SH DATABASE STATISTICS DISPLAY
XWhen you select the (S)tat operation in the main or master menus, you
Xwill get some general statistics about the database:
X.TP
Xlast_scan
X.br
XThe time stamp on the active file the last time the \fInnmaster\fP
Xread it.
X.TP
Xno of groups
X.br
XThe total number of groups in the database.
X.TP
Xnext write
X.br
XThe size of the GROUPS file containing the group names
X(used for consistency checking).
X.TP
XArticles
X.br
XThe total number of articles in all groups.  This is not an
Xexact number, because it will count split digests as a single article
X(making the number too small), and it may count some articles that
Xhave been expired (making the number too large).
X.TP
XDisk blocks
X.br
XThe total number of (512 byte) disk blocks occupied by the database.
X.SH MASTER INDEX ENTRIES
XThe master index entries displayed when you select the (H)eader
Xoperation in the master and group menus contain the following information:
X.TP
X\fIgroup_name  group_number\fP
X.br
XThe first line of the display will show the name of the group and the
Xinternal group number which is used to identify the group in the database.
X.TP
Xfirst/last art
X.br
XThis is the numbers of the first and last article that are currently
Xstored in the database.
X.TP
Xactive info
X.br
XThis is the numbers of the first and last article in the news system
Xas read from the active file.  They will normally match the numbers
Xabove, but they may differ while the \fInnmaster\fP is working on the
Xgroup (or it has not yet collected all the articles in the group).
XNotice: these numbers will be zero when administration mode is
Xselected from nn.
X.TP
XOffsets: index->..., data->...  
X.br
XThese values show the starting position for the next write operation
Xon the index and data files.  They are primarily used for consistency
Xchecking and recovery after a system crash, but after an "expire by
Xrewrite" operation which is performed "in-situ", the data and index
Xfiles may physically be longer than the actual data stored in them.
X.TP
XFlags:
X.br
XThis shows the current flags set for this group.  If no flags are set,
Xthe field is omitted from the display.  One extra flag which was not
Xexplained above is the BLOCKED flag; it is a temporary locking flag
Xset on a group by the \fInnmaster\fP while it is updating the database
Xfiles for that group to prevent \fInn\fP clients to access that group.
X.SH RAW DATABASE DISPLAY
XWhen you select the (D)ata operation on the group menu, you will get a
Xcombined display of the raw data and index files for that group.  The
Xindex file contains a single 32 bit value for each existing article
Xnumber.  This value is an offset into the data file pointing to the
Xheader for the corresponding article.
X.LP
XWhen \fInn\fP want to access the article from number N to the last
Xarticle, it looks up the offset for article number N in the index
Xfile, and uses this as the starting point for reading article header
Xinformation in the data file.  It then simply reads to the end of the
Xdata file in which the article headers for articles number N+1, N+2,
Xand so on follows immediately after the header for article number N.
X.LP
XThe article header information is presented in a very terse form; each
Xof the output lines are described below for reference purposes:
X.TP
Xoffset = \fIxxxx\fP    , article # = \fInnnnn\fP
X.br
XThis shows the offset into the data file and the article number.  The
Xoffset will be checked against the offset in the index file.
X.TP
Xxpost(\fIcount\fP):  \fInnn\fP, \fInnn\fP, \fInnn\fP, ...
X.br
XCross-postings to other groups are encoded as a list of internal group
Xnumbers; only the news groups 
X.I preceding
Xthe current news group on the Newsgroups: line are included.
X(\fInn\fP will present an article posted to several news groups in the
Xfirst group found on the Newsgroups: line to which the user subscribes.)
X.TP
X[ digest header | digest article | normal article ]
X.br
XThis information tell whether the data file entry is the header of a
Xcomplete digest (immediately followed by the split articles), an
Xarticle inside a split digest, or a normal article.
X.TP
Xts=\fInn\fP  hp=\fInn\fP  fp=\fInn\fP  lp=\fInn\fP  rep=\fInn\fP  lines=\fInn\fP
X.br
XThese values are used by \fInn\fP to sort, present, and access an
Xarticle:
X.br
X.B ts
Xis the 
X.I time stamp
Xon the article; it is a simple encoding of the posting date and time
Xfound in the Date: field.
X.br
X.BR hp ,
X.BR fp ,
Xand
X.B lp
Xare offsets into the file containing the article text: the \fIheader
Xposition\fP, \fIfirst text position\fP, and \fIlast text position\fP.
XThe first will be zero for normal articles, but not for articles in a
Xsplit digest.  The last will be equal to the length of the file for
Xnormal articles, but not inside digests.
X.br
X.B rep
Xis the "follow-up level" of this article; it is the number of "Re:"
Xprefixes which have been removed from the subject line.
X.TP
XSender(\fIlength\fP): \fIname\fP
X.br
XThe name of the sender in "ready to print" format, i.e. reduced to 16
Xcharacters as explained in the \fInn\fP manual.
X.TP
XSubj(\fIlength\fP): \fIsubject\fP
X.br
XThis is the full subject line from the article header (except for Re:
Xprefixes in various formats).
X.fi
X.SH FILES
XThe $db, $lib, and $news used below are synonyms for the DB_DIRECTORY,
XLIB_DIRECTORY, and the news system's lib directories respectively.
X.br
X.DT
X.ta \w'$db/DATA/\fInnn\fP.dx'u+3m
X$db/MASTER	Database master index
X.br
X$db/GROUPS	News group names in MASTER file order
X.br
X$db/DATA/\fInnn\fP.x	Index file for group number \fInnn\fP
X.br
X$db/DATA/\fInnn\fP.d	Data file for group number \fInnn\fP
X.br
X$lib/GATE	Message channel from \fInnadmin\fP to \fInnmaster\fP
X.br
X$lib/MPID	The process id of the \fInnmaster\fP daemon.
X.br
X$lib/Log	The log file (truncate it regularly!)
X.DT
X.LP
XThe MASTER file contains a record for each news group, occurring in
Xthe same sequence as the group names in the GROUPS file.  The sequence
Xalso defines the group numbers used to identify the files in the
Xdatabase and in a few other places.
X.LP
XThe GATE file will be created by \fInnadmin\fP when needed, and
Xremoved by \fInnmaster\fP when it has read it.  Therefore, to send a
Xmessage to the \fInnmaster\fP requires that you are allowed to write
Xin the $lib directory.
X.SH SEE ALSO
Xnn(1), nncheck(1), nngrep(1), nntidy(1)
X.br
Xnnquery(1M), nnusage(1M), nnmaster(8)
X.SH WARNINGS
XThe GATE file is created with the owner and modes of the user that
Xruns \fInnadmin\fP which may cause problems if the owner of the
X\fInnmaster\fP process (normally "news") is not allowed to read the
Xcreated GATE file (a "umask" of 022 is ok.)  Unless you allow ordinary
Xusers to create files in the LIB directory where the GATE file
Xresides, only the owner of the directory (normally "news") and "root"
Xcan use \fInnadmin\fP to send messages to the \fInnmaster\fP.
XHowever, to send a wakeup signal to the master, anybody can run
X.br
X	\fInnmaster\fP -w
X.SH BUGS
XThe user interface is completely out of line with the rest of the
X\fInn\fP family, and the way to run \fInnadmin\fP in the
Xnon-interactive mode is a bit bizarre.  This is not likely to change,
Xbecause I believe there are more important things to do!
X.SH AUTHOR
XKim F. Storm, Texas Instruments A/S, Denmark
X.br
XE-mail: storm@texas.dk
NO_NEWS_IS_GOOD_NEWS
chmod 0644 nnadmin.1m || echo "restore of nnadmin.1m fails"
set `wc -c nnadmin.1m`;Sum=$1
if test "$Sum" != "18517"
then echo original size 18517, current size $Sum;fi
echo "x - extracting nncheck.1 (Text)"
sed 's/^X//' << 'NO_NEWS_IS_GOOD_NEWS' > nncheck.1 &&
X.TH NNCHECK 1 "Release 6.3"
X.UC 4
X.SH NAME
Xnncheck \- check for unread articles
X.SH SYNOPSIS
X.B nncheck
X[ -Q -r -t ]  [ -f format ]
X.SH DESCRIPTION
X.I nncheck
Xwill report if there are some articles on the system which you have not read.
X.LP
XWithout options, \fInncheck\fP will simply print a message reporting
Xthe number of unread articles with the following format:
X.br
X	There are 327 unread articles in 25 groups
X.br
Xand when there are no unread articles, the following message will be
Xprinted:
X.br
X	No News (is good news)
X.LP
X\fInncheck\fP will exit with a value of 0 if there are unread
Xarticles, and 99 if there is no news (see the exception for the \-r
Xoption.)
X.LP
XIt is important to notice that even though unread articles have been
Xreported by \fInncheck\fP, the actual number of unread articles may be
Xmuch lower (or even zero) when \fInn\fP is invoked to read
Xthe articles.  This is because the calculation of the number of unread
Xarticles is only based on recorded article number intervals.  Invoking
X\fInn\fP to read the articles may reveal that the articles have
Xpreviously been read in another news group, have been expired, or are
X.I killed
Xusing the 
X.I auto-kill
Xfacility.
X.LP
XThe following options are used to modify the amount and format of the
Xoutput from \fInncheck\fP:
X.TP
X.B \-Q
XQuiet operation.  No output is produced, only the exit status indicate
Xwhether there is unread news.
X.TP
X.B \-t
XPrint the name of each group with unread articles, and how many unread
Xarticles there are (not counting split digests!).
X.TP
X.B \-r
XOutput a single integer value specifying the number of unread
Xarticles, and exit with a 0 status (somebody told me this would be
Xuseful).
X.TP
X\&\-\fBf\fP \fIformat\fP
XOutput the number of unread articles using the specified format.  The
Xformat is a text that may contain the following %-escapes:
X.sp 0.5v
X.DT
X.ta 1i 2i
X.nf
X	\fB%-code\fP	\fBresulting output\fP
X.sp 0.5v
X	%u	"\fIuuu\fP unread articles"
X	%g	"\fIggg\fP groups"
X	%i	"is" if 1 unread article, else "are"
X	%U	"\fIuuu\fP"
X	%G	"\fIggg\fP"
X.fi
X.DT
X.sp 0.5v
Xwhere 
X.I uuu
Xis the number of unread articles, and
X.I ggg
Xis the number of groups with unread articles.
X.sp 0.5v
XFor example, the default output format is
X.br
X	"There %i %u in %g"
X.br
Xwhich I prefer to the following less perfect format:
X.br
X	"There are %U unread article(s) in %G group(s)"
X.LP
X.SH FILES
X.DT
X.ta \w'$db/MASTER'u+6m
X~/.nn/rc	The record of read articles
X.br
X$db/MASTER	The database master index
X.DT
X.SH SEE ALSO
Xnn(1), nngoback(1), nngrep(1), nntidy(1)
X.br
Xnnadmin(1M), nnquery(1M), nnusage(1M), nnmaster(1M)
X.SH AUTHOR
XKim F. Storm, Texas Instruments A/S, Denmark
X.br
XE-mail: storm@texas.dk
NO_NEWS_IS_GOOD_NEWS
chmod 0644 nncheck.1 || echo "restore of nncheck.1 fails"
set `wc -c nncheck.1`;Sum=$1
if test "$Sum" != "2668"
then echo original size 2668, current size $Sum;fi
echo "x - extracting nngoback.1 (Text)"
sed 's/^X//' << 'NO_NEWS_IS_GOOD_NEWS' > nngoback.1 &&
X.TH NNGOBACK 1 "Release 6.3"
X.UC 4
X.SH NAME
Xnngoback \- make news articles unread on a day-by-day basis.
NO_NEWS_IS_GOOD_NEWS
echo "End of part 10"
echo "File nngoback.1 is continued in part 11"
echo "11" > s2_seq_.tmp
exit 0
---
Kim F. Storm        storm@texas.dk        Tel +45 429 174 00
Texas Instruments, Marielundvej 46E, DK-2730 Herlev, Denmark
	  No news is good news, but nn is better!

-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.