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.