Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!cs.utexas.edu!uunet!mcvax!kth!sunic!dkuug!tidk!storm From: storm@texas.dk (Kim F. Storm) Newsgroups: comp.sources.bugs Subject: NN 6.3 - Official patch #2 (part 01/02) Message-ID: <345@texas.dk> Date: 28 Jun 89 19:34:11 GMT Organization: Texas Instruments, Denmark Lines: 1659 This is patch #2 for nn release 6.3. nn and patch #1 was posted on comp.sources.unix a few days ago. Due to the size of the patches, they have been split into two postings, each containing a SHAR archive which should be unpacked in turn using the :unshar command into the nn source directory. It will create the following new files: decode.c -- new uudecode command s-dnix5-2.h -- s- file for dnix system s-hpux3-0.h -- yet another s- file for HP-UX PATCH.2 -- patch #2 diff's Then apply the patches using the command patch < PATCH.2 (pipe it though your favourite pager) Recompile (make all) and reinstall (su ; make install) the package. You can then remove the PATCH.2 file. ABOUT PATCH #2 It is of medium-high priority, since it primarily fixes some minor bugs which have surfaced since I sent the sources to Rick Salz, but also fixes a few bugs that has been reported on the nn-bugs list this week: An NNTP related database corruption bug has been fixed. Handling of multiple folders in succession did not work. Cross-posted articles in new groups confused the counting of unread articles. The FILES entries in the online manual were not formatted properly. The :unread command now works as documented + accepts optional group name. Two flags were used inconsistently to control the updating of the rc file. Patch.Result file now contains all output from the `patch' program. Regexp search in articles containing form feeds confused the display code. The use of `NEW' in the group sequence now works as documented. Cancel command now only redraws the screen if inews complains. The 'tab3' mode was turned off by nn (actually terminfo). ntohl/htonl are no longer used when NETWORK_BYTE_ORDER is defined. nnusage will now report 'no usage statistics' when there are none. It is now possible to eliminate #! escapes if necessary (see s-template.h) Some groups marked unsubsribed in .newsrc could be seen as new groups by nn. The netinet/in.h file is now included correctly in nntp.c It also adds two new `features of the month': A :decode command to concatenate & decode UUENCODED articles automagically! The C {cancel} command now uses the same dialog as the {save} commands, so cancelling more than one article is much faster now (C* also works). ++Kim Storm ---- Cut Here and unpack ---- #!/bin/sh # shar: Shell Archiver (v1.22) # # This is part 1 of a multipart archive # do not concatenate these parts, unpack them in order with /bin/sh # # Run the following text with /bin/sh to create: # PATCH.2 # decode.c # s-dnix5-2.h # s-hpux3-0.h # if test -r s2_seq_.tmp then echo "Must unpack archives in sequence!" next=`cat s2_seq_.tmp`; echo "Please unpack part $next next" exit 1; fi echo "x - extracting PATCH.2 (Text)" sed 's/^X//' << 'NO_NEWS_IS_GOOD_NEWS' > PATCH.2 && X*** /usr/storm/nn6.3.1/patchlevel.h X--- patchlevel.h X************** X*** 9,14 X * 1989-05-30: Distributed release 6.3 (World) X * X * 1989-06-06: Patch 1: rc.c X */ X X #define PATCHLEVEL 1 X--- 9,15 ----- X * 1989-05-30: Distributed release 6.3 (World) X * X * 1989-06-06: Patch 1: rc.c X+ * 1989-06-28: Patch 2: several files X */ X X #define PATCHLEVEL 2 X************** X*** 11,15 X * 1989-06-06: Patch 1: rc.c X */ X X! #define PATCHLEVEL 1 X X--- 12,16 ----- X * 1989-06-28: Patch 2: several files X */ X X! #define PATCHLEVEL 2 X X X*** /usr/storm/nn6.3.0/answer.c X--- answer.c X************** X*** 256,263 X return 2; X } X } else { X! fputs("\rConfirm cancel: ", stdout); clrline(); X! if (yes(1) <= 0) return 0; X } X X f = open_news_article(ah, FILL_NEWS_HEADER|GET_ALL_FIELDS, nhbuf, (char *)NULL); X--- 256,263 ----- X return 2; X } X } else { X! prompt("Confirm cancel: '%.50s'", ah->subject ? ah->subject : ""); X! if (yes(1) <= 0) return 1; X } X X f = open_news_article(ah, FILL_NEWS_HEADER|GET_ALL_FIELDS, nhbuf, (char *)NULL); X************** X*** 262,268 X X f = open_news_article(ah, FILL_NEWS_HEADER|GET_ALL_FIELDS, nhbuf, (char *)NULL); X if (f == NULL) { X! msg("Can't find original article"); X return 2; X } X fclose(f); X--- 262,268 ----- X X f = open_news_article(ah, FILL_NEWS_HEADER|GET_ALL_FIELDS, nhbuf, (char *)NULL); X if (f == NULL) { X! msg("Article not found"); X return 2; X } X fclose(f); X************** X*** 275,281 X X if (aux_sh("cancel", X news.ng_ident, current_group->group_name, "Not canceled")) X! return 3; X X return 1; X } X--- 275,281 ----- X X if (aux_sh("cancel", X news.ng_ident, current_group->group_name, "Not canceled")) X! return -1; X X return 0; X } X************** X*** 277,283 X news.ng_ident, current_group->group_name, "Not canceled")) X return 3; X X! return 1; X } X X X--- 277,283 ----- X news.ng_ident, current_group->group_name, "Not canceled")) X return -1; X X! return 0; X } X X X X*** /usr/storm/nn6.3.0/data.h X--- data.h X************** X*** 56,62 X X # define G_SUBSCRIPTION CF(1) /* from .rc */ X # define G_READ CF(2) /* group has been read */ X- # define G_RC_UPDATED CF(3) /* .rc is updated */ X # define G_DONE CF(4) /* finished with this group */ X # define G_NEW CF(5) /* new group */ X # define G_FOLDER CF(6) /* "group" is a folder file */ X--- 56,61 ----- X X # define G_SUBSCRIPTION CF(1) /* from .rc */ X # define G_READ CF(2) /* group has been read */ X # define G_DONE CF(4) /* finished with this group */ X # define G_NEW CF(5) /* new group */ X # define G_FOLDER CF(6) /* "group" is a folder file */ X X*** /usr/storm/nn6.3.0/folder.c X--- folder.c X************** X*** 402,408 X int cc_save; X X fake_group.group_name = path; X! fake_group.group_flag = G_RC_UPDATED | G_FOLDER | G_READ; X init_group(&fake_group); X X folder = open_file(group_path_name, OPEN_READ); X--- 402,409 ----- X int cc_save; X X fake_group.group_name = path; X! fake_group.group_flag = G_FOLDER | G_READ; X! current_group = NULL; X init_group(&fake_group); X X folder = open_file(group_path_name, OPEN_READ); X************** X*** 486,493 X if (cancel_count) { X clrdisp(); X printf("Folder: %s\nFile: %s\n\n", buffer, group_path_name); X! printf("Remove %d article%s from folder? ", X! cancel_count, cancel_count == 1 ? "" : "s"); X fl; X X switch (yes(1)) { X--- 487,497 ----- X if (cancel_count) { X clrdisp(); X printf("Folder: %s\nFile: %s\n\n", buffer, group_path_name); X! if (cancel_count == n_articles) X! printf("Cancel all articles and remove folder? "); X! else X! printf("Remove %d article%s from folder? ", X! cancel_count, cancel_count == 1 ? "" : "s"); X fl; X X switch (yes(1)) { X************** X*** 493,499 X switch (yes(1)) { X case 1: X printf("\n\n"); X! rewrite_folder(); X break; X case 0: X break; X--- 497,509 ----- X switch (yes(1)) { X case 1: X printf("\n\n"); X! if (cancel_count == n_articles) { X! if (unlink(group_path_name) < 0) { X! printf("Could not unlink %s\n", group_path_name); X! sleep(3); X! } X! } else X! rewrite_folder(); X break; X case 0: X break; X************** X*** 526,533 X X strcpy(oldfile, group_path_name); X sp = strrchr(oldfile, '/'); X! if (!sp) goto move_error; X! strcpy(sp+1, "~OLD~FOLDER~"); X X unlink(oldfile); X if (link(group_path_name, oldfile) < 0) goto move_error; X--- 536,542 ----- X X strcpy(oldfile, group_path_name); X sp = strrchr(oldfile, '/'); X! strcpy((sp == NULL ? oldfile : sp+1), "~OLD~FOLDER~"); X X unlink(oldfile); X if (link(group_path_name, oldfile) < 0) goto move_error; X X*** /usr/storm/nn6.3.0/group.c X--- group.c X************** X*** 376,383 X if ((gh->last_article = gh->first_l_article - 1) < 0) X gh->last_article = 0; X gh->first_article = gh->last_article; X! updflag = gh->group_flag & (G_RC_UPDATED|G_READ); X! gh->group_flag &= ~(G_RC_UPDATED|G_READ); X update_rc(gh); X gh->group_flag &= ~(G_RC_UPDATED|G_READ); X gh->group_flag |= updflag; X--- 376,383 ----- X if ((gh->last_article = gh->first_l_article - 1) < 0) X gh->last_article = 0; X gh->first_article = gh->last_article; X! updflag = gh->group_flag & G_READ; X! gh->group_flag &= ~G_READ; X update_rc(gh); X gh->group_flag &= ~G_READ; X gh->group_flag |= updflag; X************** X*** 379,385 X updflag = gh->group_flag & (G_RC_UPDATED|G_READ); X gh->group_flag &= ~(G_RC_UPDATED|G_READ); X update_rc(gh); X! gh->group_flag &= ~(G_RC_UPDATED|G_READ); X gh->group_flag |= updflag; X } X X--- 379,385 ----- X updflag = gh->group_flag & G_READ; X gh->group_flag &= ~G_READ; X update_rc(gh); X! gh->group_flag &= ~G_READ; X gh->group_flag |= updflag; X } X X************** X*** 455,461 X X if (menu_cmd == ME_READ || menu_cmd == ME_NO_ARTICLES) { X if (did_selection) { X! int was_read = gh->group_flag & (G_READ|G_RC_UPDATED); X X prev_last = gh->last_l_article; X gh->last_l_article = last_article; X--- 455,461 ----- X X if (menu_cmd == ME_READ || menu_cmd == ME_NO_ARTICLES) { X if (did_selection) { X! int was_read = gh->group_flag & G_READ; X X prev_last = gh->last_l_article; X gh->last_l_article = last_article; X************** X*** 463,469 X gh->last_l_article = prev_last; X X if (last_article < gh->last_l_article) { X! gh->group_flag &= ~ (G_READ|G_RC_UPDATED); X gh->group_flag |= was_read; X release_memory(&sel_marker); X goto after_selection; X--- 463,469 ----- X gh->last_l_article = prev_last; X X if (last_article < gh->last_l_article) { X! gh->group_flag &= ~G_READ; X gh->group_flag |= was_read; X release_memory(&sel_marker); X goto after_selection; X************** X*** 470,479 X } X } else X if (submask == NULL && !also_read_articles && X! (menu_cmd != ME_NO_ARTICLES || X! (gh->group_flag & G_NEW) == 0) && X! (first_art == -1 || X! current_first_article == gh->first_article + 1)) X update_rc(gh); X } X X--- 470,478 ----- X } X } else X if (submask == NULL && !also_read_articles && X! (first_art == -1 || current_first_article == gh->first_article + 1)) { X! if (menu_cmd != ME_NO_ARTICLES) X! gh->group_flag &= ~G_NEW; X update_rc(gh); X } X } X************** X*** 475,480 X (first_art == -1 || X current_first_article == gh->first_article + 1)) X update_rc(gh); X } X X current_first_article = o_first_article; X--- 474,480 ----- X if (menu_cmd != ME_NO_ARTICLES) X gh->group_flag &= ~G_NEW; X update_rc(gh); X+ } X } X X current_first_article = o_first_article; X************** X*** 890,896 X if (yes(0) <= 0) return 0; X X add_unread(gh, -1); X! gh->group_flag &= ~G_SUBSCRIPTION; X write_rc_entry(gh, 0); X return 1; X } X--- 890,896 ----- X if (yes(0) <= 0) return 0; X X add_unread(gh, -1); X! gh->group_flag &= ~(G_SUBSCRIPTION | G_NEW); X write_rc_entry(gh, 0); X return 1; X } X X*** /usr/storm/nn6.3.0/keymap.c X--- keymap.c X************** X*** 418,423 X "compress", K_COMPRESS, K_ONLY_MORE, X "continue", K_CONTINUE, 0, X X "find", K_GOTO_MATCH, K_ONLY_MORE, X "find-next", K_NEXT_MATCH, K_ONLY_MORE, X "follow", K_FOLLOW_UP, 0, X--- 418,425 ----- X "compress", K_COMPRESS, K_ONLY_MORE, X "continue", K_CONTINUE, 0, X X+ "decode", K_UUDECODE, 0, X+ X "find", K_GOTO_MATCH, K_ONLY_MORE, X "find-next", K_NEXT_MATCH, K_ONLY_MORE, X "follow", K_FOLLOW_UP, 0, X X*** /usr/storm/nn6.3.0/keymap.h X--- keymap.h X************** X*** 35,40 X #define K_UNSUBSCRIBE 0x001b /* (un)subscribe to group */ X #define K_GROUP_OVERVIEW 0x001c /* group overview */ X #define K_PATCH 0x001d /* pipe article to patch */ X X #define K_GOTO_GROUP 0x0020 /* goto named group/folder */ X X--- 35,41 ----- X #define K_UNSUBSCRIBE 0x001b /* (un)subscribe to group */ X #define K_GROUP_OVERVIEW 0x001c /* group overview */ X #define K_PATCH 0x001d /* pipe article to patch */ X+ #define K_UUDECODE 0x001e /* uudecode articles */ X X #define K_GOTO_GROUP 0x0020 /* goto named group/folder */ X X X*** /usr/storm/nn6.3.0/init.c X--- init.c X************** X*** 190,195 X "cd", 2, 1, X "compile", 7, 0, X "coredump", 8, 0, X "define", 6, 0, X "help", 4, 2, X "man", 3, 0, X--- 190,196 ----- X "cd", 2, 1, X "compile", 7, 0, X "coredump", 8, 0, X+ "decode", 6, 0, X "define", 6, 0, X "help", 4, 2, X "man", 3, 0, X************** X*** 550,557 X } X X CASE( "unread" ) { X! if (restore_rc(current_group, argv(2) ? ARGVAL(2) : 0)) X! return AC_HEADER; X break; X } X X--- 551,566 ----- X } X X CASE( "unread" ) { X! group_header *gh; X! int ix = 1; X! X! if (argv(1) && (gh = lookup(argv(1))) != NULL) X! ix = 2; X! else X! gh = current_group; X! X! if (restore_rc(gh, argv(ix) ? ARGVAL(ix) : 0)) X! if (gh == current_group) return AC_HEADER; X break; X } X X X*** /usr/storm/nn6.3.1/install_aux X--- install_aux X************** X*** 26,32 X X echo "INSTALLATION COMPLETED" X X! if [ -n "$2" ] X then X echo X echo "--------------------------------------------------------" X--- 26,32 ----- X X echo "INSTALLATION COMPLETED" X X! if [ $# -gt 1 ] X then X echo X echo "--------------------------------------------------------" X X*** /usr/storm/nn6.3.0/MANIFEST X--- MANIFEST X************** X*** 20,25 X db.c X db.h X debug.h X digest.c X execute.c X expire.c X--- 20,26 ----- X db.c X db.h X debug.h X+ decode.c X digest.c X execute.c X expire.c X************** X*** 96,101 X routes.sample X s-bsd4-2.h X s-bsd4-3.h X s-hpux.h X s-hpux2-1.h X s-sunos3.h X--- 97,103 ----- X routes.sample X s-bsd4-2.h X s-bsd4-3.h X+ s-dnix5-2.h X s-hpux.h X s-hpux2-1.h X s-hpux3-0.h X************** X*** 98,103 X s-bsd4-3.h X s-hpux.h X s-hpux2-1.h X s-sunos3.h X s-sunos4-0.h X s-template.h X--- 100,106 ----- X s-dnix5-2.h X s-hpux.h X s-hpux2-1.h X+ s-hpux3-0.h X s-sunos3.h X s-sunos4-0.h X s-template.h X X*** /usr/storm/nn6.3.0/menu.c X--- menu.c X************** X*** 433,439 X } X X last_k_cmd = cur_k_cmd; X! cur_k_cmd = k_cmd = get_k_cmd(); X if (any_message) clrmsg(-1); X X alt_key: X--- 433,439 ----- X } X X last_k_cmd = cur_k_cmd; X! k_cmd = get_k_cmd(); X if (any_message) clrmsg(-1); X X alt_key: X************** X*** 438,444 X X alt_key: X X! switch (k_cmd) { X X case K_UNBOUND: X ding(); X--- 438,444 ----- X X alt_key: X X! switch (cur_k_cmd = k_cmd) { X X case K_UNBOUND: X ding(); X************** X*** 494,499 X case K_QUIT: X menu_return(ME_QUIT); X X case K_SAVE_NO_HEADER: X case K_SAVE_SHORT_HEADER: X case K_SAVE_FULL_HEADER: X--- 494,504 ----- X case K_QUIT: X menu_return(ME_QUIT); X X+ case K_CANCEL: X+ savemode = "Cancel"; X+ fname = ""; X+ goto cancel1; X+ X case K_SAVE_NO_HEADER: X case K_SAVE_SHORT_HEADER: X case K_SAVE_FULL_HEADER: X************** X*** 500,506 X case K_PRINT: X case K_UNSHAR: X case K_PATCH: X! X if (numa < 0) goto nextmenu; X X fname = init_save(k_cmd, &savemode); X--- 505,512 ----- X case K_PRINT: X case K_UNSHAR: X case K_PATCH: X! case K_UUDECODE: X! X if (numa < 0) goto nextmenu; X X fname = init_save(k_cmd, &savemode); X************** X*** 506,511 X fname = init_save(k_cmd, &savemode); X if (fname == NULL) goto Prompt; X X enable_stop = 0; X save_selected = 0; X doing_unshar = k_cmd == K_UNSHAR || k_cmd == K_PATCH; X--- 512,518 ----- X fname = init_save(k_cmd, &savemode); X if (fname == NULL) goto Prompt; X X+ cancel1: X enable_stop = 0; X save_selected = 0; X doing_unshar = k_cmd == K_UNSHAR || k_cmd == K_PATCH; X************** X*** 542,547 X ah = articles[article_id]; X if (save_selected && (ah->flag & A_SELECT) == 0) continue; X X if (doing_unshar) { X did_unshar++; X } else X--- 549,576 ----- X ah = articles[article_id]; X if (save_selected && (ah->flag & A_SELECT) == 0) continue; X X+ if (cur_k_cmd == K_CANCEL) { X+ if (current_group->group_flag & G_FOLDER) { X+ if ((ah->flag & A_CANCEL) == 0) fcancel(ah); X+ } else X+ switch (cancel(ah)) { X+ case -1: X+ did_unshar = 1; X+ continue; X+ case 0: X+ ah->flag |= A_CANCEL; X+ break; X+ default: X+ continue; X+ } X+ X+ if (!did_unshar) { X+ how = CANCEL; X+ mark(); X+ } X+ continue; X+ } X+ X if (doing_unshar) { X did_unshar++; X } else X************** X*** 547,552 X } else X if (cura >= 0 && cura <= numa) X prompt("Processing %c...", ident[cura]); X else X prompt("Processing entry %d...", article_id); X X--- 576,583 ----- X } else X if (cura >= 0 && cura <= numa) X prompt("Processing %c...", ident[cura]); X+ else if (ah->subject != NULL) X+ prompt("Processing '%.50s'...", ah->subject); X else X prompt("Processing entry %d...", article_id); X X************** X*** 572,578 X m_endinput(); X X enable_stop = 1; X! end_save(); X X if (did_unshar) { X any_key(0); X--- 603,610 ----- X m_endinput(); X X enable_stop = 1; X! if (cur_k_cmd != K_CANCEL) X! end_save(); X X if (did_unshar) { X printf("\r\n"); X************** X*** 575,580 X end_save(); X X if (did_unshar) { X any_key(0); X goto redraw; X } X--- 607,613 ----- X end_save(); X X if (did_unshar) { X+ printf("\r\n"); X any_key(0); X goto redraw; X } X************** X*** 612,618 X goto redraw; X X goto Prompt; X! X case K_CANCEL: X if (numa < 0) goto nextmenu; X X--- 645,651 ----- X goto redraw; X X goto Prompt; X! /* X case K_CANCEL: X if (numa < 0) goto nextmenu; X X************** X*** 632,638 X if (get_k_cmd() == K_ARTICLE_ID) X if (cancel(articles[firsta+article_id]) & 1) goto redraw; X goto Prompt; X! X case K_UNSUBSCRIBE: X if (unsubscribe(current_group)) { X if (!(current_group->group_flag & G_SUBSCRIPTION)) X--- 665,671 ----- X if (get_k_cmd() == K_ARTICLE_ID) X if (cancel(articles[firsta+article_id]) & 1) goto redraw; X goto Prompt; X! */ X case K_UNSUBSCRIBE: X if (unsubscribe(current_group)) { X if (!(current_group->group_flag & G_SUBSCRIPTION)) X X*** /usr/storm/nn6.3.0/mk_online_man X--- mk_online_man X************** X*** 6,11 X -e '/^\.\\"/d' \ X -e '/^\.nf/d' \ X -e '/^\.fi/d' \ X -e 's/^\.[BI] //' "$@" | X awk ' X BEGIN { X--- 6,15 ----- X -e '/^\.\\"/d' \ X -e '/^\.nf/d' \ X -e '/^\.fi/d' \ X+ -e '/^\.if/d' \ X+ -e '/^\.DT/d' \ X+ -e '/^\.ta/d' \ X+ -e '/^\.nr/d' \ X -e 's/^\.[BI] //' "$@" | X awk ' X BEGIN { X X*** /usr/storm/nn6.3.0/more.c X--- more.c X************** X*** 58,64 X register c, col, lno; X register FILE *art; X int more_cmd, eof, skip_spaces, has_space, window_lines; X! int form_feed, ignore_nl; X off_t firstl, lastl; X off_t linepos[LINEMAX]; X char linebuf[200], *lp; X--- 58,64 ----- X register c, col, lno; X register FILE *art; X int more_cmd, eof, skip_spaces, has_space, window_lines; X! int form_feed, last_ff_line, ignore_nl; X off_t firstl, lastl; X off_t linepos[LINEMAX]; X char linebuf[200], *lp; X************** X*** 141,147 X X rot13 = 0; X compress_space = 0; X! goto_line = -1, prev_goto = 1; X match_lines = match_redraw = match_expr = 0; X underline_line = -1; X fake_underline = 0; X--- 141,147 ----- X X rot13 = 0; X compress_space = 0; X! last_ff_line = goto_line = -1, prev_goto = 1; X match_lines = match_redraw = match_expr = 0; X underline_line = -1; X fake_underline = 0; X************** X*** 398,403 X switch (c) { X X case '\f': X if (lp == linebuf) { X if (goto_line && lno == lno1) goto next_line; X form_feed = 1; X--- 398,404 ----- X switch (c) { X X case '\f': X+ last_ff_line = linenum; X if (lp == linebuf) { X if (goto_line > 0 || match_expr || lno == lno1) goto next_line; X form_feed = 1; X************** X*** 399,405 X X case '\f': X if (lp == linebuf) { X! if (goto_line && lno == lno1) goto next_line; X form_feed = 1; X goto Prompt; X } X--- 400,406 ----- X case '\f': X last_ff_line = linenum; X if (lp == linebuf) { X! if (goto_line > 0 || match_expr || lno == lno1) goto next_line; X form_feed = 1; X goto Prompt; X } X************** X*** 475,480 X match_lines = 1; X if (linenum > match_botline) { X match_redraw = 0; X linenum -= 5; X goto next_page; X } X--- 476,482 ----- X match_lines = 1; X if (linenum > match_botline) { X match_redraw = 0; X+ if (last_ff_line > linenum) last_ff_line = -1; X linenum -= 5; X if (linenum < last_ff_line) linenum = last_ff_line; X goto next_page; X************** X*** 476,481 X if (linenum > match_botline) { X match_redraw = 0; X linenum -= 5; X goto next_page; X } X match_redraw = (stop_line < 0); X--- 478,484 ----- X match_redraw = 0; X if (last_ff_line > linenum) last_ff_line = -1; X linenum -= 5; X+ if (linenum < last_ff_line) linenum = last_ff_line; X goto next_page; X } X match_redraw = (stop_line < 0); X************** X*** 665,670 X case K_PRINT: X case K_UNSHAR: X case K_PATCH: X X putchar(CR); X if (init_save(c, (char **)NULL) != NULL) { X--- 668,674 ----- X case K_PRINT: X case K_UNSHAR: X case K_PATCH: X+ case K_UUDECODE: X X putchar(CR); X if (init_save(c, (char **)NULL) != NULL) { X************** X*** 695,701 X goto Prompt; X } X X! if (cancel(ah) == 0) goto Prompt; X more_return(MC_NEXT); X X case K_UNSUBSCRIBE: X--- 699,705 ----- X goto Prompt; X } X X! if (cancel(ah) > 0) goto Prompt; X more_return(MC_NEXT); X X case K_UNSUBSCRIBE: X X*** /usr/storm/nn6.3.0/nn.1 X--- nn.1 X************** X*** 768,773 X article through the patch command. X The output from the patch process will be piped through the pager X defined in the \fBpager\fP variable and appear on the screen. X .TP X \&\fB:unshar\fP {\fBunshar\fP} X Unshar articles. You will be prompted for the name of a directory in X--- 768,775 ----- X article through the patch command. X The output from the patch process will be piped through the pager X defined in the \fBpager\fP variable and appear on the screen. X+ The output is also saved in (or appended to) a file named X+ \fIPatch.Result\fP in the patch directory. X .TP X \&\fB:unshar\fP {\fBunshar\fP} X Unshar articles. You will be prompted for the name of a directory in X************** X*** 777,782 X During the unpacking, the normal output from the unshar process will X appear on the screen, and the menu or article text will be redrawn when X the process is finished. X .LP X In reading mode, the following keys can also be used to invoke the X save commands: X--- 779,802 ----- X During the unpacking, the normal output from the unshar process will X appear on the screen, and the menu or article text will be redrawn when X the process is finished. X+ The output is also saved in (or appended to) a file named X+ \fIUnshar.Result\fP in the unshar directory. X+ .TP X+ \&\fB:decode\fP {\fBdecode\fP} X+ Decode \fIuuencoded\fP articles into binary files. You will be X+ prompted for the name of a directory in which you want \fInn\fP to X+ place the decoded binary files (the file names are taken from the X+ uuencoded data). X+ \fInn\fP will combine several articles into single files as needed, X+ and you can even decode unrelated packages (into the same directory) X+ with one \fBdecode\fP command. X+ To be able to decode a binary file which spans several articles, X+ \fInn\fP may have to \fIignore\fP lines which fail the normal sanity checks X+ on uuencoded data instead of treating them as \fItransmission errors\fP. X+ Consequently, it is strongly recommended to check the resulting X+ decoded file using the checksum which is normally contained in the X+ original article. (Actually, you are also supposed to do this after X+ decoding with a stand-alone uudecode program). X .LP X In reading mode, the following keys can also be used to invoke the X save commands: X************** X*** 1546,1553 X in the order in which they arrived on the local system (which is a X completely arbitrary order). X .TP X! \fB:unread\fP [ \fIarticles\fP ] X! Mark the current group as unread. If the argument is omitted, the X number of unread articles in the group will be set to the number of X unread articles when \fInn\fP was invoked. Otherwise, the argument X specifies the number of unread articles. X--- 1566,1574 ----- X in the order in which they arrived on the local system (which is a X completely arbitrary order). X .TP X! \fB:unread\fP [ \fIgroup\fP ] [ \fIarticles\fP ] X! Mark the current (or specified) group as unread. If the X! \fIarticles\fP argument is omitted, the X number of unread articles in the group will be set to the number of X unread articles when \fInn\fP was invoked. Otherwise, the argument X specifies the number of unread articles. X X*** /usr/storm/nn6.3.0/nngrep.sh X--- nngrep.sh X************** X*** 8,13 X if [ "$1" = "-a" ] ; then X grep "$2" .nn/rc X else X! grep "^+ .* .*$1" .nn/rc X fi | X awk '{print $3}' X--- 8,13 ----- X if [ "$1" = "-a" ] ; then X grep "$2" .nn/rc X else X! grep "^[+=] .* .*$1" .nn/rc X fi | X awk '{print $3}' X X*** /usr/storm/nn6.3.0/nntidy.sh X--- nntidy.sh X************** X*** 35,41 X if (act) { X X[$1] = 1 X L[$1] = $2+0 X! if (L[$1] == 0) F[$1] = 0; else F[$1] = $3+0 X } X next X } X--- 35,41 ----- X if (act) { X X[$1] = 1 X L[$1] = $2+0 X! if (L[$1] == 0 || $3+0 == 0) F[$1] = 0; else F[$1] = $3-1 X } X next X } X************** X*** 43,49 X print $0 X next X } X! NF == 3 && ($1 == "!" || $1 == "+") { X if (X[$3] != 1) next X S[$3] = $1 X if (L[$3] >= $2+0) X--- 43,49 ----- X print $0 X next X } X! NF == 3 && ($1 == "!" || $1 == "+" || $1 == "=") { X if (X[$3] != 1) next X S[$3] = $1 X if (L[$3] >= $2+0) X X*** /usr/storm/nn6.3.0/nntp.c X--- nntp.c X************** X*** 32,38 X #include X X /* This is necessary due to the definitions in m-XXX.h */ X! #ifdef NETWORK_BYTE_ORDER X #include X #endif X X--- 32,38 ----- X #include X X /* This is necessary due to the definitions in m-XXX.h */ X! #ifndef NETWORK_DATABASE X #include X #else X #ifdef NETWORK_BYTE_ORDER X************** X*** 34,39 X /* This is necessary due to the definitions in m-XXX.h */ X #ifdef NETWORK_BYTE_ORDER X #include X #endif X X export char nntp_server[256]; /* name of nntp server */ X--- 34,42 ----- X /* This is necessary due to the definitions in m-XXX.h */ X #ifndef NETWORK_DATABASE X #include X+ #else X+ #ifdef NETWORK_BYTE_ORDER X+ #include X #endif X #endif X X************** X*** 35,40 X #ifdef NETWORK_BYTE_ORDER X #include X #endif X X export char nntp_server[256]; /* name of nntp server */ X export int use_nntp = 0; /* bool: t iff we use nntp */ X--- 38,44 ----- X #ifdef NETWORK_BYTE_ORDER X #include X #endif X+ #endif X X export char nntp_server[256]; /* name of nntp server */ X export int use_nntp = 0; /* bool: t iff we use nntp */ X************** X*** 150,155 X fl; X } X nntp_failed = 1; X X sockt_rd = nntp_get_socket(); X if ((nntp_in = fdopen(sockt_rd, "r")) == NULL) X--- 154,160 ----- X fl; X } X nntp_failed = 1; X+ is_connected = 0; X X sockt_rd = nntp_get_socket(); X if (sockt_rd < 0) X************** X*** 152,158 X nntp_failed = 1; X X sockt_rd = nntp_get_socket(); X! if ((nntp_in = fdopen(sockt_rd, "r")) == NULL) X return -1; X X sockt_wr = dup(sockt_rd); X--- 157,167 ----- X is_connected = 0; X X sockt_rd = nntp_get_socket(); X! if (sockt_rd < 0) X! return -1; X! X! if ((nntp_in = fdopen(sockt_rd, "r")) == NULL) { X! close(sockt_rd); X return -1; X } X sockt_wr = dup(sockt_rd); X************** X*** 154,160 X sockt_rd = nntp_get_socket(); X if ((nntp_in = fdopen(sockt_rd, "r")) == NULL) X return -1; X! X sockt_wr = dup(sockt_rd); X if ((nntp_out = fdopen(sockt_wr, "w")) == NULL) { X nntp_in = NULL; /* from above */ X--- 163,169 ----- X if ((nntp_in = fdopen(sockt_rd, "r")) == NULL) { X close(sockt_rd); X return -1; X! } X sockt_wr = dup(sockt_rd); X if ((nntp_out = fdopen(sockt_wr, "w")) == NULL) { X close(sockt_wr); X************** X*** 157,162 X X sockt_wr = dup(sockt_rd); X if ((nntp_out = fdopen(sockt_wr, "w")) == NULL) { X nntp_in = NULL; /* from above */ X return -1; X } X--- 166,173 ----- X } X sockt_wr = dup(sockt_rd); X if ((nntp_out = fdopen(sockt_wr, "w")) == NULL) { X+ close(sockt_wr); X+ fclose(nntp_in); X nntp_in = NULL; /* from above */ X return -1; X } X************** X*** 228,233 X if (!is_master) X msg("Connecting to %s: %s", nntp_server, syserr()); X (void) close(s); X } X if (x < 0 && !is_master) X (*errfct)("Giving up on NNTP server %s!\n", nntp_server); X--- 239,245 ----- X if (!is_master) X msg("Connecting to %s: %s", nntp_server, syserr()); X (void) close(s); X+ s = -1; X } X if (x < 0 && !is_master) X (*errfct)("Giving up on NNTP server %s!\n", nntp_server); X************** X*** 240,245 X if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) { X if (is_master) X (*errfct)("Connecting to %s: %s", nntp_server, syserr()); X } X X #endif X--- 252,258 ----- X if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) { X if (is_master) X (*errfct)("Connecting to %s: %s", nntp_server, syserr()); X+ s = -1; X } X X #endif X************** X*** 261,266 X fprintf(nntp_out, "%s\r\n", string); X if (fflush(nntp_out) == EOF) { X nntp_error(); X } X } X X--- 274,280 ----- X fprintf(nntp_out, "%s\r\n", string); X if (fflush(nntp_out) == EOF) { X nntp_error(); X+ return -1; X } X return 0; X } X************** X*** 262,267 X if (fflush(nntp_out) == EOF) { X nntp_error(); X } X } X X /* X--- 276,282 ----- X nntp_error(); X return -1; X } X+ return 0; X } X X /* X************** X*** 277,283 X { X register char *cp, *nl; X X- errno = 0; X if (fgets(string, size, nntp_in) == NULL) { X nntp_error(); X return -1; X--- 292,297 ----- X { X register char *cp, *nl; X X if (fgets(string, size, nntp_in) == NULL) { X nntp_error(); X return -1; X************** X*** 323,329 X if (!nntp_failed) { /* avoid infinite recursion */ X char line[NNTP_STRLEN]; X X! nntp_put_server("QUIT"); X (void) nntp_get_server(line, sizeof line); X } X X--- 337,343 ----- X if (!nntp_failed) { /* avoid infinite recursion */ X char line[NNTP_STRLEN]; X X! (void) nntp_put_server("QUIT"); X (void) nntp_get_server(line, sizeof line); X } X X************** X*** 344,352 X char *string; X int size; X { X! (void)nntp_put_server(string); X! X! if (nntp_get_server(string, size) < 0) X return -1; X #ifdef DEBUG X msg("<<< %.75s", string); X--- 358,364 ----- X char *string; X int size; X { X! if (nntp_put_server(string) < 0 || nntp_get_server(string, size) < 0) X return -1; X #ifdef DEBUG X msg("<<< %.75s", string); X************** X*** 367,374 X { X nntp_failed = 1; X if (is_master) { X! log_entry('N', "Lost connection to server %s: %s", nntp_server, syserr()); X! if (is_connected) X nntp_close_server(); X } else { X #ifdef DEBUG X--- 379,386 ----- X { X nntp_failed = 1; X if (is_master) { X! if (is_connected) { X! log_entry('N', "Lost connection to server %s: %s", nntp_server, syserr()); X nntp_close_server(); X } X } else { X************** X*** 370,375 X log_entry('N', "Lost connection to server %s: %s", nntp_server, syserr()); X if (is_connected) X nntp_close_server(); X } else { X #ifdef DEBUG X printf("Can't talk to NNTP server %s: %s", nntp_server, syserr()); X--- 382,388 ----- X if (is_connected) { X log_entry('N', "Lost connection to server %s: %s", nntp_server, syserr()); X nntp_close_server(); X+ } X } else { X #ifdef DEBUG X printf("Can't talk to NNTP server %s: %s", nntp_server, syserr()); X X*** /usr/storm/nn6.3.0/nnusage.sh X--- nnusage.sh X************** X*** 8,16 X X grep '^U:' $LIB/Log | X X! awk ' X! NF == 7 { X! if (split($7, t, ".") == 2) u[$5] += t[1] * 60 + t[2] X } X END { X for (n in u) { X--- 8,16 ----- X X grep '^U:' $LIB/Log | X X! awk ' X! BEGIN { X! any=0 X } X NF == 7 { X if (split($7, t, ".") == 2) { X************** X*** 12,17 X NF == 7 { X if (split($7, t, ".") == 2) u[$5] += t[1] * 60 + t[2] X } X END { X for (n in u) { X name=substr(n, 2, length(n)-3) X--- 12,23 ----- X BEGIN { X any=0 X } X+ NF == 7 { X+ if (split($7, t, ".") == 2) { X+ u[$5] += t[1] * 60 + t[2] X+ any=1 X+ } X+ } X END { X if (!any) { X printf("No usage statistics\n") X************** X*** 13,18 X if (split($7, t, ".") == 2) u[$5] += t[1] * 60 + t[2] X } X END { X for (n in u) { X name=substr(n, 2, length(n)-3) X printf("%s%16d.%02d\n", name, u[n]/60, u[n]%60); X--- 19,28 ----- X } X } X END { X+ if (!any) { X+ printf("No usage statistics\n") X+ exit X+ } X for (n in u) { X name=substr(n, 2, length(n)-3) X printf("%-10.10s%8d.%02d\n", name, u[n]/60, u[n]%60); X************** X*** 15,21 X END { X for (n in u) { X name=substr(n, 2, length(n)-3) X! printf("%s%16d.%02d\n", name, u[n]/60, u[n]%60); X } X }' | X X--- 25,31 ----- X } X for (n in u) { X name=substr(n, 2, length(n)-3) X! printf("%-10.10s%8d.%02d\n", name, u[n]/60, u[n]%60); X } X }' | X X X*** /usr/storm/nn6.3.0/prefix.sh X--- prefix.sh X************** X*** 5,10 X #include "update.h" X X --------CUT PREFIX HERE-------- X &!/bin/sh X X & Release RELEASE,VERSION,PATCHLEVEL, No. UPDATE X--- 5,11 ----- X #include "update.h" X X --------CUT PREFIX HERE-------- X+ #ifndef AVOID_SHELL_EXEC X &!/bin/sh X #endif X X************** X*** 6,11 X X --------CUT PREFIX HERE-------- X &!/bin/sh X X & Release RELEASE,VERSION,PATCHLEVEL, No. UPDATE X X--- 7,13 ----- X --------CUT PREFIX HERE-------- X #ifndef AVOID_SHELL_EXEC X &!/bin/sh X+ #endif X X & Release RELEASE,VERSION,PATCHLEVEL, No. UPDATE X X X*** /usr/storm/nn6.3.1/rc.c X--- rc.c X************** X*** 45,51 X * master file has been read in X */ X X! #define G_OLD G_NEW /* inverse use during rc reading */ X #define G_RENUM G_DONE X X X--- 45,51 ----- X * master file has been read in X */ X X! #define G_OLD G_SELECTION X #define G_RENUM G_DONE X X X************** X*** 166,172 X fputc(NL, bak); X } X X! if (SUBSCR(line) != '+' && SUBSCR(line) != '!') { X /* unrecognized line */ X continue; X } X--- 166,172 ----- X fputc(NL, bak); X } X X! if (SUBSCR(line) != '+' && SUBSCR(line) != '!' && SUBSCR(line) != '=') { X /* unrecognized line */ X continue; X } X************** X*** 182,188 X gh->group_flag |= G_OLD; X if (SUBSCR(line) == '+') X gh->group_flag |= G_SUBSCRIPTION; X! X gh->last_article = LASTART(line); X X if (gh->last_article > gh->last_l_article) X--- 182,190 ----- X gh->group_flag |= G_OLD; X if (SUBSCR(line) == '+') X gh->group_flag |= G_SUBSCRIPTION; X! if (SUBSCR(line) == '=') X! gh->group_flag |= G_SUBSCRIPTION | G_NEW; X! X gh->last_article = LASTART(line); X X if (gh->last_article > gh->last_l_article) X************** X*** 207,213 X if (gh->group_flag & G_OLD) { X if (gh->group_flag & G_RENUM) /* group is renumbered */ X write_rc_entry(gh, 0); X! gh->group_flag &= ~(G_NEW | G_RENUM); X } else { X gh->group_flag |= G_SUBSCRIPTION | G_NEW; X gh->last_article = gh->first_l_article - 1; X--- 209,215 ----- X if (gh->group_flag & G_OLD) { X if (gh->group_flag & G_RENUM) /* group is renumbered */ X write_rc_entry(gh, 0); X! gh->group_flag &= ~(G_OLD | G_RENUM); X } else { X gh->group_flag |= G_SUBSCRIPTION | G_NEW; X gh->last_article = gh->first_l_article - 1; X************** X*** 272,278 X { X add_unread(gh, -1); X X! if (no_update || gh->group_flag & G_RC_UPDATED) return; X X gh->last_article = gh->last_l_article; X X--- 274,280 ----- X { X add_unread(gh, -1); X X! if (no_update || gh->group_flag & G_READ) return; X X gh->last_article = gh->last_l_article; X X************** X*** 284,291 X X write_rc_entry(gh, 0); X X- if (gh->group_flag & G_READ) return; X- X gh->group_flag |= G_READ; X X if ((gh->group_flag & G_SUBSCRIPTION) == 0) return; X--- 286,291 ----- X X write_rc_entry(gh, 0); X X gh->group_flag |= G_READ; X } X X************** X*** 287,294 X if (gh->group_flag & G_READ) return; X X gh->group_flag |= G_READ; X- X- if ((gh->group_flag & G_SUBSCRIPTION) == 0) return; X } X X X--- 287,292 ----- X write_rc_entry(gh, 0); X X gh->group_flag |= G_READ; X } X X X************** X*** 296,302 X register group_header *gh; X long count; X { X! if (no_update || (count == 0 && (gh->group_flag & G_RC_UPDATED) == 0)) X return 0; X X if (gh->group_flag & G_READ || count > 0) { X--- 294,300 ----- X register group_header *gh; X long count; X { X! if (no_update || (count == 0 && (gh->group_flag & G_READ) == 0)) X return 0; X X if (gh->group_flag & G_READ || count > 0) { X************** X*** 318,324 X X write_rc_entry(gh, 0); X X! gh->group_flag &= ~(G_READ|G_RC_UPDATED); X X add_unread(gh, 1); X X--- 316,322 ----- X X write_rc_entry(gh, 0); X X! gh->group_flag &= ~G_READ; X X add_unread(gh, 1); X X************** X*** 469,474 X /* update article number */ X X fprintf(rc, "%c %06ld", /* MUST CHANGE IF LASTARTZ CHANGES */ X (gh->group_flag & G_SUBSCRIPTION) ? '+' : '!', X (long)(gh->last_article)); X X--- 467,473 ----- X /* update article number */ X X fprintf(rc, "%c %06ld", /* MUST CHANGE IF LASTARTZ CHANGES */ X+ (gh->group_flag & G_NEW) ? '=' : X (gh->group_flag & G_SUBSCRIPTION) ? '+' : '!', X (long)(gh->last_article)); X X************** X*** 570,578 X X /* Notice: unread articles before the last read article are lost */ X X- if (*sub == NL) /* new group */ X- continue; X- X if (subscr) { X last = strrchr(sub, '-'); X if (last == NULL) last = strrchr(sub, ','); X--- 569,574 ----- X X /* Notice: unread articles before the last read article are lost */ X X if (subscr) { X if (*sub == NL) continue; /* new group */ X X************** X*** 574,579 X continue; X X if (subscr) { NO_NEWS_IS_GOOD_NEWS echo "End of part 1" echo "File PATCH.2 is continued in part 2" echo "2" > 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!