home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume22 / nn6.4 / patch03 < prev    next >
Encoding:
Internet Message Format  |  1990-06-07  |  54.0 KB

  1. Subject:  v22i059:  NN Newsreader, release 6.4, Patch3
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: af167553 9b54cc8a 2f7b8431 5d3d7b4f
  5.  
  6. Submitted-by: "Kim F. Storm" <storm@texas.dk>
  7. Posting-number: Volume 22, Issue 59
  8. Archive-name: nn6.4/patch3
  9.  
  10.          This is an official patch to nn release 6.4
  11.          -------------------------------------------
  12.  
  13.                    PATCH #3
  14.  
  15.                 Priority: HIGH
  16.  
  17.  
  18. These patches fix more bugs in the 6.4 release.  A major bug related
  19. to rmgroup'ing one group resulting in another group being dropped from
  20. the database has been solved.  The problems related to unsubscribing
  21. to the last group in the presentation sequence are also solved.
  22.  
  23. All changes are described in the updated RELEASE_NOTES file (read that
  24. for details about this patch).  Thanks to all who reported bugs and
  25. provided fixes.
  26.  
  27. To apply this patch, use nn's :patch command, or run this command from
  28. the shell in the root of the nn source tree:
  29.     patch -p0 < this-article
  30.  
  31.  
  32. ++Kim Storm
  33.  
  34. *** ./LAST/active.c    Sat May  5 13:37:31 1990
  35. --- active.c    Mon May 21 12:01:08 1990
  36. ***************
  37. *** 16,23 ****
  38.       int must_update;
  39.       register flag_type old_flag;
  40.       
  41. !     Loop_Groups_Header(gh)
  42.       gh->master_flag &= ~M_VALID;
  43.   
  44.       while (fgets(line, 512, act)) {
  45.       if (copy != NULL) fputs(line, copy);
  46. --- 16,26 ----
  47.       int must_update;
  48.       register flag_type old_flag;
  49.       
  50. !     Loop_Groups_Header(gh) {
  51.       gh->master_flag &= ~M_VALID;
  52. +     gh->first_a_article = 0;
  53. +     gh->last_a_article = 0;
  54. +     }
  55.   
  56.       while (fgets(line, 512, act)) {
  57.       if (copy != NULL) fputs(line, copy);
  58. *** ./LAST/admin.c    Wed May 16 11:22:33 1990
  59. --- admin.c    Mon May 21 13:45:45 1990
  60. ***************
  61. *** 262,267 ****
  62. --- 262,269 ----
  63.   
  64.       data = ix = NULL;
  65.   
  66. +     if (gh->master_flag & M_IGNORE_GROUP) return 1;
  67.       if (gh->first_db_article == (gh->last_db_article + 1)
  68.       && gh->index_write_offset == 0)
  69.       return 1;
  70. ***************
  71. *** 419,426 ****
  72.       article_number first_article;
  73.       int n;
  74.   
  75. !     if (init_group(gh) <= 0)
  76.       printf("cannot access group %s\n", gh->group_name);
  77.   
  78.       update_group(gh);
  79.   
  80. --- 421,430 ----
  81.       article_number first_article;
  82.       int n;
  83.   
  84. !     if (init_group(gh) <= 0) {
  85.       printf("cannot access group %s\n", gh->group_name);
  86. +     return 0;
  87. +     }
  88.   
  89.       update_group(gh);
  90.   
  91. ***************
  92. *** 515,520 ****
  93. --- 519,525 ----
  94.    err:
  95.       if (data != NULL) fclose(data);
  96.       if (ix != NULL) fclose(ix);
  97. +     if (gh->master_flag & M_IGNORE_GROUP) return 0;
  98.       printf("\n*** DATABASE INCONSISTENCY DETECTED - run V)alidate\n");
  99.       return 0;
  100.   }
  101. *** ./LAST/answer.c    Wed May 16 11:23:33 1990
  102. --- answer.c    Fri May 18 22:26:05 1990
  103. ***************
  104. *** 105,112 ****
  105.   FILE *t;
  106.   int use_follow;
  107.   {
  108. !     fprintf(t, "Newsgroups: %s\n",
  109. !         use_follow && news.ng_follow ? news.ng_follow : news.ng_groups);
  110.       ed_line++;
  111.   }
  112.   
  113. --- 105,116 ----
  114.   FILE *t;
  115.   int use_follow;
  116.   {
  117. !     char *ng;
  118. !     ng = use_follow && news.ng_follow ? news.ng_follow : news.ng_groups;
  119. !     if (ng == NULL) return;
  120. !     
  121. !     fprintf(t, "Newsgroups: %s\n", ng);
  122.       ed_line++;
  123.   }
  124.   
  125. ***************
  126. *** 522,540 ****
  127.       if (command == K_BUG_REPORT) {
  128.           fprintf(t, "\n=== configuration ===\n");
  129.           append_file(relative(lib_directory, "conf"), t);
  130.           fprintf(t, "=== end ===\n");
  131.       }
  132.       }
  133.   
  134. -     /* empty line terminates header */
  135. -     fputc(NL, t);
  136. -     ed_line++;
  137.       prompt("\1WAIT\1");
  138.   
  139.       if (incl) {
  140.       register c, prevnl = 1;
  141.   
  142.       while ((c = getc(art)) != EOF) {
  143.           if (c == NL) {
  144.           putc(c, t);
  145. --- 526,545 ----
  146.       if (command == K_BUG_REPORT) {
  147.           fprintf(t, "\n=== configuration ===\n");
  148.           append_file(relative(lib_directory, "conf"), t);
  149. +         fprintf(t, "=== variable settings ===\n");
  150. +         print_variable_config(t, 0);
  151.           fprintf(t, "=== end ===\n");
  152.       }
  153.       }
  154.   
  155.       prompt("\1WAIT\1");
  156.   
  157.       if (incl) {
  158.       register c, prevnl = 1;
  159.   
  160. +     fputc(NL, t);
  161. +     ed_line++;
  162.       while ((c = getc(art)) != EOF) {
  163.           if (c == NL) {
  164.           putc(c, t);
  165. ***************
  166. *** 820,826 ****
  167.       if (!post_no_edit)
  168.       prompt("\1WAIT\1");
  169.   
  170. !     ed_line = 3;
  171.   #ifdef NNTP
  172.   #ifdef NNTP_MINI_INEWS_HEADER
  173.       mini_inews_header(t);
  174. --- 825,831 ----
  175.       if (!post_no_edit)
  176.       prompt("\1WAIT\1");
  177.   
  178. !     ed_line = 4;
  179.   #ifdef NNTP
  180.   #ifdef NNTP_MINI_INEWS_HEADER
  181.       mini_inews_header(t);
  182. *** ./LAST/aux.sh    Wed May 16 11:23:33 1990
  183. --- aux.sh    Thu May 17 15:14:18 1990
  184. ***************
  185. *** 166,171 ****
  186. --- 166,175 ----
  187.         { cat $WORK ; echo ; } >> $FNAME
  188.       fi
  189.       ;;
  190. +   ENV)
  191. +     set
  192. +     ;;
  193.     esac
  194.   done
  195.   
  196. *** ./LAST/conf/s-dynix3-0.h    Wed May 16 11:23:34 1990
  197. --- conf/s-dynix3-0.h    Thu May 17 01:05:27 1990
  198. ***************
  199. *** 7,9 ****
  200. --- 7,10 ----
  201.   
  202.   #undef HAVE_MULTIGROUP
  203.   FILE *popen ();
  204. + #define FAKE_INTERRUPT
  205. *** ./LAST/db.c    Wed May 16 11:22:35 1990
  206. --- db.c    Mon May 21 13:22:43 1990
  207. ***************
  208. *** 43,49 ****
  209.       current_digest_article = 0;
  210.   
  211.       if (gh == NULL) return 0;
  212. !     if (gh->master_flag & M_IGNORE_GROUP) return 0;
  213.       if (gh == current_group) return 1;
  214.   
  215.       current_group = gh;
  216. --- 43,49 ----
  217.       current_digest_article = 0;
  218.   
  219.       if (gh == NULL) return 0;
  220. ! /*    if (gh->master_flag & M_IGNORE_GROUP) return 0;    /* OBS */
  221.       if (gh == current_group) return 1;
  222.   
  223.       current_group = gh;
  224. ***************
  225. *** 51,57 ****
  226.       if (gh->group_flag & G_FOLDER) {
  227.       group_position = NULL;
  228.       group_file_name = NULL;
  229. !     strcpy(group_path_name, gh->group_name);
  230.       return 1;
  231.       }
  232.   
  233. --- 51,57 ----
  234.       if (gh->group_flag & G_FOLDER) {
  235.       group_position = NULL;
  236.       group_file_name = NULL;
  237. !     strcpy(group_path_name, gh->archive_file);
  238.       return 1;
  239.       }
  240.   
  241. ***************
  242. *** 565,571 ****
  243.       db_data_path(data_file, gh, d_or_x);
  244.   
  245.       if (mode == -1) {
  246. !     unlink(data_file);
  247.       f = NULL;
  248.       } else {
  249.       f = open_file(data_file, (mode & ~MUST_EXIST));
  250. --- 565,572 ----
  251.       db_data_path(data_file, gh, d_or_x);
  252.   
  253.       if (mode == -1) {
  254. !     if (unlink(data_file) < 0 && errno != ENOTDIR && errno != ENOENT)
  255. !         log_entry('E', "Cannot unlink %s (errno=%d)", data_file, errno);
  256.       f = NULL;
  257.       } else {
  258.       f = open_file(data_file, (mode & ~MUST_EXIST));
  259. *** ./LAST/doc/RELEASE_NOTES    Wed May 16 11:23:35 1990
  260. --- doc/RELEASE_NOTES    Mon May 21 13:38:16 1990
  261. ***************
  262. *** 154,160 ****
  263.   Prog:    nn
  264.   Title:    Remapping keys may interfere with Junk command.
  265.   From:    Robert.Stockton@ELROND.GANDALF.CS.CMU.EDU
  266.       Menu mode macros are invoked when the appropriate keystrokes are used
  267.       in the Junk command.  For example, when I rebound 'N' in menu mode to
  268.       a macro, it interfered with Junking of "Leave-Next" articles.
  269. --- 154,163 ----
  270.   Prog:    nn
  271.   Title:    Remapping keys may interfere with Junk command.
  272.   From:    Robert.Stockton@ELROND.GANDALF.CS.CMU.EDU
  273. ! Fixed:    Patch #3 [init.c keymap.c keymap.h group.c menu.c]
  274. !     (The fix involves a "shadow" keymap for the menu map keys bound to
  275. !     a macro.  The shadow binding is shown by :show map menu, ++Kim).
  276. !     
  277.       Menu mode macros are invoked when the appropriate keystrokes are used
  278.       in the Junk command.  For example, when I rebound 'N' in menu mode to
  279.       a macro, it interfered with Junking of "Leave-Next" articles.
  280. ***************
  281. *** 310,316 ****
  282.   
  283.   Prog:    nn
  284.   Title:    Interrupt char doesn't work (CBREAK/DYNIX)
  285. ! From:    Jaap Vermeulen <jaap@sequent.uucp>
  286.   
  287.       Interrupt (^C) does not work. ^G does work.
  288.       'stty' tells me I'm really using interrupt (^C).
  289. --- 313,320 ----
  290.   
  291.   Prog:    nn
  292.   Title:    Interrupt char doesn't work (CBREAK/DYNIX)
  293. ! From:    Jaap Vermeulen <jaap@sequent.uucp> + fix
  294. ! Fixed:    Patch #3 [term.c global.c s-dynix3-0.h s-template.h]
  295.   
  296.       Interrupt (^C) does not work. ^G does work.
  297.       'stty' tells me I'm really using interrupt (^C).
  298. ***************
  299. *** 445,450 ****
  300. --- 449,552 ----
  301.   From:    Bill Gaines <bill%iccdev@relay.EU.net> + fix
  302.   Fixed:    Patch #2 [Makefile]
  303.   
  304. + Prog:    nn
  305. + Title:    Cannot unsubscribe to last group in sequence
  306. + From:    Peter Andersen <datpete@daimi.dk>
  307. +     Chuq Von Rospach <chuq@Apple.COM>
  308. +     Jaap Vermeulen <jaap%sequent@relay.EU.net>
  309. + Fixed:    Patch #3 [newsrc.c]
  310. +     When keep_unsubscribed is false, unsubscribing to the last presented
  311. +     group has no effect (it is not saved in .newsrc.)
  312. + Prog:    nnusage
  313. + Title:    Manual not updated to reflect 6.4 behaviour and options
  314. + From:    dmr@csli.Stanford.EDU (Daniel M. Rosenberg)
  315. + Fixed:    Patch #3 [nnusage.1m]
  316. + Prog:    nn
  317. + Title:    Interactive :map # doesn't work
  318. + From:    Jaap Vermeulen <jaap%sequent@relay.EU.net>
  319. + Fixed:    Patch #3 [init.c]
  320. +     Interactive ':map #' is impossible.
  321. + Prog:    nn
  322. + Title:    Macros cannot be called by number using :macro N
  323. + From:    KFS
  324. + Fixed:    Patch #3 [init.c menu.c]
  325. + Prog:    nngrab
  326. + Title:    If keyword contain upper-case characters, nothing is found
  327. + From:    James A. Woods <jaw@riacs.edu>
  328. + Fixed:    Patch #3 [nngrab.sh nngrab.1 (new -c option)]
  329. +     Removing the -i option on egrep and folding the subjects database
  330. +     to lowercase (patch #2) breaks a command like "nngrab NeXT".
  331. + Prog:    nnmaster
  332. + Title:    From: ... (First Last - Division) is packed into "F L Division"
  333. + From:    olson%anchor.esd@sgi.com (Dave Olson)
  334. + Fixed:    Patch #3 [pack_name.c]
  335. + Prog:    nn
  336. + Title:    cursor isn't placed on the proper line in editor for :post cmd.
  337. + From:    arjen@mutad.uucp (Arjen Duursma) + fix
  338. + Fixed:    Patch #3 [answer.c]
  339. + Prog:    nn
  340. + Title:    A & B commands dump core in online manual and folders.
  341. + From:    Peter Radig <peter@radig.de>
  342. + Fixed:    Patch #3 [folder.c]
  343. + Prog:    nn
  344. + Title:    Return to menu with = in preview mode does not preserve attribute.
  345. + From:    Pekka Kyt|laakso <netmgr@csc.fi>
  346. + Fixed:    Patch #3 [menu.c]
  347. + Prog:    nn
  348. + Title:    Reply to a folder article w/o Newsgroups: header may dump core
  349. + From:    KFS
  350. + Fixed:    Patch #3 [answer.c]
  351. + Prog:    nn
  352. + Title:    default-save-file for folders is interpreted incorrectly
  353. + From:    Paul Petersen <petersen@uicsrd.csrd.uiuc.edu>
  354. + Fixed:    Patch #3 [save.c group.c variable.c nn.1 -- new folder-save-file]
  355. +     Say you have a folder of +alt.sources then the default save file is
  356. +     something like +/homes/petersen/News/alt.sources
  357. + Prog:    nnmaster
  358. + Title:    rmgrouped groups were not properly cleaned from the database
  359. + From:    chuq@Apple.COM
  360. + Fixed:    Patch #3 [master.c db.c group.c admin.c active.c]
  361. +     Groups which are removed from the active file are not properly
  362. +     removed from the database (actually another group would be removed!)
  363. + Prog:    nn
  364. + Title:    May dump core if saving to pipe and command fails.
  365. + From:    grady@scam.Berkeley.EDU (Steven Grady)
  366. +     nn just segmentation-faulted on me when I was doing ":unshar" on
  367. +     multiple articles.  The disk was full.
  368. + Prog:    nn
  369. + Title:    Unmark does not clear standout mode on HP terminals
  370. + From:    Bill Gaines <bill%iccdev@relay.EU.net>
  371. +     On HP terminals, if you mark an article, and then unmark it, the
  372. +     inverse video highlight does not go away.  You have to use "^L" to
  373. +     get a correct view of which articles are marked and which are not.
  374. + Prog:    nn
  375. + Title:    extended command help causes screen to be cleared after next command
  376. + From:    shields@nccnat.uucp (Paul Shields)
  377. +     In the command, ":? [space] pwd [return]" which prints the working
  378. +     directory correctly, but then repaints the screen immediately.
  379.   
  380.   New features since initial 6.4.0 release
  381.   ----------------------------------------
  382. ***************
  383. *** 463,465 ****
  384. --- 565,598 ----
  385.   Title:    updated to nntp release 1.5.8 (very minor changes!)
  386.   From:    KFS (with patches provided by Stan Barber)
  387.   Added:    Patch #2 [inews/*]
  388. + Prog:    nn
  389. + Title:    New marked-by-<command> variables
  390. + From:    KFS (inspired by a request from Jeff Sparkes)
  391. + Added:    Patch #3 [menu.c variable.c nn.1]
  392. +     The X, Z, and N can now be tuned regarding the amount of articles on
  393. +     the menu pages they will mark seen when executed.
  394. + Prog:    nn
  395. + Title:    :bug command now includes modified variables
  396. + From:    KFS (suggested by several users)
  397. + Added:    Patch #3 [variable.c answer.c]
  398. + Prog:    nn
  399. + Title:    New :print-variables command
  400. + From:    KFS
  401. + Added:    Patch #3 [variable.c init.c]
  402. + Prog:    nn
  403. + Title:    Arrow keys can now be redefined (e.g. map #up ^[ O A)
  404. + From:    KFS (on request from Jaap Vermeulen)
  405. + Fixed:    Patch #3 [init.c nn.1]
  406. +     I cannot define the up, down, right and left keys (in case they are
  407. +     not defined in my termcap entry).  Interactive ':map #' is impossible.
  408. + Prog:    nn
  409. + Title:    New folder-save-file variable for saving from folders.
  410. + From:    KFS (to fix problem with default-save-file)
  411. + Fixed:    Patch #3 [save.c group.c variable.c nn.1]
  412. *** ./LAST/folder.c    Thu Apr 26 14:28:28 1990
  413. --- folder.c    Fri May 18 23:22:24 1990
  414. ***************
  415. *** 252,260 ****
  416.       memory_marker        mem_marker;
  417.       group_header         fake_group;
  418.       int                cc_save;
  419.       extern time_stamp pack_date();
  420.   
  421. !     fake_group.group_name = path;
  422.       fake_group.group_flag = G_FOLDER | G_FAKED;
  423.       fake_group.master_flag = 0;
  424.       fake_group.save_file = NULL;
  425. --- 252,265 ----
  426.       memory_marker        mem_marker;
  427.       group_header         fake_group;
  428.       int                cc_save;
  429. +     char folder_name[FILENAME], folder_file[FILENAME];
  430.       extern time_stamp pack_date();
  431.   
  432. !     strcpy(folder_name, path);
  433. !     fake_group.group_name = folder_name;
  434. !     if (!expand_file_name(folder_file, folder_name, 1)) return ME_NO_REDRAW;
  435. !     fake_group.archive_file = path = folder_file;
  436. !     fake_group.next_group = fake_group.prev_group = NULL;
  437.       fake_group.group_flag = G_FOLDER | G_FAKED;
  438.       fake_group.master_flag = 0;
  439.       fake_group.save_file = NULL;
  440. ***************
  441. *** 332,340 ****
  442.       msg("Not a folder (no article header)");
  443.       menu_cmd = ME_NO_REDRAW;
  444.       } else {
  445. -     strcpy(buffer, path);
  446. -     fake_group.group_name = buffer;    /* save for later use */
  447.       if (n_articles > 1) {
  448.           clrdisp();
  449.           prompt_line = 2;
  450. --- 337,342 ----
  451. ***************
  452. *** 349,355 ****
  453.   
  454.       if (cancel_count) {
  455.           clrdisp();
  456. !         printf("Folder: %s\nFile:   %s\n\n", buffer, group_path_name);
  457.           if (cancel_count == n_articles)
  458.           printf("Cancel all articles and remove folder? ");
  459.           else
  460. --- 351,357 ----
  461.   
  462.       if (cancel_count) {
  463.           clrdisp();
  464. !         printf("Folder: %s\nFile:   %s\n\n", folder_name, folder_file);
  465.           if (cancel_count == n_articles)
  466.           printf("Cancel all articles and remove folder? ");
  467.           else
  468. *** ./LAST/global.c    Wed May 16 11:23:36 1990
  469. --- global.c    Thu May 17 00:41:24 1990
  470. ***************
  471. *** 76,81 ****
  472. --- 76,88 ----
  473.   export int s_pipe        = 0;    /* broken pipe */
  474.   export int s_redraw        = 0;    /* redraw signal (if job control) */
  475.   
  476. + #ifdef FAKE_INTERRUPT
  477. + #include <setjmp.h>
  478. + export jmp_buf fake_keyb_sig;
  479. + export int arm_fake_keyb_sig = 0;
  480. + #endif
  481.   sig_type catch_hangup(n)
  482.   {
  483.       signal(n, SIG_IGN);
  484. ***************
  485. *** 85,95 ****
  486.   
  487.   static sig_type catch_keyboard(n)
  488.   {
  489. -     s_keyboard++;
  490.   #ifdef RESET_SIGNAL_WHEN_CAUGHT
  491.       signal(n, catch_keyboard);
  492.   #endif
  493.   }
  494.   
  495.   static sig_type catch_pipe(n)
  496. --- 92,105 ----
  497.   
  498.   static sig_type catch_keyboard(n)
  499.   {
  500.   #ifdef RESET_SIGNAL_WHEN_CAUGHT
  501.       signal(n, catch_keyboard);
  502.   #endif
  503. + #ifdef FAKE_INTERRUPT
  504. +     if (arm_fake_keyb_sig)
  505. +     longjmp(fake_keyb_sig, 1);
  506. + #endif
  507. +     s_keyboard++;
  508.   }
  509.   
  510.   static sig_type catch_pipe(n)
  511. *** ./LAST/group.c    Wed May 16 11:23:37 1990
  512. --- group.c    Mon May 21 13:22:43 1990
  513. ***************
  514. *** 25,31 ****
  515.   import int  merged_menu, keep_unsubscribed, keep_unsub_long;
  516.   import int  killed_articles;
  517.   import int  seq_cross_filtering;
  518. ! import char *default_save_file;
  519.   
  520.   import char delayed_msg[];
  521.   import int32 db_read_counter;
  522. --- 25,31 ----
  523.   import int  merged_menu, keep_unsubscribed, keep_unsub_long;
  524.   import int  killed_articles;
  525.   import int  seq_cross_filtering;
  526. ! import char *default_save_file, *folder_save_file;
  527.   
  528.   import char delayed_msg[];
  529.   import int32 db_read_counter;
  530. ***************
  531. *** 191,197 ****
  532.   
  533.    reenter:
  534.       for (; gh; gh = gh->merge_with) {
  535. !     if (init_group(gh) <= 0) {
  536.           if (mg_head != NULL) continue;
  537.           menu_return( ME_NEXT );
  538.       }
  539. --- 191,197 ----
  540.   
  541.    reenter:
  542.       for (; gh; gh = gh->merge_with) {
  543. !     if ((gh->master_flag & M_IGNORE_GROUP) || init_group(gh) <= 0) {
  544.           if (mg_head != NULL) continue;
  545.           menu_return( ME_NEXT );
  546.       }
  547. ***************
  548. *** 361,367 ****
  549.       article_number first;
  550.       memory_marker mem_marker;
  551.       group_header *orig_group;
  552. !     int menu_cmd;
  553.       extern int menu(), file_completion();
  554.       extern article_header *get_menu_article();
  555.       extern int get_from_macro;
  556. --- 361,367 ----
  557.       article_number first;
  558.       memory_marker mem_marker;
  559.       group_header *orig_group;
  560. !     int menu_cmd, cmd_key;
  561.       extern int menu(), file_completion();
  562.       extern article_header *get_menu_article();
  563.       extern int get_from_macro;
  564. ***************
  565. *** 397,406 ****
  566.           
  567.           prompt("\1Enter\1 %s %s?  (ABGNPy) ", gh->group_name, buffer);
  568.           
  569. !         command = get_c();
  570. !         if (command & GETC_COMMAND) goto_return(ME_REDRAW);
  571. !         if (command == 'y') break;
  572. !         command = menu_key_map[command];
  573.       }
  574.   
  575.       switch (command) {
  576. --- 397,411 ----
  577.           
  578.           prompt("\1Enter\1 %s %s?  (ABGNPy) ", gh->group_name, buffer);
  579.           
  580. !         cmd_key = get_c();
  581. !         if (cmd_key & GETC_COMMAND) {
  582. !         command = cmd_key & ~GETC_COMMAND;
  583. !         if (command == K_REDRAW) goto_return(ME_REDRAW);
  584. !         } else {
  585. !         if (cmd_key == 'y') break;
  586. !         command = menu_key_map[cmd_key];
  587. !         if (command & K_MACRO) command = orig_menu_map[cmd_key];
  588. !         }
  589.       }
  590.   
  591.       switch (command) {
  592. ***************
  593. *** 480,490 ****
  594. --- 485,507 ----
  595.       if (current_group == NULL) goto_return(ME_NO_REDRAW);
  596.       if ((current_group->group_flag & G_FOLDER) == 0) {
  597.           if (!ah) {
  598. + #ifdef NNTP
  599. +         if (use_nntp) {
  600. +             msg("Can only use G%% in reading mode");
  601. +             goto_return(ME_NO_REDRAW);
  602. +         }
  603. + #endif
  604.           prompt("\1READ\1");
  605.           if ((ah = get_menu_article()) == NULL)
  606.               goto_return(ME_NO_REDRAW);
  607.           }
  608.           if ((ah->flag & A_DIGEST) == 0) {
  609. + #ifdef NNTP
  610. +         if (use_nntp) {
  611. +             answer = nntp_get_filename(ah->a_number, current_group);
  612. +             goto get_folder;
  613. +         }
  614. + #endif
  615.           *group_file_name = NUL;
  616.           sprintf(fbuffer, "%s%ld", group_path_name, ah->a_number);
  617.           answer = fbuffer;
  618. ***************
  619. *** 686,694 ****
  620.    get_folder:
  621.       m_endinput();
  622.       if (strcmp(answer, "+") == 0)
  623. !     answer = (gh && gh->save_file != NULL) ? gh->save_file : default_save_file;
  624. !     if (!expand_file_name(buffer, answer, 1)) goto_return (ME_NO_REDRAW);
  625. !     menu_cmd = folder_menu(buffer);
  626.       gh = NULL;
  627.       goto goto_exit;
  628.   
  629. --- 703,711 ----
  630.    get_folder:
  631.       m_endinput();
  632.       if (strcmp(answer, "+") == 0)
  633. !     answer = (gh && gh->save_file != NULL) ? gh->save_file : 
  634. !         (gh->group_flag & G_FOLDER) ? folder_save_file : default_save_file;
  635. !     menu_cmd = folder_menu(answer);
  636.       gh = NULL;
  637.       goto goto_exit;
  638.   
  639. *** ./LAST/init.c    Wed May 16 11:22:39 1990
  640. --- init.c    Fri May 18 11:51:11 1990
  641. ***************
  642. *** 245,250 ****
  643. --- 245,251 ----
  644.       "local",            5,    3,
  645.       "man",            3,    0,
  646.       "map",            3,    -1,
  647. +     "map #",            5,    -2,
  648.       "map both",            8,    4,
  649.       "map key",            7,    0,
  650.       "map menu",            8,    4,
  651. ***************
  652. *** 252,258 ****
  653.       "mkdir",            5,    1,
  654.       "patch",            5,    0, /* QUICK HACK */
  655.       "post",            4,    0, /* QUICK HACK */
  656. !     "print",            5,    0, /* QUICK HACK */
  657.       "pwd",            3,    0,
  658.       "rmail",            5,    0,
  659.       "set",            3,    3,
  660. --- 253,260 ----
  661.       "mkdir",            5,    1,
  662.       "patch",            5,    0, /* QUICK HACK */
  663.       "post",            4,    0, /* QUICK HACK */
  664. !     "print",            5,    -3, /* QUICK HACK */
  665. !     "print-variables",        15,    0,
  666.       "pwd",            3,    0,
  667.       "rmail",            5,    0,
  668.       "set",            3,    3,
  669. ***************
  670. *** 315,321 ****
  671.       other_compl = NULL;
  672.   
  673.       for (; alt->alt_name; alt++) {
  674. !         if (len <= alt->alt_len || head[alt->alt_len] != SP) continue;
  675.           index = strncmp(alt->alt_name, head, alt->alt_len);
  676.           if (index < 0) continue;
  677.           if (index > 0) break;
  678. --- 317,328 ----
  679.       other_compl = NULL;
  680.   
  681.       for (; alt->alt_name; alt++) {
  682. !         if (len <= alt->alt_len) continue;
  683. !         if (head[alt->alt_len] != SP) {
  684. !         if (alt->alt_type != -2) continue;
  685. !         if (strncmp(alt->alt_name, head, alt->alt_len)) continue;
  686. !         return -1;
  687. !         }
  688.           index = strncmp(alt->alt_name, head, alt->alt_len);
  689.           if (index < 0) continue;
  690.           if (index > 0) break;
  691. ***************
  692. *** 402,407 ****
  693. --- 409,419 ----
  694.           if (list_completion(p) == 0) break;
  695.           temp = help_alt->alt_len;
  696.   
  697. +         if (help_alt->alt_type == -3) {
  698. +         help_alt++;
  699. +         continue;
  700. +         }
  701. +     
  702.           do help_alt++;
  703.           while ((q = help_alt->alt_name) && help_alt->alt_len > temp &&
  704.              strncmp(p, q, temp) == 0);
  705. ***************
  706. *** 420,435 ****
  707.       if (index > 0) break;
  708.   
  709.       p = alt->alt_name;
  710. !     sprintf(tail, "%s ", p + len);
  711.       temp = alt->alt_len;
  712.   
  713.       do alt++;
  714. !     while ((q = alt->alt_name) && alt->alt_len > temp &&
  715.              strncmp(p, q, temp) == 0);
  716.   
  717.       return 1;
  718.       }
  719. !     return 0;
  720.   }
  721.   
  722.   static print_debug_info()
  723. --- 432,459 ----
  724.       if (index > 0) break;
  725.   
  726.       p = alt->alt_name;
  727. !     sprintf(tail, "%s%s", p + len, alt->alt_type <= -2 ? "" : " ");
  728.       temp = alt->alt_len;
  729.   
  730. +     if (alt->alt_type == -3) {
  731. +         alt++;
  732. +         return 1;
  733. +     }
  734. +     
  735.       do alt++;
  736. !     while ((q = alt->alt_name) && alt->alt_len > temp && 
  737.              strncmp(p, q, temp) == 0);
  738.   
  739.       return 1;
  740.       }
  741. !     cmd_completion(head, len);
  742. !     if (temp = cmd_completion((char *)NULL, 0)) {
  743. !     other_compl = cmd_completion;
  744. !     tail = NULL;
  745. !     }
  746. !     return temp;
  747.   }
  748.   
  749.   static print_debug_info()
  750. ***************
  751. *** 574,579 ****
  752. --- 598,604 ----
  753.   FILE *initf;
  754.   {
  755.       int code, map_menu, map_show, must_redraw = 0;
  756. +     key_type bind_to;
  757.   
  758.       SWITCH( argv(1) ) {
  759.   
  760. ***************
  761. *** 587,600 ****
  762.           key_type multi_buffer[16], *mb;
  763.           int i;
  764.   
  765. !         if (!isdigit(argv(1)[1])) break;
  766.   
  767.           for (i = 2, mb = multi_buffer; argv(i); i++)
  768.           *mb++ = parse_key(argv(i));
  769.           *mb = NUL;
  770.   
  771. !         enter_multi_key(K_function(argv(1)[1] - '0'),
  772. !                 (key_type *)copy_str((char *)multi_buffer));
  773.   
  774.           goto out;
  775.       }
  776. --- 612,630 ----
  777.           key_type multi_buffer[16], *mb;
  778.           int i;
  779.   
  780. !         if (argv(1)[1] == NUL) break;
  781. !         if (isdigit(argv(1)[1])) 
  782. !         bind_to = K_function(argv(1)[1] - '0');
  783. !         else {
  784. !         bind_to = parse_key(argv(1) + 1);
  785. !         if (bind_to <= 0x80) break; /* not pretty! */
  786. !         }
  787.   
  788.           for (i = 2, mb = multi_buffer; argv(i); i++)
  789.           *mb++ = parse_key(argv(i));
  790.           *mb = NUL;
  791.   
  792. !         enter_multi_key(bind_to, (key_type *)copy_str((char *)multi_buffer));
  793.   
  794.           goto out;
  795.       }
  796. ***************
  797. *** 638,644 ****
  798.               goto mac_err;
  799.   
  800.           if (code != K_INVALID) {
  801. !         menu_key_map[parse_key(argv(2))] = code;
  802.           if (!map_show) goto out;
  803.           }
  804.       }
  805. --- 668,677 ----
  806.               goto mac_err;
  807.   
  808.           if (code != K_INVALID) {
  809. !         bind_to = parse_key(argv(2));
  810. !         if (code & K_MACRO && orig_menu_map[bind_to] == 0)
  811. !             orig_menu_map[bind_to] = menu_key_map[bind_to];
  812. !         menu_key_map[bind_to] = code;
  813.           if (!map_show) goto out;
  814.           }
  815.       }
  816. ***************
  817. *** 906,913 ****
  818.   
  819.           alt_cmd_key = lookup_command(sw_string,
  820.                    in_menu_mode ? K_ONLY_MENU : K_ONLY_MORE);
  821. !         if (alt_cmd_key != K_INVALID && alt_cmd_key != K_HELP)
  822.           return AC_KEYCMD;
  823.       }
  824.   
  825.       CASE( "q" ) {
  826. --- 939,951 ----
  827.   
  828.           alt_cmd_key = lookup_command(sw_string,
  829.                    in_menu_mode ? K_ONLY_MENU : K_ONLY_MORE);
  830. !         if (alt_cmd_key != K_INVALID && alt_cmd_key != K_HELP) {
  831. !         if (alt_cmd_key == K_MACRO) {
  832. !             if (ARGTAIL == NULL) break;
  833. !             alt_cmd_key |= atoi(ARGTAIL);
  834. !         }
  835.           return AC_KEYCMD;
  836. +         }
  837.       }
  838.   
  839.       CASE( "q" ) {
  840. ***************
  841. *** 1033,1038 ****
  842. --- 1071,1087 ----
  843.           return AC_REDRAW;
  844.       }
  845.   
  846. +     CASE( "print-variables" ) {
  847. +         import char printer[];
  848. +         FILE *p;
  849. +         if (p = popen(ARGTAIL ? ARGTAIL : printer, "w")) {
  850. +         print_variable_config(p, 1);
  851. +         pclose(p);
  852. +         msg("Variables printed");
  853. +         }
  854. +         break;
  855. +     }
  856. +     
  857.       CASE( "pwd" ) {
  858.           FILE *p = popen("exec pwd", "r");
  859.           char dir[FILENAME];
  860. *** ./LAST/keymap.c    Fri Apr 27 21:30:58 1990
  861. --- keymap.c    Thu May 17 11:19:11 1990
  862. ***************
  863. *** 410,415 ****
  864. --- 410,416 ----
  865.   /* #9  */    K_UNBOUND
  866.   };
  867.   
  868. + export int orig_menu_map[KEY_MAP_SIZE];    /* initially empty */
  869.   
  870.   
  871.   static struct command_name_map {
  872. ***************
  873. *** 797,802 ****
  874. --- 798,805 ----
  875.       if (map[c] & K_MACRO) {
  876.           if (pg_next() < 0) goto out;
  877.           printf("macro %d: %s", (map[c] & ~K_MACRO), key_name(c));
  878. +         if (map == menu_key_map && orig_menu_map[c] != K_UNBOUND) 
  879. +         printf(" (%s)", command_name(orig_menu_map[c]));
  880.       }
  881.   
  882.    out:
  883. *** ./LAST/keymap.h    Thu Apr 26 21:10:15 1990
  884. --- keymap.h    Thu May 17 11:19:12 1990
  885. ***************
  886. *** 123,128 ****
  887. --- 123,129 ----
  888.   
  889.   extern int menu_key_map[];
  890.   extern int more_key_map[];
  891. + extern int orig_menu_map[];
  892.   
  893.   extern key_type global_key_map[];
  894.   
  895. *** ./LAST/man/nn.1.A    Wed May 16 11:23:42 1990
  896. --- man/nn.1.A    Mon May 21 17:18:31 1990
  897. ***************
  898. *** 598,607 ****
  899.   articles have been read, return to selection mode in the
  900.   .I current
  901.   group.  It will mark \fIselected\fP articles \fIread\fP as they are
  902. ! read, but \fIunread\fP articles are not changed.
  903.   .TP
  904.   \&\fBX\fP    {\fBread-skip\fP}
  905. ! Mark all \fIunread\fP articles \fIseen\fP on all menu pages, and enter
  906.   reading mode \fIimmediately\fP with the currently selected articles.
  907.   As the selected articles are read, they are marked \fIread\fP.  When
  908.   all selected articles have been read, \fInn\fP will enter selection
  909. --- 598,609 ----
  910.   articles have been read, return to selection mode in the
  911.   .I current
  912.   group.  It will mark \fIselected\fP articles \fIread\fP as they are
  913. ! read, but \fIunread\fP articles are not normally changed (can be
  914. ! controlled with the variable \fBmarked-by-read-return\fP.)
  915.   .TP
  916.   \&\fBX\fP    {\fBread-skip\fP}
  917. ! Mark all \fIunmarked\fP articles \fIseen\fP on all menu pages (or the
  918. ! pages defined by the \fBmarked-by-read-skip\fP variable), and enter
  919.   reading mode \fIimmediately\fP with the currently selected articles.
  920.   As the selected articles are read, they are marked \fIread\fP.  When
  921.   all selected articles have been read, \fInn\fP will enter selection
  922. ***************
  923. *** 614,623 ****
  924.   for later, you can use the following commands which will only mark
  925.   \fIseen\fP and \fIread\fP articles as read.  Currently selected
  926.   articles will still be selected the next time you enter the group.
  927. ! None of these commands will change any attributes themselves.
  928.   .TP
  929.   \&\fBN\fP    {\fBnext-group\fP}
  930. ! Go forward to the next group in the presentation sequence.
  931.   .TP
  932.   \&\fBP\fP    {\fBprevious\fP}
  933.   Go back to the previous group.  This command will enter selection mode
  934. --- 616,627 ----
  935.   for later, you can use the following commands which will only mark
  936.   \fIseen\fP and \fIread\fP articles as read.  Currently selected
  937.   articles will still be selected the next time you enter the group.
  938. ! None of these commands will change any attributes themselves (by default).
  939.   .TP
  940.   \&\fBN\fP    {\fBnext-group\fP}
  941. ! Go forward to the next group in the presentation sequence.  If the
  942. ! variable \fBmarked-by-next-group\fP is set articles on the menu can
  943. ! optionally be marked \fIseen\fP
  944.   .TP
  945.   \&\fBP\fP    {\fBprevious\fP}
  946.   Go back to the previous group.  This command will enter selection mode
  947. ***************
  948. *** 653,661 ****
  949.   command.
  950.   .LP
  951.   \fBRelated variables\fP:
  952. ! auto-preview-mode, auto-select-subject, case-fold-search,
  953. ! confirm-auto-quit, confirm-entry,
  954. ! auto-junk-seen, confirm-junk-seen, retain-seen-status, select-on-sender.
  955.   .SH THE JUNK-ARTICLES AND LEAVE-NEXT COMMANDS
  956.   The \fBJ\fP {\fBjunk-articles\fP} command is a very flexible command
  957.   which can perform all sorts of attribute changes, either on individual
  958. --- 657,666 ----
  959.   command.
  960.   .LP
  961.   \fBRelated variables\fP:
  962. ! auto-junk-seen, auto-preview-mode, auto-select-subject, case-fold-search,
  963. ! confirm-auto-quit, confirm-entry, confirm-junk-seen,
  964. ! marked-by-next-group, marked-by-read-return, marked-by-read-skip,
  965. ! retain-seen-status, select-on-sender.
  966.   .SH THE JUNK-ARTICLES AND LEAVE-NEXT COMMANDS
  967.   The \fBJ\fP {\fBjunk-articles\fP} command is a very flexible command
  968.   which can perform all sorts of attribute changes, either on individual
  969. ***************
  970. *** 1104,1110 ****
  971.   .LP
  972.   \fBRelated variables\fP:
  973.   confirm-append, confirm-create, decode-header-file,
  974. ! decode-skip-prefix, default-save-file,
  975.   edit-patch-command, edit-print-command, edit-unshar-command, folder,
  976.   mail-format, mmdf-format, patch-command, printer, quick-save,
  977.   save-counter, save-counter-offset, save-report,
  978. --- 1109,1115 ----
  979.   .LP
  980.   \fBRelated variables\fP:
  981.   confirm-append, confirm-create, decode-header-file,
  982. ! decode-skip-prefix, default-save-file, folder-save-file,
  983.   edit-patch-command, edit-print-command, edit-unshar-command, folder,
  984.   mail-format, mmdf-format, patch-command, printer, quick-save,
  985.   save-counter, save-counter-offset, save-report,
  986. *** ./LAST/man/nn.1.B    Wed May 16 11:23:44 1990
  987. --- man/nn.1.B    Mon May 21 17:18:31 1990
  988. ***************
  989. *** 18,24 ****
  990.   \fB+\fP
  991.   A single plus is replaced by the expansion of the file name contained in the
  992.   .B default-save-file
  993. ! variable.
  994.   .TP
  995.   \fB~/\fP\fIfile\fP
  996.   The
  997. --- 18,24 ----
  998.   \fB+\fP
  999.   A single plus is replaced by the expansion of the file name contained in the
  1000.   .B default-save-file
  1001. ! variable (or by \fBfolder-save-file\fP when saving from a folder).
  1002.   .TP
  1003.   \fB~/\fP\fIfile\fP
  1004.   The
  1005. ***************
  1006. *** 85,91 ****
  1007.   next in part3.shar, and so on).
  1008.   .LP
  1009.   \fBRelated variables\fP:
  1010. ! default-save-file, folder, save-counter, save-counter-offset.
  1011.   .SH FILE AND GROUP NAME COMPLETION
  1012.   When entering a file name or a news group name, a simple
  1013.   .B completion
  1014. --- 85,91 ----
  1015.   next in part3.shar, and so on).
  1016.   .LP
  1017.   \fBRelated variables\fP:
  1018. ! default-save-file, folder, folder-save-file, save-counter, save-counter-offset.
  1019.   .SH FILE AND GROUP NAME COMPLETION
  1020.   When entering a file name or a news group name, a simple
  1021.   .B completion
  1022. ***************
  1023. *** 423,429 ****
  1024.   .fi
  1025.   .LP
  1026.   \fBRelated variables\fP:
  1027. ! case-fold-search, default-save-file
  1028.   .SH AUTOMATIC KILL AND SELECTION
  1029.   When there is a subject or an author which you are either very
  1030.   interested in, or find completely uninteresting, you can easily
  1031. --- 423,429 ----
  1032.   .fi
  1033.   .LP
  1034.   \fBRelated variables\fP:
  1035. ! case-fold-search, default-save-file, folder-save-file
  1036.   .SH AUTOMATIC KILL AND SELECTION
  1037.   When there is a subject or an author which you are either very
  1038.   interested in, or find completely uninteresting, you can easily
  1039. *** ./LAST/man/nn.1.C    Wed May 16 11:23:46 1990
  1040. --- man/nn.1.C    Mon May 21 17:18:31 1990
  1041. ***************
  1042. *** 342,350 ****
  1043.   the subject for the specified period.
  1044.   .TP
  1045.   \fBdefault-save-file\fP \fIfile\fP    (string, default +$F)
  1046. ! The default save file used in quick save mode.  It can also be
  1047. ! specified using the abbreviation "+" as the file name in normal save
  1048. ! mode.
  1049.   .TP
  1050.   \fBdelay-redraw\fP        (boolean, default false)
  1051.   Normally, \fInn\fP will redraw the screen after extended
  1052. --- 342,352 ----
  1053.   the subject for the specified period.
  1054.   .TP
  1055.   \fBdefault-save-file\fP \fIfile\fP    (string, default +$F)
  1056. ! The default save file used when saving articles in news groups where
  1057. ! no save file has been specified in the init file (either in a
  1058. ! \fBsave-files\fP section or in the presentation sequence).
  1059. ! It can also be specified using the abbreviation "+" as the file name
  1060. ! when prompted for a file name even in groups with their own save file.
  1061.   .TP
  1062.   \fBdelay-redraw\fP        (boolean, default false)
  1063.   Normally, \fInn\fP will redraw the screen after extended
  1064. ***************
  1065. *** 425,430 ****
  1066. --- 427,435 ----
  1067.   .I init
  1068.   file.
  1069.   .TP
  1070. + \fBfolder-save-file\fP \fIfile\fP    (string, default not set)
  1071. + The default save file used when saving articles \fIfrom\fP a folder.
  1072. + .TP
  1073.   \fBfsort\fP        (boolean, default true)
  1074.   When set, folders are sorted alphabetically according to the subject
  1075.   (and age).
  1076. ***************
  1077. *** 523,529 ****
  1078.   sent from \fInn\fP using the \fBreply\fP and \fBmail\fP commands.  For
  1079.   example:
  1080.   .br
  1081. !    set mail-header Reply-To: storm@texas.dk
  1082.   .br
  1083.   .TP
  1084.   \fBmail-record\fP \fIfile\fP    (string, default not set)
  1085. --- 528,534 ----
  1086.   sent from \fInn\fP using the \fBreply\fP and \fBmail\fP commands.  For
  1087.   example:
  1088.   .br
  1089. !    set mail-header Reply-To: storm@texas.dk;Organization: TI - DK
  1090.   .br
  1091.   .TP
  1092.   \fBmail-record\fP \fIfile\fP    (string, default not set)
  1093. ***************
  1094. *** 549,554 ****
  1095. --- 554,582 ----
  1096.   program.  Otherwise, the file containing the message will be given as
  1097.   the first (and only) argument to the \fBmailer\fP command.
  1098.   .TP
  1099. + \fBmarked-by-next-group\fP \fIN\fP    (integer, default 0)
  1100. + Specifies the amount of (unmarked) articles on the menu marked
  1101. + \fIseen\fP by the \fBN\fP {\fBnext-group\fP} command in selection
  1102. + mode.  See \fBmarked-by-read-skip\fP for possible values of \fIN\fP.
  1103. + .TP
  1104. + \fBmarked-by-read-return\fP \fIN\fP    (integer, default 0)
  1105. + Specifies the amount of (unmarked) articles on the menu marked
  1106. + \fIseen\fP by the \fBZ\fP {\fBread-return\fP} command in selection
  1107. + mode.  See \fBmarked-by-read-skip\fP for possible values of \fIN\fP.
  1108. + .TP
  1109. + \fBmarked-by-read-skip\fP \fIN\fP    (integer, default 4)
  1110. + Specifies the amount of (unmarked) articles on the menu marked
  1111. + \fIseen\fP by the \fBX\fP {\fBread-skip\fP} command in selection mode.
  1112. + The following values of \fIN\fP are recognized:
  1113. + .br
  1114. + .nf
  1115. +     0:  No articles are marked seen
  1116. +     1:  Current page is marked seen
  1117. +     2:  Previous pages are marked seen
  1118. +     3:  Previous and current pages are marked seen
  1119. +     4:  All pages are marked seen
  1120. + .fi
  1121. + .TP
  1122.   \fBmark-overlap\fP    (boolean, default false)
  1123.   When set, \fInn\fP will draw a line (using the underline capabilities
  1124.   of the terminal if possible) to indicate the end of the overlap (see the
  1125. ***************
  1126. *** 602,608 ****
  1127.   The \fIheaders\fP string specifies one or more extra header lines
  1128.   (separated by semi-colons `;') which are added to the header of
  1129.   articles posted from \fInn\fP using the \fBfollow\fP and \fBpost\fP
  1130. ! commands.
  1131.   .TP
  1132.   \fBnews-record\fP \fIfile\fP    (string, default not set)
  1133.   Save file for follow-ups and postings.  Same rules and format as the
  1134. --- 630,636 ----
  1135.   The \fIheaders\fP string specifies one or more extra header lines
  1136.   (separated by semi-colons `;') which are added to the header of
  1137.   articles posted from \fInn\fP using the \fBfollow\fP and \fBpost\fP
  1138. ! commands.  See \fBmail-header\fP for an example.
  1139.   .TP
  1140.   \fBnews-record\fP \fIfile\fP    (string, default not set)
  1141.   Save file for follow-ups and postings.  Same rules and format as the
  1142. ***************
  1143. *** 919,925 ****
  1144.   \fBsuggest-default-save\fP    (boolean, default true)
  1145.   When set, \fInn\fP will present the \fBdefault-save-file\fP when
  1146.   prompting for a save file name in a group without a specific save
  1147. ! file.  When not set, no file name is presented, and to use the default
  1148.   save file, a single + must be specified.
  1149.   .TP
  1150.   \fBtidy-newsrc\fP        (boolean, default false)
  1151. --- 947,954 ----
  1152.   \fBsuggest-default-save\fP    (boolean, default true)
  1153.   When set, \fInn\fP will present the \fBdefault-save-file\fP when
  1154.   prompting for a save file name in a group without a specific save
  1155. ! file, or \fBfolder-save-file\fP when saving from a folder.  When not
  1156. ! set, no file name is presented, and to use the default
  1157.   save file, a single + must be specified.
  1158.   .TP
  1159.   \fBtidy-newsrc\fP        (boolean, default false)
  1160. *** ./LAST/man/nn.1.D    Wed May 16 11:23:47 1990
  1161. --- man/nn.1.D    Mon May 21 17:18:31 1990
  1162. ***************
  1163. *** 423,429 ****
  1164.   .BR #9
  1165.   for the user-defined keys.
  1166.   .sp 0.5v
  1167. ! Multikey #\fIi\fP is defined using the following command:
  1168.   .sp 0.5v
  1169.       \fBmap #\fP\fIi\fP \fIkey-sequence\fP
  1170.   .sp 0.5v
  1171. --- 423,430 ----
  1172.   .BR #9
  1173.   for the user-defined keys.
  1174.   .sp 0.5v
  1175. ! Multikey #\fIi\fP (where \fIi\fP is a digit or an arrow key name) is
  1176. ! defined using the following command:
  1177.   .sp 0.5v
  1178.       \fBmap #\fP\fIi\fP \fIkey-sequence\fP
  1179.   .sp 0.5v
  1180. *** ./LAST/man/nngrab.1    Wed May 16 11:23:50 1990
  1181. --- man/nngrab.1    Fri May 18 20:22:23 1990
  1182. ***************
  1183. *** 3,10 ****
  1184.   .SH NAME
  1185.   nngrab \- news retrieval by keyword (nn)
  1186.   .SH SYNOPSIS
  1187. ! .B nngrab
  1188. ! .I keyword
  1189.   .SH DESCRIPTION
  1190.   .I nngrab
  1191.   invokes \fInn\fP
  1192. --- 3,9 ----
  1193.   .SH NAME
  1194.   nngrab \- news retrieval by keyword (nn)
  1195.   .SH SYNOPSIS
  1196. ! \fBnngrab\fP [ \-\fBc\fP ] \fIkeyword\fP
  1197.   .SH DESCRIPTION
  1198.   .I nngrab
  1199.   invokes \fInn\fP
  1200. ***************
  1201. *** 20,26 ****
  1202.   .sp 0.5v
  1203.   will retrieve items concerning Nikola Tesla.
  1204.   .LP
  1205. ! Keyword case is ignored, and the \fIkeyword\fP can be a regular
  1206.   expressions (escaped to avoid conflicts with the shell).  For example,
  1207.   .sp 0.5v
  1208.       nngrab "n.*tesla"
  1209. --- 19,26 ----
  1210.   .sp 0.5v
  1211.   will retrieve items concerning Nikola Tesla.
  1212.   .LP
  1213. ! Keyword case is ignored unless \-\fBc\fP is specified, and the
  1214. ! \fIkeyword\fP can be a regular
  1215.   expressions (escaped to avoid conflicts with the shell).  For example,
  1216.   .sp 0.5v
  1217.       nngrab "n.*tesla"
  1218. *** ./LAST/man/nnusage.1m    Sat Mar 31 23:12:58 1990
  1219. --- man/nnusage.1m    Fri May 18 23:22:23 1990
  1220. ***************
  1221. *** 5,21 ****
  1222.   nnusage \- display \fInn\fP usage statistics
  1223.   .SH SYNOPSIS
  1224.   .B nnusage
  1225. ! [ -t ]
  1226.   .SH DESCRIPTION
  1227.   .B nnusage
  1228.   will extract the usage entries from the log file and calculate the
  1229. ! total usage time for each \fInn\fP user.
  1230.   .LP
  1231. ! Without options, the output will be sorted according to user names.
  1232.   .LP
  1233. - With the \-t option, \fInnusage\fP will list the users ordered after
  1234. - the total usage time.
  1235. - .LP
  1236.   Since it is possible to
  1237.   suspend
  1238.   \fInn\fP, or leave the terminal while \fInn\fP is active, \fInn\fP
  1239. --- 5,21 ----
  1240.   nnusage \- display \fInn\fP usage statistics
  1241.   .SH SYNOPSIS
  1242.   .B nnusage
  1243. ! [ \-\fBat\fP ]
  1244.   .SH DESCRIPTION
  1245.   .B nnusage
  1246.   will extract the usage entries from the log file and calculate the
  1247. ! total usage time for the current user, or for all \fInn\fP users if
  1248. ! \-\fBa\fP is specified.
  1249.   .LP
  1250. ! When \-\fBt\fP is used with the \-\fBa\fP option, \fInnusage\fP will
  1251. ! list the users ordered after the total usage time.  Otherwise, the
  1252. ! output will be sorted according to user names.
  1253.   .LP
  1254.   Since it is possible to
  1255.   suspend
  1256.   \fInn\fP, or leave the terminal while \fInn\fP is active, \fInn\fP
  1257. ***************
  1258. *** 30,37 ****
  1259.   .SH SEE ALSO
  1260.   nn(1), nncheck(1), nngoback(1), nngrep(1), nntidy(1)
  1261.   .br
  1262. ! nnadmin(1M), nnquery(1M), nnmaster(8)
  1263.   .SH NOTES
  1264.   The \fInn\fP package must have been compiled with the STATISTICS
  1265.   option turned on to produce the usage entries in the log file.
  1266.   .LP
  1267. --- 30,40 ----
  1268.   .SH SEE ALSO
  1269.   nn(1), nncheck(1), nngoback(1), nngrep(1), nntidy(1)
  1270.   .br
  1271. ! nnacct(1m), nnadmin(1M), nnquery(1M), nnmaster(8)
  1272.   .SH NOTES
  1273. + If \fInn\fP is compiled with ACCOUNTING turned on, then calls to
  1274. + \fInnusage\fP are converted into equivalent calls to \fInnacct\fP.
  1275. + .LP
  1276.   The \fInn\fP package must have been compiled with the STATISTICS
  1277.   option turned on to produce the usage entries in the log file.
  1278.   .LP
  1279. *** ./LAST/master.c    Wed May 16 11:22:45 1990
  1280. --- master.c    Mon May 21 13:22:43 1990
  1281. ***************
  1282. *** 171,183 ****
  1283.       gh->first_db_article = 0;
  1284.       gh->last_db_article = 0;
  1285.   
  1286. !     if (gh->data_write_offset > (off_t)0) {
  1287. !     gh->data_write_offset = (off_t)0;
  1288.       (void)open_data_file(gh, 'd', -1);
  1289. -     }
  1290. -     
  1291. -     if (gh->index_write_offset) {
  1292. -     gh->index_write_offset = (off_t)0;
  1293.       (void)open_data_file(gh, 'x', -1);
  1294.       }
  1295.       
  1296. --- 171,181 ----
  1297.       gh->first_db_article = 0;
  1298.       gh->last_db_article = 0;
  1299.   
  1300. !     gh->data_write_offset = (off_t)0;
  1301. !     gh->index_write_offset = (off_t)0;
  1302. !     if (init_group(gh)) {
  1303.       (void)open_data_file(gh, 'd', -1);
  1304.       (void)open_data_file(gh, 'x', -1);
  1305.       }
  1306.       
  1307. ***************
  1308. *** 438,445 ****
  1309.       next_g->next_group = gh;
  1310.       next_g = gh;
  1311.       gh->next_group = NULL;
  1312. -     init_group(gh);    /* for clean_group() */
  1313.   
  1314.       /* moderation flag will be set by first visit_active_file call */
  1315.   
  1316. --- 436,441 ----
  1317. *** ./LAST/menu.c    Wed May 16 11:23:53 1990
  1318. --- menu.c    Fri May 18 22:26:07 1990
  1319. ***************
  1320. *** 24,29 ****
  1321. --- 24,32 ----
  1322.   export int  collapse_subject = 25; /* collapse long subjects at position */
  1323.   export int  conf_group_entry = 0; /* ask whether group should be entered */
  1324.   export int  conf_entry_limit = 0; /* ask only if more than .. unread */
  1325. + export int  mark_read_skip = 4; /* effect of X command */
  1326. + export int  mark_read_return = 0; /* effect of Z command */
  1327. + export int  mark_next_group = 0; /* effect of N command */
  1328.   
  1329.   export int  auto_preview_mode = 0; /* preview rather than select */
  1330.   export int  preview_continuation = 12; /* what to do after preview */
  1331. ***************
  1332. *** 452,458 ****
  1333.   static int article_id;
  1334.   static int cur_key;
  1335.   
  1336. ! static int get_k_cmd()
  1337.   {
  1338.       extern int any_message;
  1339.       register int c, map;
  1340. --- 455,461 ----
  1341.   static int article_id;
  1342.   static int cur_key;
  1343.   
  1344. ! static int get_k_cmd_1()
  1345.   {
  1346.       extern int any_message;
  1347.       register int c, map;
  1348. ***************
  1349. *** 472,482 ****
  1350.       }
  1351.       if (s_hangup) map = K_QUIT;
  1352.   
  1353. -     if (map & K_MACRO) {
  1354. -     m_invoke(map & ~K_MACRO);
  1355. -     goto loop;
  1356. -     }
  1357.       if (map & K_ARTICLE_ID) {
  1358.       article_id = map & ~K_ARTICLE_ID;
  1359.       map = K_ARTICLE_ID;
  1360. --- 475,480 ----
  1361. ***************
  1362. *** 491,496 ****
  1363. --- 489,504 ----
  1364.       return map;
  1365.   }
  1366.   
  1367. + static int get_k_cmd()
  1368. + {
  1369. +     register int map;
  1370. +     map = get_k_cmd_1();
  1371. +     if (map & K_MACRO)
  1372. +     map = orig_menu_map[cur_key];
  1373. +     return map;
  1374. + }
  1375.   
  1376.   char *pct(start, end, first, last)
  1377.   long start, end, first, last;
  1378. ***************
  1379. *** 592,598 ****
  1380.       int            doing_unshar, did_unshar, junk_prompt;
  1381.       char         *fname, *savemode, *init_save();
  1382.       int         maxa;    /* max no of articles per menu page */
  1383. !     int         o_firsta, o_mode;    /* for recursive calls */
  1384.       static        menu_level = 0;
  1385.       char        purpose[80], pr_fmt[60];
  1386.       extern int         enable_stop, file_completion();
  1387. --- 600,607 ----
  1388.       int            doing_unshar, did_unshar, junk_prompt;
  1389.       char         *fname, *savemode, *init_save();
  1390.       int         maxa;    /* max no of articles per menu page */
  1391. !     article_number    o_firsta, temp1, temp2;
  1392. !     int            o_mode;    /* for recursive calls */
  1393.       static        menu_level = 0;
  1394.       char        purpose[80], pr_fmt[60];
  1395.       extern int         enable_stop, file_completion();
  1396. ***************
  1397. *** 752,760 ****
  1398.        }
  1399.   
  1400.        last_k_cmd = cur_k_cmd;
  1401. -      k_cmd = get_k_cmd();
  1402.   
  1403.     alt_key:
  1404.   
  1405.        switch (cur_k_cmd = k_cmd) {
  1406.   
  1407. --- 761,775 ----
  1408.        }
  1409.   
  1410.        last_k_cmd = cur_k_cmd;
  1411.   
  1412. +   get_next_k_cmd:
  1413. +      k_cmd = get_k_cmd_1();
  1414.     alt_key:
  1415. +     if (k_cmd & K_MACRO) {
  1416. +     m_invoke(k_cmd & ~K_MACRO);
  1417. +     goto get_next_k_cmd;
  1418. +     }
  1419.   
  1420.        switch (cur_k_cmd = k_cmd) {
  1421.   
  1422. ***************
  1423. *** 1022,1035 ****
  1424.        if (nexta < n_articles) goto nextmenu;
  1425.        break;
  1426.   
  1427. -       case K_READ_GROUP_UPDATE:
  1428. -      repl_attr_all(0, A_SEEN, 0);
  1429. -      break;
  1430.         case K_READ_GROUP_THEN_SAME:
  1431.        break;
  1432.   
  1433.         case K_NEXT_GROUP_NO_UPDATE:
  1434.        menu_return(ME_NEXT);
  1435.   
  1436.         case K_PREVIOUS:
  1437. --- 1037,1068 ----
  1438.        if (nexta < n_articles) goto nextmenu;
  1439.        break;
  1440.   
  1441.         case K_READ_GROUP_THEN_SAME:
  1442. +      if (temp = mark_read_return) goto do_marked_by;
  1443.        break;
  1444.   
  1445.         case K_NEXT_GROUP_NO_UPDATE:
  1446. +      if (temp = mark_next_group) goto do_marked_by;
  1447. +      menu_return(ME_NEXT);
  1448. +       case K_READ_GROUP_UPDATE:
  1449. +      if (temp = mark_read_skip) break;
  1450. +       do_marked_by:
  1451. +      temp1 = 0; temp2 = n_articles;
  1452. +      switch (temp) {
  1453. +       case 1:
  1454. +          temp1 = firsta;
  1455. +       case 3:
  1456. +          temp2 = nexta;
  1457. +          break;
  1458. +       case 2:
  1459. +          temp2 = firsta - 1;
  1460. +          break;
  1461. +       case 4:
  1462. +          break;
  1463. +      }
  1464. +      repl_attr(temp1, temp2, 0, A_SEEN, 0);
  1465. +      if (k_cmd != K_NEXT_GROUP_NO_UPDATE) break;
  1466.        menu_return(ME_NEXT);
  1467.   
  1468.         case K_PREVIOUS:
  1469. ***************
  1470. *** 1103,1109 ****
  1471.         junk_another:
  1472.            if (cura < 0 || cura > numa) cura = 0;
  1473.            gotoxy(0, firstl + cura); fl;
  1474. !          
  1475.            switch (get_k_cmd()) {
  1476.             case K_JUNK_ARTICLES:
  1477.            junk_prompt++;    /* can be 0 */
  1478. --- 1136,1142 ----
  1479.         junk_another:
  1480.            if (cura < 0 || cura > numa) cura = 0;
  1481.            gotoxy(0, firstl + cura); fl;
  1482.            switch (get_k_cmd()) {
  1483.             case K_JUNK_ARTICLES:
  1484.            junk_prompt++;    /* can be 0 */
  1485. ***************
  1486. *** 1394,1403 ****
  1487. --- 1427,1438 ----
  1488.        ah = articles[firsta+cura];
  1489.   
  1490.        no_raw();
  1491. +      orig_attr = ah->attr;
  1492.        ah->attr = 0;
  1493.        menu_cmd = more(ah, MM_PREVIEW, prompt_line);
  1494.        if (menu_cmd == MC_MENU) {
  1495.            next_cura = cura;
  1496. +          if (ah->attr == 0) ah->attr = orig_attr;
  1497.            if (prompt_line < 0) goto redraw;
  1498.            mark();
  1499.            prompt_line = temp;
  1500. ***************
  1501. *** 1404,1410 ****
  1502.            goto build_prompt;
  1503.        }
  1504.   
  1505. !      if (preview_mark_read && ah->attr == 0) ah->attr = A_READ;
  1506.        if (prompt_line >= 0)
  1507.            mark();
  1508.        next_cura = ++cura;
  1509. --- 1439,1447 ----
  1510.            goto build_prompt;
  1511.        }
  1512.   
  1513. !      if (ah->attr == 0)
  1514. !          ah->attr = preview_mark_read ? A_READ : orig_attr;
  1515.        if (prompt_line >= 0)
  1516.            mark();
  1517.        next_cura = ++cura;
  1518. *** ./LAST/more.c    Wed May 16 11:22:46 1990
  1519. --- more.c    Mon May 21 14:02:04 1990
  1520. ***************
  1521. *** 595,602 ****
  1522.       }
  1523.       skip_char = NUL;
  1524.       if (overlap > 0) {
  1525. !         underline_line = linenum;
  1526. !         linenum -= overlap;
  1527.           goto next_page;
  1528.       }
  1529.       }
  1530. --- 595,602 ----
  1531.       }
  1532.       skip_char = NUL;
  1533.       if (overlap > 0) {
  1534. !         underline_line = linenum - 1;
  1535. !         linenum -= overlap + 1;
  1536.           goto next_page;
  1537.       }
  1538.       }
  1539. *** ./LAST/newsrc.c    Wed May 16 11:23:54 1990
  1540. --- newsrc.c    Wed May 16 21:49:04 1990
  1541. ***************
  1542. *** 989,994 ****
  1543. --- 989,999 ----
  1544.           if (gh->newsrc_line != NULL && gh->newsrc_orig != gh->newsrc_line)
  1545.           freeobj(gh->newsrc_line);
  1546.           gh->newsrc_line = NULL;
  1547. +         if (gh->newsrc_orig != NULL) dump_newsrc();
  1548. +         if (gh->select_line != NULL && gh->newsrc_orig != gh->select_line)
  1549. +         freeobj(gh->select_line);
  1550. +         gh->select_line = NULL;
  1551. +         if (gh->select_orig != NULL) dump_select();
  1552.           return;
  1553.       }
  1554.       
  1555. *** ./LAST/nngrab.sh    Wed May 16 11:22:50 1990
  1556. --- nngrab.sh    Fri May 18 22:59:11 1990
  1557. ***************
  1558. *** 8,20 ****
  1559.   
  1560.   trap "rm -f $TMP/nngrab$$" 0 1 2 15
  1561.   
  1562.   if [ ! $# -eq 1 ] ; then
  1563. !     echo "usage: $0 keyword-pattern"
  1564.       exit 1
  1565.   fi
  1566.   
  1567.   if [ -s $DB/subjects ] ; then
  1568. !     egrep "^[^:]*:.*$1" $DB/subjects |
  1569.       sed 's/^\([^:]*\):.*/\1/' |
  1570.       uniq > $TMP/nngrab$$
  1571.   
  1572. --- 8,28 ----
  1573.   
  1574.   trap "rm -f $TMP/nngrab$$" 0 1 2 15
  1575.   
  1576. + FOLDCASE=""
  1577. + if [ x"$1" = x"-c" ] ; then
  1578. +     FOLDCASE="-i"
  1579. +     shift
  1580. + fi
  1581.   if [ ! $# -eq 1 ] ; then
  1582. !     echo "usage: $0 [-c] keyword-pattern"
  1583.       exit 1
  1584.   fi
  1585.   
  1586. + KW="`echo "$1" | tr '[A-Z]' '[a-z]'`"
  1587.   if [ -s $DB/subjects ] ; then
  1588. !     egrep "^[^:]*:.*${KW}" $DB/subjects |
  1589.       sed 's/^\([^:]*\):.*/\1/' |
  1590.       uniq > $TMP/nngrab$$
  1591.   
  1592. ***************
  1593. *** 23,29 ****
  1594.           exit
  1595.       fi
  1596.   
  1597. !     $BIN/nn -Q -mxX -s/"$1" -G `cat $TMP/nngrab$$`
  1598.   else
  1599. !     $BIN/nn -Q -mxX -s/"$1" all
  1600.   fi
  1601. --- 31,37 ----
  1602.           exit
  1603.       fi
  1604.   
  1605. !     $BIN/nn -Q -mxX $FOLDCASE -s/"$1" -G `cat $TMP/nngrab$$`
  1606.   else
  1607. !     $BIN/nn -Q -mxX $FOLDCASE -s/"$1" all
  1608.   fi
  1609. *** ./LAST/pack_name.c    Mon Apr 23 18:25:58 1990
  1610. --- pack_name.c    Fri May 18 15:05:58 1990
  1611. ***************
  1612. *** 339,347 ****
  1613.           name++;
  1614.           continue;
  1615.           }
  1616. !         if (prev_space)
  1617. !         *p = TAB;
  1618. !         else {
  1619.           *p = '-';
  1620.           lname++;
  1621.           }
  1622. --- 339,348 ----
  1623.           name++;
  1624.           continue;
  1625.           }
  1626. !         if (prev_space) {
  1627. !         *p = NUL; break;    /* strip from " -" */
  1628. !         /* *p = TAB;     /* do not strip from " -" */
  1629. !         } else {
  1630.           *p = '-';
  1631.           lname++;
  1632.           }
  1633. *** ./LAST/patchlevel.h    Wed May 16 11:23:57 1990
  1634. --- patchlevel.h    Mon May 21 13:32:45 1990
  1635. ***************
  1636. *** 11,19 ****
  1637.    *    1990-03-03: Release 6.4beta    (FTP)
  1638.    *    1990-05-07: Release 6.4        (comp.sources.unix)
  1639.    *
  1640. !  *    1990-05-10: Patch #1 (6.4.1)
  1641. !  *    1990-05-15: Patch #2 (6.4.2)
  1642.    */
  1643.   
  1644. ! #define PATCHLEVEL 2
  1645.   
  1646. --- 11,20 ----
  1647.    *    1990-03-03: Release 6.4beta    (FTP)
  1648.    *    1990-05-07: Release 6.4        (comp.sources.unix)
  1649.    *
  1650. !  *    1990-05-10: Patch #1 (6.4.1) - HIGH
  1651. !  *    1990-05-15: Patch #2 (6.4.2) - HIGH
  1652. !  *    1990-05-21: Patch #3 (6.4.3) - HIGH
  1653.    */
  1654.   
  1655. ! #define PATCHLEVEL 3
  1656.   
  1657. *** ./LAST/save.c    Thu Apr 26 20:34:11 1990
  1658. --- save.c    Fri May 18 23:31:03 1990
  1659. ***************
  1660. *** 12,17 ****
  1661. --- 12,18 ----
  1662.   #include "news.h"
  1663.   
  1664.   export char *default_save_file = "+$F";
  1665. + export char *folder_save_file = NULL;
  1666.   export int suggest_save_file = 1;
  1667.   export char *unshar_header_file = "Unshar.Headers";
  1668.   export int  use_mail_folders = 0;
  1669. ***************
  1670. *** 183,189 ****
  1671.   
  1672.           save_name = current_group->save_file;
  1673.           if (save_name == NULL && suggest_save_file)
  1674. !         save_name = default_save_file;
  1675.           if (save_name != NULL) {
  1676.           if (!expand_file_name(name_buf, save_name, 2)) return NULL;
  1677.           save_name = name_buf;
  1678. --- 184,191 ----
  1679.   
  1680.           save_name = current_group->save_file;
  1681.           if (save_name == NULL && suggest_save_file)
  1682. !         save_name = (current_group->group_flag & G_FOLDER) ?
  1683. !             folder_save_file : default_save_file;
  1684.           if (save_name != NULL) {
  1685.           if (!expand_file_name(name_buf, save_name, 2)) return NULL;
  1686.           save_name = name_buf;
  1687. ***************
  1688. *** 193,203 ****
  1689.           if (save_name == NULL || *save_name == NUL) return NULL;
  1690.   
  1691.           if (save_name[1] == NUL && save_name[0] == '+')
  1692. !         save_name = default_save_file;
  1693.           else
  1694.           if (current_group->save_file == NULL ||
  1695.               strcmp(save_name, current_group->save_file))
  1696.               strcpy(last_input, save_name);
  1697.       }
  1698.   
  1699.       if (*save_name == '|') {
  1700. --- 195,207 ----
  1701.           if (save_name == NULL || *save_name == NUL) return NULL;
  1702.   
  1703.           if (save_name[1] == NUL && save_name[0] == '+')
  1704. !         save_name = (current_group->group_flag & G_FOLDER) ?
  1705. !             folder_save_file : default_save_file;
  1706.           else
  1707.           if (current_group->save_file == NULL ||
  1708.               strcmp(save_name, current_group->save_file))
  1709.               strcpy(last_input, save_name);
  1710. +         if (save_name == NULL || *save_name == NUL) return NULL;
  1711.       }
  1712.   
  1713.       if (*save_name == '|') {
  1714. *** ./LAST/sequence.c    Wed May 16 11:22:51 1990
  1715. --- sequence.c    Fri May 18 15:56:23 1990
  1716. ***************
  1717. *** 451,462 ****
  1718.           continue;
  1719.       }
  1720.   
  1721. !     if (file_exist(group, "fr")) {
  1722.           faked_entry(group, G_FOLDER);
  1723.           any++;
  1724.           continue;
  1725.       }
  1726.   
  1727.       if (*group == '+' || *group == '~') {
  1728.           char exp_file[FILENAME];
  1729.           group_header fake_group;
  1730. --- 451,463 ----
  1731.           continue;
  1732.       }
  1733.   
  1734. !     if (*group == '+' || *group == '~' || file_exist(group, "fr")) {
  1735.           faked_entry(group, G_FOLDER);
  1736.           any++;
  1737.           continue;
  1738.       }
  1739.   
  1740. + #ifdef NOT_DEF
  1741.       if (*group == '+' || *group == '~') {
  1742.           char exp_file[FILENAME];
  1743.           group_header fake_group;
  1744. ***************
  1745. *** 474,479 ****
  1746. --- 475,481 ----
  1747.           errors++;
  1748.           continue;
  1749.       }
  1750. + #endif
  1751.   
  1752.       found = 0;
  1753.       start_group_search(group);
  1754. *** ./LAST/term.c    Wed May 16 11:23:58 1990
  1755. --- term.c    Thu May 17 01:15:32 1990
  1756. ***************
  1757. *** 107,112 ****
  1758. --- 107,119 ----
  1759.   
  1760.   #else    /* V7/BSD TTY DRIVER */
  1761.   
  1762. + #ifdef FAKE_INTERRUPT
  1763. + #include <setjmp.h>
  1764. + extern jmp_buf fake_keyb_sig;
  1765. + extern int arm_fake_keyb_sig;
  1766. + #endif
  1767.   #include <sgtty.h>
  1768.   
  1769.   static struct sgttyb norm_tty, raw_tty;
  1770. ***************
  1771. *** 803,809 ****
  1772.       while (--n >= 0) {
  1773.       c = (key_type)*cp++;
  1774.   #else
  1775.       while ((n = read(0, (char *)&c, 1)) > 0) {
  1776.       c &= 0177;    /* done by ISTRIP on USG systems */
  1777.   #endif
  1778. --- 810,822 ----
  1779.       while (--n >= 0) {
  1780.       c = (key_type)*cp++;
  1781.   #else
  1782. ! #ifdef FAKE_INTERRUPT
  1783. !     if (setjmp(fake_keyb_sig)) {
  1784. !     arm_fake_keyb_sig = 0;
  1785. !     return K_interrupt;
  1786. !     }
  1787. !     arm_fake_keyb_sig = 1;
  1788. ! #endif
  1789.       while ((n = read(0, (char *)&c, 1)) > 0) {
  1790.       c &= 0177;    /* done by ISTRIP on USG systems */
  1791.   #endif
  1792. ***************
  1793. *** 830,836 ****
  1794. --- 843,853 ----
  1795.           first_key = c;
  1796.           alarm_on = 1;
  1797.           signal(SIGALRM, mk_timeout);
  1798. + #ifdef MICRO_ALARM
  1799.           MICRO_ALARM();
  1800. + #else
  1801. +         sleep(1);
  1802. + #endif
  1803.           }
  1804.   #endif
  1805.           key_cnt++;
  1806. ***************
  1807. *** 852,857 ****
  1808. --- 869,877 ----
  1809.   #endif
  1810.   
  1811.   #ifndef KEY_BURST
  1812. + #ifdef FAKE_INTERRUPT
  1813. +     arm_fake_keyb_sig = 0;
  1814. + #endif
  1815.       if (n < 0) {
  1816.       if (errno != EINTR) s_hangup++;
  1817.       return K_interrupt;
  1818. *** ./LAST/variable.c    Wed May 16 11:23:59 1990
  1819. --- variable.c    Mon May 21 17:08:29 1990
  1820. ***************
  1821. *** 18,23 ****
  1822. --- 18,24 ----
  1823.       *editor_program,
  1824.       *extra_mail_headers,
  1825.       *extra_news_headers,
  1826. +     *folder_save_file,
  1827.       *header_lines,
  1828.       *folder_directory,
  1829.       included_mark[],
  1830. ***************
  1831. *** 120,125 ****
  1832. --- 121,129 ----
  1833.       fmt_linenum,
  1834.       Lines,
  1835.       match_skip_prefix,
  1836. +     mark_next_group,
  1837. +     mark_read_return,
  1838. +     mark_read_skip,
  1839.       min_pv_window,
  1840.       new_group_action,
  1841.       newsrc_update_freq,
  1842. ***************
  1843. *** 229,234 ****
  1844. --- 233,239 ----
  1845.       "flow-control",        BOOL 0,        (char **)&flow_control,
  1846.       "flush-typeahead",        BOOL 0,        (char **)&flush_typeahead,
  1847.       "folder",            STR 2,        (char **)&folder_directory,
  1848. +     "folder-save-file",        STR 3,        (char **)&folder_save_file,
  1849.       "fsort",            BOOL 2,        (char **)&dont_sort_folders,
  1850.       "header-lines",        STR 0,        (char **)&header_lines,
  1851.       "help-key",            KEY 0,        (char **)&help_key,
  1852. ***************
  1853. *** 251,256 ****
  1854. --- 256,264 ----
  1855.       "mailer",            STR 0,        (char **)&mailer_program,
  1856.       "mailer-pipe-input",    BOOL 0,        (char **)&mailer_pipe_input,
  1857.       "mark-overlap",        BOOL 0,        (char **)&mark_overlap,
  1858. +     "marked-by-next-group",    INT 0,        (char **)&mark_next_group,
  1859. +     "marked-by-read-return",    INT 0,        (char **)&mark_read_return,
  1860. +     "marked-by-read-skip",    INT 0,        (char **)&mark_read_skip,
  1861.       "min-window",        INT 1,        (char **)&min_pv_window,
  1862.       "mmdf-format",        BOOL 0,        (char **)&use_mmdf_folders,
  1863.       "monitor",            BOOL 0,        (char **)&monitor_mode,
  1864. ***************
  1865. *** 531,536 ****
  1866. --- 539,590 ----
  1867.   }
  1868.   
  1869.   
  1870. + static char *var_value(var, tag)
  1871. + register struct variable_defs *var;
  1872. + char *tag;
  1873. + {
  1874. +     static char ival[16];
  1875. +     register char *str;
  1876. +     register int b;
  1877. +     *tag = var_on_stack(var) ? '>' :
  1878. +     (var->var_flags & V_MODIFIED) ? '*' : ' ';
  1879. +     switch (VAR_TYPE) {
  1880. +      case V_STRING:
  1881. +     str = (VAR_OP == 1) ? CBUF_VAR : STR_VAR;
  1882. +     break;
  1883. +      case V_BOOLEAN:
  1884. +     b = BOOL_VAR;
  1885. +     if (VAR_OP == 2 || VAR_OP == 4) b = !b;
  1886. +     str = b ? "on" : "off";
  1887. +     break;
  1888. +      case V_INTEGER:
  1889. +     sprintf(ival, "%d", INT_VAR);
  1890. +     str = ival;
  1891. +     break;
  1892. +     
  1893. +      case V_KEY:
  1894. +     str = key_name(KEY_VAR);
  1895. +     break;
  1896. +      case V_SPECIAL:
  1897. +     str = "UNDEF";
  1898. +     switch (VAR_OP) {
  1899. +      case 2:
  1900. +         if (!also_read_articles) break;
  1901. +         sprintf(ival, "%d", article_limit);
  1902. +         str = ival;
  1903. +         break;
  1904. +     }
  1905. +     break;
  1906. +     }
  1907. +     if (str == NULL) str = "NULL";
  1908. +     return str;
  1909. + }
  1910.   test_variable(expr)
  1911.   char *expr;
  1912.   {
  1913. ***************
  1914. *** 865,868 ****
  1915. --- 919,938 ----
  1916.   
  1917.   out:
  1918.       pg_end();
  1919. + }
  1920. + print_variable_config(f, all)
  1921. + FILE *f;
  1922. + int all;
  1923. + {
  1924. +     register struct variable_defs *var;
  1925. +     char *str, tag[2];
  1926. +     register int b;
  1927. +     
  1928. +     tag[1] = NUL;
  1929. +     for (var = variables; var < &variables[TABLE_SIZE]; var++) {
  1930. +     if (!all && (var->var_flags & V_MODIFIED) == 0) continue;
  1931. +     str = var_value(var, tag);
  1932. +     fprintf(f, "%s%s='%s'\n", all ? tag : "", var->var_name, str);
  1933. +     }
  1934.   }
  1935.  
  1936. exit 0 # Just in case...
  1937.