rsalz@uunet.uu.net (Rich Salz) (06/23/89)
Submitted-by: storm@texas.dk (Kim F. Storm) Posting-number: Volume 19, Issue 68 Archive-name: nn/part07 #!/bin/sh # this is part 7 of a multipart archive # do not concatenate these parts, unpack them in order with /bin/sh # file master.c continued # CurArch=7 if test ! -r s2_seq_.tmp then echo "Please unpack part 1 first!" exit 1; fi ( read Scheck if test "$Scheck" != $CurArch then echo "Please unpack part $Scheck next!" exit 1; else exit 0; fi ) < s2_seq_.tmp || exit 1 echo "x - Continuing file master.c" sed 's/^X//' << 'NO_NEWS_IS_GOOD_NEWS' >> master.c X write_error(); X fflush(master_file); X} X X Xclean_group(gh) Xregister group_header *gh; X{ X if (trace) X log_entry('T', "CLEAN %s", gh->group_name); X X gh->first_l_article = 0; X gh->last_l_article = 0; X X gh->index_write_offset = (off_t)0; X gh->data_write_offset = (off_t)0; X X gh->group_flag &= ~G_EXPIRE; X gh->group_flag |= G_BLOCKED; X X save_group(gh); X} X X/* X * Build initial master file ; calls Initialize script and X * reads info from its standard output X */ X Xbuild_master() X{ X char command[512]; X char groupname[512]; X group_header group; X FILE *group_file, *src; X int lcount, use_group_file; X X X printf("Confirm initialization by typing 'OK': "); X fl; X gets(command); X if (strcmp(command, "OK")) { X printf("No initialization\n"); X nn_exit(0); X } X X printf("Initializing master data base..."); X fl; X X if (chdir(lib_directory) < 0) /* so we can use open_file */ X sys_error("lib"); X X#ifdef NNTP X if (use_nntp && nntp_get_active() < 0) X sys_error("Can't get active file"); X#endif X /* check active file for duplicates */ X X sprintf(command, "awk 'NF>0{print $1}' %s | sort | uniq -d", news_active); X X src = popen(command, "r"); X X for (lcount = 0; fgets(groupname, 512, src); lcount++) { X if (lcount == 0) X printf("\n%s contains duplicate entries for the following groups:", X news_active); X X fputs(groupname, stdout); X } X X pclose(src); X X if (lcount > 0) { X printf("Do you want to repair this file before continuing ? (y)"); X gets(command); X if (command[0] == NUL || command[0] == 'y' || command[0] == 'Y') X nn_exit(0); X } X X /* if a "GROUPS" file exist offer to use that, else */ X /* read group names from active file */ X X use_group_file = 0; X X if (src = open_groups(OPEN_READ)) { X printf("\nA GROUPS file already exist -- reuse it? (y)"); X fl; X gets(command); X if (command[0] == NUL || command[0] == 'y' || command[0] == 'Y') { X use_group_file = 1; X } else X fclose(src); X } X X if (!use_group_file) { X strcpy(command, "awk 'NF>0{print $1}' "); X strcat(command, news_active); X strcat(command, " | sort -u"); X X src = popen(command, "r"); X X group_file = open_groups(OPEN_CREATE|MUST_EXIST); X } X X open_master(OPEN_CREATE); X X fseek(master_file, sizeof(master), 0); X X master.number_of_groups = 0; X X while (fgets(groupname, 512, src)) { X X group.group_num = master.number_of_groups++; X X group.group_name_length = strlen(groupname) - 1; /* strip NL */ X groupname[group.group_name_length] = NUL; X group.group_name = groupname; X X init_group(&group); X X clean_group(&group); X X group.group_flag = 0; X X /* moderation flag will be set by first visit_active_file call */ X X if (strcmp(groupname, "control") == 0) X group.group_flag |= G_CONTROL; X X save_group(&group); X X if (!use_group_file) { X groupname[group.group_name_length] = NL; X Fwrite(groupname, sizeof(char), X group.group_name_length + 1, group_file); X } X } X X if (use_group_file) { X master.next_group_write_offset = ftell(src); X fclose(src); X } else { X master.next_group_write_offset = ftell(group_file); X fclose(group_file); X pclose(src); X } X X master.last_scan = 0; X X save_master(); X X close_master(); X X printf("done\n"); X X log_entry('M', "Master data base initialized"); X X fl; X} X X X/* X * receive commands from administrator X */ X Xreceive_admin() X{ X FILE *gate; X char buffer[128], *bp; X char command, *user_date; X long arg1, arg2; X int must_collect; X register group_header *gh; X X gate = open_file(relative(lib_directory, "GATE"), OPEN_READ | OPEN_UNLINK); X if (gate == NULL) return 0; X X sleep(2); /* give administrator time to flush buffers */ X X must_collect = 0; X X while (fgets(buffer, 128, gate)) { X bp = buffer; X command = *bp; X if ((bp = strchr(bp, ';')) == NULL) continue; X arg1 = atol(++bp); X if ((bp = strchr(bp, ';')) == NULL) continue; X arg2 = atol(++bp); X if ((bp = strchr(bp, ';')) == NULL) continue; X user_date = ++bp; X if ((bp = strchr(bp, ';')) == NULL) continue; X *bp++ = NUL; X if (*bp != NL) continue; X X log_entry('A', "RECV %c %ld %ld (%s)", X command, arg1, arg2, user_date); X X if (arg1 >= 0 && arg1 < master.number_of_groups) X gh = &active_groups[arg1]; X else X gh = NULL; X X switch (command) { X X case 'r': X repeat_delay = arg1; X continue; X X case 'e': X expire_level = arg1; X continue; X X case 'X': /* expire */ X if (gh) { X gh->group_flag |= G_EXPIRE | G_BLOCKED; X save_group(gh); X break; X } X visit_active_file(); /* just in case */ X Loop_Groups_Header(gh) { X if (gh->first_l_article + arg2 < gh->first_article) { X gh->group_flag |= G_EXPIRE; X save_group(gh); /* could block here */ X } X } X break; X X case 'S': /* set flag */ X gh->group_flag |= arg2; X save_group(gh); X continue; X X case 'C': /* clear flag */ X gh->group_flag |= arg2; X save_group(gh); X continue; X X case 'R': /* recollect */ X if (gh) { X clean_group(gh); X } else X Loop_Groups_Header(gh) X clean_group(gh); X break; X X case 'U': /* unconditional pass */ X unconditional++; X break; X X case 'T': /* toggle trace flag */ X trace = !trace; X continue; X X default: X continue; X } X must_collect++; X } X X fclose(gate); X X return must_collect; X} X X X/* X * disk write with check -- halt if no space on disk X */ X X XFwrite(buf, size, nitems, stream) Xchar *buf; Xint size; Xint nitems; XFILE *stream; X{ X if (fwrite(buf, size, nitems, stream) != nitems) X write_error(); X} X Xwrite_error() X{ X /* X * should wait for problems to clear out rather than die... X */ X sys_error("DISK WRITE ERROR"); X} X X/* X * dummy routines - should never be called by master X */ X X/*VARARGS*/ Xuser_error() X{ X dummy_error("user_error"); X} X Xdummy_error(name) Xchar *name; X{ X sys_error("Dummy routine called by master: %s", name); X} X X X#ifdef NNTP /* XXX */ Xmsg() {} X#endif /* NNTP Bogus */ NO_NEWS_IS_GOOD_NEWS echo "File master.c is complete" chmod 0644 master.c || echo "restore of master.c fails" set `wc -c master.c`;Sum=$1 if test "$Sum" != "15145" then echo original size 15145, current size $Sum;fi echo "x - extracting match.c (Text)" sed 's/^X//' << 'NO_NEWS_IS_GOOD_NEWS' > match.c && X#define NUL '\0' X#define NULL ((char *)0) X X X#ifdef notdef X X/* use this table for creating input to the match.h routines */ X Xchar match_xxx[128] = { X X/* NUL SOH STX ETX EOT ENQ ACK BEL BS TAB NL VT FF CR SO SI */ X 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, X X/* DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US */ X 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, X X/* SP ! " # $ % & ' ( ) * + , - . / */ X 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, X X/* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */ X 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, X X/* @ A B C D E F G H I J K L M N O */ X 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, X X/* P Q R S T U V W X Y Z [ \ ] ^ _ */ X 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, X X/* ` a b c d e f g h i j k l m n o */ X 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, X X/* p q r s t u v w x y z { | } ~ DEL */ X 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 X X}; X#endif X X X/* X * the following routines only works for ASCII !!!! X * X * they are a quick hack to check for the occurrence of a word X * (regardless of case) in a string X */ X X#define UNIFY 040 X Xinit_quick_match(mask) Xchar *mask; X{ X register char *m; X X for (m = mask; *m; m++) *m |= UNIFY; X} X Xchar *quick_match(subject, mask) Xregister char *subject; Xchar *mask; X{ X register char *q, *m; X register char m1 = *mask; X X for (; *subject; subject++) { X if ((*subject | UNIFY) != m1) continue; X X q = subject; m = mask; X do X if (*++m == NUL) return subject; X while ((*++q | UNIFY) == *m); X } X return NULL; X} NO_NEWS_IS_GOOD_NEWS chmod 0644 match.c || echo "restore of match.c fails" set `wc -c match.c`;Sum=$1 if test "$Sum" != "1884" then echo original size 1884, current size $Sum;fi echo "x - extracting match.h (Text)" sed 's/^X//' << 'NO_NEWS_IS_GOOD_NEWS' > match.h && X/* usage: X * MATCH_DROP(t, a) and MATCH_DROP(t, b) must both be proven false X * before MATCH_EQ(t, a, b) is used. X */ X X#define MATCH_DROP(table, c) ( c & 0200 || table[c] == 0 ) X X#define MATCH_EQ(table, a, b) ( a == b || table[a] == table[b] ) X X#define MATCH_LS_EQ(table, a, b) ( a <= b || table[a] <= table[b] ) X X#define MATCH_LS(table, a, b) ( a < b || table[a] < table[b] ) X X#define MATCH_CMP(table, a, b) (table[a] - table[b]) NO_NEWS_IS_GOOD_NEWS chmod 0644 match.h || echo "restore of match.h fails" set `wc -c match.h`;Sum=$1 if test "$Sum" != "439" then echo original size 439, current size $Sum;fi echo "x - extracting menu.c (Text)" sed 's/^X//' << 'NO_NEWS_IS_GOOD_NEWS' > menu.c && X/* X * selection mode menu X */ X X#include "config.h" X#include "articles.h" X#include "term.h" X#include "keymap.h" X#include "menu.h" X X Xexport int preview_window = 0; /* size of preview window */ Xexport int fmt_linenum = 1; /* menu line format */ Xexport int fmt_rptsubj = 0; /* repeat identical subjects if !0 */ Xexport int novice = 1; /* novice mode -- use extended prompts */ Xexport int long_menu = 0; /* don't put empty lines around menu lines */ Xexport int delay_redraw = 0; /* prompt again if :-command clears screen */ X Xexport char *delayed_msg = NULL; /* give to msg() after redraw */ X Ximport also_read_articles; Ximport merged_menu; X Xextern group_completion(); X Xstatic int firstl; /* first menu line */ X Xstatic int firsta; /* first article on menu (0 based) */ Xstatic int cura; /* current article */ Xstatic int next_cura; /* article to become cura if >= 0 */ Xstatic int numa; /* no of articles on menu - 1 */ X X#define INTERVAL1 ('z' - 'a' + 1) X#define INTERVAL2 ('9' - '0' + 1) X Xchar ident[] = "abcdefghijklmnopqrstuvwxyz0123456789"; Xchar Ident[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ&&&&&&&&&&"; X X/* mark commands */ X X#define OFF 0 X#define ON 1 X#define TOGGLE 2 X#define INIT 3 X#define SAVED 4 X#define REMOVE 5 X#define CANCEL 6 X Xstatic int how; X Xstatic mark() X{ X register article_header *ah; X int lno, curhow, must_print, lnum, lsubj, lname; X X ah = articles[firsta + cura]; X curhow = (ah->flag & A_SELECT) ? ON : OFF; X if (how == curhow) return; X X lno = firstl + cura; X must_print = STANDOUT; X X toggle: X X switch (how) { X X case TOGGLE: X how = (curhow == ON) ? OFF : ON; X goto toggle; X X case ON: X if (ah->flag & A_CANCEL) { X if (curhow == OFF) return; X how = OFF; X goto toggle; X } X ah->flag |= A_SELECT; X break; X X case OFF: X ah->flag &= ~A_SELECT; X break; X X case INIT: X gotoxy(0, lno); X putchar(ident[cura]); X how = curhow; X must_print = 1; X break; X X case SAVED: X gotoxy(0, lno); X putchar(Ident[cura]); X return; X X case REMOVE: X gotoxy(0, lno); X clrline(); X return; X X case CANCEL: X gotoxy(1, lno); X if (ah->flag & A_SELECT) { X ah->flag &= ~A_SELECT; X break; X } X putchar((ah->flag & A_CANCEL) ? '#' : ' '); X return; X } X X if (cura < 0 || cura > numa) return; X X /* menu line formats: X 1 3 8 10 20 22 xx X : : : : : : : X 0 id name subject +lines X 1 id name lines subject X 2 id lines subject X 3 id subject X 4 id name:8 subject X */ X X if (must_print) { X X if (fmt_linenum > 4) fmt_linenum = 1; X X if (ah->flag & A_CANCEL) { X gotoxy(1, lno); X putchar('#'); X } else X if (how == ON) { X if (so_gotoxy(1, lno, 1) == 0) putchar('*'); X } else { X gotoxy(1, lno); X putchar(' '); X } X X if (fmt_linenum > 1) lnum = 0; else X if (ah->lines < 10) lnum = 1; else X if (ah->lines < 100) lnum = 2; else X if (ah->lines < 1000) lnum = 3; else X if (ah->lines < 10000) lnum = 4; else lnum = 5; X X lsubj = Columns - cookie_size - 2; /* ident char + space */ X X switch (fmt_linenum) { X X case 0: X lsubj -= NAME_LENGTH + 1 + 2 + lnum; /* name. .subj. +.lines */ X so_printf("%-*s ", NAME_LENGTH, ah->sender); X break; X X case 1: X lsubj -= NAME_LENGTH + 4; X /* name.lines. .subj (name may be shortened) */ X lname = NAME_LENGTH + 2 - lnum; X lsubj -= 4; /* 2 columns for the number + 2 spaces */ X so_printf("%-*.*s ", lname, lname, ah->sender); X so_printf(ah->lines >= 0 ? "%d " : "? ", ah->lines); X break; X X case 2: X lsubj -= 6; X so_printf("%5d ", ah->lines); X break; X X case 3: X break; X X case 4: X lsubj -= 9; X so_printf("%-8.8s ", ah->sender); X break; X } X X if (!fmt_rptsubj && lno > firstl && ah->flag & A_SAME) { X if (ah->replies == 0) X so_printf("-"); X else X prt_replies(ah->replies); X } else { X lsubj -= prt_replies(ah->replies); X so_printf("%-.*s", lsubj, ah->subject); X } X X if (fmt_linenum == 0) X so_printf(ah->lines >= 0 ? " +%d" : " +?", ah->lines); X X so_end(); X } else X putchar((how == OFF) ? ' ' : '*'); X X fl; X X return; X} X X Xstatic prt_replies(level) X{ X if (level == 0) return 0; X X if (level < 10) { X so_printf("%-.*s", level, ">>>>>>>>>"); X return level; X } X X so_printf(">>>%3d >>>>", level); X return 11; X} X X Xstatic int article_id; X Xstatic int get_k_cmd() X{ X register int c, map; X X loop: X X article_id = -1; X X if ((c = get_c()) & GETC_COMMAND) X map = c & ~GETC_COMMAND; X else X map = menu_key_map[c]; X X if (s_hangup) map = K_QUIT; X X if (map & K_MACRO) { X m_invoke(map & ~K_MACRO); X goto loop; X } X X if (map & K_ARTICLE_ID) { X article_id = map & ~K_ARTICLE_ID; X map = K_ARTICLE_ID; X X if (article_id < 0 || article_id > numa) { X ding(); X goto loop; X } X } X X return map; X} X X Xchar *pct(start, end, first, last) Xlong start, end, first, last; X{ X long n = end - start; X static char buf[16]; X char *fmt; X X if (first <= start || n <= 0) X if (last >= end) X return "All"; X else X fmt = "Top %d%%"; X else X if (last >= end) X return "Bot"; X else X fmt = "%d%%"; X X sprintf(buf, fmt, ((last - start) * 100)/n); X return buf; X} X Xmenu(print_header) Xint (* print_header)(); X{ X register k_cmd, cur_k_cmd; X register article_header *ah; X int last_k_cmd, last_how, was_selected; X int seen_all, menu_cmd, temp; X int save_selected, last_save; X int doing_unshar, did_unshar; X char *fname, *savemode, *init_save(); X int nexta; /* first article on next menu */ X int maxa; /* max no of articles per menu page */ X int o_firsta, o_mode; /* for recursive calls */ X static menu_level = 0; X char purpose[80], pr_fmt[60]; X extern int enable_stop, file_completion(); X extern int alt_cmd_key, in_menu_mode, slow_mode, any_message; X X#define menu_return(cmd) \ X { menu_cmd = (cmd); goto menu_exit; } X X o_firsta = firsta; X o_mode = in_menu_mode; X in_menu_mode = 1; X X menu_level++; X X sprintf(pr_fmt, X menu_level == 1 ? X "\1\2-- SELECT %s-----%%s-----\1" : X "\1\2-- SELECT %s-----%%s-----<%s%d>--\1", X novice ? "-- help:? " : "", X novice ? "level " : "", X menu_level); X X purpose[0] = NUL; X if (!merged_menu && current_group->group_flag & G_NEW) X get_purpose(purpose); X X seen_all = 0; X firsta = 0; X while (firsta < n_articles && articles[firsta]->flag & A_SEEN) X firsta++; X X if (firsta == n_articles) { X seen_all++; X firsta = 0; X } X X next_cura = -1; X cur_k_cmd = K_UNBOUND; X X#ifdef HAVE_JOBCONTROL X#define REDRAW_CHECK if (s_redraw) goto do_redraw X X do_redraw: X /* safe to clear here, because we are going to redraw anyway */ X s_redraw = 0; X#else X#define REDRAW_CHECK X#endif X X redraw: X s_keyboard = 0; X X empty_menu_hack: /* do: "s_keyboard=1; goto empty_menu_hack;" */ X if (!slow_mode) s_keyboard = 0; X X nexta = firsta; X X clrdisp(); X X firstl = (*print_header)(); X maxa = Lines - preview_window - firstl - 2; X if (!long_menu) firstl++, maxa -= 2; X X if (maxa > (INTERVAL1 + INTERVAL2)) X maxa = INTERVAL1 + INTERVAL2; X X nextmenu: X X no_raw(); X gotoxy(0, firstl); X clrpage(firstl); X X if (nexta > 0) { X while (firsta < nexta) X articles[firsta++]->flag |= A_SEEN; X } else X if (purpose[0]) { X msg(purpose); X } X X firsta = nexta; X numa = Lines; /* for mark; is set correctly below */ X cura = 0; X X REDRAW_CHECK; X X if (!s_keyboard) X while (nexta < n_articles && cura < maxa) { X X REDRAW_CHECK; X X how = INIT; X mark(); fl; X X if (s_keyboard) { /* Signal may have corrupted output. */ X if (cura == 0) X mark(); /* redraw first entry */ X else { X how = REMOVE; /* We delete the last entry (the user */ X mark(); /* wanted to stop the output anyway) */ X cura--; X nexta--; X } X break; X } X X nexta++; cura++; X } X X s_keyboard = 0; X X prompt_line = firstl + cura; X if (!long_menu || cura < maxa) prompt_line++; X X numa = nexta - firsta - 1; X if (numa < 0) prompt_line++; X X if (next_cura >= 0) { X cura = next_cura; X next_cura = -1; X } else { X cura = 0; X for (article_id = firsta; cura < numa; article_id++, cura++) X if ((articles[article_id]->flag & A_SELECT) == 0) break; X } X X how = TOGGLE; X X build_prompt: X X raw(); X X Prompt: X X prompt(pr_fmt, X pct(0L, (long)(n_articles-1), (long)firsta, (long)(firsta+numa))); X X if (delayed_msg != NULL) { X msg(delayed_msg); X delayed_msg = NULL; X } X X same_prompt: X X if (cura < 0 || cura > numa) cura = 0; X X if (numa >= 0) { X gotoxy(0, firstl + cura); X fl; /* place cursor at current article id */ 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 X switch (k_cmd) { X X case K_UNBOUND: X ding(); X flush_input(); X goto same_prompt; X X case K_REDRAW: X goto redraw; X X case K_LAST_MESSAGE: X msg((char *)NULL); X goto same_prompt; X X case K_HELP: X if (numa < 0) goto nextmenu; /* give specific help here */ X display_help("menu"); X goto redraw; X X case K_SHELL: X if (group_file_name) *group_file_name = NUL; X if (shell_escape()) goto redraw; X goto Prompt; X X case K_VERSION: X prompt(P_VERSION); X goto same_prompt; X X case K_EXTENDED_CMD: X switch (alt_command()) { X X case AC_QUIT: X menu_return( ME_QUIT ); X X case AC_PROMPT: X goto Prompt; X X case AC_REORDER: X firsta = 0; X /* fall thru */ X case AC_REDRAW: X goto redraw; X X case AC_KEYCMD: X k_cmd = alt_cmd_key; X goto alt_key; X X case AC_HEADER: X home(); X (*print_header)(); X goto Prompt; X } X 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 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 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 did_unshar = 0; X X m_startinput(); X X while (!save_selected && !did_unshar) { X prompt("\1%s\1 %.*s Article (* +): ", X savemode, Columns - 25, fname); X X k_cmd = get_k_cmd(); X X if (k_cmd == K_SELECT_SUBJECT) { X save_selected = 1; X cura = 0; X article_id = firsta; X last_save = firsta + numa; X } else X if (k_cmd == K_AUTO_SELECT) { X save_selected = 2; X cura = -firsta; X article_id = 0; X last_save = n_articles - 1; X } else X if (k_cmd == K_ARTICLE_ID) { X cura = article_id; X article_id += firsta; X last_save = article_id; X } else X break; X X for ( ; article_id <= last_save ; article_id++, cura++) { 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 if (cura >= 0 && cura <= numa) X prompt("Processing %c...", ident[cura]); X else X prompt("Processing entry %d...", article_id); X X if (save(ah)) { X if (doing_unshar) { X if (save_selected) X ah->flag &= ~A_SELECT; X } else X if (cura >= 0 && cura <= numa) { X how = save_selected ? OFF : SAVED; X mark(); X how = TOGGLE; X } else X if (save_selected) X ah->flag &= ~A_SELECT; X } X } X } X X if (save_selected) cura = 0; X how = TOGGLE; X X m_endinput(); X X enable_stop = 1; X end_save(); X X if (did_unshar) { X any_key(0); X goto redraw; X } X goto Prompt; X X case K_REPLY: X case K_FOLLOW_UP: X if (numa < 0) goto nextmenu; X X prompt(k_cmd == K_REPLY ? X "\1Reply to author\1 of article: " : X "\1Follow Up\1 to article: "); X X if (get_k_cmd() == K_ARTICLE_ID) X if (answer(articles[firsta+article_id], k_cmd, -1)) X goto redraw; X X goto Prompt; X X case K_POST: X if (post_menu()) goto redraw; X goto Prompt; X X case K_MAIL_OR_FORWARD: X if (numa < 0) goto nextmenu; X X prompt("\1Article to be forwarded\1 (SP if none): "); X X if ((k_cmd = get_k_cmd()) == K_ARTICLE_ID) { X if (answer(articles[firsta+article_id], K_MAIL_OR_FORWARD, 1)) X goto redraw; X } else X if (k_cmd == K_CONTINUE) X if (answer((article_header *)NULL, K_MAIL_OR_FORWARD, 0)) X goto redraw; X X goto Prompt; X X case K_CANCEL: X if (numa < 0) goto nextmenu; X X if (current_group->group_flag & G_FOLDER) { X prompt("\1Cancel Folder\1 Article: "); X if (get_k_cmd() == K_ARTICLE_ID) { X cura = article_id; X fcancel(articles[firsta+article_id]); X how = CANCEL; X mark(); X } X goto Prompt; X } X X prompt("\1Cancel\1 Article: "); X 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 menu_return(ME_NEXT); X home(); X (*print_header)(); X } X goto Prompt; X X case K_GROUP_OVERVIEW: X group_overview(0); X goto redraw; X X case K_KILL_HANDLING: X kill_menu((article_header *)NULL); X goto Prompt; X X case K_CONTINUE: /* goto next menu page or show the articles */ X if (nexta < n_articles && !seen_all) goto nextmenu; X /* fall thru */ X X case K_READ_GROUP_UPDATE: X case K_READ_GROUP_THEN_SAME: X no_raw(); X clrdisp(); X X switch (show_articles()) { X X case SH_MENU: X goto redraw; X X case SH_QUIT: X menu_return(ME_QUIT); X X case SH_NO_SELECT: X break; X X case SH_NEXT: X menu_return(ME_NEXT); X X case SH_READ: X if (k_cmd == K_READ_GROUP_THEN_SAME || also_read_articles) goto redraw; X break; X X default: X user_error("show_articles returned improper value"); X } X X menu_return(ME_READ); X X case K_NEXT_GROUP_NO_UPDATE: X menu_return(ME_NEXT); X X case K_PREVIOUS: X menu_return(ME_PREV); X X case K_ADVANCE_GROUP: X case K_BACK_GROUP: X if (merged_menu) { X msg("No possible on merged menu"); X goto same_prompt; X } X /* FALL THRU */ X X case K_GOTO_GROUP: X X switch (goto_group(k_cmd, (article_header *)NULL)) { X X case ME_REDRAW: X firsta = 0; X goto redraw; X X case ME_NO_ARTICLES: X msg("No selections made."); X X case ME_NO_REDRAW: X goto Prompt; X X case ME_QUIT: X menu_return( ME_QUIT ); X X case ME_PREV: X goto redraw; X X case ME_NEXT: X case ME_READ: X s_keyboard = 1; X goto empty_menu_hack; X } X X case K_ARTICLE_ID: X if (numa < 0) goto nextmenu; X X cura = article_id; X how = TOGGLE; X mark(); X last_how = how; X cura++; X X goto same_prompt; X X case K_SELECT_INVERT: X if (numa < 0) goto nextmenu; X X temp = cura; X X no_raw(); /* for x-on/x-off */ X for (cura = 0; cura <= numa; cura++) { X how = TOGGLE; X mark(); X } X fl; X X REDRAW_CHECK; X raw(); X X how = TOGGLE; cura = temp; X goto same_prompt; X X X case K_SELECT: X if (numa < 0) goto nextmenu; X X how = TOGGLE; X mark(); X last_how = how; X cura++; X goto same_prompt; X X case K_UNSELECT_ALL: X for (cura = -firsta; cura < n_articles - firsta; cura++) { X how = OFF; X mark(); X } X fl; X cura = 0; X goto same_prompt; X X case K_NEXT_LINE: X if (numa < 0) goto nextmenu; X X cura++; X how = TOGGLE; X goto same_prompt; X X case K_PREV_LINE: X if (numa < 0) goto nextmenu; X X if (--cura < 0) cura = numa; X how = TOGGLE; X goto same_prompt; X X case K_SELECT_SUBJECT: X if (numa < 0) goto nextmenu; X X mark(); X X while (firsta+cura > 0 && articles[firsta+cura]->flag & A_SAME) X cura--; X X do { X mark(); X cura++; X if (firsta+cura >= n_articles) break; X } while (articles[firsta+cura]->flag & A_SAME); X X how = TOGGLE; X goto same_prompt; X X case K_SELECT_RANGE: X if (numa < 0) goto nextmenu; X X if (last_k_cmd == K_ARTICLE_ID || last_k_cmd == K_SELECT) { X how = last_how; X cura--; X if (cura < 0) cura = numa; X } else X how = articles[firsta+cura]->flag & A_SELECT ? OFF : ON; X X range_again: X X prompt("\1%select range\1 %c-", how == ON ? "S" : "Des", ident[cura]); X X k_cmd = get_k_cmd(); X if (k_cmd == K_SELECT_RANGE) { X how = !how; X goto range_again; X } X X if (k_cmd != K_ARTICLE_ID) goto Prompt; X X if (last_k_cmd != K_ARTICLE_ID && last_k_cmd != K_SELECT) X mark(); X X if (article_id <= cura) { X while (--cura >= article_id) mark(); X if (cura < 0) cura = 0; X } else { X while (++cura <= article_id) mark(); X if (cura > numa) cura = numa; X } X X how = TOGGLE; X goto Prompt; X X case K_AUTO_SELECT: X do_auto_select(); X goto same_prompt; X X case K_NEXT_PAGE: X if (nexta < n_articles) goto nextmenu; X if (firsta == 0) goto same_prompt; X X seen_all++; X nexta = 0; X goto nextmenu; X X case K_PREV_PAGE: X if (firsta == 0 && nexta == n_articles) goto same_prompt; X X nexta = (firsta > 0 ? firsta : n_articles) - maxa; X if (nexta <= 1) nexta = 0; X goto nextmenu; X X case K_FIRST_PAGE: X if (firsta == 0) goto same_prompt; X X nexta = 0; X goto nextmenu; X X case K_LAST_PAGE: X if (nexta == n_articles) goto same_prompt; X X nexta = n_articles - maxa; X if (nexta <= 1) nexta = 0; X goto nextmenu; X X case K_PREVIEW: X if (numa < 0) goto nextmenu; X X preview_other: X X prompt("\1Preview article\1"); X k_cmd = get_k_cmd(); X X if (k_cmd != K_ARTICLE_ID) { X if (k_cmd != K_PREVIEW) X goto Prompt; X article_id = cura; X } X X temp = prompt_line; X X preview_next: X ah = articles[firsta+article_id]; X cura = article_id + 1; X was_selected = (ah->flag & A_SELECT); X X switch (more(ah, MM_PREVIEW, prompt_line)) { X X case MC_REDRAW: X next_cura = cura; X goto redraw; X X case MC_NO_REDRAW: X break; X X case MC_QUIT: X menu_return( ME_QUIT ); X X case MC_NEXT: /* article not found -- preview next */ X if (prompt_line == temp) X break; /* not redrawn -- return to menu instead */ X user_delay(1); X /* FALL THRU */ X X case MC_PREVIEW_NEXT: X if (prompt_line < 0) { /* redrawn screen ! */ X if ((firsta + cura) >= n_articles) goto redraw; X prompt_line = Lines; X } else { X if ((ah->flag & A_SELECT) && was_selected == 0) { X cura--; X ah->flag &= ~A_SELECT; X how = ON; X mark(); X cura++; X } X if (cura > numa) break; X prompt_line = temp; X } X article_id = cura; X goto preview_next; X X case MC_PREVIEW_OTHER: X prompt_line = temp; X raw(); X goto preview_other; X X default: X break; X } X X prompt_line = temp; X goto build_prompt; X X case K_LAYOUT: X if (++fmt_linenum > 3) fmt_linenum = 0; X goto redraw; X X default: X msg("Command %d not supported", k_cmd); X goto same_prompt; X } X X X menu_exit: X X firsta = o_firsta; X in_menu_mode = o_mode; X menu_level--; X X no_raw(); X return menu_cmd; X} X X Xstatic show_articles() X{ X register cur, next, mode; X int cmd, prev = -1, again; X X do { X again = 0; X X for (cur = 0; cur < n_articles; cur++) { X if (articles[cur]->flag & A_SELECT) break; X } X X while (cur < n_articles) { X X for (next = cur+1; next < n_articles; next++) { X if (articles[next]->flag & A_SELECT) break; X } X X articles[cur]->flag &= ~A_SELECT; X X show: X mode = 0; X if (prev >= 0) mode |= MM_PREVIOUS; X if (next == n_articles) mode |= MM_LAST_ARTICLE; X X cmd = more(articles[cur], mode, 0); X X switch(cmd) { X X case MC_PREV: X if (prev == next) break; X X next = cur; cur = prev; prev = next; X goto show; X X case MC_NEXTSUBJ: X for (next = cur+1; next < n_articles; next++) { X if ((articles[next]->flag & A_SAME) == 0) break; X articles[next]->flag &= ~A_SELECT; X } X for (; next < n_articles; next++) { X if (articles[next]->flag & A_SELECT) break; X } X break; X X case MC_ALLSUBJ: X for (next = cur+1; next < n_articles; next++) { X if ((articles[next]->flag & A_SAME) == 0) break; X articles[next]->flag |= A_SELECT; X } X for (next = cur+1; next < n_articles; next++) X if (articles[next]->flag & A_SELECT) break; X break; X X case MC_MENU: X articles[cur]->flag |= A_SELECT; X firsta = cur - 5; X if (firsta < 0) firsta = 0; X next_cura = cur - firsta; X X return SH_MENU; X X case MC_QUIT: X return SH_QUIT; X X case MC_NEXT: X if (articles[cur]->flag & A_SELECT) again++; X break; X X case MC_NEXTGROUP: X return SH_NEXT; X X case MC_READGROUP: X return SH_READ; X } X X prev = cur; cur = next; X } X X if (again > 1) X delayed_msg = "Showing this and the following articles again"; X else X if (again == 1) X delayed_msg = "Showing article again"; X X } while (again); X X return prev < 0 ? SH_NO_SELECT : SH_READ; X} X X/* X * return article header for article on menu X */ X Xarticle_header *get_menu_article() X{ X register article_header *ah; X X fputs(" from article: ", stdout); fl; X X if (get_k_cmd() == K_ARTICLE_ID) { X ah = articles[firsta + article_id]; X if (ah->a_group) init_group(ah->a_group); X return ah; X } X X return NULL; X} X X Xstatic get_purpose(purpose) Xchar *purpose; X{ X#ifdef NNTP X return; /* newsgroups file is not available */ X#else X FILE *f; X char line[256], group[80]; X register char *cp, *pp; X register int len; X extern char news_active[]; X X strcpy(line, news_active); X if ((cp = strrchr(line, '/')) == NULL) return; X strcat(cp + 1, "newsgroups"); X X if ((f = fopen(line, "r")) == NULL) return; X X sprintf(group, "%s\t", current_group->group_name); X len = current_group->group_name_length + 1; X X while (fgets(line, 256, f) != NULL) { X if (strncmp(line, group, len)) continue; X cp = line + len; X while (*cp && isspace(*cp)) cp++; X for (pp = purpose, len = 76; --len >= 0 && *cp && *cp != NL; ) X *pp++ = *cp++; X *pp = NUL; X } X X fclose(f); X#endif X} X X/* X * perform auto selections that are not already selected X * if article is in range firsta..firsta+numa (incl) mark article X */ X Xstatic do_auto_select() X{ X register int i; X register article_header *ah, **ahp; X int count = 0, o_cura; X X o_cura = cura; X X for (i = 0, ahp = articles; i < n_articles; i++, ahp++) { X ah = *ahp; X if (auto_select_article(ah)) { X count++; X if (ah->flag & A_SELECT) continue; X if (firsta <= i && i <= (firsta+numa)) { X cura = i - firsta; X how = ON; X mark(); X } else X ah->flag |= A_SELECT; X } X } X X msg(count == 0 ? "No selections" : "Selected %d article%s", X count, count > 1 ? "s" : ""); X cura = o_cura; X} X X X X/* X * read command from command line X */ X Xalt_command() X{ X int ok_val, macro_cmd; X char *cmd; X extern char erase_key; X extern int get_from_macro; X extern int alt_completion(); X X prompt(":"); X ok_val = AC_PROMPT; X X again: X X cmd = "?? "; X cmd[1] = erase_key; X X cmd = get_s(NONE, NONE, cmd, alt_completion); X if (cmd == NULL || X *cmd == NUL || *cmd == SP || *cmd == erase_key) X return ok_val; X X macro_cmd = get_from_macro; X X if (*cmd == '?') { X display_file("help.extended", CLEAR_DISPLAY); X ok_val = AC_REDRAW; X goto new_prompt; X } X X ok_val = parse_command(cmd, ok_val, (FILE *)NULL); X if (ok_val != AC_REDRAW || !delay_redraw) return ok_val; X X new_prompt: X if (macro_cmd) return ok_val; X X prompt_line = -1; X printf("\n\r:"); X fl; X goto again; X} NO_NEWS_IS_GOOD_NEWS chmod 0644 menu.c || echo "restore of menu.c fails" set `wc -c menu.c`;Sum=$1 if test "$Sum" != "23564" then echo original size 23564, current size $Sum;fi echo "x - extracting menu.h (Text)" sed 's/^X//' << 'NO_NEWS_IS_GOOD_NEWS' > menu.h && X/* menu commands */ X X#define ME_QUIT 0 /* quit nn */ X#define ME_NEXT 1 /* continue to next group */ X#define ME_READ 2 /* read this group, cont to next */ X#define ME_PREV 3 /* previous group */ X#define ME_NO_ARTICLES 4 /* no articles in group */ X#define ME_REDRAW 5 /* redraw screen after return */ X#define ME_NO_REDRAW 6 /* screen is not corrupted */ X X/* show_articles commands */ X X#define SH_QUIT 0 /* quit nn */ X#define SH_NEXT 1 /* goto next group, no read */ X#define SH_READ 2 /* articles has been read */ X#define SH_MENU 3 /* redraw menu */ X#define SH_NO_SELECT 4 /* no articles was selected */ X X X/* more commands */ X X#define MC_QUIT 0 /* quit nn */ X#define MC_NEXT 1 /* next article */ X#define MC_MENU 2 /* return to menu */ X#define MC_PREV 3 /* previous article */ X#define MC_NEXTSUBJ 4 /* show next subject */ X#define MC_ALLSUBJ 5 /* show all with same subject */ X#define MC_NEXTGROUP 6 /* next group, no read */ X#define MC_READGROUP 7 /* next group, mark as read */ X#define MC_PREVIEW_NEXT 8 /* preview next article */ X#define MC_PREVIEW_OTHER 9 /* preview another article */ X#define MC_REDRAW 10 /* redraw screen after return */ X#define MC_NO_REDRAW 11 /* screen is not corrupted */ X X/* more modes */ X X#define MM_NORMAL 0 /* show article */ X#define MM_DIGEST 1 /* show full digest */ X#define MM_PREVIOUS 0x10 /* previous article exists */ X#define MM_LAST_ARTICLE 0x20 /* last article in group */ X#define MM_LAST_GROUP 0x40 /* last group */ X#define MM_PREVIEW 0x80 /* preview mode flag */ X X/* alt_command return values */ X X#define AC_QUIT 0 /* quit nn */ X#define AC_PROMPT 1 /* just redraw prompt line */ X#define AC_REDRAW 2 /* redraw screen */ X#define AC_REORDER 3 /* articles have been reordered */ X#define AC_HEADER 4 /* update header line + Prompt */ X#define AC_KEYCMD 5 /* alt_cmd_key contains command */ NO_NEWS_IS_GOOD_NEWS chmod 0644 menu.h || echo "restore of menu.h fails" set `wc -c menu.h`;Sum=$1 if test "$Sum" != "1853" then echo original size 1853, current size $Sum;fi echo "x - extracting mk_online_man (Text)" sed 's/^X//' << 'NO_NEWS_IS_GOOD_NEWS' > mk_online_man && X# convert a manual to a folder X Xsed -e 's/\\f[BPI]//g' \ X -e 's/\\-/-/g' \ X -e 's/\\&//' \ X -e '/^\.\\"/d' \ X -e '/^\.nf/d' \ X -e '/^\.fi/d' \ X -e 's/^\.[BI] //' "$@" | Xawk ' XBEGIN { X l="" X o="" X m=72 X a=0 X h="" X} X/^\.SH / { X if (a) printf("%s\n\n", l) X a++ X l=o="" X z=u=0 X printf("From: %s\nSubject:", h); X for (i = 2; i <= NF; i++) printf(" %s", $i); X printf("\n\n"); X next X} X/^\.TH / { X h=$2 X next X} X/^\.UC / { X next X} X/^\.br/ { X if (l != o) printf("%s\n", l) X l=o X z=u X next X} X/^\.PP/ { X if (l != o) printf("%s\n", l) X printf("\n") X l=" " X z=3 X o="" X u=0 X next X} X/^\.LP/ || /^\.sp/ { X if (l != o) printf("%s\n", l) X printf("\n") X l="" X o="" X z=u=0 X next X} X/^\.TP/ { X if (l != o) printf("%s\n", l) X printf("\n") X getline X l=$0 X z=u=5 X o=" " X if (length(l) >= 5) { X printf("%s\n", l) X l=o X } else while (length(l) < 4) l=l " " X next X} X{ X s=1 X p=" " X q=1 X} X/^[ ]/ { X if (l != o) printf("%s\n",l) X l=o " " X z=u+5 X} X/^\.[IB] / { X s=2 X} X/^\.[IB]R / { X s=2 X p="" X q=0 X} X{ X r=" " X while (s <= NF) { X k=length($s) X if ((z+k) > m) { X printf("%s\n", l) X l=o X z=u X } X if (l != o) X l=l r $s X else X l=l $s X z=z + q + k X r=p X s++ X } X} XEND { X if (l != o) printf("%s\n\n", l) X}' NO_NEWS_IS_GOOD_NEWS chmod 0644 mk_online_man || echo "restore of mk_online_man fails" set `wc -c mk_online_man`;Sum=$1 if test "$Sum" != "1198" then echo original size 1198, current size $Sum;fi echo "x - extracting more.c (Text)" sed 's/^X//' << 'NO_NEWS_IS_GOOD_NEWS' > more.c && X#include "config.h" X#include "news.h" X#include "term.h" X#include "menu.h" X#include "keymap.h" X#include "regexp.h" X Xexport int monitor_mode = 0; Xexport int show_article_date = 1; Xexport int first_page_lines = 0; Xexport int overlap = 2; Xexport int mark_overlap = 0; Xexport char *header_lines = NULL; X Ximport int preview_window; Ximport int novice; X Ximport char *delayed_msg; X Xextern char *init_save(); X Xstatic char rot13tab[128]; Xstatic int norot13 = 1, rot13; Xstatic int compress_space; X Xstatic regexp *regular_expr = NULL; X X#define LINEMAX 5000 /* max no of lines backed up */ X Xstatic struct header_def { X char field; X char *text; X char **news; X char **digest; X} header_defs[] = { X 'A', "Approved", &news.ng_appr, 0, X 'B', "Distribution",&news.ng_dist, 0, X 'D', "Date", &news.ng_date, &digest.dg_date, X 'F', "From", &news.ng_from, &digest.dg_from, X 'I', "Message-Id", &news.ng_ident, 0, X 'K', "Keywords", &news.ng_keyw, 0, X 'L', "Lines", &news.ng_xlines, 0, X 'N', "Newsgroups", &news.ng_groups, 0, X 'O', "Organization",&news.ng_org, 0, X 'P', "Path", &news.ng_path, 0, X 'R', "Reply-To", &news.ng_reply, 0, X 'S', "Subject", &news.ng_subj, &digest.dg_subj, X 'W', "Followup-To", &news.ng_follow, 0, X 'X', "References", &news.ng_ref, 0, X 0 X}; X X Xmore(ah, mode, screen_offset) Xarticle_header *ah; Xint mode, screen_offset; X{ 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 int linenum, maxline, topline, print_lines, lno1; X int underline_line, fake_underline; X int match_lines, match_redraw, match_topline, match_botline; X int goto_line, prev_goto, stop_line, extra_lines; X int in_digest = ah->flag & A_DIGEST; X article_header digestah; X char *fname, *hdrline; X extern STANDOUT; X char pr_fmt[60], send_date[40]; X int match_expr; X char *match_start, *match_end; X int open_modes, hdr_mode, o_mode; X struct header_def *hdef; X extern int alt_cmd_key, in_menu_mode, any_message; X#ifdef RESIZING X int entry_col = Columns; X#endif X extern char *pct(); X X#define more_return(cmd) \ X { more_cmd = cmd; goto more_exit; } X X if (ah->a_group != NULL) init_group(ah->a_group); X X open_modes = SKIP_HEADER; X if (show_article_date || header_lines) { X open_modes |= FILL_NEWS_HEADER; X if (header_lines == NULL) X open_modes |= GET_DATE_ONLY; X else X open_modes |= GET_ALL_FIELDS; X if (in_digest) open_modes |= FILL_DIGEST_HEADER; X } X X /* temporary use of linepos array as header buffers... */ X X art = open_news_article(ah, open_modes, (char *)&linepos[100], (char *)&linepos[LINEMAX/2]); X X if (art == NULL) { X msg("Expired: \"%s: %-.50s\"", ah->sender, ah->subject); X if ((mode & MM_PREVIEW) == 0) user_delay(1); X return MC_NEXT; X } X X o_mode = in_menu_mode; X in_menu_mode = 0; X X if (screen_offset) X if (preview_window < 1 && Lines - screen_offset < 6) X screen_offset = 0; X else { X so_printxy(0, screen_offset++, "%s: %s ", ah->sender, ah->subject); X if (!STANDOUT) screen_offset++; X clrline(); X } X X if (show_article_date) { X if (in_digest && digest.dg_date) X strncpy(send_date, digest.dg_date, 40); X else X if (news.ng_date) { X strncpy(send_date, news.ng_date, 40); X } else X send_date[0] = NUL; X send_date[39] = NUL; X if (lp = strrchr(send_date, ':')) *lp = NUL; X } X X linepos[0] = ah->hpos; X linepos[1] = firstl = ah->fpos; X maxline = 1; X topline = 1; X hdrline = screen_offset == 0 ? header_lines : ""; X X lastl = (ah->lpos - firstl + 99)/100; X if (lastl == 0) lastl = 1; /* impossible ? */ 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 X stop_line = first_page_lines ? first_page_lines : -1; X X sprintf(pr_fmt, X "\1\2-- %s%s %s-----%%s-----\1", X (mode & MM_PREVIEW) ? "PREVIEW " : "", X (mode & MM_DIGEST) ? "FULL DIGEST" : X (mode & MM_LAST_ARTICLE) ? "LAST ARTICLE" : "ARTICLE", X novice ? "-- help:? " : ""); X X if (screen_offset) goto safe_redraw; X X redraw: /* redraw that will destroy whole screen */ X screen_offset = 0; X X safe_redraw: /* redraw of "more window" only */ X linenum = topline; X X next_page: X no_raw(); X X s_keyboard = 0; X X if (stop_line) { X X if (lno = screen_offset) { X gotoxy(0, lno); X clrpage(lno); X } else X clrdisp(); X X print_header: X if (hdrline == NULL || *hdrline == '*') { X if (hdrline && *++hdrline == NUL) hdrline = NULL; X X if (linenum <= 1) { X if (linenum == 0 || (mode & MM_DIGEST)) { X if (screen_offset) { X lno--; X if (!STANDOUT) lno--; X gotoxy(0, lno); X clrpage(lno); X } X so_printxy(0, lno, X "Newsgroup: %s, article: %ld%s", X current_group->group_name, X (long)(ah->a_number), X ((mode & MM_DIGEST) || in_digest) X ? " *DIGEST*" : ""); X/* fseek(art, linepos[0], 0); */ X X lno++; X if (!STANDOUT) lno++; X } else { X if (screen_offset == 0 && linenum == 1) { X if (show_article_date) so_printxy(-1, 0, send_date); X X /* so_printxy will cut subject */ X so_printxy(0, lno, "%s: %s ", ah->sender, ah->subject); X lno++; X if (!STANDOUT) lno++; X } X } X } X } X X if (hdrline && screen_offset == 0) { X X hdr_mode = 0; X while (*hdrline) { X X if (*hdrline == '*') goto print_header; X X if (*hdrline == '=') { X hdr_mode = 1; X hdrline++; X continue; X } X if (*hdrline == '_') { X hdr_mode = 2; X hdrline++; X continue; X } X for (hdef = header_defs; hdef->field; hdef++) { X if (hdef->field != *hdrline) continue; X if (in_digest) { X if (hdef->digest == NULL) break; X if ((lp = *(hdef->digest)) == NULL) X break; X } else X if ((lp = *(hdef->news)) == NULL) X break; X gotoxy(0, lno++); X c = strlen(hdef->text) + 2; X col = c + strlen(lp); X if (col > Columns) lp[Columns - c] = 0; X printf("%s: ", hdef->text); X switch (hdr_mode) { X case 0: X break; X case 1: X highlight(1); X break; X case 2: X underline(1); X break; X } X printf("%s", lp); X switch (hdr_mode) { X case 0: X break; X case 1: X highlight(0); X break; X case 2: X underline(0); X break; X } X break; X } X hdr_mode = 0; X hdrline++; X } X X hdrline = NULL; X putchar(NL); X lno++; X } X X lno1 = lno; X topline = linenum; X X window_lines = Lines - lno - 2; X print_lines = window_lines; X X ignore_nl = 1; /* ignore blank lines at top op screen */ X } else X print_lines = extra_lines; /* LINT complaints here -- ignore */ X X if (stop_line > 0) { X if (print_lines > stop_line) { X extra_lines = print_lines - stop_line; X print_lines = stop_line; X underline_line = -1; X } X stop_line = 0; X } else X stop_line = -1; X X next_line: X X if (linenum == LINEMAX) { X /* THIS IS EXTREMELY DIRTY (like most quick hacks) */ X /* the following definitions assume that LINEMAX >> START+SIZE */ X#define HACK_START 1000 /* line numbers > START_POS are wrong */ X#define HACK_SIZE 1000 /* we simply delete HACK_SIZE lines */ X for (linenum = HACK_START; linenum < (LINEMAX-HACK_SIZE); linenum++) X linepos[linenum] = linepos[linenum+HACK_SIZE]; X maxline = linenum - 1; X if (goto_line > 0) goto_line -= HACK_SIZE; X if (prev_goto > HACK_START) X if (prev_goto > (HACK_START + HACK_SIZE)) X prev_goto -= HACK_SIZE; X else X prev_goto = HACK_START; X } X X if (goto_line == linenum) { X goto_line = -1; X goto next_page; X } X X eof = 0; X X if (linenum > maxline) X linepos[++maxline] = ftell(art); X else X if (linenum > 0) X fseek(art, linepos[linenum], 0); X X X if (linepos[linenum] >= ah->lpos) { X if (match_expr) { X match_expr = 0; X topline = match_topline; /* LINT complaints here -- ignore */ X linenum = match_botline; /* LINT complaints here -- ignore */ X fseek(art, linepos[linenum], 0); X msg("Not found"); X goto Prompt; X } X eof++; X if (goto_line > 0) { X goto_line = -1; X linenum -= window_lines/2; X goto next_page; X } X goto Prompt; X } X X if (linenum == 0) { X if (ftell(art) >= linepos[1]) { X linenum = 2; /* current line is 1st line ! */ X lno1 = lno; X } X } else X linenum++; X X lp = linebuf; X col = 0; X form_feed = 0; X X next_char: X X c = getc(art); X if (c == EOF) { X eof++; X if (lp == linebuf) goto Prompt; X goto end_line; X } X X if (c & 0200) { X col += 4; X if (col > Columns) { /* then there is no room for M-^X */ X ungetc(c, art); X goto long_line; X } X c &= 0177; X *lp++ = 'M'; X *lp++ = '-'; X if (c < SP) { X *lp++ = '^'; X c += '@'; X } else X col--; X } else X if (c < SP) { X if (monitor_mode) { X if (c == NL) { X *lp++ = '$'; X goto end_line; X } X if (col + 2 > Columns) { X *lp++ = '\\'; X ungetc(c, art); X goto end_line; X } X *lp++ = '^'; X c += '@'; X col++; X } else 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 goto Prompt; X } X form_feed = 1; X goto end_line; X X case CR: X if (lp == linebuf || ignore_nl) goto next_char; X ignore_nl = 1; X goto end_line; X X case NL: X if (ignore_nl) { X ignore_nl = 0; X if (lp == linebuf) { X if (lno == lno1) { X ignore_nl = 1; X goto next_line; X } X goto next_char; X } X } X goto end_line; X X case BS: X if (col) { X lp--; X col--; X } X goto next_char; X X case TAB: X if (col + 8 - (col & 07) >= Columns) X goto long_line; X X do { X *lp++ = SP; X col++; X } while (col & 07); X goto next_char; X X default: X if (col + 2 > Columns) { X ungetc(c, art); X goto long_line; X } X *lp++ = '^'; X c += '@'; X col++; X break; X } X } X X *lp++ = c; X col++; X ignore_nl = 0; X X if (col < Columns) goto next_char; X Xlong_line: X ignore_nl = 1; X X end_line: X /* if we are seaching for a specific line, repeat until it is found */ X if (goto_line >= linenum) goto next_line; X X *lp++ = NUL; X X if (match_expr) { X if (!regexec(regular_expr, linebuf)) X goto next_line; X match_expr = 0; NO_NEWS_IS_GOOD_NEWS echo "End of part 7" echo "File more.c is continued in part 8" echo "8" > s2_seq_.tmp exit 0 --- Kim F. Storm storm@texas.dk Tel +45 429 174 00 Texas Instruments, Marielundvej 46E, DK-2730 Herlev, Denmark No news is good news, but nn is better! -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net. Use a domain-based address or give alternate paths, or you may lose out.