home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume23 / tin / part03 < prev    next >
Text File  |  1991-09-25  |  51KB  |  2,186 lines

  1. Newsgroups: comp.sources.misc
  2. From: iain@estevax.uucp (Iain J. Lea)
  3. Subject:  v23i017:  tin - threaded full screen newsreader v1.0 PL2, Part03/09
  4. Message-ID: <1991Sep25.205118.1911@sparky.imd.sterling.com>
  5. X-Md4-Signature: 783c40b3b984ffbc96f69cb5a9e9092b
  6. Date: Wed, 25 Sep 1991 20:51:18 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: iain@estevax.uucp (Iain J. Lea)
  10. Posting-number: Volume 23, Issue 17
  11. Archive-name: tin/part03
  12. Environment: BSD, SCO, ISC, SUNOS, SYSVR3, SYSVR4, ULTRIX, XENIX
  13.  
  14. #!/bin/sh
  15. # this is tin.shar.03 (part 3 of tin1.02)
  16. # do not concatenate these parts, unpack them in order with /bin/sh
  17. # file curses.c continued
  18. #
  19. if touch 2>&1 | fgrep '[-amc]' > /dev/null
  20.  then TOUCH=touch
  21.  else TOUCH=true
  22. fi
  23. if test ! -r shar3_seq_.tmp; then
  24.     echo "Please unpack part 1 first!"
  25.     exit 1
  26. fi
  27. (read Scheck
  28.  if test "$Scheck" != 3; then
  29.     echo "Please unpack part $Scheck next!"
  30.     exit 1
  31.  else
  32.     exit 0
  33.  fi
  34. ) < shar3_seq_.tmp || exit 1
  35. echo "x - Continuing file curses.c"
  36. sed 's/^X//' << 'SHAR_EOF' >> curses.c &&
  37. X
  38. Xvoid Raw(state)
  39. X    int state;
  40. X{
  41. X    /** state is either TRUE or FALSE, as indicated by call **/
  42. X
  43. X    if (state == FALSE && _inraw) {
  44. X      (void) ioctl(TTYIN, TCSETAW, &_original_tty);
  45. X      _inraw = 0;
  46. X    }
  47. X    else if (state == TRUE && ! _inraw) {
  48. X
  49. X      (void) ioctl(TTYIN, TCGETA, &_original_tty);    /** current setting **/
  50. X
  51. X      (void) ioctl(TTYIN, TCGETA, &_raw_tty);    /** again! **/
  52. X#ifdef BSD
  53. X      _raw_tty.sg_flags &= ~(ECHO | CRMOD);    /* echo off */
  54. X      _raw_tty.sg_flags |= CBREAK;    /* raw on    */
  55. X#else
  56. X      _raw_tty.c_lflag &= ~(ICANON | ECHO);    /* noecho raw mode        */
  57. X
  58. X      _raw_tty.c_cc[VMIN] = '\01';    /* minimum # of chars to queue    */
  59. X      _raw_tty.c_cc[VTIME] = '\0';    /* minimum time to wait for input */
  60. X#endif
  61. X
  62. X      (void) ioctl(TTYIN, TCSETAW, &_raw_tty);
  63. X
  64. X      _inraw = 1;
  65. X    }
  66. X}
  67. X
  68. Xint ReadCh()
  69. X{
  70. X    /** read a character with Raw mode set! **/
  71. X
  72. X    register int result;
  73. X    char ch;
  74. X    result = read(0, &ch, 1);
  75. X        return((result <= 0 ) ? EOF : ch & 0x7F);
  76. X}
  77. X
  78. X
  79. Xint outchar(c)
  80. Xchar c;
  81. X{
  82. X    /** output the given character.  From tputs... **/
  83. X    /** Note: this CANNOT be a macro!              **/
  84. X
  85. X    putc(c, stdout);
  86. X}
  87. X
  88. SHAR_EOF
  89. echo "File curses.c is complete" &&
  90. $TOUCH -am 0923175591 curses.c &&
  91. chmod 0600 curses.c ||
  92. echo "restore of curses.c failed"
  93. set `wc -c curses.c`;Wc_c=$1
  94. if test "$Wc_c" != "6043"; then
  95.     echo original size 6043, current size $Wc_c
  96. fi
  97. # ============= debug.c ==============
  98. echo "x - extracting debug.c (Text)"
  99. sed 's/^X//' << 'SHAR_EOF' > debug.c &&
  100. X/*
  101. X *  Project   : tin - a visual threaded usenet newsreader
  102. X *  Module    : debug.c
  103. X *  Author    : I.Lea
  104. X *  Created   : 01-04-91
  105. X *  Updated   : 06-09-91
  106. X *  Release   : 1.0
  107. X *  Notes     : debug routines
  108. X *  Copyright : (c) Copyright 1991 by Iain Lea
  109. X *                You may  freely  copy or  redistribute  this software,
  110. X *              so  long as there is no profit made from its use, sale
  111. X *              trade or  reproduction.  You may not change this copy-
  112. X *              right notice, and it must be included in any copy made
  113. X */
  114. X
  115. X#include "tin.h"
  116. X
  117. Xint debug;
  118. X
  119. X
  120. Xvoid debug_print_arts ()
  121. X{
  122. X    int i;
  123. X
  124. X    if (! debug)
  125. X        return;
  126. X
  127. X    for (i = 0; i < top; i++) {    /* for each group */
  128. X        debug_print_header (&arts[i]);
  129. X    }
  130. X}
  131. X
  132. X
  133. Xvoid debug_print_header (s)
  134. X    struct header *s;
  135. X{
  136. X    FILE *fp;
  137. X
  138. X    if (! debug)
  139. X        return;
  140. X
  141. X    if ((fp = fopen ("/tmp/DUMP","a+")) != NULL) {
  142. X        fprintf (fp,"art=[%5ld] killed=[%s]\n", s->artnum,
  143. X            (s->tagged ? "TRUE" : "FALSE"));
  144. X        fprintf (fp,"subj=[%-38s]  from=[%-20s]\n", s->subject, s->from);
  145. X         if (s->archive) {
  146. X             fprintf (fp, "arch=[%-38s]  ", s->archive);
  147. X         } else {
  148. X             fprintf (fp, "arch=[%-38s]  ", "");
  149. X         }
  150. X         if (s->part) {
  151. X             fprintf (fp, "part=[%s]  ", s->part);
  152. X         } else {
  153. X             fprintf (fp, "part=[%s]  ", "");
  154. X         }
  155. X         if (s->patch) {
  156. X             fprintf (fp, "patch=[%s]\n", s->patch);
  157. X        } else {
  158. X             fprintf (fp, "patch=[%s]\n", "");
  159. X         }
  160. X        fprintf (fp,"thread=[%s]  inthread=[%s]  unread=[%s]\n",
  161. X        (s->thread == ART_NORMAL ? "ART_NORMAL" : "ART_EXPIRED"),
  162. X        (s->inthread ? "TRUE" : "FALSE"),
  163. X        (s->unread ? "TRUE" : "FALSE"));
  164. X        fflush (fp);
  165. X        fclose (fp);
  166. X        chmod ("/tmp/DUMP", 0666);
  167. X    }
  168. X}
  169. X
  170. X
  171. Xvoid debug_print_comment (comment)
  172. X    char *comment;
  173. X{
  174. X    FILE *fp;
  175. X
  176. X    if (! debug)
  177. X        return;
  178. X
  179. X    if ((fp = fopen ("/tmp/BASE","a+")) != NULL) {
  180. X        fprintf (fp,"\n%s\n\n", comment);
  181. X        fflush (fp);
  182. X        fclose (fp);
  183. X        chmod ("/tmp/BASE", 0666);
  184. X    }
  185. X}
  186. X
  187. X
  188. Xvoid debug_print_base ()
  189. X{
  190. X    FILE *fp;
  191. X    int i;
  192. X
  193. X    if (! debug)
  194. X        return;
  195. X
  196. X    if ((fp = fopen ("/tmp/BASE","a+")) != NULL) {
  197. X        for (i = 0; i < top_base; i++) {
  198. X            fprintf (fp, "base[%3d]=[%5ld]\n",i,base[i]);
  199. X        }
  200. X        fflush (fp);
  201. X        fclose (fp);
  202. X        chmod ("/tmp/BASE", 0666);
  203. X    }
  204. X}
  205. X
  206. X
  207. Xvoid debug_print_active ()
  208. X{
  209. X    FILE *fp;
  210. X    int i;
  211. X
  212. X    if (! debug)
  213. X        return;
  214. X
  215. X    if ((fp = fopen ("/tmp/ACTIVE","w")) != NULL) {
  216. X        for (i = 0; i < num_active; i++) {    /* for each group */
  217. X            fprintf (fp, "[%4d]=[%-28s] max=[%4ld] min=[%4ld] nxt=[%4d] flag=[%d]\n",
  218. X                i, active[i].name, active[i].max, active[i].min, active[i].next, active[i].flag);
  219. X        }
  220. X        fflush (fp);
  221. X        fclose (fp);
  222. X        chmod ("/tmp/ACTIVE", 0666);
  223. X    }
  224. X}
  225. SHAR_EOF
  226. $TOUCH -am 0923175591 debug.c &&
  227. chmod 0600 debug.c ||
  228. echo "restore of debug.c failed"
  229. set `wc -c debug.c`;Wc_c=$1
  230. if test "$Wc_c" != "2575"; then
  231.     echo original size 2575, current size $Wc_c
  232. fi
  233. # ============= feed.c ==============
  234. echo "x - extracting feed.c (Text)"
  235. sed 's/^X//' << 'SHAR_EOF' > feed.c &&
  236. X/*
  237. X *  Project   : tin - a visual threaded usenet newsreader
  238. X *  Module    : feed.c
  239. X *  Author    : I.Lea
  240. X *  Created   : 31-08-91
  241. X *  Updated   : 22-09-91
  242. X *  Release   : 1.0
  243. X *  Notes     : provides same interface to mail,pipe,print and save commands
  244. X *  Copyright : (c) Copyright 1991 by Iain Lea
  245. X *                You may  freely  copy or  redistribute  this software,
  246. X *              so  long as there is no profit made from its use, sale
  247. X *              trade or  reproduction.  You may not change this copy-
  248. X *              right notice, and it must be included in any copy made
  249. X */
  250. X
  251. X#include    "tin.h"
  252. X
  253. Xextern char *glob_group;            /* Group name */
  254. Xextern char note_h_subj[LEN+1];        /* Subject:    */
  255. Xextern char note_h_from[LEN+1];        /* From:    */
  256. Xextern FILE *note_fp;                /* the body of the current article */
  257. Xextern int note_end;                /* end of article ? */
  258. Xextern int note_page;                /* what page we're on */
  259. Xextern long note_mark[MAX_PAGES];    /* ftells on beginnings of pages */
  260. X
  261. Xchar default_mail_address[LEN];
  262. Xchar default_pipe_command[LEN];
  263. Xchar default_save_file[LEN];
  264. Xchar default_regex_pattern[LEN];
  265. Xchar proc_ch_default;                /* set in change_rcfile () */
  266. X
  267. X
  268. Xvoid feed_articles (function, level, prompt, respnum, group_path)
  269. X    int function;
  270. X    int level;
  271. X    char *prompt;
  272. X    int respnum;
  273. X    char *group_path;
  274. X{
  275. X    char address[LEN+1];
  276. X    char command[LEN+1];
  277. X    char file[LEN+1], *p;
  278. X    char mailbox[LEN+1];
  279. X    char pattern[LEN+1];
  280. X    char ch = 'a', ch_default = 'a';
  281. X    char proc_ch = proc_ch_default;
  282. X    FILE *fp;
  283. X    int b, i, j, count = 1;
  284. X    int is_mailbox = FALSE;
  285. X    int orig_note_end;
  286. X    int orig_note_page;
  287. X    int ret1, ret2;
  288. X    int redraw_screen = FALSE;
  289. X    
  290. X    if (level == PAGE_LEVEL) {
  291. X        orig_note_end = note_end;
  292. X        orig_note_page = note_page;
  293. X    }
  294. X
  295. X    b = which_base (respnum);
  296. X
  297. X    if (num_of_tagged_files) {
  298. X        ch_default = 'T';
  299. X    }
  300. X    if (! num_of_tagged_files && nresp (b)) {
  301. X        ch_default = 't';
  302. X    }
  303. X    do {
  304. X        sprintf (msg, "%s%s%c", prompt, txt_art_thread_regex_tag, ch_default);
  305. X        wait_message (msg);
  306. X        MoveCursor (LINES, strlen (msg)-1);
  307. X        if ((ch = ReadCh ()) == CR)
  308. X            ch = ch_default;
  309. X    } while (ch != 'a' && ch != 't' && ch != 'T' && ch != 'r' && ch != 'e');
  310. X
  311. X    if (ch == 'e') {    /* exit */
  312. X        clear_message ();
  313. X        return;
  314. X    }
  315. X    
  316. X    if (ch == 'r') {
  317. X        sprintf (msg, txt_feed_pattern, default_regex_pattern);
  318. X        if (! parse_string (msg, pattern)) {
  319. X            clear_message ();
  320. X            return;
  321. X        }    
  322. X        if (strlen (pattern)) {
  323. X            my_strncpy (default_regex_pattern, pattern, LEN);
  324. X        } else {
  325. X            if (default_regex_pattern[0]) {
  326. X                my_strncpy (pattern, default_regex_pattern, LEN);
  327. X            } else {
  328. X                info_message (txt_no_match);
  329. X                return;
  330. X            }
  331. X        }
  332. X    }
  333. X
  334. X    switch (function) {
  335. X        case FEED_MAIL:
  336. X            sprintf (msg, txt_mail_art_to, default_mail_address);
  337. X            if (! parse_string (msg, address)) {
  338. X                clear_message ();
  339. X                return;
  340. X            }    
  341. X            if (strlen (address)) {
  342. X                strcpy (default_mail_address, address);
  343. X            } else {
  344. X                if (default_mail_address[0]) {
  345. X                    strcpy (address, default_mail_address);
  346. X                } else {
  347. X                    info_message (txt_no_mail_address);    
  348. X                    return;
  349. X                }
  350. X            }
  351. X            break;
  352. X        case FEED_PIPE:
  353. X            sprintf (msg, txt_pipe_to_command, default_pipe_command);
  354. X            if (! parse_string (msg, command)) {
  355. X                clear_message ();
  356. X                return;
  357. X            }
  358. X            if (strlen (command)) {
  359. X                strcpy (default_pipe_command, command);
  360. X            } else {
  361. X                if (default_pipe_command[0]) {
  362. X                    strcpy (command, default_pipe_command);
  363. X                } else {
  364. X                    info_message (txt_no_command);    
  365. X                    return;
  366. X                }
  367. X            }
  368. X            if ((fp = popen (command, "w")) == NULL) {
  369. X                error_message (txt_command_failed_s, command);
  370. X                return;
  371. X            }
  372. X            Raw (FALSE);
  373. X            break;
  374. X        case FEED_PRINT:    
  375. X            if (default_printer) {
  376. X                sprintf (command, "%s -P%s > /dev/null 2>&1",
  377. X                    printer, get_val ("PRINTER","ps0"));
  378. X            } else {
  379. X                sprintf (command, "%s > /dev/null 2>&1", printer);
  380. X            }
  381. X            if ((fp = popen (command, "w")) == NULL) {
  382. X                error_message (txt_command_failed_s, command);
  383. X                return;
  384. X            }
  385. X            break;
  386. X        case FEED_SAVE:        /* ask user for filename */
  387. X            free_save_array ();
  388. X            if ((save_archive_name == FALSE || arts[respnum].archive == (char *) 0)) {
  389. X                sprintf (msg, txt_save_filename, default_save_file);
  390. X                if (! parse_string (msg, file)) {
  391. X                    clear_message ();
  392. X                    return;
  393. X                }
  394. X                if (strlen (file)) {
  395. X                    strcpy (default_save_file, file);
  396. X                } else {
  397. X                    if (default_save_file[0]) {
  398. X                        strcpy (file, default_save_file);
  399. X                    } else {
  400. X                        info_message (txt_no_filename);    
  401. X                        return;
  402. X                    }
  403. X                }
  404. X                for (p = file; *p && (*p == ' ' || *p == '\t'); p++) {
  405. X                    continue;
  406. X                }
  407. X                if (! *p) {
  408. X                    info_message (txt_no_filename);
  409. X                    return;
  410. X                }
  411. X                if ((file[0] == '~' || file[0] == '+') && strlen (file) == 1) {
  412. X                    info_message (txt_no_filename);
  413. X                    return;
  414. X                }
  415. X                if (is_mailbox = create_path (file)) {
  416. X                    if ((int) strlen (file) > 1) {
  417. X                        my_strncpy (mailbox, file+1, LEN);        
  418. X                    } else {
  419. X                        my_strncpy (mailbox, glob_group, LEN);
  420. X                        /*
  421. X                         *  convert 1st letter to uppercase
  422. X                         */
  423. X                        if (mailbox[0] >= 'a' && mailbox[0] <= 'z') {
  424. X                            mailbox[0] = mailbox[0] - 32;
  425. X                        }
  426. X                    }
  427. X                    my_strncpy (file, mailbox, LEN);
  428. X                } else {        /* ask for post processing type */
  429. X                    do {
  430. X                        sprintf (msg, "%s%c", txt_post_procees_type, proc_ch_default);
  431. X                        wait_message (msg);
  432. X                        MoveCursor (LINES, strlen (msg)-1);
  433. X                        if ((proc_ch = ReadCh ()) == CR)
  434. X                            proc_ch = proc_ch_default;
  435. X                        } while (proc_ch != 'n' && proc_ch != 's' &&
  436. X                                proc_ch != 'u' && proc_ch != 'U' &&
  437. X                                proc_ch != 'p');
  438. X                }
  439. X            }
  440. X            clear_message ();
  441. X            break;
  442. X    }
  443. X    
  444. X    switch (ch) {
  445. X        case 'a':        /* article */
  446. X            if (level == GROUP_LEVEL) {
  447. X                open_note (arts[respnum].artnum, group_path);    
  448. X            }
  449. X            switch (function) {
  450. X                case FEED_MAIL:
  451. X                    redraw_screen = mail_to_someone (address);
  452. X                    break;
  453. X                case FEED_PIPE:
  454. X                    fseek (note_fp, 0L, 0);
  455. X                    copy_fp (note_fp, fp, "");
  456. X                    break;
  457. X                case FEED_PRINT:
  458. X                    wait_message (txt_printing);
  459. X                    if (print_header) {
  460. X                        fseek(note_fp, 0L, 0);
  461. X                    } else {
  462. X                        fprintf (fp, "From: %s\n", note_h_from);
  463. X                        fprintf (fp, "Subject: %s\n\n", note_h_subj);
  464. X                        fseek (note_fp, note_mark[0], 0);
  465. X                    }
  466. X                    copy_fp(note_fp, fp, "");
  467. X                    pclose (fp);        
  468. X                    break;
  469. X                case FEED_SAVE:
  470. X                    add_to_save_list (0, &arts[respnum], is_mailbox, file);
  471. X                    (void) save_art_to_file (respnum, 0, FALSE, "");
  472. X                    break;
  473. X            }
  474. X            if (level == GROUP_LEVEL) {
  475. X                note_cleanup ();
  476. X            }
  477. X            break;
  478. X            
  479. X        case 't':         /* thread */
  480. X            for (i = base[b]; i >= 0; i = arts[i].thread) {
  481. X                if (function == FEED_PRINT) {
  482. X                    if ((fp = popen (command, "w")) == NULL) {
  483. X                        error_message (txt_command_failed_s, command);
  484. X                        return;
  485. X                    }
  486. X                }
  487. X                if (level == PAGE_LEVEL) {
  488. X                    note_cleanup ();
  489. X                }
  490. X                open_note (arts[i].artnum, group_path);    
  491. X                switch (function) {
  492. X                    case FEED_MAIL:
  493. X                        mail_to_someone (address);
  494. X                        break;
  495. X                    case FEED_PIPE:
  496. X                        fseek (note_fp, 0L, 0);
  497. X                        copy_fp (note_fp, fp, "");
  498. X                        break;
  499. X                    case FEED_PRINT:
  500. X                        sprintf (msg, "%s%d", txt_printing, count++);
  501. X                        wait_message (msg);
  502. X                        if (print_header) {
  503. X                            fseek(note_fp, 0L, 0);
  504. X                        } else {
  505. X                            fprintf (fp, "From: %s\n", note_h_from);
  506. X                            fprintf (fp, "Subject: %s\n\n", note_h_subj);
  507. X                            fseek (note_fp, note_mark[0], 0);
  508. X                        }
  509. X                        copy_fp(note_fp, fp, "");
  510. X                        pclose (fp);
  511. X                        break;
  512. X                    case FEED_SAVE:
  513. X                        add_to_save_list (i, &arts[i], is_mailbox, file);
  514. X                        break;
  515. X                }
  516. X            }
  517. X            if (function == FEED_SAVE) {
  518. X                sort_save_list ();
  519. X                (void) save_thread_to_file (is_mailbox, group_path);
  520. X            }
  521. X            break;
  522. X
  523. X        case 'T':         /* tagged articles */
  524. X            for (i=1 ; i <= num_of_tagged_files ; i++) {
  525. X                for (j=0 ; j < top ; j++) {
  526. X                    if (arts[j].tagged && arts[j].tagged == i) { 
  527. X                        if (function == FEED_PRINT) {
  528. X                            if ((fp = popen (command, "w")) == NULL) {
  529. X                                error_message (txt_command_failed_s, command);
  530. X                                return;
  531. X                            }
  532. X                        }
  533. X                        if (level == PAGE_LEVEL) {
  534. X                            note_cleanup ();
  535. X                        }
  536. X                        open_note (arts[j].artnum, group_path);    
  537. X                        switch (function) {
  538. X                            case FEED_MAIL:
  539. X                                mail_to_someone (address);
  540. X                                break;
  541. X                            case FEED_PIPE:
  542. X                                fseek (note_fp, 0L, 0);
  543. X                                copy_fp (note_fp, fp, "");
  544. X                                break;
  545. X                            case FEED_PRINT:
  546. X                                sprintf (msg, "%s%d", txt_printing, count++);
  547. X                                wait_message (msg);
  548. X                                if (print_header) {
  549. X                                    fseek(note_fp, 0L, 0);
  550. X                                } else {
  551. X                                    fprintf (fp, "From: %s\n", note_h_from);
  552. X                                    fprintf (fp, "Subject: %s\n\n", note_h_subj);
  553. X                                    fseek (note_fp, note_mark[0], 0);
  554. X                                }
  555. X                                copy_fp(note_fp, fp, "");
  556. X                                pclose (fp);
  557. X                                break;
  558. X                            case FEED_SAVE:
  559. X                                add_to_save_list (j, &arts[j], is_mailbox, file);
  560. X                                break;
  561. X                        }
  562. X                    }
  563. X                }
  564. X            }
  565. X            if (function == FEED_SAVE) {                
  566. X                (void) save_regex_arts (is_mailbox, group_path);
  567. X            }
  568. X            break;
  569. X
  570. X        case 'r':         /* regex pattern matched articles */
  571. X            for (i=0 ; i < top ; i++) {
  572. X#ifdef DONT_USE_REGEX 
  573. X                if (str_str (arts[i].subject, pattern) != 0) {
  574. X#else        
  575. X                if (wildmat (arts[i].subject, pattern)) {
  576. X#endif        
  577. X                    if (function == FEED_PRINT) {
  578. X                        if ((fp = popen (command, "w")) == NULL) {
  579. X                            error_message (txt_command_failed_s, command);
  580. X                            return;
  581. X                        }
  582. X                    }
  583. X                    if (level == PAGE_LEVEL) {
  584. X                        note_cleanup ();
  585. X                    }
  586. X                    open_note (arts[i].artnum, group_path);    
  587. X                    switch (function) {
  588. X                        case FEED_MAIL:
  589. X                            mail_to_someone (address);
  590. X                            break;
  591. X                        case FEED_PIPE:
  592. X                            fseek (note_fp, 0L, 0);
  593. X                            copy_fp (note_fp, fp, "");
  594. X                            break;
  595. X                        case FEED_PRINT:
  596. X                            sprintf (msg, "%s%d", txt_printing, count++);
  597. X                            wait_message (msg);    
  598. X                            if (print_header) {
  599. X                                fseek(note_fp, 0L, 0);
  600. X                            } else {
  601. X                                fprintf (fp, "From: %s\n", note_h_from);
  602. X                                fprintf (fp, "Subject: %s\n\n", note_h_subj);
  603. X                                fseek (note_fp, note_mark[0], 0);
  604. X                            }
  605. X                            copy_fp(note_fp, fp, "");
  606. X                            pclose (fp);
  607. X                            break;
  608. X                        case FEED_SAVE:
  609. X                            add_to_save_list (i, &arts[i], is_mailbox, file);
  610. X                            break;
  611. X                    }
  612. X                }
  613. X            }
  614. X            if (function == FEED_SAVE) {                
  615. X                sort_save_list ();
  616. X                (void) save_regex_arts (is_mailbox, group_path);
  617. X            }
  618. X            break;
  619. X    }
  620. X
  621. X    switch (function) {
  622. X        case FEED_PIPE:
  623. X            pclose (fp);        
  624. X            Raw (TRUE);
  625. X            continue_prompt ();
  626. X            redraw_screen = TRUE;
  627. X            break;
  628. X        case FEED_PRINT:    
  629. X            info_message (txt_printed);
  630. X            redraw_screen = mail_check ();    /* in case of sending to oneself */
  631. X            break;
  632. X        case FEED_SAVE:
  633. X            ret1 = (mark_saved_read ? TRUE : FALSE);
  634. X            if (proc_ch != 'n' && is_mailbox == FALSE) {
  635. X                ret2 = post_process_files (proc_ch);
  636. X            }
  637. X            if (ret1 || ret2) {
  638. X                redraw_screen = TRUE;
  639. X            }
  640. X            free_save_array ();
  641. X            break;
  642. X    }
  643. X
  644. X    if (level == PAGE_LEVEL) {
  645. X        if (ch != 'a') {
  646. X            open_note (arts[respnum].artnum, group_path);
  647. X        }
  648. X        note_end = orig_note_end;
  649. X        note_page = orig_note_page;
  650. X        fseek (note_fp, note_mark[note_page], 0);
  651. X        if (redraw_screen) {
  652. X            if (note_page == 0) {
  653. X                show_note_page (respnum, glob_group);
  654. X            } else {
  655. X                redraw_page (respnum, glob_group);
  656. X            }
  657. X        }
  658. X    } else {
  659. X        if (redraw_screen) {
  660. X            show_group_page (glob_group);
  661. X        }
  662. X    }
  663. X}
  664. SHAR_EOF
  665. $TOUCH -am 0923175591 feed.c &&
  666. chmod 0600 feed.c ||
  667. echo "restore of feed.c failed"
  668. set `wc -c feed.c`;Wc_c=$1
  669. if test "$Wc_c" != "11087"; then
  670.     echo original size 11087, current size $Wc_c
  671. fi
  672. # ============= group.c ==============
  673. echo "x - extracting group.c (Text)"
  674. sed 's/^X//' << 'SHAR_EOF' > group.c &&
  675. X/*
  676. X *  Project   : tin - a visual threaded usenet newsreader
  677. X *  Module    : group.c
  678. X *  Author    : R.Skrenta / I.Lea
  679. X *  Created   : 01-04-91
  680. X *  Updated   : 22-09-91
  681. X *  Release   : 1.0
  682. X *  Notes     :
  683. X *  Copyright : (c) Copyright 1991 by Rich Skrenta & Iain Lea
  684. X *                You may  freely  copy or  redistribute  this software,
  685. X *              so  long as there is no profit made from its use, sale
  686. X *              trade or  reproduction.  You may not change this copy-
  687. X *              right notice, and it must be included in any copy made
  688. X */
  689. X
  690. X#include    "tin.h"
  691. X
  692. Xextern char cvers[LEN+1];
  693. Xextern int cur_groupnum;
  694. Xextern int last_resp;        /* page.c */
  695. Xextern int this_resp;        /* page.c */
  696. Xextern int space_mode;        /* select.c */
  697. X
  698. Xchar *glob_group;
  699. Xint index_point;
  700. Xint first_subj_on_screen;
  701. Xint last_subj_on_screen;
  702. X
  703. X
  704. Xvoid group_page (group)
  705. X    char *group;
  706. X{
  707. X    char group_path[LEN+1];
  708. X    char ch;
  709. X    char *p;
  710. X    int flag, i, n;
  711. X    int kill_state;
  712. X    long old_artnum;
  713. X    int old_top;
  714. X    int sav_groupnum;
  715. X    int thread_marked_unread = FALSE;
  716. X
  717. X    glob_group = group;
  718. X    sav_groupnum = cur_groupnum;
  719. X    
  720. X    strcpy (group_path, group);            /* turn comp.unix.amiga into */
  721. X    for (p = group_path; *p; p++)        /* comp/unix/amiga */
  722. X        if (*p == '.')
  723. X            *p = '/';
  724. X
  725. X    last_resp = -1;
  726. X    this_resp = -1;
  727. X    index_group (group, group_path);    /* update index file */
  728. X    read_newsrc_line (group);            /* get sequencer information */
  729. X
  730. X    if (space_mode) {
  731. X        for (i = 0; i < top_base; i++) {
  732. X            if (new_responses (i)) {
  733. X                break;
  734. X            }
  735. X        }
  736. X        if (i < top_base) {
  737. X            index_point = i;
  738. X        } else {
  739. X            index_point = top_base - 1;
  740. X        }
  741. X    } else {
  742. X        index_point = top_base - 1;
  743. X    }
  744. X    
  745. X    clear_note_area ();
  746. X
  747. X    show_group_page (group);
  748. X
  749. X    while (1) {
  750. X        ch = ReadCh();
  751. X
  752. X        if (ch > '0' && ch <= '9') {    /* 0 goes to basenote */
  753. X            prompt_subject_num(ch, group);
  754. X        } else switch (ch) {
  755. X            case '!':
  756. X                shell_escape ();
  757. X                show_group_page (group);
  758. X                break;
  759. X
  760. X            case '$':    /* show last page of articles */
  761. Xend_of_list:            
  762. X                if (index_point != top_base - 1) {
  763. X                    index_point = top_base - 1;
  764. X                    show_group_page (group);
  765. X                }
  766. X                break;
  767. X                
  768. X            case '-':    /* go to last viewed article */
  769. X                if (this_resp < 0) {
  770. X                    info_message(txt_no_last_message);
  771. X                    break;
  772. X                }
  773. X                index_point = show_page (this_resp, group, group_path);
  774. X                if (index_point < 0) {
  775. X                    space_mode = FALSE;
  776. X                    goto group_done;
  777. X                }
  778. X                clear_note_area ();
  779. X                show_group_page (group);
  780. X                break;
  781. X
  782. X            case '|':    /* pipe article/thread/tagged arts to command */
  783. X                if (index_point >= 0) {
  784. X                    feed_articles (FEED_PIPE, GROUP_LEVEL, "Pipe",
  785. X                        (int) base[index_point], group_path);
  786. X                }
  787. X                break;
  788. X
  789. X            case '/':    /* forward/backward search */
  790. X            case '?':
  791. X                i = (ch == '/');
  792. X                search_subject (i, group);
  793. X                break;
  794. X
  795. X            case '\r':
  796. X            case '\n':    /* read current basenote */
  797. X                if (index_point < 0) {
  798. X                    info_message(txt_no_arts);
  799. X                    break;
  800. X                }
  801. X                i = (int) base[index_point];
  802. X                index_point = show_page(i, group, group_path);
  803. X                if (index_point < 0) {
  804. X                    space_mode = FALSE;
  805. X                    goto group_done;
  806. X                }
  807. X                clear_note_area ();
  808. X                show_group_page (group);
  809. X                break;
  810. X
  811. X            case '\t':
  812. X                 space_mode = TRUE;
  813. X
  814. X                if (index_point < 0
  815. X                || (n=next_unread((int) base[index_point]))<0) {
  816. X                    for (i = cur_groupnum+1 ; i < local_top ; i++)
  817. X                        if (unread[i] > 0)
  818. X                            break;
  819. X                    if (i >= local_top)
  820. X                        goto group_done;
  821. X
  822. X                    cur_groupnum = i;
  823. X                    index_point = -3;
  824. X                    goto group_done;
  825. X                }
  826. X                index_point = show_page(n, group, group_path);
  827. X                if (index_point < 0)
  828. X                    goto group_done;
  829. X                clear_note_area ();
  830. X                show_group_page(group);
  831. X                break;
  832. X    
  833. X            case 27:    /* common arrow keys */
  834. X                ch = ReadCh();
  835. X                if (ch == '[' || ch == 'O')
  836. X                    ch = ReadCh();
  837. X                switch (ch) {
  838. X                case 'A':
  839. X                case 'D':
  840. X                    goto group_up;
  841. X
  842. X                case 'B':
  843. X                case 'C':
  844. X                    goto group_down;
  845. X
  846. X                case 'G':        /* ansi  PgDn */
  847. X                case 'U':        /* at386 PgDn */
  848. X                    goto group_page_down;
  849. X
  850. X                case 'I':        /* ansi  PgUp */
  851. X                case 'V':        /* at386 PgUp */
  852. X                    goto group_page_up;
  853. X
  854. X                case 'H':        /* at386  Home */
  855. X                    if (index_point != 0) {
  856. X                        index_point = 0;
  857. X                        show_group_page (group);
  858. X                    }
  859. X                    break;
  860. X                    
  861. X                case 'F':        /* ansi  End */
  862. X                case 'Y':        /* at386  End */
  863. X                    goto end_of_list;
  864. X                }
  865. X                break;
  866. X
  867. X            case ctrl('D'):        /* page down */
  868. X            case ' ':    
  869. Xgroup_page_down:
  870. X                if (!top_base || index_point == top_base - 1)
  871. X                    break;
  872. X
  873. X                erase_subject_arrow();
  874. X                index_point += NOTESLINES / 2;
  875. X                if (index_point >= top_base)
  876. X                    index_point = top_base - 1;
  877. X
  878. X                if (index_point < first_subj_on_screen
  879. X                || index_point >= last_subj_on_screen)
  880. X                    show_group_page(group);
  881. X                else
  882. X                    draw_subject_arrow();
  883. X                break;
  884. X
  885. X            case ctrl('K'):        /* kill article */
  886. X                 if (index_point < 0) {
  887. X                     info_message (txt_no_arts);
  888. X                    break;
  889. X                }
  890. X                if (kill_articles) {
  891. X                    old_top = top;
  892. X                    n = base[index_point];
  893. X                    old_artnum = arts[n].artnum;
  894. X                    if (kill_art_menu (group, (int) base[index_point])) {
  895. X                        kill_any_articles (group);
  896. X                        reload_index_file (group, TRUE);
  897. X                        index_point = find_new_pos (old_top, old_artnum, index_point);
  898. X                    }
  899. X                    show_group_page (group);
  900. X                } else {
  901. X                    info_message (txt_switch_on_kill_art_menu);
  902. X                }
  903. X                break;
  904. X
  905. X            case ctrl('L'):        /* return to index */
  906. X            case ctrl('R'):
  907. X            case ctrl('W'):
  908. X#ifndef USE_CLEARSCREEN
  909. X                ClearScreen ();
  910. X#endif
  911. X                show_group_page(group);
  912. X                break;
  913. X
  914. X            case ctrl('N'):
  915. X            case 'j':        /* line down */
  916. Xgroup_down:
  917. X                if (!top_base || index_point + 1 >= top_base)
  918. X                    break;
  919. X
  920. X                if (index_point + 1 >= last_subj_on_screen) {
  921. X#ifndef USE_CLEARSCREEN
  922. X                    erase_subject_arrow();
  923. X#endif                    
  924. X                    index_point++;
  925. X                    show_group_page(group);
  926. X                } else {
  927. X                    erase_subject_arrow();
  928. X                    index_point++;
  929. X                    draw_subject_arrow();
  930. X                }
  931. X                break;
  932. X
  933. X            case ctrl('P'):
  934. X            case 'k':        /* line up */
  935. Xgroup_up:
  936. X                if (!top_base || !index_point)
  937. X                    break;
  938. X
  939. X                if (index_point <= first_subj_on_screen) {
  940. X                    index_point--;
  941. X                    show_group_page(group);
  942. X                } else {
  943. X                    erase_subject_arrow();
  944. X                    index_point--;
  945. X                    draw_subject_arrow();
  946. X                }
  947. X                break;
  948. X
  949. X            case ctrl('U'):        /* page up */
  950. X            case 'b':
  951. Xgroup_page_up:
  952. X                if (!top_base)
  953. X                    break;
  954. X
  955. X#ifndef USE_CLEARSCREEN
  956. X                clear_message ();
  957. X#endif
  958. X                erase_subject_arrow();
  959. X                index_point -= NOTESLINES / 2;
  960. X                if (index_point < 0)
  961. X                    index_point = 0;
  962. X                if (index_point < first_subj_on_screen
  963. X                || index_point >= last_subj_on_screen)
  964. X                    show_group_page(group);
  965. X                else
  966. X                    draw_subject_arrow();
  967. X                break;
  968. X
  969. X            case 'a':    /* author search forward */
  970. X            case 'A':    /* author search backward */
  971. X                if (index_point < 0) {
  972. X                    info_message(txt_no_arts);
  973. X                    break;
  974. X                }
  975. X
  976. X                i = (ch == 'a');
  977. X
  978. X                n = search_author((int) base[index_point], i);
  979. X                if (n < 0)
  980. X                    break;
  981. X
  982. X                index_point = show_page(n, group, group_path);
  983. X                if (index_point < 0) {
  984. X                    space_mode = FALSE;
  985. X                    goto group_done;
  986. X                }
  987. X                clear_note_area ();
  988. X                show_group_page (group);
  989. X                break;
  990. X
  991. X            case 'B':    /* bug/gripe/comment mailed to author */
  992. X                mail_bug_report ();
  993. X#ifndef USE_CLEARSCREEN
  994. X                ClearScreen ();
  995. X#endif
  996. X                show_group_page (group);
  997. X                break;
  998. X                
  999. X            case 'c':    /* catchup--mark all articles as read */
  1000. X                if (prompt_yn (LINES, txt_mark_all_read, 'y')) {
  1001. X                    for (n = 0; n < top; n++) {
  1002. X                        arts[n].unread = ART_READ;
  1003. X                    }
  1004. X                    if (cur_groupnum + 1 < local_top) {
  1005. X                        cur_groupnum++;
  1006. X                    }
  1007. X                    goto group_done;
  1008. X                }
  1009. X                break;
  1010. X
  1011. X            case 'g':    /* choose a new group by name */
  1012. X                n = choose_new_group ();
  1013. X                if (n >= 0 && n != cur_groupnum) {
  1014. X                    cur_groupnum = n;
  1015. X                    index_point = -3;
  1016. X                    goto group_done;
  1017. X                }
  1018. X                break;
  1019. X
  1020. X            case 'h':
  1021. X                show_info_page (HELP_INFO, help_group, txt_index_page_com);
  1022. X                show_group_page (group);
  1023. X                break;
  1024. X
  1025. X            case 'H':
  1026. X                help_group_info ();
  1027. X                show_group_page (group);
  1028. X                break;
  1029. X
  1030. X            case 'I':    /* toggle inverse video */
  1031. X                inverse_okay = !inverse_okay;
  1032. X                if (inverse_okay) {
  1033. X                    info_message (txt_inverse_on);
  1034. X                } else {
  1035. X                    draw_arrow_mark = TRUE;
  1036. X                    info_message (txt_inverse_off);
  1037. X                }
  1038. X                show_group_page (group);
  1039. X                break;
  1040. X
  1041. X            case 'K':    /* mark rest of thread as read */
  1042. X                if (index_point < 0) {
  1043. X                    info_message (txt_no_next_unread_art);
  1044. X                    break;
  1045. X                }
  1046. X                if (new_responses (index_point)) {
  1047. X                    for (i = base[index_point]; i >= 0; i = arts[i].thread)
  1048. X                        arts[i].unread = 0;
  1049. X                    mark_screen (SCREEN_READ_UNREAD, "   ");    
  1050. X                    flag = FALSE;
  1051. X                } else
  1052. X                    flag = TRUE;
  1053. X
  1054. X                n = next_unread (next_response ((int) base[index_point]));
  1055. X                if (n < 0) {
  1056. X                    if (flag)
  1057. X                        info_message (txt_no_next_unread_art);
  1058. X                    else
  1059. X                        MoveCursor (LINES, 0);
  1060. X                    break;
  1061. X                }
  1062. X
  1063. X                if ((n = which_base(n)) < 0) {
  1064. X                    info_message("Internal error: K which_base < 0");
  1065. X                    break;
  1066. X                }
  1067. X
  1068. X                if (n >= last_subj_on_screen) {
  1069. X                    index_point = n;
  1070. X                    show_group_page (group);
  1071. X                } else {
  1072. X                    erase_subject_arrow ();
  1073. X                    index_point = n;
  1074. X                    draw_subject_arrow ();
  1075. X                }
  1076. X                break;
  1077. X
  1078. X            case 'm':    /* mail article to somebody */
  1079. X                if (index_point >= 0) {
  1080. X                    feed_articles (FEED_MAIL, GROUP_LEVEL, "Mail",
  1081. X                        (int) base[index_point], group_path);
  1082. X                }
  1083. X                break;
  1084. X
  1085. X            case 'M':    /* options menu */
  1086. X                old_top = top;
  1087. X                n = base[index_point];
  1088. X                old_artnum = arts[n].artnum;
  1089. X                n = sort_art_type;
  1090. X                kill_state = change_rcfile (group, TRUE);
  1091. X                if (kill_state == NO_KILLING && n != sort_art_type) {
  1092. X                    make_threads (TRUE);
  1093. X                    find_base ();
  1094. X                }
  1095. X                index_point = find_new_pos (old_top, old_artnum, index_point);
  1096. X                show_group_page (group);
  1097. X                break;
  1098. X
  1099. X            case 'n':    /* next group */
  1100. X                clear_message();
  1101. X                if (cur_groupnum + 1 >= local_top)
  1102. X                    info_message(txt_no_more_groups);
  1103. X                else {
  1104. X                    cur_groupnum++;
  1105. X                    index_point = -3;
  1106. X                    space_mode = pos_first_unread;
  1107. X                    goto group_done;
  1108. X                }
  1109. X                break;
  1110. X
  1111. X            case 'N':    /* go to next unread article */
  1112. X                if (index_point < 0) {
  1113. X                    info_message(txt_no_next_unread_art);
  1114. X                    break;
  1115. X                }
  1116. X
  1117. X                n = next_unread ((int) base[index_point]);
  1118. X                if (n == -1)
  1119. X                    info_message (txt_no_next_unread_art);
  1120. X                else {
  1121. X                    index_point = show_page (n, group, group_path);
  1122. X                    if (index_point < 0) {
  1123. X                        space_mode = pos_first_unread;
  1124. X                        goto group_done;
  1125. X                    }
  1126. X                    clear_note_area ();
  1127. X                    show_group_page (group);
  1128. X                }
  1129. X                break;
  1130. X
  1131. X            case 'o':    /* output art/thread/tagged arts to printer */
  1132. X                if (index_point >= 0) {
  1133. X                    feed_articles (FEED_PRINT, GROUP_LEVEL, "Print",
  1134. X                        (int) base[index_point], group_path);
  1135. X                }
  1136. X                break;
  1137. X
  1138. X            case 'p':    /* previous group */
  1139. X                clear_message();
  1140. X                if (cur_groupnum <= 0)
  1141. X                    info_message(txt_no_prev_group);
  1142. X                else {
  1143. X                    cur_groupnum--;
  1144. X                    index_point = -3;
  1145. X                    space_mode = pos_first_unread;
  1146. X                    goto group_done;
  1147. X                }
  1148. X                break;
  1149. X
  1150. X            case 'P':    /* go to previous unread article */
  1151. X                if (index_point < 0) {
  1152. X                    info_message(txt_no_prev_unread_art);
  1153. X                    break;
  1154. X                }
  1155. X                n = prev_response( (int) base[index_point]);
  1156. X                n = prev_unread(n);
  1157. X                if (n == -1)
  1158. X                    info_message(txt_no_prev_unread_art);
  1159. X                else {
  1160. X                    index_point = show_page (n, group, group_path);
  1161. X                    if (index_point < 0) {
  1162. X                        space_mode = pos_first_unread;
  1163. X                        goto group_done;
  1164. X                    }
  1165. X                    clear_note_area ();
  1166. X                    show_group_page (group);
  1167. X                }
  1168. X                break;
  1169. X
  1170. X            case 'q':        /* quit */
  1171. X                index_point = -2;
  1172. X                space_mode = FALSE;
  1173. X                goto group_done;
  1174. X
  1175. X            case 's':    /* save regex pattern to file/s */
  1176. X                if (index_point >= 0) {
  1177. X                    feed_articles (FEED_SAVE, GROUP_LEVEL, "Save",
  1178. X                        (int) base[index_point], group_path);
  1179. X                }
  1180. X                break;
  1181. X            
  1182. X            case 't':
  1183. X            case 'i':    /* return to group selection page */
  1184. X                goto group_done;
  1185. X
  1186. X            case 'T':    /* tag/untag art for mailing/piping/printing/saving */
  1187. X                 if (index_point >= 0) {
  1188. X                    n = base[index_point];
  1189. X                    if (arts[n].tagged) {
  1190. X                        arts[n].tagged = 0;
  1191. X                        sprintf (msg, "%3s", (arts[n].unread ? "  +" : "   "));
  1192. X                        info_message (txt_untagged_art);
  1193. X                    } else {
  1194. X                        arts[n].tagged = ++num_of_tagged_files;
  1195. X                        sprintf (msg, "%3d", arts[n].tagged);
  1196. X                        info_message (txt_tagged_art);
  1197. X                    }
  1198. X                    mark_screen (SCREEN_READ_UNREAD, msg);
  1199. X                }
  1200. X                break;
  1201. X
  1202. X            case 'U':    /* untag all articles */
  1203. X                 if (index_point >= 0) {
  1204. X                    untag_all_articles ();
  1205. X                    show_group_page (group);
  1206. X                }
  1207. X                break;
  1208. X
  1209. X            case 'v':
  1210. X                info_message (cvers);
  1211. X                break;
  1212. X
  1213. X            case 'w':    /* post a basenote */
  1214. X                if (post_base (group)) {
  1215. X                    update_newsrc (group, my_group[cur_groupnum], FALSE);
  1216. X                    index_group (group, group_path);
  1217. X                    read_newsrc_line (group);
  1218. X                    index_point = top_base - 1;
  1219. X                    show_group_page (group);
  1220. X                }
  1221. X                break;
  1222. X
  1223. X            case 'W':    /* display messages posted by user */
  1224. X                if (user_posted_messages ()) {
  1225. X                    show_group_page(group);
  1226. X                }
  1227. X                break;
  1228. X
  1229. X            case 'z':    /* mark article as unread (to return) */
  1230. X                 if (index_point < 0) {
  1231. X                     info_message (txt_no_arts);
  1232. X                    break;
  1233. X                }
  1234. X                i = base[index_point];
  1235. X                arts[i].unread = ART_UNREAD;
  1236. X                mark_screen (SCREEN_READ_UNREAD, "  +");    
  1237. X                info_message (txt_art_marked_as_unread);
  1238. X                break;
  1239. X
  1240. X            case 'Z':    /* mark thread as unread */
  1241. X                 if (index_point < 0) {
  1242. X                     info_message (txt_no_arts);
  1243. X                    break;
  1244. X                }
  1245. X                for (i = base[index_point] ; i != -1 ; i = arts[i].thread) {
  1246. X                    arts[i].unread = ART_UNREAD;
  1247. X                    thread_marked_unread = TRUE;
  1248. X                }
  1249. X                if (thread_marked_unread) {
  1250. X                    mark_screen (SCREEN_READ_UNREAD, "  +");    
  1251. X                    info_message (txt_thread_marked_as_unread);
  1252. X                    thread_marked_unread = FALSE;
  1253. X                }
  1254. X                break;
  1255. X
  1256. X            default:
  1257. X                info_message (txt_bad_command);
  1258. X        }
  1259. X    }
  1260. X
  1261. Xgroup_done:
  1262. X    fix_new_highest (sav_groupnum);
  1263. X    update_newsrc (group, my_group[sav_groupnum], FALSE);
  1264. X    clear_note_area ();
  1265. X
  1266. X    if (index_point == -2)
  1267. X        tin_done(0);
  1268. X}
  1269. X
  1270. X
  1271. X/*
  1272. X *  Correct highest[] for the group selection page display since
  1273. X *  new articles may have been read or marked unread
  1274. X */
  1275. X
  1276. Xvoid fix_new_highest (groupnum)
  1277. X    int groupnum;
  1278. X{
  1279. X    register int i;
  1280. X    int sum = 0;
  1281. X
  1282. X    for (i = 0; i < top; i++) {
  1283. X        if (arts[i].unread) {
  1284. X            sum++;
  1285. X        }
  1286. X    }
  1287. X    
  1288. X    unread[groupnum] = sum;
  1289. X}
  1290. X
  1291. X
  1292. Xvoid show_group_page (group)
  1293. X    char *group;
  1294. X{
  1295. X    char buf[LEN];
  1296. X    char new_resps[8];
  1297. X    char resps[8];
  1298. X    char from[LEN];
  1299. X    char subject[LEN];
  1300. X    int col, i, j, n;
  1301. X    int len_from;
  1302. X    int len_subj;
  1303. X    int respnum;
  1304. X
  1305. X#ifdef SIGTSTP
  1306. X    if (do_sigtstp) {
  1307. X#ifdef POSIX_JOB_CONTROL
  1308. X        sigemptyset (&group_act.sa_mask);
  1309. X        group_act.sa_flags = SA_RESTART | SA_RESETHAND;
  1310. X        group_act.sa_handler = group_suspend;
  1311. X        sigaction (SIGTSTP, &group_act, 0L);
  1312. X#else
  1313. X        signal (SIGTSTP, group_suspend);
  1314. X#endif
  1315. X    }
  1316. X#endif
  1317. X
  1318. X#ifdef SIGWINCH
  1319. X    signal (SIGWINCH, group_resize);
  1320. X#endif
  1321. X
  1322. X#ifdef USE_CLEARSCREEN
  1323. X    ClearScreen ();
  1324. X#else
  1325. X    MoveCursor (0, 0);
  1326. X    CleartoEOLN ();
  1327. X#endif
  1328. X
  1329. X    sprintf (buf, "%s (%d)", group, top_base);
  1330. X    center_line (0, TRUE, buf);
  1331. X
  1332. X    if (col = (COLS - (int) strlen (txt_type_h_for_help))+1) {
  1333. X        MoveCursor (0, 0);
  1334. X        if (kill_articles) {        /* display KILL on screen */
  1335. X            printf ("KILL ON");
  1336. X        }
  1337. X        
  1338. X        MoveCursor (0, col);
  1339. X        if (mail_check ()) {        /* you have mail message in */
  1340. X            printf (txt_you_have_mail);
  1341. X        } else {
  1342. X            printf (txt_type_h_for_help);
  1343. X        }
  1344. X    }
  1345. X
  1346. X#ifndef USE_CLEARSCREEN
  1347. X    MoveCursor (1, 0);
  1348. X    CleartoEOLN ();
  1349. X#endif
  1350. X
  1351. X    MoveCursor (INDEX_TOP, 0);
  1352. X
  1353. X    if (NOTESLINES <= 0) {
  1354. X        first_subj_on_screen = 0;
  1355. X    } else {
  1356. X        first_subj_on_screen = (index_point / NOTESLINES) * NOTESLINES;
  1357. X        if (first_subj_on_screen < 0)
  1358. X            first_subj_on_screen = 0;
  1359. X    }
  1360. X
  1361. X    last_subj_on_screen = first_subj_on_screen + NOTESLINES;
  1362. X    if (last_subj_on_screen >= top_base) {
  1363. X        last_subj_on_screen = top_base;
  1364. X        first_subj_on_screen = top_base - NOTESLINES;
  1365. X
  1366. X        if (first_subj_on_screen < 0)
  1367. X            first_subj_on_screen = 0;
  1368. X    }
  1369. X
  1370. X    if (show_author) {
  1371. X#ifdef RESP_AT_END
  1372. X       len_from = max_from-BLANK_GROUP_COLS;
  1373. X#else
  1374. X       len_from = max_from-BLANK_GROUP_COLS;
  1375. X#endif
  1376. X        } else {
  1377. X#ifdef RESP_AT_END
  1378. X        len_subj = (max_subj+max_from)-BLANK_GROUP_COLS;
  1379. X#else
  1380. X        len_subj = (max_subj+max_from+3)-BLANK_GROUP_COLS;
  1381. X#endif
  1382. X    }
  1383. X
  1384. X    for (j=0, i = first_subj_on_screen; i < last_subj_on_screen; i++, j++) {
  1385. X        respnum = base[i];
  1386. X
  1387. X        if (arts[respnum].tagged) {
  1388. X            sprintf (new_resps, "%3d", arts[respnum].tagged);
  1389. X        } else if (new_responses(i)) {
  1390. X            strcpy (new_resps, "  +");
  1391. X        } else {
  1392. X            strcpy (new_resps, "   ");
  1393. X        }
  1394. X
  1395. X        n = nresp(i);
  1396. X        if (n) {
  1397. X            sprintf (resps, "%-3d", n); 
  1398. X        } else {
  1399. X            strcpy (resps, "   ");
  1400. X        }
  1401. X
  1402. X        my_strncpy (from, arts[respnum].from, max_from);
  1403. X
  1404. X        if (show_author) {
  1405. X#ifdef RESP_AT_END
  1406. X            my_strncpy (subject, arts[respnum].subject, max_subj);
  1407. X            sprintf (screen[j].col, "  %4d%3s  %-*s%s %-*s\r\n",
  1408. X                   i+1, new_resps, max_subj, subject, resps, len_from, from);
  1409. X#else
  1410. X            my_strncpy (subject, arts[respnum].subject, max_subj);
  1411. X            sprintf (screen[j].col, "  %4d%3s %s%-*s   %-*s\r\n",
  1412. X                   i+1, new_resps, resps, max_subj, subject, len_from, from);
  1413. X#endif
  1414. X        } else {
  1415. X#ifdef RESP_AT_END
  1416. X            my_strncpy (subject, arts[respnum].subject, max_subj+max_from);
  1417. X            sprintf(screen[j].col, "  %4d%3s  %-*s %s\r\n",
  1418. X                   i+1, new_resps, len_subj, subject, resps);
  1419. X#else
  1420. X            my_strncpy (subject, arts[respnum].subject, max_subj+max_from+3);
  1421. X            sprintf(screen[j].col, "  %4d%3s %s%-*s\r\n",
  1422. X                   i+1, new_resps, resps, len_subj, subject);
  1423. X#endif
  1424. X        }
  1425. X        printf("%s", screen[j].col);
  1426. X    }
  1427. X
  1428. X#ifndef USE_CLEARSCREEN
  1429. X    CleartoEOS ();
  1430. X#endif
  1431. X
  1432. X    if (top_base <= 0) {
  1433. X        info_message(txt_no_arts);
  1434. X        return;
  1435. X    } else if (last_subj_on_screen == top_base) {
  1436. X        info_message(txt_end_of_arts);
  1437. X    }
  1438. X
  1439. X    draw_subject_arrow();
  1440. X}
  1441. X
  1442. Xvoid draw_subject_arrow()
  1443. X{
  1444. X    draw_arrow (INDEX_TOP + (index_point-first_subj_on_screen));
  1445. X}
  1446. X
  1447. Xvoid erase_subject_arrow()
  1448. X{
  1449. X    erase_arrow (INDEX_TOP + (index_point-first_subj_on_screen));
  1450. X}
  1451. X
  1452. X
  1453. Xint prompt_subject_num (ch, group)
  1454. X    char ch;
  1455. X    char *group;
  1456. X{
  1457. X    int num;
  1458. X
  1459. X    clear_message();
  1460. X
  1461. X    if ((num = parse_num(ch, txt_read_art)) == -1) {
  1462. X        clear_message();
  1463. X        return FALSE;
  1464. X    }
  1465. X    num--;        /* index from 0 (internal) vs. 1 (user) */
  1466. X
  1467. X    if (num >= top_base)
  1468. X        num = top_base - 1;
  1469. X
  1470. X    if (num >= first_subj_on_screen
  1471. X    &&  num < last_subj_on_screen) {
  1472. X        erase_subject_arrow();
  1473. X        index_point = num;
  1474. X        draw_subject_arrow();
  1475. X    } else {
  1476. X#ifndef USE_CLEARSCREEN
  1477. X        erase_subject_arrow();
  1478. X#endif        
  1479. X        index_point = num;
  1480. X        show_group_page(group);
  1481. X    }
  1482. X    return TRUE;
  1483. X}
  1484. X
  1485. X/*
  1486. X *  Return the number of unread articles there are within a thread
  1487. X */
  1488. X
  1489. Xint new_responses (thread)
  1490. X    int thread;
  1491. X{
  1492. X    int i;
  1493. X    int sum = 0;
  1494. X
  1495. X    for (i = base[thread]; i >= 0; i = arts[i].thread)
  1496. X            if (arts[i].unread)
  1497. X                sum++;
  1498. X    
  1499. X    return sum;
  1500. X}
  1501. X
  1502. X
  1503. Xvoid clear_note_area ()
  1504. X{
  1505. X#ifndef USE_CLEARSCREEN
  1506. X    MoveCursor (INDEX_TOP, 0);
  1507. X    CleartoEOS ();
  1508. X#endif
  1509. X}
  1510. X
  1511. X
  1512. Xint find_new_pos (old_top, old_artnum, cur_pos)
  1513. X    int old_top;
  1514. X    long old_artnum;
  1515. X    int cur_pos;
  1516. X{
  1517. X    int pos;
  1518. X    
  1519. X    if (top != old_top) {
  1520. X        if ((pos = valid_artnum (old_artnum)) >= 0) {
  1521. X            if ((pos = which_base (pos)) >= 0) {
  1522. X                return pos;
  1523. X            } else {
  1524. X                return top_base - 1;
  1525. X            }
  1526. X        } else {
  1527. X            return top_base - 1;
  1528. X        }
  1529. X    }
  1530. X
  1531. X    return cur_pos;
  1532. X}
  1533. X
  1534. X
  1535. Xmark_screen (col, value)
  1536. X    int col;
  1537. X    char *value;
  1538. X{
  1539. X    int i, len;
  1540. X
  1541. X    len = strlen (value);
  1542. X    
  1543. X    if (draw_arrow_mark) {
  1544. X        MoveCursor(INDEX_TOP + (index_point - first_subj_on_screen), col);
  1545. X        printf ("%s", value);
  1546. X        MoveCursor (LINES, 0);
  1547. X        fflush(stdout);
  1548. X    } else {
  1549. X        for (i=0 ; i < len ; i++) {
  1550. X            screen[index_point-first_subj_on_screen].col[col+i] = value[i];
  1551. X        }
  1552. X        draw_subject_arrow();
  1553. X    }
  1554. X}
  1555. SHAR_EOF
  1556. $TOUCH -am 0923175591 group.c &&
  1557. chmod 0600 group.c ||
  1558. echo "restore of group.c failed"
  1559. set `wc -c group.c`;Wc_c=$1
  1560. if test "$Wc_c" != "19165"; then
  1561.     echo original size 19165, current size $Wc_c
  1562. fi
  1563. # ============= hashstr.c ==============
  1564. echo "x - extracting hashstr.c (Text)"
  1565. sed 's/^X//' << 'SHAR_EOF' > hashstr.c &&
  1566. X/*
  1567. X *  Project   : tin - a visual threaded usenet newsreader
  1568. X *  Module    : hashstr.c
  1569. X *  Author    : R.Skrenta
  1570. X *  Created   : 01-04-91
  1571. X *  Updated   : 05-09-91
  1572. X *  Release   : 1.0
  1573. X *  Notes     :
  1574. X *  Copyright : (c) Copyright 1991 by Rich Skrenta
  1575. X *                You may  freely  copy or  redistribute  this software,
  1576. X *              so  long as there is no profit made from its use, sale
  1577. X *              trade or  reproduction.  You may not change this copy-
  1578. X *              right notice, and it must be included in any copy made
  1579. X */
  1580. X
  1581. X#include    <stdio.h>
  1582. X#ifdef BSD
  1583. X#include    <strings.h>
  1584. X#else
  1585. X#include    <string.h>
  1586. X#include    <malloc.h>
  1587. X#endif
  1588. X#include    "proto.h"
  1589. X
  1590. X/*
  1591. X *  Maintain a table of all strings we have seen.
  1592. X *  If a new string comes in, add it to the table and return a pointer
  1593. X *  to it.  If we've seen it before, just return the pointer to it.
  1594. X *
  1595. X *  Usage:  hash_str("some string") returns char *
  1596. X *
  1597. X *  Spillovers are chained on the end
  1598. X *
  1599. X *  !!! NOTE: CHECK OUT add_string FOR THE *iptr TRICK THAT IS LATER !!!
  1600. X *  !!! USED IN dump_index (art.c)                                   !!!
  1601. X *
  1602. X */
  1603. X
  1604. X/*
  1605. X *  Arbitrary table size, but make sure it's prime!
  1606. X */
  1607. X
  1608. X/* #define        TABLE_SIZE    1409    */
  1609. X
  1610. X#define        TABLE_SIZE    2411
  1611. X
  1612. X
  1613. Xstruct hashnode {
  1614. X    char *s;            /* the string we're saving */
  1615. X    struct hashnode *next;        /* chain for spillover */
  1616. X};
  1617. X
  1618. Xstruct hashnode *table[TABLE_SIZE];
  1619. X
  1620. X
  1621. Xchar *hash_str (s)
  1622. X    char *s;
  1623. X{
  1624. X    struct hashnode *p;    /* used to descend the spillover structs */
  1625. X    long h;                /* result of hash:  index into hash table */
  1626. X
  1627. X    if (s == (char *) 0) {
  1628. X        return ((char *) 0);
  1629. X    }
  1630. X
  1631. X    {
  1632. X        unsigned char *t = (unsigned char *) s;
  1633. X
  1634. X        h = *t++;
  1635. X        while (*t)
  1636. X            h = ((h << 1) ^ *t++) % TABLE_SIZE;
  1637. X    }
  1638. X
  1639. X    p = table[h];
  1640. X
  1641. X    if (p == NULL) {
  1642. X        table[h] = add_string (s);
  1643. X        return table[h]->s;
  1644. X    }
  1645. X
  1646. X    while (1) {
  1647. X        if (strcmp (s, p->s) == 0) {
  1648. X            return (p->s);
  1649. X        }
  1650. X
  1651. X        if (p->next == (struct hashnode *) 0) {
  1652. X            p->next = add_string (s);
  1653. X            return p->next->s;
  1654. X        } else
  1655. X            p = p->next;
  1656. X    }
  1657. X    /* NOTREACHED */
  1658. X}
  1659. X
  1660. X
  1661. Xstruct hashnode *add_string (s)
  1662. X    char *s;
  1663. X{
  1664. X    struct hashnode *p;
  1665. X    int *iptr;
  1666. X
  1667. X    p = (struct hashnode *) my_malloc (sizeof (*p));
  1668. X
  1669. X    p->next = (struct hashnode *) 0;
  1670. X    iptr = (int *) my_malloc ((unsigned) strlen (s) + sizeof (int)+1);
  1671. X    *iptr++ = -1;
  1672. X    p->s = (char *) iptr;
  1673. X    strcpy (p->s, s);
  1674. X    return (p);
  1675. X}
  1676. X
  1677. X
  1678. Xvoid hash_init ()
  1679. X{
  1680. X    int i;
  1681. X
  1682. X    for (i = 0; i < TABLE_SIZE; i++) {
  1683. X        table[i] = (struct hashnode *) 0;
  1684. X    }
  1685. X}
  1686. X
  1687. X
  1688. Xvoid hash_reclaim ()
  1689. X{
  1690. X    int i;
  1691. X    struct hashnode *p, *next;
  1692. X    int *iptr;
  1693. X
  1694. X    for (i = 0; i < TABLE_SIZE; i++)
  1695. X        if (table[i] != (struct hashnode *) 0) {
  1696. X            p = table[i];
  1697. X            while (p != (struct hashnode *) 0) {
  1698. X                next = p->next;
  1699. X                if (p->s != (char *) 0) {
  1700. X                    iptr = (int *) p->s;
  1701. X                    free ((char *) --iptr);
  1702. X                }
  1703. X                free ((char *) p);
  1704. X                p = next;
  1705. X            }
  1706. X            table[i] = (struct hashnode *) 0;
  1707. X        }
  1708. X}
  1709. SHAR_EOF
  1710. $TOUCH -am 0923175591 hashstr.c &&
  1711. chmod 0600 hashstr.c ||
  1712. echo "restore of hashstr.c failed"
  1713. set `wc -c hashstr.c`;Wc_c=$1
  1714. if test "$Wc_c" != "2811"; then
  1715.     echo original size 2811, current size $Wc_c
  1716. fi
  1717. # ============= help.c ==============
  1718. echo "x - extracting help.c (Text)"
  1719. sed 's/^X//' << 'SHAR_EOF' > help.c &&
  1720. X/*
  1721. X *  Project   : tin - a visual threaded usenet newsreader
  1722. X *  Module    : help.c
  1723. X *  Author    : R.Skrenta / I.Lea
  1724. X *  Created   : 01-04-91
  1725. X *  Updated   : 24-09-91
  1726. X *  Release   : 1.0
  1727. X *  Notes     :
  1728. X *  Copyright : (c) Copyright 1991 by Rich Skrenta & Iain Lea
  1729. X *                You may  freely  copy or  redistribute  this software,
  1730. X *              so  long as there is no profit made from its use, sale
  1731. X *              trade or  reproduction.  You may not change this copy-
  1732. X *              right notice, and it must be included in any copy made
  1733. X */
  1734. X
  1735. X#include    "tin.h"
  1736. X#include    "nntp.h"
  1737. X
  1738. Xchar *help_select[] = {
  1739. X    txt_help_g_4,
  1740. X    txt_help_ctrl_d,
  1741. X    txt_help_ctrl_l,
  1742. X    txt_help_g_ctrl_k,
  1743. X    txt_help_g_ctrl_r,
  1744. X    txt_help_g_cr,
  1745. X    txt_help_g_tab,
  1746. X    txt_help_b,
  1747. X    txt_help_bug_report,
  1748. X    txt_help_sel_c,
  1749. X    txt_help_g,
  1750. X    txt_help_j,
  1751. X    txt_help_h,
  1752. X    txt_help_I,
  1753. X    txt_help_m,
  1754. X    txt_help_M,
  1755. X    txt_help_q,
  1756. X    txt_help_s,
  1757. X    txt_help_S,
  1758. X    txt_help_v,
  1759. X    txt_help_w,
  1760. X    txt_help_W,
  1761. X    txt_help_g_y,
  1762. X    txt_help_g_z,
  1763. X    txt_help_g_dollar,
  1764. X    txt_help_g_search,
  1765. X    (char *) 0
  1766. X};
  1767. X
  1768. Xchar *help_group[] = {
  1769. X    txt_help_i_4,
  1770. X    txt_help_ctrl_d,
  1771. X    txt_help_ctrl_k,
  1772. X    txt_help_ctrl_l,
  1773. X    txt_help_i_cr,
  1774. X    txt_help_i_tab,
  1775. X    txt_help_a,
  1776. X    txt_help_b,
  1777. X    txt_help_bug_report,
  1778. X    txt_help_c,
  1779. X    txt_help_g,
  1780. X    txt_help_h,
  1781. X    txt_help_I,
  1782. X    txt_help_j,
  1783. X    txt_help_K,
  1784. X    txt_help_p_m,
  1785. X    txt_help_M,
  1786. X    txt_help_o,
  1787. X    txt_help_i_n,
  1788. X    txt_help_i_p,
  1789. X    txt_help_q,
  1790. X    txt_help_p_s,
  1791. X    txt_help_t,
  1792. X    txt_help_T,
  1793. X    txt_help_U,
  1794. X    txt_help_v,
  1795. X    txt_help_w,
  1796. X    txt_help_W,
  1797. X    txt_help_p_z,
  1798. X    txt_help_i_search,
  1799. X    txt_help_dash,
  1800. X    txt_help_pipe,
  1801. X    (char *) 0
  1802. X};
  1803. X
  1804. Xchar *help_page[] = {
  1805. X    txt_help_p_0,
  1806. X    txt_help_p_4,
  1807. X    txt_help_ctrl_h,
  1808. X    txt_help_ctrl_k,
  1809. X    txt_help_ctrl_l,
  1810. X    txt_help_p_ctrl_r,
  1811. X    txt_help_p_cr,
  1812. X    txt_help_p_tab,
  1813. X    txt_help_b,
  1814. X    txt_help_a,
  1815. X    txt_help_bug_report,
  1816. X    txt_help_c,
  1817. X    txt_help_C,
  1818. X    txt_help_p_d,
  1819. X    txt_help_p_f,
  1820. X    txt_help_p_g,
  1821. X    txt_help_h,
  1822. X    txt_help_p_i,
  1823. X    txt_help_I,
  1824. X    txt_help_p_k,
  1825. X    txt_help_p_m,
  1826. X    txt_help_M,
  1827. X    txt_help_p_n,
  1828. X    txt_help_o,
  1829. X    txt_help_p_p,
  1830. X    txt_help_q,
  1831. X    txt_help_p_r,
  1832. X    txt_help_p_s,
  1833. X    txt_help_t,
  1834. X    txt_help_T,
  1835. X    txt_help_v,
  1836. X    txt_help_w,
  1837. X    txt_help_W,
  1838. X    txt_help_p_z,
  1839. X    txt_help_p_search,
  1840. X    txt_help_dash,
  1841. X    txt_help_pipe,
  1842. X    txt_help_thread,
  1843. X    (char *) 0
  1844. X};
  1845. X
  1846. X
  1847. Xvoid show_info_page (type, help, title)
  1848. X    int type; 
  1849. X    char *help[];
  1850. X    char *title;
  1851. X{
  1852. X    char buf[LEN+1];
  1853. X    char ch;
  1854. X    int i, len;
  1855. X    int group_len = 0;
  1856. X    int old_page = 0;
  1857. X    int cur_page = 1;
  1858. X    int max_page = 1;
  1859. X    int pos_help = 0;
  1860. X
  1861. X    if (NOTESLINES <= 0) {
  1862. X        return;
  1863. X    }
  1864. X
  1865. X    /*
  1866. X     *  find how many elements in array
  1867. X     */
  1868. X    if (type == HELP_INFO) {
  1869. X        for (i=0 ; help[i] ; i++) {
  1870. X            continue;
  1871. X        }
  1872. X    } else {
  1873. X        for (i=0 ; posted[i].date[0] ; i++) {
  1874. X            len = strlen (posted[i].group);
  1875. X            if (len > group_len) {
  1876. X                 group_len = len;
  1877. X            }
  1878. X         }
  1879. X    }
  1880. X    
  1881. X    max_page = i / NOTESLINES;
  1882. X    if (i % NOTESLINES) {
  1883. X        max_page++;
  1884. X    }
  1885. X
  1886. X    while (1) {
  1887. X        if (cur_page != old_page) {
  1888. X            ClearScreen ();
  1889. X            sprintf (buf, title, cur_page, max_page);
  1890. X            center_line (0, TRUE, buf);
  1891. X            MoveCursor (INDEX_TOP, 0);
  1892. X
  1893. X            if (type == HELP_INFO) { 
  1894. X                for (i=pos_help ; i < (pos_help + NOTESLINES) && help[i] ; i++) {
  1895. X                    printf ("%s", help[i]);
  1896. X                }
  1897. X            } else {
  1898. X                for (i=pos_help ; i < (pos_help + NOTESLINES) && posted[i].date[0] ; i++) {
  1899. X                    sprintf (msg, "%8s  %-*s  %s", posted[i].date,
  1900. X                        group_len, posted[i].group, posted[i].subj);
  1901. X                        msg[COLS-2] = '\0';
  1902. X                    printf ("%s\r\n", msg);
  1903. X                }
  1904. X            }
  1905. X        }
  1906. X
  1907. X        if (cur_page != old_page) {
  1908. X            center_line (LINES, FALSE, txt_hit_space_for_more);
  1909. X        }
  1910. X
  1911. X        old_page = cur_page;
  1912. X        
  1913. X        ch = ReadCh ();
  1914. X        switch (ch) {
  1915. X            case 27:    /* (ESC) common arrow keys */
  1916. X                ch = ReadCh();
  1917. X                if (ch == '[' || ch == 'O')
  1918. X                    ch = ReadCh();
  1919. X                switch (ch) {
  1920. X                    case 'B':        /* page down */
  1921. X                    case 'C':
  1922. X                    case 'G':        /* ansi  */
  1923. X                    case 'U':        /* at386 */
  1924. X                        if (cur_page < max_page) {
  1925. X                            pos_help = cur_page*NOTESLINES;
  1926. X                            cur_page++;
  1927. X                        }
  1928. X                        break;
  1929. X
  1930. X                    case 'A':        /* page up */
  1931. X                    case 'D':
  1932. X                    case 'i':
  1933. X                    case 'I':        /* ansi  */
  1934. X                    case 'V':        /* at386 */
  1935. X                        if (cur_page > 1) {
  1936. X                            cur_page--;
  1937. X                            pos_help = (cur_page-1)*NOTESLINES;
  1938. X                        }
  1939. X                        break;
  1940. X
  1941. X                    case 'H':        /* at386  Home */
  1942. X                        if (cur_page != 1) {
  1943. X                            cur_page = 1;
  1944. X                            pos_help = 0;
  1945. X                        }
  1946. X                        break;
  1947. X                    
  1948. X                    case 'F':        /* ansi  End */
  1949. X                    case 'Y':        /* at386  End */
  1950. X                        if (cur_page != max_page) {
  1951. X                            cur_page = max_page;
  1952. X                            pos_help = (max_page-1) * NOTESLINES;
  1953. X                        }
  1954. X                        break;
  1955. X                }
  1956. X                break;
  1957. X
  1958. X            case ctrl('D'):            /* page down */
  1959. X            case ' ':
  1960. X                if (cur_page < max_page) {
  1961. X                    pos_help = cur_page*NOTESLINES;
  1962. X                    cur_page++;
  1963. X                }
  1964. X                break;
  1965. X            
  1966. X            case ctrl('U'):            /* page up */
  1967. X            case 'b':
  1968. X                if (cur_page > 1) {
  1969. X                    cur_page--;
  1970. X                    pos_help = (cur_page-1)*NOTESLINES;
  1971. X                }
  1972. X                break;
  1973. X
  1974. X            case ctrl('R'):            /* Home */
  1975. X                if (cur_page != 1) {
  1976. X                    cur_page = 1;
  1977. X                    pos_help = 0;
  1978. X                }
  1979. X                break;
  1980. X
  1981. X            case '$':                /* End */
  1982. X                if (cur_page != max_page) {
  1983. X                    cur_page = max_page;
  1984. X                    pos_help = (max_page-1) * NOTESLINES;
  1985. X                }
  1986. X                break;
  1987. X
  1988. X            default:
  1989. X#ifndef USE_CLEARSCREEN
  1990. X                ClearScreen ();
  1991. X#endif    
  1992. X                return;
  1993. X        }    
  1994. X    }
  1995. X}
  1996. X
  1997. X
  1998. Xvoid help_select_info ()
  1999. X{
  2000. X}
  2001. X
  2002. X
  2003. Xvoid help_group_info ()
  2004. X{
  2005. X}
  2006. X
  2007. X
  2008. Xvoid help_page_info ()
  2009. X{
  2010. X}
  2011. SHAR_EOF
  2012. $TOUCH -am 0924083991 help.c &&
  2013. chmod 0600 help.c ||
  2014. echo "restore of help.c failed"
  2015. set `wc -c help.c`;Wc_c=$1
  2016. if test "$Wc_c" != "5124"; then
  2017.     echo original size 5124, current size $Wc_c
  2018. fi
  2019. # ============= kill.c ==============
  2020. echo "x - extracting kill.c (Text)"
  2021. sed 's/^X//' << 'SHAR_EOF' > kill.c &&
  2022. X/*
  2023. X *  Project   : tin - a visual threaded usenet newsreader
  2024. X *  Module    : kill.c
  2025. X *  Author    : I.Lea
  2026. X *  Created   : 01-04-91
  2027. X *  Updated   : 28-08-91
  2028. X *  Release   : 1.0
  2029. X *  Notes     : kill articles
  2030. X *  Copyright : (c) Copyright 1991 by Iain Lea
  2031. X *                You may  freely  copy or  redistribute  this software,
  2032. X *              so  long as there is no profit made from its use, sale
  2033. X *              trade or  reproduction.  You may not change this copy-
  2034. X *              right notice, and it must be included in any copy made
  2035. X */
  2036. X
  2037. X#include    "tin.h"
  2038. X
  2039. Xextern char index_file[LEN+1];
  2040. X
  2041. Xstruct kill_t *killf;
  2042. Xint kill_num = 0;
  2043. Xint max_kill;
  2044. X
  2045. X/*
  2046. X *  read_kill_file - read ~/.tin/kill file contents into kill array
  2047. X */
  2048. X
  2049. Xint read_kill_file ()
  2050. X{
  2051. X    char buf[LEN+1];
  2052. X    FILE *fp;
  2053. X
  2054. X    free_kill_array ();
  2055. X    
  2056. X    set_real_uid_gid ();
  2057. X
  2058. X    if ((fp = fopen (killfile, "r")) != NULL) {
  2059. X        kill_num=0;
  2060. X        while (fgets (buf, sizeof buf, fp) != NULL) {
  2061. X            if (buf[0] != '#') {
  2062. X                if (kill_num == max_kill-1) {
  2063. X                    expand_kill ();
  2064. X                }
  2065. X                killf[kill_num].kill_type = (int) atoi (buf);
  2066. X                if (fgets (buf, sizeof buf, fp) != NULL) {
  2067. X                    killf[kill_num].kill_group = (long) atol (buf);
  2068. X                } else {    
  2069. X                    goto corrupt_killfile;
  2070. X                }    
  2071. X                switch (killf[kill_num].kill_type) {
  2072. X                    case KILL_SUBJ:
  2073. X                        if (fgets (buf, sizeof buf, fp) != NULL) {
  2074. X                            buf[strlen (buf)-1] = '\0';
  2075. X                            killf[kill_num].kill_subj = str_dup (buf);
  2076. X                        }
  2077. X                        break;
  2078. X                    case KILL_FROM:
  2079. X                        if (fgets (buf, sizeof buf, fp) != NULL) {
  2080. X                            buf[strlen (buf)-1] = '\0';
  2081. X                            killf[kill_num].kill_from = str_dup (buf);
  2082. X                        }
  2083. X                        break;
  2084. X                    case KILL_BOTH:
  2085. X                        if (fgets (buf, sizeof buf, fp) != NULL) {
  2086. X                            buf[strlen (buf)-1] = '\0';
  2087. X                            killf[kill_num].kill_subj = str_dup (buf);
  2088. X                        }
  2089. X                        if (fgets (buf, sizeof buf, fp) != NULL) {
  2090. X                            buf[strlen (buf)-1] = '\0';
  2091. X                            killf[kill_num].kill_from = str_dup (buf);
  2092. X                        }
  2093. X                        break;
  2094. X                    default:
  2095. X                        goto corrupt_killfile;
  2096. X                }
  2097. X                kill_num++;
  2098. X            }
  2099. X        }
  2100. X        fclose (fp);
  2101. X        set_tin_uid_gid ();
  2102. X        return TRUE;        
  2103. X    } else {
  2104. X        set_tin_uid_gid ();
  2105. X        return FALSE;
  2106. X    }
  2107. X
  2108. Xcorrupt_killfile:
  2109. X    fclose (fp);
  2110. X    killf[kill_num].kill_type = 0;
  2111. X    error_message ("corrupt kill file %s", killfile);
  2112. X    set_tin_uid_gid ();
  2113. X    return FALSE;
  2114. X}
  2115. X
  2116. X/*
  2117. X *  write_kill_file - write kill strings to ~/.tin/kill
  2118. X */
  2119. X
  2120. Xvoid write_kill_file ()
  2121. X{
  2122. X    FILE *fp;
  2123. X    int i;
  2124. X    
  2125. X    set_real_uid_gid ();
  2126. X
  2127. X    if (kill_num && (fp = fopen (killfile, "w")) != NULL) {
  2128. X        wait_message (txt_saving);
  2129. X        fprintf (fp, "# 1st line  1=(Subject: only)  2=(From: only)  3=(Subject: & From:)\n");
  2130. X        fprintf (fp, "# 2nd line  0=(kill on all newsgroups)  >0=(kill on specific newsgroup)\n");
  2131. X        for (i=0 ; i < kill_num ; i++) {
  2132. X            if (killf[i].kill_type && (killf[i].kill_subj || killf[i].kill_from)) {
  2133. X                fprintf (fp, "#\n# kill description %d\n", i+1);
  2134. X                fprintf (fp, "%d\n", killf[i].kill_type);
  2135. X                fprintf (fp, "%ld\n", killf[i].kill_group);
  2136. X                switch (killf[i].kill_type) {
  2137. X                    case KILL_SUBJ:
  2138. X                        fprintf (fp, "%s\n", killf[i].kill_subj);
  2139. X                        break;
  2140. X                    case KILL_FROM:
  2141. X                        fprintf (fp, "%s\n", killf[i].kill_from);
  2142. X                        break;
  2143. X                    case KILL_BOTH:
  2144. X                        fprintf (fp, "%s\n", killf[i].kill_subj);
  2145. X                        fprintf (fp, "%s\n", killf[i].kill_from);
  2146. X                        break;
  2147. X                }
  2148. X            }
  2149. X        }
  2150. X        fclose (fp);
  2151. X        chmod (killfile, 0600);
  2152. X    }
  2153. X    set_tin_uid_gid ();
  2154. X}
  2155. X
  2156. X/*
  2157. X *  options menu so that the user can dynamically change parameters
  2158. X */
  2159. Xint kill_art_menu (group_name, index)
  2160. X    char *group_name;
  2161. X    int index;
  2162. X{
  2163. X    char text[LEN+1];
  2164. X    char kill_from[LEN+1];
  2165. X    char kill_subj[LEN+1];
  2166. X    char kill_group[LEN+1];
  2167. X    char ch_default = 's';
  2168. X    char *str;    
  2169. X    int ch;
  2170. X    int counter;
  2171. X    int kill_from_ok = FALSE;
  2172. X    int kill_subj_ok = FALSE;
  2173. SHAR_EOF
  2174. echo "End of tin1.02 part 3"
  2175. echo "File kill.c is continued in part 4"
  2176. echo "4" > shar3_seq_.tmp
  2177. exit 0
  2178.  
  2179. exit 0 # Just in case...
  2180. -- 
  2181. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  2182. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  2183. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  2184. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  2185.