storm@texas.dk (Kim F. Storm) (06/30/89)
This is patch #3 for nn release 6.3. Apply it using the :patch command in nn. ABOUT PATCH #3 This patch fixes a major problem on some systems which is not seen at all on other systems (including mine): NN wont find any news. A zillion thanks to Aaron Pelton for tracking down this nasty bug. It also fixes a few portability problems related to cpp (Thanks to Chip Rosenthal). It provides a faked siginterrupt for systems that need it. (Thanks to Chris Smith). The m-template.h file now describes the possibility to set STRCSPN and NO_SIGINTERRUPT. The stdin, stdout, and stderr are closed by the nnmaster when it is collecting news. (Thanks to Brad Allen). The right patchlevel will be shown by nn after compilation. Two new commands in reading mode: a {advance-article} b {back-article} These go to the next or previous article (on the menu) even when they are not selected. An addition to the K {kill-select} command: If the specified name or subject starts with a /, the rest of the input string is used as a regular expression. There is a new variable 'cross-post' to have cross-posted articles shown in all the addressed groups. The reading mode prompt line will now show when articles have been saved or responded to, e.g. -----(Filed)----- nnquery has been fixed (it could not locate the active file). Since the header file data.h has been changed, all files will be recompiled when you `make all'. I have received new s- and m- files for the following systems and/or machines: dynix / symmetry A/UX 1.1 convex xenix386 If you need one of these now, mail me. I will not post them until I have got a few more. ++Kim Storm *** /usr/storm/nn6.3.2/patchlevel.h --- patchlevel.h ************** *** 10,15 * * 1989-06-06: Patch 1: rc.c * 1989-06-28: Patch 2: several files */ #define PATCHLEVEL 2 --- 10,16 ----- * * 1989-06-06: Patch 1: rc.c * 1989-06-28: Patch 2: several files + * 1989-06-30: Patch 3: several files */ #define PATCHLEVEL 3 ************** *** 12,16 * 1989-06-28: Patch 2: several files */ ! #define PATCHLEVEL 2 --- 13,17 ----- * 1989-06-30: Patch 3: several files */ ! #define PATCHLEVEL 3 *** /usr/storm/nn6.3.2/answer.c --- answer.c ************** *** 72,77 if (command == K_REPLY) { pgm = "reply"; if (reply_to(t, news.ng_reply) || reply_to(t, news.ng_from) || --- 72,78 ----- if (command == K_REPLY) { pgm = "reply"; + ah->flag |= A_ST_REPLY; if (reply_to(t, news.ng_reply) || reply_to(t, news.ng_from) || ************** *** 108,113 if (command == K_FOLLOW_UP) { pgm = "follow"; record_file = news_record; ng_line(t); --- 109,115 ----- if (command == K_FOLLOW_UP) { pgm = "follow"; record_file = news_record; + ah->flag |= A_ST_FOLLOW; ng_line(t); *** /usr/storm/nn6.3.0/collect.c --- collect.c ************** *** 103,109 art_hdr.a_number = art_num; art_hdr.hpos = (off_t)0; art_hdr.lpos = (off_t)0; ! mode = FILL_NEWS_HEADER | FILL_OFFSETS | SKIP_HEADER; if ((gh->group_flag & (G_CONTROL | G_NEVER_DIGEST | G_ALWAYS_DIGEST)) == 0) mode |= DIGEST_CHECK; --- 103,110 ----- art_hdr.a_number = art_num; art_hdr.hpos = (off_t)0; art_hdr.lpos = (off_t)0; ! art_hdr.flag = 0; ! mode = FILL_NEWS_HEADER | FILL_OFFSETS | SKIP_HEADER; if ((gh->group_flag & (G_CONTROL | G_NEVER_DIGEST | G_ALWAYS_DIGEST)) == 0) mode |= DIGEST_CHECK; *** /usr/storm/nn6.3.2/data.h --- data.h ************** *** 84,90 char *kill_list; char *save_file; /* default save file from init */ ! off_t rc_offset; /* offset in rc_file */ } group_header; --- 84,91 ----- char *kill_list; char *save_file; /* default save file from init */ ! char *enter_macro; ! off_t rc_offset; /* offset in rc_file */ } group_header; ************** *** 119,125 group_header *a_group; /* if merged article menu */ ! int flag; /* flags: */ # define AF(n) (1<<(n-1)) --- 120,126 ----- group_header *a_group; /* if merged article menu */ ! int32 flag; /* flags: */ # define AF(n) (1<<(n-1)) ************** *** 131,136 # define A_FOLDER AF(6) /* article file = "folder_path" */ # define A_CANCEL AF(7) /* folder entry cancelled */ # define A_SEEN AF(8) /* article presented on menu */ } article_header; --- 132,141 ----- # define A_FOLDER AF(6) /* article file = "folder_path" */ # define A_CANCEL AF(7) /* folder entry cancelled */ # define A_SEEN AF(8) /* article presented on menu */ + + # define A_ST_FILED AF(16) /* articles is saved */ + # define A_ST_REPLY AF(17) /* sent reply to article */ + # define A_ST_FOLLOW AF(18) /* sent followup to article */ } article_header; *** /usr/storm/nn6.3.2/group.c --- group.c ************** *** 13,18 export int dont_split_digests = 0; export int dont_sort_articles = 0; import int article_limit, also_read_articles; import int no_update; --- 13,19 ----- export int dont_split_digests = 0; export int dont_sort_articles = 0; + export int also_cross_postings = 0; import int article_limit, also_read_articles; import int no_update; ************** *** 390,396 fl; access_mode = 0; ! if (also_read_articles || submask) access_mode |= ALSO_CROSS_POSTINGS; if (dont_split_digests) access_mode |= DONT_SPLIT_DIGESTS; --- 391,397 ----- fl; access_mode = 0; ! if (also_read_articles || submask || also_cross_postings) access_mode |= ALSO_CROSS_POSTINGS; if (dont_split_digests) access_mode |= DONT_SPLIT_DIGESTS; ************** *** 835,841 free_memory(); access_mode = DONT_SORT_ARTICLES; ! if (also_read_articles || submask) access_mode |= ALSO_CROSS_POSTINGS; if (dont_split_digests) access_mode |= DONT_SPLIT_DIGESTS; --- 836,842 ----- free_memory(); access_mode = DONT_SORT_ARTICLES; ! if (also_read_articles || submask || also_cross_postings) access_mode |= ALSO_CROSS_POSTINGS; if (dont_split_digests) access_mode |= DONT_SPLIT_DIGESTS; *** /usr/storm/nn6.3.2/keymap.c --- keymap.c ************** *** 153,160 /* ^ */ K_FIRST_PAGE, /* _ */ K_UNBOUND, /* ` */ K_UNBOUND, ! /* a */ K_UNBOUND, ! /* b */ K_UNBOUND, /* c */ K_COMPRESS, /* d */ K_NEXT_HALF_PAGE, /* e */ K_UNBOUND, --- 153,160 ----- /* ^ */ K_FIRST_PAGE, /* _ */ K_UNBOUND, /* ` */ K_UNBOUND, ! /* a */ K_FORW_ARTICLE, ! /* b */ K_BACK_ARTICLE, /* c */ K_COMPRESS, /* d */ K_NEXT_HALF_PAGE, /* e */ K_UNBOUND, ************** *** 409,414 int cmd_restriction; } command_name_map[] = { "advance-group", K_ADVANCE_GROUP, 0, "back-group", K_BACK_GROUP, 0, --- 409,415 ----- int cmd_restriction; } command_name_map[] = { + "advance-article", K_FORW_ARTICLE, K_ONLY_MORE, "advance-group", K_ADVANCE_GROUP, 0, "back-article", K_BACK_ARTICLE, K_ONLY_MORE, ************** *** 411,416 "advance-group", K_ADVANCE_GROUP, 0, "back-group", K_BACK_GROUP, 0, "cancel", K_CANCEL, 0, --- 412,418 ----- "advance-article", K_FORW_ARTICLE, K_ONLY_MORE, "advance-group", K_ADVANCE_GROUP, 0, + "back-article", K_BACK_ARTICLE, K_ONLY_MORE, "back-group", K_BACK_GROUP, 0, "cancel", K_CANCEL, 0, *** /usr/storm/nn6.3.2/keymap.h --- keymap.h ************** *** 71,76 #define K_ROT13 0x0037 /* do rot13 */ #define K_COMPRESS 0x0038 /* compress spaces */ #define K_BACK_TO_MENU 0x0039 /* return to menu */ /* menu() SPECIFIC COMMANDS */ --- 71,78 ----- #define K_ROT13 0x0037 /* do rot13 */ #define K_COMPRESS 0x0038 /* compress spaces */ #define K_BACK_TO_MENU 0x0039 /* return to menu */ + #define K_BACK_ARTICLE 0x003a /* back one article */ + #define K_FORW_ARTICLE 0x003b /* forward one article */ /* menu() SPECIFIC COMMANDS */ *** /usr/storm/nn6.3.0/kill.c --- kill.c ************** *** 1,5 #include "config.h" #include "term.h" /* * kill file handling --- 1,6 ----- #include "config.h" #include "term.h" + #include "regexp.h" /* * kill file handling ************** *** 22,27 #define ON_SENDER 0x00 /* pseudo flag */ #define KILL_MUST_MATCH 0x10 /* * external flag representation --- 23,29 ----- #define ON_SENDER 0x00 /* pseudo flag */ #define KILL_MUST_MATCH 0x10 + #define KILL_ON_REGEXP 0x20 /* * external flag representation ************** *** 32,37 #define EXT_ON_SUBJECT 's' #define EXT_ON_SENDER 'n' #define EXT_KILL_MUST_MATCH '=' /* * period = nnn DAYS --- 34,40 ----- #define EXT_ON_SUBJECT 's' #define EXT_ON_SENDER 'n' #define EXT_KILL_MUST_MATCH '=' + #define EXT_KILL_ON_REGEXP '/' /* * period = nnn DAYS ************** *** 79,85 if (strcmp(kl->kill_pattern, string)) continue; } else ! if (quick_match(string, kl->kill_pattern) == NULL) continue; if (kl->kill_flag & AUTO_KILL) --- 82,89 ----- if (strcmp(kl->kill_pattern, string)) continue; } else ! if (kl->kill_flag & KILL_ON_REGEXP) { ! if (regexec((regexp *)(kl->kill_pattern), string) == 0) continue; } else if (quick_match(string, kl->kill_pattern) == NULL) ************** *** 81,86 } else if (quick_match(string, kl->kill_pattern) == NULL) continue; if (kl->kill_flag & AUTO_KILL) return 1; --- 85,93 ----- if (kl->kill_flag & KILL_ON_REGEXP) { if (regexec((regexp *)(kl->kill_pattern), string) == 0) continue; + } else + if (quick_match(string, kl->kill_pattern) == NULL) + continue; if (kl->kill_flag & AUTO_KILL) return 1; ************** *** 116,122 if (strcmp(kl->kill_pattern, string)) continue; } else ! if (quick_match(string, kl->kill_pattern) == NULL) continue; return 1; } --- 123,130 ----- if (strcmp(kl->kill_pattern, string)) continue; } else ! if (kl->kill_flag & KILL_ON_REGEXP) { ! if (regexec((regexp *)(kl->kill_pattern), string) == 0) continue; } else if (quick_match(string, kl->kill_pattern) == NULL) ************** *** 118,123 } else if (quick_match(string, kl->kill_pattern) == NULL) continue; return 1; } --- 126,134 ----- if (kl->kill_flag & KILL_ON_REGEXP) { if (regexec((regexp *)(kl->kill_pattern), string) == 0) continue; + } else + if (quick_match(string, kl->kill_pattern) == NULL) + continue; return 1; } ************** *** 139,144 register kill_list_entry *kl; char *str; killf = open_file(relative(nn_directory, "kill"), OPEN_APPEND); if (killf == NULL) { msg("cannot create kill file"); --- 150,168 ----- register kill_list_entry *kl; char *str; + if (flag & KILL_ON_REGEXP) { + str = (char *)regcomp(pattern); + if (str == NULL) return; + } else { + str = malloc(strlen(pattern) + 1); + mem_check(str, 1, "string"); + + strcpy(str, pattern); + + if ((flag & KILL_MUST_MATCH) == 0) + init_quick_match(str); + } + killf = open_file(relative(nn_directory, "kill"), OPEN_APPEND); if (killf == NULL) { msg("cannot create kill file"); ************** *** 157,162 fputc(flag & AUTO_KILL ? EXT_AUTO_KILL : EXT_AUTO_SELECT, killf); fputc(flag & ON_SUBJECT ? EXT_ON_SUBJECT : EXT_ON_SENDER, killf); if (flag & KILL_MUST_MATCH) fputc(EXT_KILL_MUST_MATCH, killf); fputc(':', killf); fputs(pattern, killf); --- 181,187 ----- fputc(flag & AUTO_KILL ? EXT_AUTO_KILL : EXT_AUTO_SELECT, killf); fputc(flag & ON_SUBJECT ? EXT_ON_SUBJECT : EXT_ON_SENDER, killf); if (flag & KILL_MUST_MATCH) fputc(EXT_KILL_MUST_MATCH, killf); + if (flag & KILL_ON_REGEXP) fputc(EXT_KILL_ON_REGEXP, killf); fputc(':', killf); fputs(pattern, killf); ************** *** 165,178 fclose(killf); rm_kill_file(); - str = malloc(strlen(pattern) + 1); - mem_check(str, 1, "string"); - - strcpy(str, pattern); - - if ((flag & KILL_MUST_MATCH) == 0) - init_quick_match(str); - kl = (kill_list_entry *)calloc(1, sizeof(kill_list_entry)); mem_check(kl, 1, "kill list entry"); --- 190,195 ----- fclose(killf); rm_kill_file(); kl = (kill_list_entry *)calloc(1, sizeof(kill_list_entry)); mem_check(kl, 1, "kill list entry"); ************** *** 269,275 prompt("\1%s %s:\1", mode1, mode2); ! pattern = get_s(dflt, NONE, "%=", NO_COMPLETION); if (pattern == NULL) return; if (*pattern == NUL || *pattern == '%' || *pattern == '=') { if (dflt && *dflt) --- 286,292 ----- prompt("\1%s %s:\1", mode1, mode2); ! pattern = get_s(dflt, NONE, "%=/", NO_COMPLETION); if (pattern == NULL) return; if (*pattern == NUL || *pattern == '%' || *pattern == '=') { if (dflt && *dflt) ************** *** 279,285 pattern = (flag & ON_SUBJECT) ? ah->subject : ah->sender; } flag |= KILL_MUST_MATCH; ! } strcpy(buffer, pattern); pattern = buffer; --- 296,304 ----- pattern = (flag & ON_SUBJECT) ? ah->subject : ah->sender; } flag |= KILL_MUST_MATCH; ! } else ! if (*pattern == '/') { ! prompt("\1%s %s\1 (regexp): ", mode1, mode2); pattern = get_s(NONE, NONE, NONE, NO_COMPLETION); if (pattern == NULL || *pattern == NUL) return; ************** *** 281,286 flag |= KILL_MUST_MATCH; } strcpy(buffer, pattern); pattern = buffer; --- 300,310 ----- if (*pattern == '/') { prompt("\1%s %s\1 (regexp): ", mode1, mode2); + pattern = get_s(NONE, NONE, NONE, NO_COMPLETION); + if (pattern == NULL || *pattern == NUL) return; + flag |= KILL_ON_REGEXP; + } + strcpy(buffer, pattern); pattern = buffer; ************** *** 323,329 prompt("\1CONFIRM\1 %s %s %s%s: %-.35s%s ", mode1, mode2, days_str, ! (flag & KILL_MUST_MATCH) ? " exact" : "", pattern, strlen(pattern) > 35 ? "..." : ""); if (yes(0) <= 0) return; --- 347,354 ----- prompt("\1CONFIRM\1 %s %s %s%s: %-.35s%s ", mode1, mode2, days_str, ! (flag & KILL_MUST_MATCH) ? " exact" : ! (flag & KILL_ON_REGEXP) ? " regexp" : "", pattern, strlen(pattern) > 35 ? "..." : ""); if (yes(0) <= 0) return; ************** *** 372,377 kl->kill_pattern = patterns + entry.ck_pattern_index; kl->kill_flag = entry.ck_flag; if (entry.ck_group >= 0) { gh = active_groups + entry.ck_group; --- 397,405 ----- kl->kill_pattern = patterns + entry.ck_pattern_index; kl->kill_flag = entry.ck_flag; + + if (kl->kill_flag & KILL_ON_REGEXP) + kl->kill_pattern = (char *)regcomp(kl->kill_pattern); if (entry.ck_group >= 0) { gh = active_groups + entry.ck_group; ************** *** 500,505 case EXT_KILL_MUST_MATCH: flag |= KILL_MUST_MATCH; continue; case ':': break; case NL: --- 528,536 ----- case EXT_KILL_MUST_MATCH: flag |= KILL_MUST_MATCH; continue; + case EXT_KILL_ON_REGEXP: + flag |= KILL_ON_REGEXP; + continue; case ':': break; case NL: ************** *** 517,523 if ((np = strchr(cp, NL)) == NULL) goto bad_entry; *np++ = NUL; ! if ((flag & KILL_MUST_MATCH) == 0) init_quick_match(cp); entry.ck_pattern_index = ftell(patternf); --- 548,554 ----- if ((np = strchr(cp, NL)) == NULL) goto bad_entry; *np++ = NUL; ! if ((flag & (KILL_MUST_MATCH | KILL_ON_REGEXP)) == 0) init_quick_match(cp); entry.ck_pattern_index = ftell(patternf); ************** *** 638,644 printf("\r%s ON %s '%.35s'%s\n", kl->kill_flag & AUTO_KILL ? "KILL" : "SELECT", kl->kill_flag & ON_SUBJECT ? "SUBJECT" : "NAME", ! kl->kill_pattern, kl->kill_flag & KILL_MUST_MATCH ? " (exact)" : ""); return 0; --- 669,675 ----- printf("\r%s ON %s '%.35s'%s\n", kl->kill_flag & AUTO_KILL ? "KILL" : "SELECT", kl->kill_flag & ON_SUBJECT ? "SUBJECT" : "NAME", ! kl->kill_flag & KILL_ON_REGEXP ? "*regexp*" : kl->kill_pattern, kl->kill_flag & KILL_MUST_MATCH ? " (exact)" : ""); return 0; *** /usr/storm/nn6.3.0/m-template.h --- m-template.h ************** *** 27,32 /* #define NO_VARARGS */ #ifdef NETWORK_DATABASE --- 27,45 ----- /* #define NO_VARARGS */ + /* + * Define STRCSPN if the strcspn() function is not available. + */ + + /* #define STRCSPN /* */ + + /* + * Define NO_SIGINTERRUPT on BSD based systems which don't have + * a siginterrupt() function, but provides an SV_INTERRUPT flag + * in <signal.h>. + */ + + /* #define NO_SIGINTERRUPT /* */ #ifdef NETWORK_DATABASE *** /usr/storm/nn6.3.0/master.c --- master.c ************** *** 115,120 nn_exit(0); } if (repeat_delay && !debug_mode) { while ((temp = fork()) < 0) sleep(1); if (temp) nn_exit(0); --- 115,126 ----- nn_exit(0); } + if (!debug_mode) { + close(0); + close(1); + close(2); + } + if (repeat_delay && !debug_mode) { while ((temp = fork()) < 0) sleep(1); if (temp) nn_exit(0); *** /usr/storm/nn6.3.2/menu.c --- menu.c ************** *** 1016,1022 show: mode = 0; if (prev >= 0) mode |= MM_PREVIOUS; ! if (next == n_articles) mode |= MM_LAST_ARTICLE; cmd = more(articles[cur], mode, 0); --- 1016,1024 ----- show: mode = 0; if (prev >= 0) mode |= MM_PREVIOUS; ! if (next == n_articles) mode |= MM_LAST_SELECTED; ! if ((cur + 1) >= n_articles) mode |= MM_LAST_ARTICLE; ! if (cur == 0) mode |= MM_FIRST_ARTICLE; cmd = more(articles[cur], mode, 0); ************** *** 1061,1066 case MC_NEXT: if (articles[cur]->flag & A_SELECT) again++; break; case MC_NEXTGROUP: return SH_NEXT; --- 1063,1075 ----- case MC_NEXT: if (articles[cur]->flag & A_SELECT) again++; break; + + case MC_BACK_ART: + if (cur > 0) { + next = cur - 1; + break; + } + goto show; case MC_FORW_ART: next = cur + 1; ************** *** 1062,1067 if (articles[cur]->flag & A_SELECT) again++; break; case MC_NEXTGROUP: return SH_NEXT; --- 1071,1080 ----- } goto show; + case MC_FORW_ART: + next = cur + 1; + break; + case MC_NEXTGROUP: return SH_NEXT; ************** *** 1178,1184 alt_command() { int ok_val, macro_cmd; ! char *cmd; extern char erase_key; extern int get_from_macro; extern int alt_completion(); --- 1191,1197 ----- alt_command() { int ok_val, macro_cmd; ! char *cmd, brkchars[10]; extern char erase_key; extern int get_from_macro; extern int alt_completion(); ************** *** 1188,1195 again: ! cmd = "?? "; ! cmd[1] = erase_key; cmd = get_s(NONE, NONE, cmd, alt_completion); if (cmd == NULL || --- 1201,1207 ----- again: ! sprintf(brkchars, "?%c ", erase_key); cmd = get_s(NONE, NONE, brkchars, alt_completion); if (cmd == NULL || ************** *** 1191,1197 cmd = "?? "; cmd[1] = erase_key; ! cmd = get_s(NONE, NONE, cmd, alt_completion); if (cmd == NULL || *cmd == NUL || *cmd == SP || *cmd == erase_key) return ok_val; --- 1203,1209 ----- sprintf(brkchars, "?%c ", erase_key); ! cmd = get_s(NONE, NONE, brkchars, alt_completion); if (cmd == NULL || *cmd == NUL || *cmd == SP || *cmd == erase_key) return ok_val; *** /usr/storm/nn6.3.0/menu.h --- menu.h ************** *** 31,36 #define MC_PREVIEW_OTHER 9 /* preview another article */ #define MC_REDRAW 10 /* redraw screen after return */ #define MC_NO_REDRAW 11 /* screen is not corrupted */ /* more modes */ --- 31,38 ----- #define MC_PREVIEW_OTHER 9 /* preview another article */ #define MC_REDRAW 10 /* redraw screen after return */ #define MC_NO_REDRAW 11 /* screen is not corrupted */ + #define MC_BACK_ART 12 /* back one article (don't deselect cur) */ + #define MC_FORW_ART 13 /* forward one article (deselect cur) */ /* more modes */ ************** *** 34,45 /* more modes */ ! #define MM_NORMAL 0 /* show article */ ! #define MM_DIGEST 1 /* show full digest */ ! #define MM_PREVIOUS 0x10 /* previous article exists */ ! #define MM_LAST_ARTICLE 0x20 /* last article in group */ ! #define MM_LAST_GROUP 0x40 /* last group */ ! #define MM_PREVIEW 0x80 /* preview mode flag */ /* alt_command return values */ --- 36,49 ----- /* more modes */ ! #define MM_NORMAL 0x0000 /* show article */ ! #define MM_DIGEST 0x0001 /* show full digest */ ! #define MM_PREVIOUS 0x0010 /* previous article exists */ ! #define MM_LAST_SELECTED 0x0020 /* last selected article in group */ ! #define MM_LAST_GROUP 0x0040 /* last group */ ! #define MM_PREVIEW 0x0080 /* preview mode flag */ ! #define MM_FIRST_ARTICLE 0x0100 /* first article in group */ ! #define MM_LAST_ARTICLE 0x0200 /* last article in group */ /* alt_command return values */ *** /usr/storm/nn6.3.2/more.c --- more.c ************** *** 50,55 0 }; more(ah, mode, screen_offset) article_header *ah; --- 50,97 ----- 0 }; + static char *a_st_flags(flag) + int32 flag; + { + static char buf[40]; + register char *cp, *sp; + static int32 prevflag = 0; + + flag &= A_ST_FILED | A_ST_REPLY | A_ST_FOLLOW; + if (flag == 0) { + prevflag = 0; + return ""; + } + + if (flag == prevflag) return buf; + prevflag = flag; + + cp = buf; + *cp++ = '('; + if (flag & A_ST_FILED) { + *cp++ = 'F'; + *cp++ = 'i'; + *cp++ = 'l'; + *cp++ = 'e'; + *cp++ = 'd'; + } + + if (flag & A_ST_REPLY) { + if (cp[-1] != '(') *cp++ = SP; + *cp++ = 'R'; + *cp++ = 'e'; + } + + if (flag & A_ST_FOLLOW) { + if (cp[-1] != '(') *cp++ = SP; + *cp++ = 'F'; + *cp++ = 'o'; + *cp++ = 'l'; + } + + strcpy(cp, ")------"); + return buf; + } more(ah, mode, screen_offset) article_header *ah; ************** *** 149,155 stop_line = first_page_lines ? first_page_lines : -1; sprintf(pr_fmt, ! "\1\2-- %s%s %s-----%%s-----\1", (mode & MM_PREVIEW) ? "PREVIEW " : "", (mode & MM_DIGEST) ? "FULL DIGEST" : (mode & MM_LAST_ARTICLE) ? "LAST ARTICLE" : "ARTICLE", --- 191,197 ----- stop_line = first_page_lines ? first_page_lines : -1; sprintf(pr_fmt, ! "\1\2-- %s%s %s-----%%s-----%%s\1", (mode & MM_PREVIEW) ? "PREVIEW " : "", (mode & MM_DIGEST) ? "FULL DIGEST" : (mode & MM_LAST_SELECTED) ? "LAST ARTICLE" : "ARTICLE", ************** *** 152,158 "\1\2-- %s%s %s-----%%s-----\1", (mode & MM_PREVIEW) ? "PREVIEW " : "", (mode & MM_DIGEST) ? "FULL DIGEST" : ! (mode & MM_LAST_ARTICLE) ? "LAST ARTICLE" : "ARTICLE", novice ? "-- help:? " : ""); if (screen_offset) goto safe_redraw; --- 194,200 ----- "\1\2-- %s%s %s-----%%s-----%%s\1", (mode & MM_PREVIEW) ? "PREVIEW " : "", (mode & MM_DIGEST) ? "FULL DIGEST" : ! (mode & MM_LAST_SELECTED) ? "LAST ARTICLE" : "ARTICLE", novice ? "-- help:? " : ""); if (screen_offset) goto safe_redraw; ************** *** 576,582 prompt(pr_fmt, pct((long)(ah->fpos), (long)(ah->lpos), ! (long)(linepos[topline]), (long)ftell(art))); if (delayed_msg != NULL) { msg(delayed_msg); --- 618,625 ----- prompt(pr_fmt, pct((long)(ah->fpos), (long)(ah->lpos), ! (long)(linepos[topline]), (long)ftell(art)), ! a_st_flags(ah->flag)); if (delayed_msg != NULL) { msg(delayed_msg); ************** *** 905,910 if ((mode & MM_PREVIEW) == 0) break; more_return(MC_PREVIEW_NEXT); case K_NEXT_SUBJECT: more_return(MC_NEXTSUBJ); --- 948,967 ----- if ((mode & MM_PREVIEW) == 0) break; more_return(MC_PREVIEW_NEXT); + case K_BACK_ARTICLE: + if (mode & MM_FIRST_ARTICLE) { + msg("First article is displayed"); + goto same_prompt; + } + more_return(MC_BACK_ART); + + case K_FORW_ARTICLE: + if (mode & MM_LAST_ARTICLE) { + msg("Last article is displayed"); + goto same_prompt; + } + more_return(MC_FORW_ART); + case K_NEXT_SUBJECT: more_return(MC_NEXTSUBJ); *** /usr/storm/nn6.3.2/nn.1 --- nn.1 ************** *** 552,558 The following commands are used to move among the selected articles. .TP \&\fBn\fP {\fBnext-article\fP} ! Goto next article. This command skips the rest of the current article and jumps directly to the first page of the next article (or to the next group if it is the last article). .TP --- 552,558 ----- The following commands are used to move among the selected articles. .TP \&\fBn\fP {\fBnext-article\fP} ! Goto next selected article. This command skips the rest of the current article and jumps directly to the first page of the next article (or to the next group if it is the last article). .TP ************** *** 583,588 select only the first article on a subject in selection mode, and then select all follow-ups in reading mode if you find the article interesting. .LP The following commands perform an immediate return from reading mode to selection mode in --- 583,598 ----- select only the first article on a subject in selection mode, and then select all follow-ups in reading mode if you find the article interesting. + .TP + \&\fBa\fP {\fBadvance-article\fP} + Goto the following article on the menu even if it is not selected. + This command skips the rest of the current article + and jumps directly to the first page of the next article (it will not skip + to the next group if it is the last article). + .TP + \&\fBb\fP {\fBback-article\fP} + Goto the article before current article on the menu even if it is not + selected. .LP The following commands perform an immediate return from reading mode to selection mode in ************** *** 1267,1272 name or subject matches the original name or subject exactly including case. .sp 0.5v Otherwise, \fInn\fP will select or kill articles which .I contain the specified name or subject (or part thereof) anywhere in the name --- 1277,1286 ----- name or subject matches the original name or subject exactly including case. .sp 0.5v + If the first character typed at the prompt is a slash `/', the rest of + the line is used as a \fIregular expression\fP which is used to match + the name or subject. + .sp 0.5v Otherwise, \fInn\fP will select or kill articles which .I contain the specified name or subject (or part thereof) anywhere in the name ************** *** 1330,1336 specifying whether the entry applies to the name or to the subject of an article. .br ! \- The optional third character is an .B = sign which specify that the match against the name or subject must be an --- 1344,1350 ----- specifying whether the entry applies to the name or to the subject of an article. .br ! \- The optional third character can be an .B = sign which specify that the match against the name or subject must be an ************** *** 1334,1340 .B = sign which specify that the match against the name or subject must be an ! exact match (including case). .LP The .I string --- 1348,1355 ----- .B = sign which specify that the match against the name or subject must be an ! exact match (including case), or it can be a slash `/' specifying that ! the name or subject is matched against a regular expression. .LP The .I string ************** *** 1338,1344 .LP The .I string ! field in the entry is the name or subject that will be matched against the name or subject of each article in the group (or all groups). Notice, that unless an exact match is specified, the specified name or subject may occur --- 1353,1359 ----- .LP The .I string ! field in the entry is the name, subject or regular expression that will be matched against the name or subject of each article in the group (or all groups). Notice, that unless an exact match or a regular expression match is specified, the ************** *** 1340,1346 .I string field in the entry is the name or subject that will be matched against the name or subject of each article in the group (or ! all groups). Notice, that unless an exact match is specified, the specified name or subject may occur .I anywhere in a name or a subject, and that case is ignored. --- 1355,1362 ----- .I string field in the entry is the name, subject or regular expression that will be matched against the name or subject of each article in the group (or ! all groups). Notice, that unless an exact match or a regular ! expression match is specified, the specified name or subject may occur .I anywhere in a name or a subject, and that case is ignored. ************** *** 1702,1707 is set, you will also be asked for confirmation before appending an article to an existing file. .TP \fBdate\fP (boolean, default true) If set \fInn\fP will show the article posting date when articles are read. --- 1718,1730 ----- is set, you will also be asked for confirmation before appending an article to an existing file. .TP + \fBcross-post\fP (boolean, default false) + Normally, \fInn\fP will only show cross-posted articles in the first + subscribed group on the Newsgroups: line. When + .B cross-post + is set, \fInn\fP will show cross-posted articles in all subscribed + groups to which they are posted. + .TP \fBdate\fP (boolean, default true) If set \fInn\fP will show the article posting date when articles are read. ************** *** 2265,2270 .br \fIFunction Selection mode Reading mode .br \fBadvance-group\fP A A .br \fBback-group\fP B B --- 2288,2295 ----- .br \fIFunction Selection mode Reading mode .br + \fBadvance-article\fP \fBnix\fP a + .br \fBadvance-group\fP A A .br \fBback-article\fP \fBnix\fP b ************** *** 2266,2271 \fIFunction Selection mode Reading mode .br \fBadvance-group\fP A A .br \fBback-group\fP B B .br --- 2291,2298 ----- \fBadvance-article\fP \fBnix\fP a .br \fBadvance-group\fP A A + .br + \fBback-article\fP \fBnix\fP b .br \fBback-group\fP B B .br *** /usr/storm/nn6.3.0/nnquery.sh --- nnquery.sh ************** *** 1,6 # CONFIG file is insert above this line by make ! if [ -f ${ACTIVE} ] ; then echo "Cannot locate active file ${ACTIVE}" exit 3 fi --- 1,6 ----- # CONFIG file is insert above this line by make ! if [ ! -f ${ACTIVE} ] ; then echo "Cannot locate active file ${ACTIVE}" exit 3 fi *** /usr/storm/nn6.3.2/prefix.sh --- prefix.sh ************** *** 1,4 ! WARNING: DON'T CHANGE THE ORDER OR CONTENTS OF THE FOLLOWING LINES #include "config.h" #include "patchlevel.h" --- 1,4 ----- ! WARNING: DO NOT CHANGE THE ORDER OR CONTENTS OF THE FOLLOWING LINES #include "config.h" #include "patchlevel.h" ************** *** 5,11 #include "update.h" --------CUT PREFIX HERE-------- ! #ifndef AVOID_SHELL_EXEC &!/bin/sh #endif --- 5,13 ----- #include "update.h" --------CUT PREFIX HERE-------- ! #ifdef AVOID_SHELL_EXEC ! : ! #else &!/bin/sh #endif *** /usr/storm/nn6.3.2/save.c --- save.c ************** *** 456,461 #endif if (was_raw) raw(); return !s_pipe || (save_mode & SEPARATE_FILES); } --- 456,463 ----- #endif if (was_raw) raw(); + ah->flag |= A_ST_FILED; + return !s_pipe || (save_mode & SEPARATE_FILES); } *** /usr/storm/nn6.3.2/term.c --- term.c ************** *** 204,209 } #endif /* RESIZING */ init_term() { --- 204,221 ----- } #endif /* RESIZING */ + #ifdef SV_INTERRUPT + #ifdef NO_SIGINTERRUPT + static siginterrupt(signo, on) + { + struct sigvec sv; + sv.sv_handler = signal (signo, SIG_DFL); + sv.sv_mask = 0; + sv.sv_flags = on ? SV_INTERRUPT : 0; + sigvec (signo, &sv, 0); + } + #endif + #endif init_term() { *** /usr/storm/nn6.3.0/variable.c --- variable.c ************** *** 23,28 *save_counter_format; import int /* boolean variables */ conf_append, conf_dont_sleep, delay_redraw, --- 23,29 ----- *save_counter_format; import int /* boolean variables */ + also_cross_postings, conf_append, conf_dont_sleep, delay_redraw, ************** *** 81,86 "comp2_key", V_KEY, 0, (char **)&comp2_key, "confirm", V_BOOLEAN, 0, (char **)&conf_dont_sleep, "confirm-append", V_BOOLEAN, 0, (char **)&conf_append, "date", V_BOOLEAN, 0, (char **)&show_article_date, "debug", V_INTEGER, 0, (char **)&Debug, "default-save-file",V_STRING, 0, (char **)&default_save_file, --- 82,88 ----- "comp2_key", V_KEY, 0, (char **)&comp2_key, "confirm", V_BOOLEAN, 0, (char **)&conf_dont_sleep, "confirm-append", V_BOOLEAN, 0, (char **)&conf_append, + "cross-post", V_BOOLEAN, 0, (char **)&also_cross_postings, "date", V_BOOLEAN, 0, (char **)&show_article_date, "debug", V_INTEGER, 0, (char **)&Debug, "default-save-file",V_STRING, 0, (char **)&default_save_file, *** /usr/storm/nn6.3.2/xmakefile --- xmakefile ************** *** 123,129 * Compilation counter updating * ! update.o: update.h update.c -$(CC) -c $(CFLAGS) update.c * --- 123,129 ----- * Compilation counter updating * ! update.o: update.h update.c patchlevel.h -$(CC) -c $(CFLAGS) update.c * ************** *** 259,265 nn1: $(NN) $(CC) $(CFLAGS) $(NN) TERMLIB EXTRA_LIB -Mnn1 -o nn1 ! * this is probably non-portable so it is ifdef'ed #ifdef WITH_LINT lint: --- 259,265 ----- nn1: $(NN) $(CC) $(CFLAGS) $(NN) TERMLIB EXTRA_LIB -Mnn1 -o nn1 ! * this is probably non-portable so it is ifdef-ed #ifdef WITH_LINT lint: -- 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!