This is more.c in view mode; [Download] [Up]
/* * (c) Copyright 1990, Kim Fabricius Storm. All rights reserved. * * Article browser. */ #include "config.h" #include "articles.h" #include "news.h" #include "term.h" #include "menu.h" #include "keymap.h" #include "regexp.h" export int monitor_mode = 0; export int compress_mode = 0; export int show_article_date = 1; export int first_page_lines = 0; export int overlap = 2; export int mark_overlap = 0; export char *header_lines = NULL; export int min_pv_window = 7; export int wrap_headers = 6; export int data_bits = 7; export int scroll_clear_page = 1; export int expired_msg_delay = 1; export char *trusted_escapes = NULL; export int new_read_prompt = 1; export int re_layout_more = -1; export int scroll_last_lines = 0; import int preview_window; import int novice; import int slow_mode; import int auto_preview_mode; import int flush_typeahead; import int case_fold_search; import int echo_prefix_key; import int re_layout; import char delayed_msg[]; extern char *init_save(); static int rot13_must_init = 1; static char rot13_table[128]; export int rot13_active = 0; #define ROT13_DECODE(c) ((c & 0x80) ? c : rot13_table[c]) static int compress_space; static regexp *regular_expr = NULL; #define LINEMAX 100 /* most articles are less than 100 lines */ export int mark_overlap_shading = 0; export char *shade_on_attr = NULL; export char *shade_off_attr = NULL; static shadeline(on) int on; { if (on) { if (shade_on_attr) fputs(shade_on_attr, stdout); else underline(1); } else if (shade_off_attr) fputs(shade_off_attr, stdout); else underline(0); } static struct header_def { char field; char *text; char **news; char **digest; } header_defs[] = { 'A', "Approved", &news.ng_appr, 0, 'B', "Distribution",&news.ng_dist, 0, 'C', "Control", &news.ng_control, 0, 'D', "Date", &news.ng_date, &digest.dg_date, 'F', "From", &news.ng_from, &digest.dg_from, 'f', "Sender", &news.ng_sender, 0, 'I', "Message-Id", &news.ng_ident, 0, 'K', "Keywords", &news.ng_keyw, 0, 'L', "Lines", &news.ng_xlines, 0, 'N', "Newsgroups", &news.ng_groups, 0, 'O', "Organization",&news.ng_org, 0, 'P', "Path", &news.ng_path, 0, 'R', "Reply-To", &news.ng_reply, 0, 'S', "Subject", &news.ng_subj, &digest.dg_subj, 'W', "Followup-To", &news.ng_follow, 0, 'X', "References", &news.ng_ref, 0, 'Y', "Summary", &news.ng_summ, 0, 'd', "Date-Received", &news.ng_rdate, 0, 'g', "Newsgroup", &news.ng_groups, 0, 'G', "Newsgroup", &news.ng_groups, 0, 'n', "Newsgroups", &news.ng_groups, 0, 'x', "Back-Ref", &news.ng_bref, 0, 'v', "Save-File", NULL, 0, 'a', "Spool-File", NULL, 0, 'i', "DB-Info", NULL, 0, 0 }; get_header_field(code, namep, valp, ah) char code, **namep, **valp; register article_header *ah; { static char special[FILENAME]; register struct header_def *hdef; import char *folder_save_file, *default_save_file; char *lp; lp = NULL; for (hdef = header_defs; hdef->field; hdef++) { if (hdef->field != code) continue; if ((ah->flag & A_DIGEST) && hdef->digest) lp = *(hdef->digest); if (lp == NULL && hdef->news) lp = *(hdef->news); break; } switch (code) { case 'n': case 'g': if (lp == NULL) break; if (!(current_group->group_flag & G_MERGED) && strchr(lp, ',') == NULL) return 0; if (code == 'n') break; case 'G': if (ah->a_number > 0) { sprintf(special, "%s/%ld", current_group->group_name, (long)ah->a_number); lp = special; } else lp = current_group->group_name; break; case 'a': if (current_group->group_flag & G_FOLDER) lp = current_group->archive_file; else if (group_file_name && *group_file_name) lp = group_path_name; break; case 'v': if ((lp = current_group->save_file) == NULL) lp = (current_group->group_flag & G_FOLDER) ? folder_save_file : default_save_file; if (lp == NULL) return 0; if (expand_file_name(special, lp, 2)) lp = special; break; case 'i': sprintf(special, "#%ld fl=%lx re=%d li=%d hp=%ld fp=%ld lp=%ld ts=%ld", (long)ah->a_number, (long)ah->flag, ah->replies, ah->lines, (long)ah->hpos, (long)ah->fpos, (long)ah->lpos, (long)ah->t_stamp); lp = special; break; } if (lp == NULL) return 0; *namep = hdef->text; *valp = lp; return 1; } static char *scan_codes; static article_header *scan_arthdr; scan_header_fields(fields, ah) char *fields; article_header *ah; { scan_codes = fields; scan_arthdr = ah; } next_header_field(namep, valp, attrp) char **namep, **valp; fct_type *attrp; { fct_type attr; extern highlight(), underline(); while (*scan_codes) { attr = NULL_FCT; *namep = NULL; switch (*scan_codes) { case '*': scan_codes++; return 1; /* name == NULL */ case '=': attr = highlight; scan_codes++; break; case '_': attr = underline; scan_codes++; break; case '+': attr = shadeline; scan_codes++; break; } if (*scan_codes == NUL) break; if (attrp) *attrp = attr; if (get_header_field(*scan_codes++, namep, valp, scan_arthdr)) return 1; } return 0; } static do_auto_select() { register article_header *ah; register int32 n; import int show_art_next_invalid; int count = 0; for (n = 0; n < n_articles; n++) { ah = articles[n]; if (ah->attr == A_READ) continue; if (ah->attr & A_SELECT) continue; if (auto_select_article(ah, 2)) { ah->attr = A_AUTO_SELECT; show_art_next_invalid = 1; count++; } } if (count) msg("Selected %d articles", count); } static char *a_st_flags(flag) flag_type flag; { static char buf[40]; register char *cp; static flag_type 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, new_read_prompt ? ")--" : ")------"); return buf; } static brief_header_line(ah, lno) register article_header *ah; int lno; { int o_re_layout; so_gotoxy(0, lno, 0); so_printf("%s: ", ah->sender); o_re_layout = re_layout; if (re_layout_more >= 0) re_layout = re_layout_more; prt_replies(ah->replies); re_layout = o_re_layout; so_printf("%s", ah->subject); so_end(); } more(ah, mode, screen_offset) article_header *ah; int mode, screen_offset; { register char *lp; register int c, col, lno; register FILE *art; int more_cmd, eof, skip_spaces, has_space, window_lines; int form_feed, last_ff_line, ignore_nl; off_t firstl, lastl; off_t lineposbuf[LINEMAX]; off_t *linepos = lineposbuf; int linemax = LINEMAX; char linebuf[200], skip_char; int skip_wrap; news_header_buffer ngheader, dgheader; struct news_header news_save; struct digest_header digest_save; int linenum, maxline, topline, print_lines, lno1; int scroll_lines, scroll_from; off_t scroll_offset; int underline_line, fake_underline; int match_lines, match_redraw, match_topline, match_botline; int goto_line, prev_goto, stop_line, extra_lines; flag_type in_digest = ah->flag & A_DIGEST; article_header digestah; char *fname, *hdrline; extern STANDOUT; char pr_fmt[200], send_date[40]; int match_expr, shade_overlap, shade_line; int *key_map; key_type cur_key; fct_type hdrattr; char *match_start, *match_end; int open_modes, hdr_mode, o_mode; struct header_def *hdef; extern int alt_cmd_key, in_menu_mode, any_message; #ifdef RESIZING int entry_col = Columns; #endif extern char *pct(); #define more_return(cmd) \ { more_cmd = cmd; goto more_exit; } if (ah->a_group != NULL) init_group(ah->a_group); open_modes = SKIP_HEADER; if (show_article_date || header_lines) { open_modes |= FILL_NEWS_HEADER; if (header_lines == NULL) open_modes |= GET_DATE_ONLY; else open_modes |= GET_ALL_FIELDS; if (in_digest) open_modes |= FILL_DIGEST_HEADER; } art = open_news_article(ah, open_modes, ngheader, dgheader); if (art == NULL) { if (expired_msg_delay >= 0) { msg("Canceled or expired: \"%s: %-.35s\"", ah->sender, ah->subject); if ((mode & MM_PREVIEW) == 0 && expired_msg_delay > 0) user_delay(expired_msg_delay); } return MC_NEXT; } o_mode = in_menu_mode; in_menu_mode = 0; if (screen_offset) if (preview_window < 1 && Lines - screen_offset < min_pv_window) screen_offset = 0; else { brief_header_line(ah, screen_offset++); if (!STANDOUT) screen_offset++; clrline(); } if (show_article_date) { if (in_digest && digest.dg_date) strncpy(send_date, digest.dg_date, 40); else if (news.ng_date) { strncpy(send_date, news.ng_date, 40); } else send_date[0] = NUL; send_date[39] = NUL; if (lp = strrchr(send_date, ':')) *lp = NUL; } linepos[0] = ah->hpos; linepos[1] = firstl = ah->fpos; maxline = 1; topline = 1; hdrline = screen_offset == 0 ? header_lines : ""; lastl = (ah->lpos - firstl + 99)/100; if (lastl == 0) lastl = 1; /* impossible ? */ rot13_active = 0; compress_space = compress_mode; last_ff_line = goto_line = -1, prev_goto = 1; skip_char = NUL; skip_wrap = 0; match_lines = match_redraw = match_expr = 0; underline_line = -1; fake_underline = 0; shade_overlap = 0; scroll_lines = scroll_from = 0; scroll_offset = 0; if (scroll_last_lines < 0) scroll_from = -1; else if (scroll_last_lines > 0) { if (ah->lines > 0) scroll_from = ah->lines - scroll_last_lines; else scroll_offset = ah->lpos - (scroll_last_lines * 64); } stop_line = first_page_lines ? first_page_lines : -1; if (new_read_prompt) { import long n_selected; char *xp, *group_name = current_group->group_name; int len, maxl; maxl = novice ? 18 : 25; if ((len = strlen(group_name)) > maxl) { for (xp = group_name + len - maxl; *xp; xp++) { if (*xp == '.') break; if (*xp == '/') { xp++; break; } } if (*xp) group_name = xp; else group_name += len - maxl; } if (mode & (MM_PREVIEW | MM_DIGEST) || n_selected == 0) sprintf(pr_fmt, "\1\2--%s-- %s%s %s--%%s--%%s\1", group_name, (mode & MM_DIGEST) ? "DIGEST" : (mode & MM_PREVIEW) ? "PREVIEW" : "LAST", (ah->flag & A_NEXT_SAME) ? "+next" : "", novice ? "--help:?" : ""); else sprintf(pr_fmt, "\1\2--%s-- %ld MORE%s %s--%%s--%%s\1", group_name, n_selected, (ah->flag & A_NEXT_SAME) ? "+next" : "", novice ? "--help:?" : ""); } else sprintf(pr_fmt, "\1\2-- %s%s %s-----%%s%s-----%%s\1", (mode & MM_PREVIEW) ? "PREVIEW " : "", (mode & MM_DIGEST) ? "FULL DIGEST" : (mode & MM_LAST_SELECTED) ? "LAST ARTICLE" : "ARTICLE", novice ? "-- help:? " : "", (ah->flag & A_NEXT_SAME) ? " (+next)" : ""); if (screen_offset) goto safe_redraw; redraw: /* redraw that will destroy whole screen */ screen_offset = 0; safe_redraw: /* redraw of "more window" only */ linenum = topline; next_page: no_raw(); s_keyboard = 0; if (stop_line) { lno = screen_offset; if (scroll_clear_page || linenum <= 1) { if (lno) { gotoxy(0, lno); clrpage(lno); } else clrdisp(); } if (linenum == 1) { hdrline = screen_offset == 0 ? header_lines : ""; if (hdrline && hdrline[0] == '@') { topline = linenum = 0; fseek(art, linepos[0], 0); hdrline = NULL; } } print_header: if (hdrline == NULL || *hdrline == '*') { if (hdrline && *++hdrline == NUL) hdrline = NULL; if (linenum <= 1) { if (linenum == 0 || (mode & MM_DIGEST)) { if (screen_offset) { lno--; if (!STANDOUT) lno--; gotoxy(0, lno); } so_printxy(0, lno, "Newsgroup: %s, article: %ld%s", current_group->group_name, (long)(ah->a_number), ((mode & MM_DIGEST) || in_digest) ? " *DIGEST*" : ""); /* fseek(art, linepos[0], 0); */ lno++; if (!STANDOUT) lno++; } else { if (screen_offset == 0 && linenum == 1) { if (show_article_date) so_printxy(-1, 0, send_date); brief_header_line(ah, lno++); if (!STANDOUT) lno++; } } } } if (hdrline && screen_offset == 0) { scan_header_fields(hdrline, ah); while (next_header_field(&fname, &hdrline, &hdrattr)) { if (fname == NULL) { hdrline = --scan_codes; /* this is a hack! */ goto print_header; } lp = hdrline; gotoxy(0, lno++); printf("%s: ", fname); c = col = strlen(fname) + 2; split_header_line: if (hdrattr) CALL(hdrattr)(1); while (*lp && c < Columns) { if (isspace(*lp)) { while (lp[1] && isspace(lp[1])) lp++; if (wrap_headers > 0 && (c + wrap_headers) >= Columns && strlen(lp) >= wrap_headers) { lp++; break; } *lp = SP; } putchar(*lp++); c++; } if (hdrattr) CALL(hdrattr)(0); if (*lp && wrap_headers >= 0) { gotoxy(col, lno++); c = col; goto split_header_line; } } hdrline = NULL; putchar(NL); lno++; } lno1 = lno; topline = linenum; window_lines = Lines - lno - 2; print_lines = window_lines; ignore_nl = 1; /* ignore blank lines at top op screen */ } else { putchar(CR); clrline(); print_lines = extra_lines; /* LINT complaints here -- ignore */ } if (stop_line > 0) { if (print_lines > stop_line) { extra_lines = print_lines - stop_line; print_lines = stop_line; underline_line = -1; shade_overlap = 0; } stop_line = 0; } else stop_line = -1; next_line: if (linenum == linemax) { linemax += 500; if (linepos == lineposbuf) { linepos = newobj(off_t, linemax); for (linenum = 0; linenum < LINEMAX; linenum++) linepos[linenum] = lineposbuf[linenum]; } else linepos = resizeobj(linepos, off_t, linemax); } if (goto_line == linenum) { goto_line = -1; goto next_page; } eof = 0; if (linenum > maxline) linepos[++maxline] = ftell(art); else if (linenum > 0) fseek(art, linepos[linenum], 0); if (linepos[linenum] >= ah->lpos) { if (match_expr) { match_expr = 0; topline = match_topline; /* LINT complaints here -- ignore */ linenum = match_botline; /* LINT complaints here -- ignore */ fseek(art, linepos[linenum], 0); msg("Not found"); goto Prompt; } eof++; if (goto_line > 0) { goto_line = -1; linenum -= window_lines/2; goto next_page; } goto Prompt; } if (linenum == 0) { if (ftell(art) >= linepos[1]) { linenum = 2; /* current line is 1st line ! */ lno1 = lno; } } else { if (match_expr && linenum == match_botline) msg("Searching..."); linenum++; } lp = linebuf; col = 0; form_feed = 0; next_char: c = getc(art); if (c == EOF) { eof++; if (lp == linebuf) goto Prompt; goto end_line; } if (c & 0200) { if (monitor_mode || data_bits != 8) { col += 4; if (col > Columns) { /* then there is no room for M-^X */ ungetc(c, art); goto long_line; } c &= 0177; *lp++ = 'M'; *lp++ = '-'; if (c < SP) { *lp++ = '^'; c += '@'; } else col--; } } else if (c < SP) { if (monitor_mode) { if (c == NL) { *lp++ = '$'; goto end_line; } if (col + 2 > Columns) { *lp++ = '\\'; ungetc(c, art); goto end_line; } *lp++ = '^'; c += '@'; col++; } else switch (c) { case '\f': last_ff_line = linenum; if (lp == linebuf) { if (goto_line > 0 || skip_char || match_expr || lno == lno1) goto next_line; form_feed = 1; goto Prompt; } form_feed = 1; goto end_line; case CR: if (lp == linebuf || ignore_nl) goto next_char; ignore_nl = 1; goto end_line; case NL: if (ignore_nl) { ignore_nl = 0; if (lp == linebuf) { if (lno == lno1) { ignore_nl = 1; goto next_line; } goto next_char; } } goto end_line; case BS: if (col) { lp--; col--; } goto next_char; case TAB: if (col + 8 - (col & 07) >= Columns) goto long_line; do { *lp++ = SP; col++; } while (col & 07); goto next_char; case 033: /* ESC may be a start/end of kanji or similar */ if (trusted_escapes != NULL) { if (col + 3 > Columns) { ungetc(c, art); goto long_line; } if (strcmp(trusted_escapes, "all") == 0) break; c = getc(art); if (c == EOF) goto next_char; ungetc(c, art); for (fname = trusted_escapes; *fname; fname++) if (c == *fname) break; c = 033; if (*fname != NUL) break; } /* FALL THRU */ default: if (col + 2 > Columns) { ungetc(c, art); goto long_line; } *lp++ = '^'; c += '@'; col++; break; } } else if (rot13_active && linenum > 0) c = ROT13_DECODE(c); *lp++ = c; col++; ignore_nl = 0; if (col < Columns) goto next_char; long_line: ignore_nl = 1; end_line: /* if we are seaching for a specific line, repeat until it is found */ if (skip_wrap) { skip_wrap = ignore_nl; goto next_line; } if (goto_line >= linenum) goto next_line; if (skip_char) { if (lp == linebuf || linebuf[0] == skip_char) { skip_wrap = ignore_nl; goto next_line; } skip_char = NUL; if (overlap > 0) { underline_line = linenum - 1; linenum -= overlap + 1; shade_overlap = mark_overlap_shading; goto next_page; } } *lp++ = NUL; if (match_expr) { if (!regexec_cf(regular_expr, linebuf)) goto next_line; match_expr = 0; match_lines = 1; if (linenum > match_botline) { match_redraw = 0; if (last_ff_line > linenum) last_ff_line = -1; linenum -= 5; if (linenum < last_ff_line) linenum = last_ff_line; goto next_page; } match_redraw = (stop_line < 0); stop_line = -1; lno = lno1 + linenum - topline - 1; print_lines = window_lines - lno + lno1; } /* now print the line */ shade_line = 0; if ((shade_overlap > 0 && linenum <= underline_line) || (shade_overlap < 0 && linenum > underline_line)) { if (match_redraw) goto no_print; match_start = NULL; shade_line = 1; } else if (match_lines && underline_line != linenum && regexec_cf(regular_expr, linebuf)) { match_start = regular_expr->startp[0]; match_end = regular_expr->endp[0]; if (match_start == match_end) { match_start = NULL; /* null string */ if (match_redraw) goto no_print; } } else { if (match_redraw) goto no_print; match_start = NULL; } gotoxy(0, lno); if (!scroll_clear_page) clrline(); if (shade_line) shadeline(1); else if (mark_overlap && underline_line == linenum) if (!underline(1)) fake_underline = 1; skip_spaces = has_space = 0; for (lp = linebuf; c = *lp; lp++) { if (match_start) { if (lp == match_start) highlight(1); if (lp == match_end) { highlight(0); match_start = NULL; if (regexec_cf(regular_expr, lp)) { match_start = regular_expr->startp[0]; match_end = regular_expr->endp[0]; lp--; continue; } if (match_redraw) goto no_print; } } if (c == SP) { if (skip_spaces) { if (has_space) continue; has_space++; } if (fake_underline) c = '_'; } else { if (compress_space && c != ' ') { skip_spaces = 1; has_space = 0; } } putchar(c); } if (match_start) highlight(0); if (shade_line) { shadeline(0); if (shade_overlap > 0 && underline_line == linenum) { underline_line = -1; shade_overlap = 0; } } else if (mark_overlap && underline_line == linenum) { while (lp - linebuf < 10) { putchar(fake_underline ? '_' : ' '); lp++; } underline(0); underline_line = -1; fake_underline = 0; } no_print: ++lno; if (--print_lines > 0 && s_keyboard == 0 && form_feed == 0) goto next_line; if (shade_overlap) { underline_line = -1; shade_overlap = 0; } if (!eof && linenum >= maxline) { if (ignore_nl) { c = getc(art); if (c == EOF) eof++; else if (c != NL) ungetc(c, art); else ignore_nl = 0; } if (!eof && ftell(art) >= ah->lpos) eof++; } match_redraw = 0; Prompt: if (eof && lno == screen_offset) more_return(MC_NEXT); if (scroll_lines > 0) { if (eof) scroll_lines = 0; else { print_lines = 1; scroll_lines--; prompt_line = lno; goto scroll_next; } } raw(); prompt_line = lno; if (!scroll_clear_page) clrpage(prompt_line); dflt_prompt: prompt(pr_fmt, pct((long)(ah->fpos), (long)(ah->lpos), (long)(linepos[topline]), (long)ftell(art)), a_st_flags(ah->flag)); if (delayed_msg[0] != NUL) { msg(delayed_msg); delayed_msg[0] = NUL; } same_prompt: if (flush_typeahead) flush_input(); key_map = more_key_map; prefix_key: if ((c = get_c()) & GETC_COMMAND) c &= ~GETC_COMMAND; else c = key_map[cur_key = c]; if (s_hangup) c = K_QUIT; if (c & K_PREFIX_KEY) { key_map = keymaps[c & ~K_PREFIX_KEY].km_map; if (echo_prefix_key) msg("%s", key_name(cur_key)); goto prefix_key; } if (any_message && c != K_LAST_MESSAGE) clrmsg(0); if (c & K_MACRO) { m_invoke(c & ~K_MACRO); goto same_prompt; } alt_key: switch (c) { case K_UNBOUND: ding(); case K_INVALID: goto same_prompt; case K_REDRAW: #ifdef RESIZING if (Columns != entry_col) { entry_col = Columns; maxline = topline = 1; } #endif goto redraw; case K_NEXT_PAGE: if (eof) { ding(); goto same_prompt; } /* FALL THRU */ case K_CONTINUE: if (eof) break; if (screen_offset == 0 && form_feed == 0 && stop_line) { if ((scroll_from && linenum > scroll_from) || (scroll_offset && ftell(art) > scroll_offset)) { scroll_lines = Lines - 2 - overlap; print_lines = 1; goto scroll; } if (linenum > overlap) { underline_line = linenum; linenum -= overlap; shade_overlap = mark_overlap_shading; } } goto next_page; case K_LAST_MESSAGE: msg((char *)NULL); goto dflt_prompt; case K_HELP: display_help("more"); goto redraw; case K_SHELL: putchar(CR); if (shell_escape()) goto redraw; goto dflt_prompt; case K_VERSION: prompt(P_VERSION); goto same_prompt; case K_EXTENDED_CMD: news_save = news; digest_save = digest; more_cmd = alt_command(); news = news_save; digest = digest_save; switch (more_cmd) { case AC_UNCHANGED: goto same_prompt; case AC_QUIT: more_return( MC_QUIT ); case AC_PROMPT: goto dflt_prompt; case AC_REENTER_GROUP: more_return( MC_REENTER_GROUP ); case AC_REORDER: more_return( MC_MENU ); case AC_REDRAW: goto redraw; case AC_KEYCMD: c = alt_cmd_key; goto alt_key; } case K_QUIT: ah->attr = A_LEAVE_NEXT; more_return( MC_QUIT ); case K_SAVE_NO_HEADER: case K_SAVE_SHORT_HEADER: case K_SAVE_FULL_HEADER: case K_PRINT: case K_UNSHAR: case K_PATCH: case K_UUDECODE: news_save = news; digest_save = digest; putchar(CR); if (init_save(c, (char **)NULL) != NULL) { if (c == K_UNSHAR) prompt_line = Lines - 2; save(ah); end_save(); } news = news_save; digest = digest_save; if (!slow_mode && (c == K_UNSHAR || c == K_PATCH)) { printf("\r\n\n"); any_key(0); goto redraw; } goto Prompt; case K_FOLLOW_UP: #ifdef NNTP_POST if (use_nntp && nntp_no_post()) goto Prompt; #endif case K_REPLY: case K_MAIL_OR_FORWARD: news_save = news; digest_save = digest; more_cmd = answer(ah, c, -1); news = news_save; digest = digest_save; if (more_cmd) if (slow_mode) clrdisp(); else goto redraw; goto Prompt; case K_POST: if (post_menu()) if (slow_mode) clrdisp(); else goto redraw; goto Prompt; case K_CANCEL: if (current_group->group_flag & G_FOLDER) { prompt("%s this folder entry", (ah->attr == A_CANCEL) ? "UNcancel" : "Cancel"); if (yes(0)) fcancel(ah); goto Prompt; } if (cancel(ah) > 0) goto Prompt; more_return(MC_NEXT); case K_UNSUBSCRIBE: if (!unsubscribe(current_group)) goto Prompt; if ((current_group->group_flag & G_UNSUBSCRIBED) == 0) goto Prompt; more_return(MC_NEXTGROUP); case K_GROUP_OVERVIEW: group_overview(-1); goto redraw; case K_KILL_HANDLING: switch (kill_menu(ah)) { case 0: do_auto_select(); ah->attr = 0; break; case 1: more_return(MC_DO_KILL); default: break; } goto Prompt; case K_READ_GROUP_UPDATE: if (mode & MM_PREVIEW) more_return(MC_MENU); prompt("Mark rest of current group as read?"); if (yes(1) <= 0) goto Prompt; more_return(MC_READGROUP); case K_NEXT_GROUP_NO_UPDATE: if (mode & MM_PREVIEW) more_return(MC_MENU); more_return(MC_NEXTGROUP); case K_BACK_TO_MENU: more_return(MC_MENU); case K_PREVIOUS: if ((mode & MM_PREVIOUS) == 0) { msg("No previous article"); goto dflt_prompt; } more_return(MC_PREV); case K_ADVANCE_GROUP: case K_BACK_GROUP: case K_GOTO_GROUP: news_save = news; digest_save = digest; more_cmd = goto_group(c, ah, (flag_type)0); news = news_save; digest = digest_save; switch (more_cmd) { case ME_NO_REDRAW: goto Prompt; case ME_QUIT: more_return( ME_QUIT ); default: goto redraw; } case K_NEXT_LINE: if (eof) break; if (screen_offset) goto same_prompt; print_lines = 1; goto scroll; case K_NEXT_HALF_PAGE: if (eof) break; if (screen_offset) goto same_prompt; print_lines = window_lines/2; scroll: gotoxy(0, prompt_line); clrpage(prompt_line); no_raw(); if (print_lines + lno < (Lines - 1)) goto next_page; stop_line = -1; scroll_next: gotoxy(0, Lines-1); c = print_lines + lno - Lines + 2; while (--c >= 0) { putchar(NL); if (--lno1 < 0) topline++; prompt_line--; } if (lno1 < 0) lno1 = 0; if (prompt_line < 0) prompt_line = 0; lno = prompt_line; goto next_line; case K_PREV_HALF_PAGE: if (topline <= 1) goto Prompt; linenum = topline - window_lines/2; if (linenum < 1) linenum = 1; goto next_page; case K_PREV_PAGE: if (topline <= 1) goto Prompt; linenum = topline - window_lines + overlap; /* not perfect after FF */ underline_line = topline; shade_overlap = -mark_overlap_shading; if (linenum < 1) linenum = 1; goto next_page; case K_SKIP_LINES: skip_char = linebuf[0]; goto next_page; case K_GOTO_LINE: prompt("\1Go to line:\1 "); if ((fname = get_s(NONE, NONE, "$^", NULL_FCT)) == NULL) goto Prompt; if (*fname == NUL) { if (prev_goto < 0) goto Prompt; goto_line = prev_goto; } else if (*fname == '$') goto_line = 30000; else if (*fname == '^') goto_line = 1; else { goto_line = atoi(fname); if (goto_line <= 0) { goto_line = -1; goto Prompt; } } goto_page: prev_goto = topline; if (goto_line <= maxline) { linenum = goto_line; goto_line = -1; } goto next_page; case K_SELECT_SUBJECT: more_return(MC_ALLSUBJ); case K_HEADER_PAGE: fseek(art, linepos[0], 0); goto_line = 0; goto goto_page; case K_FIRST_PAGE: goto_line = 1; goto goto_page; case K_LAST_PAGE: goto_line = 30000; goto goto_page; case K_GOTO_MATCH: prompt("\1/\1"); if ((fname = get_s(NONE, NONE, "/", NULL_FCT)) == NULL) goto Prompt; if (*fname && *fname != '/') { if (regular_expr) freeobj(regular_expr); if (case_fold_search) fold_string(fname); regular_expr = regcomp(fname); match_lines = 0; } case K_NEXT_MATCH: if (regular_expr == NULL) { msg("No previous expression"); goto Prompt; } match_expr = 1; if (match_topline != topline) prev_goto = topline; match_topline = topline; match_botline = linenum; if (match_lines == 0 && topline <= 1) linenum = topline; match_lines = 0; goto next_line; /* don't clear the screen if no match */ case K_FULL_DIGEST: if (mode & MM_DIGEST) more_return( MC_NO_REDRAW ); if (!in_digest) goto same_prompt; /* could do something more clever here later */ digestah = *ah; digestah.flag &= ~A_DIGEST; digestah.hpos = digestah.fpos = 0; fseek(art, 0L, 2); digestah.lpos = ftell(art); switch (more(&digestah, mode | MM_DIGEST, screen_offset)) { case MC_REDRAW: goto redraw; case MC_NO_REDRAW: goto safe_redraw; case MC_QUIT: more_return( MC_QUIT ); case MC_REENTER_GROUP: more_return( MC_REENTER_GROUP ); default: goto safe_redraw; } case K_LEAVE_NEXT: ah->attr = A_LEAVE_NEXT; more_return(MC_PREVIEW_NEXT); case K_LEAVE_ARTICLE: ah->attr = (mode & MM_PREVIEW) ? A_SELECT : A_LEAVE; /* fall thru */ case K_NEXT_ARTICLE: 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); case K_ROT13: if (rot13_must_init) { register i; for (i=0; i<=127; i++) { c = i; if (c >= 'a' && c <= 'm') c += 13; else if (c >= 'n' && c <= 'z') c -= 13; else if (c >= 'A' && c <= 'M') c += 13; else if (c >= 'N' && c <= 'Z') c -= 13; rot13_table[i] = c; } rot13_must_init = 0; } rot13_active = !rot13_active; goto safe_redraw; case K_COMPRESS: compress_space = !compress_space; goto safe_redraw; case K_PREVIEW: if (mode & MM_PREVIEW) more_return(MC_PREVIEW_OTHER); /* fall thru to "default" */ default: msg("Command %d not supported", c); goto dflt_prompt; } more_return(MC_NEXT); more_exit: in_menu_mode = o_mode; rot13_active = 0; if (linepos != lineposbuf) freeobj(linepos); no_raw(); fclose(art); if (mode & MM_PREVIEW) if (more_cmd != MC_QUIT && more_cmd != MC_REENTER_GROUP) { gotoxy(0, screen_offset); clrpage(screen_offset); if (auto_preview_mode && ah->attr == 0) ah->attr = A_READ; if (screen_offset == 0) prompt_line = -1; } return more_cmd; } rot13_line(cp) register char *cp; { register int c; while (c = *cp) *cp++ = ROT13_DECODE(c); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.