home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume29 / tin / part10 < prev    next >
Text File  |  1992-03-28  |  52KB  |  2,464 lines

  1. Newsgroups: comp.sources.misc
  2. From: iain%anl433.uucp@germany.eu.net (Iain J. Lea)
  3. Subject:  v29i028:  tin - threaded full screen newsreader v1.1P1, Part10/12
  4. Message-ID: <1992Mar27.033917.3623@sparky.imd.sterling.com>
  5. X-Md4-Signature: e71e215cb29cc88ef52ae8315429d575
  6. Date: Fri, 27 Mar 1992 03:39:17 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: iain%anl433.uucp@germany.eu.net (Iain J. Lea)
  10. Posting-number: Volume 29, Issue 28
  11. Archive-name: tin/part10
  12. Environment: BSD, SCO, ISC, SUNOS, SYSVR3, SYSVR4, ULTRIX, XENIX
  13. Supersedes: tin: Volume 28, Issue 45-55
  14.  
  15. #!/bin/sh
  16. # this is tin.shar.10 (part 10 of tin1.1)
  17. # do not concatenate these parts, unpack them in order with /bin/sh
  18. # file save.c continued
  19. #
  20. if test ! -r _shar_seq_.tmp; then
  21.     echo 'Please unpack part 1 first!'
  22.     exit 1
  23. fi
  24. (read Scheck
  25.  if test "$Scheck" != 10; then
  26.     echo Please unpack part "$Scheck" next!
  27.     exit 1
  28.  else
  29.     exit 0
  30.  fi
  31. ) < _shar_seq_.tmp || exit 1
  32. if test ! -f _shar_wnt_.tmp; then
  33.     echo 'x - still skipping save.c'
  34. else
  35. echo 'x - continuing file save.c'
  36. sed 's/^X//' << 'SHAR_EOF' >> 'save.c' &&
  37. X                set_real_uid_gid ();
  38. X                error_message ("Post processing failed", "");
  39. X            }
  40. X            set_real_uid_gid ();
  41. X        }
  42. X    }
  43. X    delete_processed_files ();
  44. X
  45. X    unlink (file_out);
  46. X
  47. #endif /* INDEX_DAEMON */
  48. }
  49. X
  50. /*
  51. X *  Unpack /bin/sh archives
  52. X */
  53. void post_process_sh ()
  54. {
  55. #ifndef INDEX_DAEMON
  56. X
  57. X    char buf[LEN];
  58. X    char file_in[LEN];
  59. X    char file_out[LEN];
  60. X    char file_out_dir[LEN];
  61. X    char *ptr1, *ptr2;
  62. X    char sh_pattern_1[16];
  63. X    char sh_pattern_2[16];
  64. X    FILE *fp_in, *fp_out;
  65. X    int found_header;
  66. X    int i, j;
  67. X    int patlen1, patlen2;
  68. X
  69. X    strcpy (sh_pattern_1, "#! /bin/sh");
  70. X    strcpy (sh_pattern_2, "#!/bin/sh");
  71. X
  72. X    my_strncpy (file_out_dir, save_filename (0), LEN);
  73. X    for (i=strlen(file_out_dir) ; i > 0 ; i--) {
  74. X        if (file_out_dir[i] == '/') {
  75. X            file_out_dir[i] = '\0';
  76. X            break;
  77. X        }
  78. X    }
  79. X
  80. X    sprintf (file_out, "%s/tin.%05d", file_out_dir, process_id);
  81. X
  82. X    for (j=0 ; j < save_num ; j++) {
  83. X        my_strncpy (file_in, save_filename (j), LEN);
  84. X
  85. X        printf ("\r\nExtracting %s...\r\n", file_in);
  86. X        fflush (stdout);
  87. X
  88. X        found_header = FALSE;
  89. X        
  90. X        if ((fp_out = fopen (file_out, "w")) != NULL) {
  91. X            if ((fp_in = fopen (file_in, "r")) != NULL) {
  92. X                ptr1 = sh_pattern_1;
  93. X                ptr2 = sh_pattern_2;
  94. X                patlen1 = strlen (sh_pattern_1);
  95. X                patlen2 = strlen (sh_pattern_2);
  96. X                while (! feof (fp_in)) {
  97. X                    if (fgets (buf, sizeof buf, fp_in)) {
  98. X                        /*
  99. X                         *  find #!/bin/sh or #! /bin/sh pattern
  100. X                         */
  101. X                        if (!found_header) {
  102. X                            if (str_str (buf, ptr1, patlen1) != 0 ||
  103. X                                str_str (buf, ptr2, patlen2) != 0) {
  104. X                                found_header = TRUE;
  105. X                            }
  106. X                        }
  107. X                    
  108. X                        /*
  109. X                         *  Write to temp file
  110. X                         */
  111. X                        if (found_header) {
  112. X                            fputs (buf, fp_out);
  113. X                        }
  114. X                    }
  115. X                }
  116. X                fclose (fp_in);
  117. X            }
  118. X            fclose (fp_out);
  119. X
  120. X            sprintf (buf, "cd %s; sh %s", file_out_dir, file_out); 
  121. X            printf ("\r\n");
  122. X            fflush (stdout);
  123. X            Raw (FALSE);
  124. X            invoke_cmd (buf);
  125. X            set_real_uid_gid ();
  126. X            Raw (TRUE);
  127. X            unlink (file_out);
  128. X        }
  129. X    }
  130. X    delete_processed_files ();
  131. X
  132. #endif /* INDEX_DAEMON */
  133. }
  134. X
  135. X
  136. char *get_archive_file (dir, ext)
  137. X    char *dir;
  138. X    char *ext;
  139. {
  140. X    char buf[LEN];
  141. X    char *file = NULL;
  142. X    FILE *fp;
  143. X    
  144. X    sprintf (buf, "ls -t %s/%s", dir, ext);
  145. X
  146. X    if ((fp = popen (buf, "r")) == NULL) {
  147. X        return (char *) 0;
  148. X    }
  149. X
  150. X    if (fgets (buf, sizeof buf, fp) != NULL) {
  151. X        file = str_dup (buf);
  152. X        file[strlen (file)-1] = '\0';
  153. X    }
  154. X    
  155. X    fclose (fp);
  156. X
  157. X    return (file);
  158. }
  159. X
  160. X
  161. void delete_processed_files ()
  162. {
  163. X    int i;
  164. X
  165. X    printf ("\r\n");
  166. X    fflush (stdout);
  167. X    
  168. X    if (prompt_yn (LINES, "Delete saved files that have been post processed? (y/n): ", 'y')) {
  169. X        wait_message (txt_deleting);
  170. X
  171. X        for (i=0 ; i < save_num ; i++) {
  172. X            unlink (save_filename (i));
  173. X        }
  174. X    }
  175. }
  176. SHAR_EOF
  177. echo 'File save.c is complete' &&
  178. chmod 0600 save.c ||
  179. echo 'restore of save.c failed'
  180. Wc_c="`wc -c < 'save.c'`"
  181. test 25511 -eq "$Wc_c" ||
  182.     echo 'save.c: original size 25511, current size' "$Wc_c"
  183. rm -f _shar_wnt_.tmp
  184. fi
  185. # ============= screen.c ==============
  186. if test -f 'screen.c' -a X"$1" != X"-c"; then
  187.     echo 'x - skipping screen.c (File already exists)'
  188.     rm -f _shar_wnt_.tmp
  189. else
  190. > _shar_wnt_.tmp
  191. echo 'x - extracting screen.c (Text)'
  192. sed 's/^X//' << 'SHAR_EOF' > 'screen.c' &&
  193. /*
  194. X *  Project   : tin - a threaded Netnews reader
  195. X *  Module    : screen.c
  196. X *  Author    : I.Lea & R.Skrenta
  197. X *  Created   : 01-04-91
  198. X *  Updated   : 15-12-91
  199. X *  Notes     :
  200. X *  Copyright : (c) Copyright 1991-92 by Iain Lea & Rich Skrenta
  201. X *              You may  freely  copy or  redistribute  this software,
  202. X *              so  long as there is no profit made from its use, sale
  203. X *              trade or  reproduction.  You may not change this copy-
  204. X *              right notice, and it must be included in any copy made
  205. X */
  206. X
  207. #include    "tin.h"
  208. X
  209. extern int errno;
  210. X
  211. char msg[LEN];
  212. struct screen_t *screen;
  213. X
  214. X
  215. void info_message (str)
  216. X    char *str;
  217. {
  218. X    clear_message ();                /* Clear any old messages hanging around */
  219. X    center_line (LINES, FALSE, str);    /* center the message at screen bottom */
  220. X    if (! cmd_line) {
  221. X        MoveCursor (LINES, 0);
  222. X    }
  223. }
  224. X
  225. X
  226. void wait_message (str)
  227. X    char *str;
  228. {
  229. X    clear_message ();      /* Clear any old messages hanging around */
  230. X    printf ("%s", str);
  231. X    fflush (stdout);
  232. }
  233. X
  234. X
  235. void error_message (template, str)
  236. X    char *template;
  237. X    char *str;
  238. {
  239. X    errno = 0;
  240. X
  241. X    clear_message ();      /* Clear any old messages hanging around */
  242. X    
  243. X    fprintf (stderr, template, str);
  244. X    fflush (stderr);
  245. X
  246. X    if (cmd_line) {
  247. X        fprintf (stderr, "\n");
  248. X        fflush (stderr);
  249. X    } else {
  250. X        MoveCursor (LINES, 0);
  251. X        sleep (2);
  252. X    }
  253. }
  254. X
  255. X
  256. void clear_message ()
  257. {
  258. X    if (! cmd_line) {
  259. X        MoveCursor (LINES, 0);
  260. X        CleartoEOLN ();
  261. X    }
  262. }
  263. X
  264. X
  265. void center_line (line, inverse, str)
  266. X    int line;
  267. X    int inverse;
  268. X    char *str;
  269. {
  270. X    int pos;
  271. X
  272. X    if (! cmd_line) {
  273. X        pos = (COLS - (int) strlen (str)) / 2;
  274. X        MoveCursor (line, pos);
  275. X        if (inverse) {
  276. X            StartInverse ();
  277. X        }
  278. X    }
  279. X
  280. X    printf ("%s", str);
  281. X    fflush (stdout);
  282. X
  283. X    if (! cmd_line) {
  284. X        if (inverse) {
  285. X            EndInverse ();
  286. X        }
  287. X    }
  288. }
  289. X
  290. X
  291. void draw_arrow (line)
  292. X    int line;
  293. {
  294. X    MoveCursor (line, 0);
  295. X
  296. X    if (draw_arrow_mark) {
  297. X        printf ("->");
  298. X        fflush (stdout);
  299. X    } else {
  300. X        StartInverse ();
  301. X        printf ("%s", screen[line-INDEX_TOP].col);
  302. X        fflush (stdout);
  303. X        EndInverse ();
  304. X    }
  305. X    MoveCursor (LINES, 0);
  306. }
  307. X
  308. X
  309. void erase_arrow (line)
  310. X    int line;
  311. {
  312. X    MoveCursor (line, 0);
  313. X
  314. X    if (draw_arrow_mark) {
  315. X        printf ("  ");
  316. X    } else {
  317. X        EndInverse ();
  318. X        printf ("%s", screen[line-INDEX_TOP].col);
  319. X    }
  320. X    fflush (stdout);
  321. }
  322. X
  323. X
  324. void show_title (title)
  325. X    char *title;
  326. {    
  327. X    int col;
  328. X    
  329. X    col = (COLS - (int) strlen (txt_type_h_for_help))+1;
  330. X    if (col) {
  331. X        MoveCursor (0, 0);
  332. X        if (kill_articles) {        /* display KILL on screen */
  333. X            printf ("KILL ON");
  334. X        }
  335. X        
  336. X        MoveCursor (0, col);
  337. X        if (mail_check ()) {        /* you have mail message in */
  338. X            printf (txt_you_have_mail);
  339. X        } else {
  340. X            printf (txt_type_h_for_help);
  341. X        }
  342. X    }
  343. X    center_line (0, TRUE, title);
  344. }
  345. X
  346. X
  347. void ring_bell ()
  348. {
  349. X    fputc ('\007', stdout);
  350. X    fflush (stdout);
  351. }
  352. SHAR_EOF
  353. chmod 0600 screen.c ||
  354. echo 'restore of screen.c failed'
  355. Wc_c="`wc -c < 'screen.c'`"
  356. test 2662 -eq "$Wc_c" ||
  357.     echo 'screen.c: original size 2662, current size' "$Wc_c"
  358. rm -f _shar_wnt_.tmp
  359. fi
  360. # ============= search.c ==============
  361. if test -f 'search.c' -a X"$1" != X"-c"; then
  362.     echo 'x - skipping search.c (File already exists)'
  363.     rm -f _shar_wnt_.tmp
  364. else
  365. > _shar_wnt_.tmp
  366. echo 'x - extracting search.c (Text)'
  367. sed 's/^X//' << 'SHAR_EOF' > 'search.c' &&
  368. /*
  369. X *  Project   : tin - a threaded Netnews reader
  370. X *  Module    : search.c
  371. X *  Author    : I.Lea & R.Skrenta
  372. X *  Created   : 01-04-91
  373. X *  Updated   : 13-03-92
  374. X *  Notes     :
  375. X *  Copyright : (c) Copyright 1991-92 by Iain Lea & Rich Skrenta
  376. X *              You may  freely  copy or  redistribute  this software,
  377. X *              so  long as there is no profit made from its use, sale
  378. X *              trade or  reproduction.  You may not change this copy-
  379. X *              right notice, and it must be included in any copy made
  380. X */
  381. X
  382. #include    "tin.h"
  383. X
  384. extern FILE *note_fp;
  385. extern int cur_groupnum;
  386. extern int first_group_on_screen;
  387. extern int last_group_on_screen;
  388. extern int first_subj_on_screen;
  389. extern int last_subj_on_screen;
  390. extern int index_point;
  391. extern int note_line;
  392. extern int note_page;
  393. extern int note_end;
  394. extern long note_mark[MAX_PAGES];
  395. X
  396. /*
  397. X * last search patterns
  398. X */
  399. X
  400. char author_search_string[LEN];
  401. char group_search_string[LEN];
  402. char subject_search_string[LEN];
  403. char art_search_string[LEN];
  404. X
  405. X
  406. /*
  407. X *  group.c & page.c
  408. X */
  409. int search_author (only_unread, current_art, forward)
  410. X    int only_unread;
  411. X    int current_art;
  412. X    int forward;
  413. {
  414. X    char buf[LEN];
  415. X    char buf2[LEN];
  416. X    int i, patlen;
  417. X
  418. X    clear_message ();
  419. X
  420. X    if (forward) {
  421. X        sprintf (buf2, txt_author_search_forwards, author_search_string);
  422. X    } else {
  423. X        sprintf (buf2, txt_author_search_backwards, author_search_string);
  424. X    }
  425. X    
  426. X    if (! prompt_string (buf2, buf)) {
  427. X        return -1;
  428. X    }
  429. X    
  430. X    if (strlen (buf)) {
  431. X        strcpy (author_search_string, buf);
  432. X    } else {
  433. X        if (author_search_string[0]) {
  434. X            strcpy (buf, author_search_string);
  435. X        } else {
  436. X            info_message (txt_no_search_string);    
  437. X            return -1;
  438. X        }
  439. X    }
  440. X
  441. X    wait_message (txt_searching);
  442. X
  443. X    make_lower (author_search_string, buf);
  444. X
  445. X    patlen = strlen (author_search_string);
  446. X
  447. X    i = current_art;
  448. X
  449. X    do {
  450. X        if (forward) {
  451. X            i = next_response (i);
  452. X            if (i < 0)
  453. X                i = base[0];
  454. X        } else {
  455. X            i = prev_response (i);
  456. X            if (i < 0)
  457. X                i = base[top_base - 1] + 
  458. X                    num_of_responses (top_base - 1);
  459. X        }
  460. X
  461. X        if (only_unread && arts[i].unread != ART_UNREAD) {
  462. X            continue;
  463. X        }
  464. X            
  465. X        if (arts[i].name == (char *) 0) {
  466. X            make_lower (arts[i].from, buf2);
  467. X        } else {
  468. X            sprintf (msg, "%s (%s)", arts[i].from, arts[i].name);
  469. X            make_lower (msg, buf2);
  470. X        }
  471. X
  472. X        if (str_str (buf2, buf, patlen) != 0) {
  473. X            clear_message ();
  474. X            return i;
  475. X        }
  476. X    } while (i != current_art);
  477. X
  478. X    info_message (txt_no_match);
  479. X    return -1;
  480. }
  481. X
  482. /*
  483. X * select.c
  484. X */
  485. void search_group (forward)
  486. X    int forward;
  487. {
  488. X    char buf[LEN];
  489. X    char buf2[LEN];
  490. X    int i, patlen;
  491. X
  492. X    clear_message ();
  493. X
  494. X    if (forward) {
  495. X        sprintf (buf2, txt_search_forwards, group_search_string);
  496. X    } else {
  497. X        sprintf (buf2, txt_search_backwards, group_search_string);
  498. X    }
  499. X
  500. X    if (! prompt_string (buf2, buf)) {
  501. X        return;
  502. X    }
  503. X
  504. X    if (strlen (buf)) {
  505. X        strcpy (group_search_string, buf);
  506. X    } else {
  507. X        if (group_search_string[0]) {
  508. X            strcpy (buf, group_search_string);
  509. X        } else {
  510. X            info_message (txt_no_search_string);    
  511. X            return;
  512. X        }
  513. X    }
  514. X
  515. X    wait_message (txt_searching);
  516. X
  517. X    make_lower (group_search_string, buf);
  518. X
  519. X    patlen = strlen (group_search_string);
  520. X
  521. X    i = cur_groupnum;
  522. X
  523. X    do {
  524. X        if (forward)
  525. X            i++;
  526. X        else
  527. X            i--;
  528. X
  529. X        if (i >= group_top)
  530. X            i = 0;
  531. X        if (i < 0)
  532. X            i = group_top - 1;
  533. X
  534. X        make_lower (active[my_group[i]].name, buf2);
  535. X
  536. X        if (str_str (buf2, buf, patlen) != 0) {
  537. X            if (i >= first_group_on_screen
  538. X            &&  i < last_group_on_screen) {
  539. X                clear_message ();
  540. X                erase_group_arrow ();
  541. X                cur_groupnum = i;
  542. X                draw_group_arrow ();
  543. X            } else {
  544. X                cur_groupnum = i;
  545. X                group_selection_page ();
  546. X            }
  547. X            return;
  548. X        }
  549. X    } while (i != cur_groupnum);
  550. X
  551. X    info_message (txt_no_match);
  552. }
  553. X
  554. /*
  555. X * group.c
  556. X */
  557. X
  558. void search_subject (forward, group)
  559. X    int forward;
  560. X    char *group;
  561. {
  562. X    char buf[LEN];
  563. X    char buf2[LEN];
  564. X    int i, j, patlen;
  565. X
  566. X    if (index_point < 0) {
  567. X        info_message (txt_no_arts);
  568. X        return;
  569. X    }
  570. X    
  571. X    clear_message ();
  572. X
  573. X    if (forward) {
  574. X        sprintf (buf2, txt_search_forwards, subject_search_string);
  575. X    } else {
  576. X        sprintf (buf2, txt_search_backwards, subject_search_string);
  577. X    }
  578. X
  579. X    if (! prompt_string (buf2, buf)) {
  580. X        return;
  581. X    }
  582. X
  583. X    if (strlen (buf)) {
  584. X        strcpy (subject_search_string, buf);
  585. X    } else {
  586. X        if (subject_search_string[0]) {
  587. X            strcpy (buf, subject_search_string);
  588. X        } else {
  589. X            info_message (txt_no_search_string);    
  590. X            return;
  591. X        }
  592. X    }
  593. X
  594. X    wait_message (txt_searching);
  595. X
  596. X    make_lower (subject_search_string, buf);
  597. X
  598. X    patlen = strlen (subject_search_string);
  599. X
  600. X    i = index_point;
  601. X
  602. X    do {
  603. X        if (forward)
  604. X            i++;
  605. X        else
  606. X            i--;
  607. X
  608. X        if (i >= top_base)
  609. X            i = 0;
  610. X        if (i < 0)
  611. X            i = top_base - 1;
  612. X
  613. X        j = (int) base[i];
  614. X
  615. X        make_lower (arts[j].subject, buf2);
  616. X
  617. X        if (str_str (buf2, buf, patlen) != 0) {
  618. X            if (i >= first_subj_on_screen
  619. X                &&  i < last_subj_on_screen) {
  620. X                clear_message ();
  621. X                erase_subject_arrow ();
  622. X                index_point = i;
  623. X                draw_subject_arrow ();
  624. X            } else {
  625. X                index_point = i;
  626. X                show_group_page (group);
  627. X            }
  628. X            return;
  629. X        }
  630. X    } while (i != index_point);
  631. X
  632. X    info_message (txt_no_match);
  633. }
  634. X
  635. /*
  636. X *  page.c (search article body)
  637. X */
  638. X
  639. int search_article (forward)
  640. X    int forward;
  641. {
  642. X    char buf[LEN];
  643. X    char buf2[LEN];
  644. X    char string[LEN];
  645. X    char pattern[LEN];
  646. X    char *p, *q;
  647. X    int ctrl_L;
  648. X    int i, j, patlen;
  649. X    int orig_note_end;
  650. X    int orig_note_page;
  651. X
  652. X    clear_message ();
  653. X
  654. X    if (forward) {
  655. X        sprintf (buf2, txt_search_forwards, art_search_string);
  656. X    } else {
  657. X        sprintf (buf2, txt_search_backwards, art_search_string);
  658. X    }
  659. X
  660. X    if (! prompt_string (buf2, buf)) {
  661. X        return FALSE;
  662. X    }
  663. X
  664. X    if (strlen (buf)) {
  665. X        strcpy (art_search_string, buf);
  666. X    } else {
  667. X        if (art_search_string[0]) {
  668. X            strcpy (buf, art_search_string);
  669. X        } else {
  670. X            info_message (txt_no_search_string);    
  671. X            return FALSE;
  672. X        }
  673. X    }
  674. X
  675. X    wait_message (txt_searching);
  676. X    
  677. X    make_lower (art_search_string, pattern);
  678. X
  679. X    patlen = strlen (art_search_string);
  680. X
  681. X    /*
  682. X     *  save current position in article
  683. X     */
  684. X    orig_note_end = note_end;
  685. X    orig_note_page = note_page;
  686. X    
  687. X    while (! note_end) {
  688. X        note_line = 1;
  689. X        ctrl_L = FALSE;
  690. X
  691. X        if (note_page == 0) {
  692. X            note_line += 4;
  693. X        } else {
  694. X            note_line += 2;
  695. X        }
  696. X        while (note_line < LINES) {
  697. X            if (fgets (buf, sizeof buf, note_fp) == NULL) {
  698. X                note_end = TRUE;
  699. X                break;
  700. X            }
  701. X            buf[LEN-1] = '\0';
  702. X            for (p = buf, q = buf2;    *p && *p != '\n' && q<&buf2[LEN]; p++) {
  703. X                if (*p == '\b' && q > buf2) {
  704. X                    q--;
  705. X                } else if (*p == '\f') {        /* ^L */
  706. X                    *q++ = '^';
  707. X                    *q++ = 'L';
  708. X                    ctrl_L = TRUE;
  709. X                } else if (*p == '\t') {
  710. X                    i = q - buf2;
  711. X                    j = (i|7) + 1;
  712. X
  713. X                    while (i++ < j) {
  714. X                        *q++ = ' ';
  715. X                    }
  716. X                } else if (((*p) & 0xFF) < ' ') {
  717. X                    *q++ = '^';
  718. X                    *q++ = ((*p) & 0xFF) + '@';
  719. X                } else {
  720. X                    *q++ = *p;
  721. X                }
  722. X            }
  723. X            *q = '\0';
  724. X
  725. X            make_lower (buf2, string);
  726. X
  727. X            if (str_str (string, pattern, patlen) != 0) {
  728. X                fseek (note_fp, note_mark[note_page], 0);
  729. X                return TRUE;
  730. X            }
  731. X
  732. X            note_line += ((int) strlen(buf2) / COLS) + 1;
  733. X
  734. X            if (ctrl_L) {
  735. X                break;
  736. X            }
  737. X        }
  738. X        if (! note_end) {
  739. X            note_mark[++note_page] = ftell (note_fp);
  740. X        }
  741. X    }
  742. X
  743. X    note_end = orig_note_end;
  744. X    note_page = orig_note_page;
  745. X    fseek (note_fp, note_mark[note_page], 0);
  746. X    info_message (txt_no_match);
  747. X    return FALSE;
  748. }
  749. X
  750. X
  751. void make_lower (s, t)
  752. X    char *s;
  753. X    char *t;
  754. {
  755. X
  756. X    while (*s) {
  757. X        if (isupper(*s))
  758. X            *t = tolower(*s);
  759. X        else
  760. X            *t = *s;
  761. X        s++;
  762. X        t++;
  763. X    }
  764. X    *t = 0;
  765. }
  766. SHAR_EOF
  767. chmod 0600 search.c ||
  768. echo 'restore of search.c failed'
  769. Wc_c="`wc -c < 'search.c'`"
  770. test 7141 -eq "$Wc_c" ||
  771.     echo 'search.c: original size 7141, current size' "$Wc_c"
  772. rm -f _shar_wnt_.tmp
  773. fi
  774. # ============= select.c ==============
  775. if test -f 'select.c' -a X"$1" != X"-c"; then
  776.     echo 'x - skipping select.c (File already exists)'
  777.     rm -f _shar_wnt_.tmp
  778. else
  779. > _shar_wnt_.tmp
  780. echo 'x - extracting select.c (Text)'
  781. sed 's/^X//' << 'SHAR_EOF' > 'select.c' &&
  782. /*
  783. X *  Project   : tin - a threaded Netnews reader
  784. X *  Module    : select.c
  785. X *  Author    : I.Lea & R.Skrenta
  786. X *  Created   : 01-04-91
  787. X *  Updated   : 22-03-92
  788. X *  Notes     :
  789. X *  Copyright : (c) Copyright 1991-92 by Iain Lea & Rich Skrenta
  790. X *              You may  freely  copy or  redistribute  this software,
  791. X *              so  long as there is no profit made from its use, sale
  792. X *              trade or  reproduction.  You may not change this copy-
  793. X *              right notice, and it must be included in any copy made
  794. X */
  795. X
  796. #include    "tin.h"
  797. X
  798. X
  799. extern char cvers[LEN];
  800. extern int index_point;
  801. extern int reread_active_file;
  802. X
  803. int cur_groupnum = 0;
  804. int first_group_on_screen;
  805. int last_group_on_screen;
  806. int space_mode;
  807. int yank_active_file = TRUE;
  808. X
  809. X
  810. void selection_index (start_groupnum)
  811. X    int start_groupnum;
  812. {
  813. #ifndef INDEX_DAEMON
  814. X
  815. X    char buf[LEN];
  816. X    char post_group[LEN];
  817. X    char ch;
  818. X    int i, n;
  819. X    int patlen;
  820. X    int posted;
  821. X    int scroll_lines;
  822. X    int subscribe_num;
  823. X    int time_remaining;
  824. X    
  825. X    cur_groupnum = start_groupnum;
  826. X    
  827. X    mail_setup ();        /* record mailbox size for "you have mail" */
  828. X
  829. #ifdef READ_CHAR_HACK
  830. X    setbuf (stdin, 0);
  831. #endif
  832. X
  833. #ifndef USE_CLEARSCREEN
  834. X    ClearScreen();
  835. #endif
  836. X
  837. X    group_selection_page ();    /* display group selection page */
  838. X
  839. X    set_alarm_signal ();        /* set alarm signal for resync_active_file () */
  840. X    
  841. X    while (TRUE) {
  842. X        resync_active_file ();    /* reread active file if alarm set */
  843. X        num_of_killed_files = 0;
  844. X        num_of_tagged_files = 0;
  845. X        ch = (char) ReadCh();
  846. X
  847. X        resync_active_file ();    /* reread active file if alarm set */
  848. X
  849. X        if (ch > '0' && ch <= '9') {
  850. X            prompt_group_num (ch);
  851. X            continue;
  852. X        }
  853. X        switch (ch) {
  854. X            case ESC:    /* (ESC) common arrow keys */
  855. X                switch (get_arrow_key ()) {
  856. X                    case KEYMAP_UP:
  857. X                        goto select_up;
  858. X
  859. X                    case KEYMAP_DOWN:
  860. X                        goto select_down;
  861. X
  862. X                    case KEYMAP_PAGE_UP:
  863. X                        goto select_page_up;
  864. X
  865. X                    case KEYMAP_PAGE_DOWN:
  866. X                        goto select_page_down;
  867. X
  868. X                    case KEYMAP_HOME:
  869. X                        if (cur_groupnum != 0) {
  870. X                            cur_groupnum = 0;
  871. X                            group_selection_page ();
  872. X                        }
  873. X                        break;
  874. X                    
  875. X                    case KEYMAP_END:
  876. X                        goto end_of_list;
  877. X                }
  878. X                break;
  879. X
  880. #ifndef NO_SHELL_ESCAPE
  881. X            case '!':
  882. X                shell_escape ();
  883. X                group_selection_page ();
  884. X                break;
  885. #endif
  886. X
  887. X            case '$':    /* show last page of groups */
  888. end_of_list:
  889. X                if (cur_groupnum != group_top - 1) {
  890. X                    cur_groupnum = group_top - 1;
  891. X                    group_selection_page ();
  892. X                }
  893. X                break;
  894. X
  895. X            case '/':    /* search forward */
  896. X            case '?':    /* search backward */
  897. X                i = (ch == '/');
  898. X                search_group (i);
  899. X                break;
  900. X
  901. X            case '\r':    /* go into group */
  902. X            case '\n':
  903. X                if (group_top == 0) {
  904. X                    info_message (txt_no_groups);
  905. X                    break;
  906. X                }
  907. X                
  908. X                n = my_group[cur_groupnum];
  909. X                if (active[n].min <= active[n].max) {
  910. X                    space_mode = pos_first_unread;
  911. X                    clear_message();
  912. X                    index_point = -1;
  913. X                    do {
  914. X                        n = my_group[cur_groupnum];
  915. X                        group_page (active[n].name);
  916. X                    } while (index_point == -3);
  917. X                    if (! reread_active_file) {    
  918. X                        group_selection_page ();
  919. X                    }
  920. X                } else {
  921. X                    info_message (txt_no_arts);
  922. X                }
  923. X                break;
  924. X
  925. X            case '\t':    /* enter next group containing unread articles */
  926. X            case 'n':
  927. X                next_unread_group (TRUE);
  928. X                break;
  929. X
  930. X            case ' ':            /* page down */
  931. X            case ctrl('D'):        /* vi style */
  932. X            case ctrl('V'):        /* emacs style */
  933. select_page_down:
  934. X                if (group_top == 0) {
  935. X                    break;
  936. X                }
  937. X                if (cur_groupnum == group_top - 1) {
  938. X                    break;
  939. X                }
  940. X                erase_group_arrow ();
  941. X                scroll_lines = (full_page_scroll ? NOTESLINES : NOTESLINES / 2);
  942. X                cur_groupnum = ((cur_groupnum + scroll_lines) / scroll_lines) * scroll_lines;
  943. X                if (cur_groupnum >= group_top) {
  944. X                    cur_groupnum = (group_top / scroll_lines) * scroll_lines;
  945. X                    if (cur_groupnum < group_top - 1) {
  946. X                        cur_groupnum = group_top - 1;
  947. X                    }
  948. X                }
  949. X
  950. X                if (cur_groupnum <= first_group_on_screen
  951. X                ||  cur_groupnum >= last_group_on_screen)
  952. X                    group_selection_page ();
  953. X                else
  954. X                    draw_group_arrow ();
  955. X                break;
  956. X
  957. X            case ctrl('K'):
  958. X                if (group_top <= 0) {
  959. X                    info_message (txt_no_groups_to_delete);
  960. X                    break;
  961. X                }
  962. X
  963. X                sprintf (buf, active[my_group[cur_groupnum]].name);
  964. X                sprintf (msg, txt_del_group_in_newsrc, buf);
  965. X                if (prompt_yn (LINES, msg, 'y')) {
  966. X                    delete_group (active[my_group[cur_groupnum]].name);
  967. X                    active[my_group[cur_groupnum]].flag = UNSUBSCRIBED;    
  968. X
  969. X                    group_top--;
  970. X                    for (i = cur_groupnum; i < group_top; i++) {
  971. X                        my_group[i] = my_group[i+1];
  972. X                        unread[i] = unread[i+1];
  973. X                    }
  974. X                    if (cur_groupnum >= group_top)
  975. X                        cur_groupnum = group_top - 1;    
  976. X
  977. X                    group_selection_page ();
  978. X                    sprintf (msg, txt_group_deleted, buf);
  979. X                    info_message (msg);
  980. X                }
  981. X                break;
  982. X
  983. X            case ctrl('L'):        /* redraw */
  984. #ifndef USE_CLEARSCREEN
  985. X                ClearScreen ();
  986. #endif
  987. X                group_selection_page ();
  988. X                break;
  989. X
  990. X            case ctrl('N'):        /* line down */
  991. X            case 'j':
  992. select_down:
  993. X                if (cur_groupnum + 1 >= group_top) {
  994. X                    break;
  995. X                }
  996. X                if (cur_groupnum + 1 >= last_group_on_screen) {
  997. #ifndef USE_CLEARSCREEN
  998. X                    erase_group_arrow();
  999. #endif                    
  1000. X                    cur_groupnum++;
  1001. X                    group_selection_page();
  1002. X                } else {
  1003. X                    erase_group_arrow();
  1004. X                    cur_groupnum++;
  1005. X                    draw_group_arrow();
  1006. X                }
  1007. X                break;
  1008. X
  1009. X            case ctrl('P'):        /* line up */
  1010. X            case 'k':
  1011. select_up:
  1012. X                if (cur_groupnum == 0) {
  1013. X                    break;
  1014. X                }
  1015. X                if (cur_groupnum <= first_group_on_screen) {
  1016. X                    cur_groupnum--;
  1017. X                    group_selection_page();
  1018. X                } else {
  1019. X                    erase_group_arrow();
  1020. X                    cur_groupnum--;
  1021. X                    draw_group_arrow();
  1022. X                }
  1023. X                break;
  1024. X
  1025. X            case ctrl('R'):    /* reset .newsrc */
  1026. X                if (prompt_yn (LINES, txt_reset_newsrc, 'n')) {
  1027. X                    reset_newsrc ();
  1028. X                    cur_groupnum = 0;
  1029. X                    group_selection_page ();
  1030. X                }
  1031. X                break;
  1032. X
  1033. X            case ctrl('U'):        /* page up */
  1034. X            case 'b':
  1035. select_page_up:
  1036. X                if (group_top == 0) {
  1037. X                    break;
  1038. X                }
  1039. X                if (cur_groupnum == 0) {
  1040. X                    break;
  1041. X                }
  1042. X                erase_group_arrow ();
  1043. X                scroll_lines = (full_page_scroll ? NOTESLINES : NOTESLINES / 2);
  1044. X                if ((n = cur_groupnum % scroll_lines) > 0) {
  1045. X                    cur_groupnum = cur_groupnum - n;
  1046. X                } else {
  1047. X                    cur_groupnum = ((cur_groupnum - scroll_lines) / scroll_lines) * scroll_lines;
  1048. X                }
  1049. X                if (cur_groupnum < 0) {
  1050. X                    cur_groupnum = 0;
  1051. X                }
  1052. X                if (cur_groupnum < first_group_on_screen
  1053. X                ||  cur_groupnum >= last_group_on_screen)
  1054. X                    group_selection_page ();
  1055. X                else
  1056. X                    draw_group_arrow ();
  1057. X                break;
  1058. X
  1059. X            case 'B':    /* bug/gripe/comment mailed to author */
  1060. X                mail_bug_report ();
  1061. #ifndef USE_CLEARSCREEN
  1062. X                ClearScreen ();
  1063. #endif
  1064. X                group_selection_page();
  1065. X                break;
  1066. X                
  1067. X            case 'c':    /* catchup--mark all articles as read */
  1068. X            case 'C':    /* catchup & goto next unread group */
  1069. X                if (group_top == 0) {
  1070. X                    break;
  1071. X                }
  1072. X                catchup_group ((ch == 'C'));
  1073. X                break;
  1074. X
  1075. X            case 'g':    /* prompt for a new group name */
  1076. X                if ((n = choose_new_group ()) >= 0) {
  1077. X                    if (active[my_group[n]].flag != SUBSCRIBED) {
  1078. X                        subscribe (active[my_group[n]].name, ':',
  1079. X                            my_group[n], FALSE);
  1080. X                    }
  1081. X                    erase_group_arrow();
  1082. X                    cur_groupnum = reposition_group (active[my_group[n]].name,
  1083. X                                    (n ? n : cur_groupnum));
  1084. X                    if (cur_groupnum < first_group_on_screen ||
  1085. X                        cur_groupnum >= last_group_on_screen ||
  1086. X                        cur_groupnum != n) {
  1087. X                        group_selection_page();
  1088. X                    } else {
  1089. X                        clear_message ();
  1090. X                        draw_group_arrow();
  1091. X                    }
  1092. X                }
  1093. X                break;
  1094. X
  1095. X            case 'h':    /* help */
  1096. X                show_info_page (HELP_INFO, help_select, txt_group_select_com);
  1097. X                group_selection_page ();
  1098. X                break;
  1099. X
  1100. X            case 'I':    /* toggle inverse video */
  1101. X                erase_group_arrow ();
  1102. X                toggle_inverse_video ();
  1103. X                group_selection_page ();
  1104. X                break;
  1105. X
  1106. X            case 'm':    /* reposition group within group list */
  1107. X                if (active[my_group[cur_groupnum]].flag == SUBSCRIBED) {
  1108. X                    n = cur_groupnum;
  1109. X                    erase_group_arrow ();
  1110. X                    cur_groupnum = reposition_group (active[my_group[n]].name, n);
  1111. X                    if (cur_groupnum < first_group_on_screen ||
  1112. X                        cur_groupnum >= last_group_on_screen ||
  1113. X                        cur_groupnum != n) {
  1114. X                        group_selection_page ();
  1115. X                    } else {
  1116. X                        clear_message ();
  1117. X                        draw_group_arrow ();
  1118. X                    }
  1119. X                }
  1120. X                break;
  1121. X
  1122. X            case 'M':    /* options menu */
  1123. X                time_remaining = alarm (0);
  1124. X                change_rcfile ("", TRUE);
  1125. X                group_selection_page ();
  1126. X                alarm (time_remaining);
  1127. X                break;
  1128. X
  1129. X            case 'N':    /* goto next unread group */
  1130. X                next_unread_group (FALSE);
  1131. X                break;
  1132. X
  1133. X            case 'q':    /* quit */
  1134. X                tin_done (0);
  1135. X                break;
  1136. X
  1137. X            case 's':    /* subscribe to current group */
  1138. X                if (group_top == 0) {
  1139. X                    break;
  1140. X                }
  1141. X                if (active[my_group[cur_groupnum]].flag != SUBSCRIBED) {
  1142. X                    MoveCursor (INDEX_TOP + (cur_groupnum-first_group_on_screen), 3);
  1143. X                    if (draw_arrow_mark) {
  1144. X                        putchar (' ');
  1145. X                    } else {
  1146. X                        screen[cur_groupnum-first_group_on_screen].col[3] = ' ';
  1147. X                        draw_group_arrow ();
  1148. X                    }
  1149. X                    fflush (stdout);
  1150. X                    MoveCursor (LINES, 0);    
  1151. X
  1152. X                    subscribe (active[my_group[cur_groupnum]].name,
  1153. X                        ':', my_group[cur_groupnum], FALSE);
  1154. X                    sprintf (buf, txt_subscribed_to, active[my_group[cur_groupnum]].name);
  1155. X                    info_message (buf);
  1156. X                }
  1157. X                break;
  1158. X
  1159. X            case 'S':    /* subscribe to groups matching pattern */
  1160. X                if (prompt_string (txt_subscribe_pattern, buf) && buf[0]) {
  1161. X                    wait_message (txt_subscribing);
  1162. X                    patlen = strlen (buf);
  1163. X                    for (subscribe_num=0, i=0 ; i < group_top ; i++) {
  1164. #ifdef NO_REGEX 
  1165. X                        if (str_str (active[my_group[i]].name, buf, patlen)) {
  1166. #else        
  1167. X                        if (wildmat (active[my_group[i]].name, buf)) {
  1168. #endif        
  1169. X                                if (active[my_group[i]].flag != SUBSCRIBED) {
  1170. #ifndef SLOW_SCREEN_UPDATE
  1171. X                                sprintf (msg, txt_subscribing_to, active[my_group[i]].name);
  1172. X                                wait_message (msg);
  1173. #endif                                
  1174. X                                subscribe (active[my_group[i]].name,
  1175. X                                    ':', my_group[i], FALSE);
  1176. X                            }
  1177. X                            subscribe_num++;
  1178. X                        }
  1179. X                    }
  1180. X                    if (subscribe_num) {
  1181. X                        group_selection_page ();    
  1182. X                        sprintf (buf, txt_subscribed_num_groups, subscribe_num);
  1183. X                        info_message (buf);
  1184. X                    } else {
  1185. X                        info_message (txt_no_match);
  1186. X                    }
  1187. X                } else {
  1188. X                    clear_message ();
  1189. X                }
  1190. X                break;
  1191. X
  1192. X            case 'u':    /* unsubscribe to current group */
  1193. X                if (group_top == 0) {
  1194. X                    break;
  1195. X                }
  1196. X                if (active[my_group[cur_groupnum]].flag == SUBSCRIBED) {
  1197. X                    MoveCursor(INDEX_TOP + (cur_groupnum-first_group_on_screen), 3);
  1198. X                    if (draw_arrow_mark) {
  1199. X                        putchar('u');
  1200. X                    } else {
  1201. X                        screen[cur_groupnum-first_group_on_screen].col[3] = 'u';
  1202. X                        draw_group_arrow ();
  1203. X                    }
  1204. X                    fflush(stdout);
  1205. X                    MoveCursor(LINES, 0);
  1206. X
  1207. X                    subscribe(active[my_group[cur_groupnum]].name,
  1208. X                        '!', my_group[cur_groupnum], FALSE);
  1209. X                    sprintf(buf, txt_unsubscribed_to,active[my_group[cur_groupnum]].name);
  1210. X                    info_message(buf);
  1211. X                }
  1212. X                break;
  1213. X
  1214. X            case 'U':    /* unsubscribe to groups matching pattern */
  1215. X                if (prompt_string (txt_unsubscribe_pattern, buf) && buf[0]) {    
  1216. X                    wait_message (txt_unsubscribing);
  1217. X                    patlen = strlen (buf);    
  1218. X                    for (subscribe_num=0, i=0 ; i < group_top ; i++) {        
  1219. #ifdef NO_REGEX
  1220. X                        if (str_str (active[my_group[i]].name, buf, patlen)) {
  1221. #else        
  1222. X                        if (wildmat (active[my_group[i]].name, buf)) {
  1223. #endif        
  1224. X                                if (active[my_group[i]].flag == SUBSCRIBED) {
  1225. #ifndef SLOW_SCREEN_UPDATE
  1226. X                                sprintf (msg, txt_unsubscribing_from, active[my_group[i]].name);
  1227. X                                wait_message (msg);
  1228. #endif                                
  1229. X                                subscribe (active[my_group[i]].name,
  1230. X                                    '!', my_group[i], FALSE);
  1231. X                            }
  1232. X                            subscribe_num++;
  1233. X                        }
  1234. X                    }
  1235. X                    if (subscribe_num) {
  1236. X                        group_selection_page ();    
  1237. X                        sprintf (buf, txt_unsubscribed_num_groups, subscribe_num);
  1238. X                        info_message (buf);
  1239. X                    } else {
  1240. X                        info_message (txt_no_match);
  1241. X                    }
  1242. X                } else {
  1243. X                    clear_message ();
  1244. X                }
  1245. X                break;
  1246. X
  1247. X            case 'v':    /* show tin version */
  1248. X                info_message (cvers);
  1249. X                break;
  1250. X
  1251. X            case 'w':    /* post a basenote */
  1252. X                if (! can_post) {
  1253. X                    info_message (txt_cannot_post);
  1254. X                    break;
  1255. X                }
  1256. X                if (group_top == 0) {
  1257. X                    if (! prompt_string (txt_post_newsgroup, buf)) 
  1258. X                        break;
  1259. X                    if (buf[0] == '\0')
  1260. X                        break;
  1261. X                    strcpy (post_group, buf);
  1262. X                } else {
  1263. X                    strcpy (post_group, active[my_group[cur_groupnum]].name);
  1264. X                }
  1265. X                if (post_base (post_group, &posted)) {
  1266. X                    group_selection_page ();
  1267. X                }
  1268. X                break;
  1269. X
  1270. X            case 'W':    /* display messages posted by user */
  1271. X                if (user_posted_messages ()) {
  1272. X                    group_selection_page ();
  1273. X                }
  1274. X                break;
  1275. X
  1276. X            case 'y':    /* pull in rest of groups from active */
  1277. X                if (yank_active_file) {
  1278. X                    wait_message (txt_yanking_all_groups);
  1279. X                    n = group_top;
  1280. X                    for (i = 0; i < num_active; i++) {
  1281. X                        active[i].flag = UNSUBSCRIBED;
  1282. X                    }
  1283. X                    read_newsrc (FALSE);
  1284. X                    for (i = 0; i < num_active; i++) {
  1285. X                        if (active[i].flag & UNSUBSCRIBED) {
  1286. X                            active[i].flag &= ~UNSUBSCRIBED;
  1287. X                            my_group[group_top] = i;
  1288. X                            unread[group_top] = -1;
  1289. X                            group_top++;
  1290. X                        }
  1291. X                    }
  1292. X                    if (n < group_top) {
  1293. X                        sprintf (buf, txt_added_groups, group_top - n,
  1294. X                            group_top - n == 1 ? "" : txt_plural);
  1295. X                        group_selection_page ();
  1296. X                        info_message (buf);
  1297. X                    } else {
  1298. X                        info_message (txt_no_groups_to_yank_in);
  1299. X                    }
  1300. X                    yank_active_file = FALSE;
  1301. X                } else {
  1302. X                    wait_message (txt_yanking_sub_groups);
  1303. X                    read_newsrc (TRUE);
  1304. X                    cur_groupnum = group_top - 1;
  1305. X                    group_selection_page ();
  1306. X                    yank_active_file = TRUE;
  1307. X                }
  1308. X                break;
  1309. X
  1310. X            case 'Y':    /* reread .newsrc, no unsub groups */
  1311. X                wait_message (txt_yanking_sub_groups);
  1312. X                cur_groupnum = 0;
  1313. X                group_top = 0;
  1314. X                for (i = 0; i < num_active; i++) {
  1315. X                    active[i].flag = UNSUBSCRIBED;
  1316. X                }
  1317. X                read_newsrc (TRUE);
  1318. X                group_selection_page ();
  1319. X                break;
  1320. X
  1321. X            case 'z':    /* mark group unread */
  1322. X                if (group_top == 0) {
  1323. X                    break;
  1324. X                }
  1325. X                n = cur_groupnum;
  1326. X                update_newsrc (active[my_group[n]].name, my_group[n], TRUE);
  1327. X                cur_groupnum = 0;
  1328. X                group_top = 0;
  1329. X                read_newsrc (TRUE);            
  1330. X                cur_groupnum = n;
  1331. X                group_selection_page ();
  1332. X                break;
  1333. X
  1334. X            case 'Z':    /* undelete groups deleted by ctrl-K */
  1335. X                if (undel_group ()) {
  1336. X                    group_selection_page ();
  1337. X                    info_message (txt_group_undeleted);
  1338. X                }
  1339. X                break;
  1340. X
  1341. X            default:
  1342. X                info_message(txt_bad_command);
  1343. X        }
  1344. X    }
  1345. X
  1346. #endif /* INDEX_DAEMON */
  1347. }
  1348. X
  1349. X
  1350. void group_selection_page ()
  1351. {
  1352. #ifndef INDEX_DAEMON
  1353. X
  1354. X    char buf[LEN];
  1355. X    char new[10];
  1356. X    char subs;
  1357. X    int i, j, n;
  1358. X
  1359. X    set_signals_select ();
  1360. X
  1361. #ifdef USE_CLEARSCREEN
  1362. X    ClearScreen ();
  1363. #else
  1364. X    MoveCursor (0, 0);        /* top left corner */
  1365. X    CleartoEOLN ();
  1366. #endif
  1367. X
  1368. X    sprintf (buf, "%s (%d)", txt_group_selection, group_top);
  1369. X    show_title (buf);
  1370. X
  1371. #ifndef USE_CLEARSCREEN
  1372. X    MoveCursor (1, 0);
  1373. X    CleartoEOLN ();
  1374. #endif
  1375. X
  1376. X    MoveCursor (INDEX_TOP, 0);
  1377. X
  1378. X    if (cur_groupnum >= group_top) {
  1379. X        cur_groupnum = group_top - 1;
  1380. X    }
  1381. X    if (cur_groupnum < 0) {
  1382. X        cur_groupnum = 0;
  1383. X    }
  1384. X    if (NOTESLINES <= 0) {
  1385. X        first_group_on_screen = 0;
  1386. X    } else {
  1387. X        first_group_on_screen = (cur_groupnum / NOTESLINES) * NOTESLINES;
  1388. X        if (first_group_on_screen < 0) {
  1389. X            first_group_on_screen = 0;
  1390. X        }
  1391. X    }
  1392. X
  1393. X    last_group_on_screen = first_group_on_screen + NOTESLINES;
  1394. X
  1395. X    if (last_group_on_screen >= group_top) {
  1396. X        last_group_on_screen = group_top;
  1397. X        first_group_on_screen = (cur_groupnum / NOTESLINES) * NOTESLINES;
  1398. X
  1399. X        if (first_group_on_screen == last_group_on_screen ||
  1400. X            first_group_on_screen < 0) {
  1401. X            if (first_group_on_screen < 0) {
  1402. X                first_group_on_screen = 0;
  1403. X            } else {
  1404. X                first_group_on_screen = last_group_on_screen - NOTESLINES;    
  1405. X            }
  1406. X        }    
  1407. X    }
  1408. X
  1409. X    if (group_top == 0) {
  1410. X        first_group_on_screen = 0;
  1411. X        last_group_on_screen = 0;
  1412. X    }
  1413. X
  1414. X    for (j=0, i = first_group_on_screen; i < last_group_on_screen; i++,j++) {
  1415. X        switch (unread[i]) {
  1416. X            case -2:
  1417. X                sprintf (new, "?    ");
  1418. X                break;
  1419. X
  1420. X            case -1:
  1421. X                sprintf (new, "-    ");
  1422. X                break;
  1423. X
  1424. X            case 0:
  1425. X                sprintf (new, "     ");
  1426. X                break;
  1427. X
  1428. X            default:
  1429. X                sprintf (new, "%-5d", unread[i]);
  1430. X        }
  1431. X        
  1432. X        n = my_group[i];
  1433. X        if (active[n].flag & SUBSCRIBED)    /* subscribed? */
  1434. X            subs = ' ';
  1435. X        else
  1436. X            subs = 'u';    /* u next to unsubscribed groups */
  1437. X
  1438. X        if (draw_arrow_mark) {
  1439. X            printf ("   %c %4d  %-40s %s\r\n",
  1440. X                   subs, i+1, active[n].name, new);
  1441. X        } else {
  1442. X            sprintf (screen[j].col, "   %c %4d  %-40s %s%*s\r\n",
  1443. X                subs, i+1, active[n].name, new, COLS-BLANK_SELECT_COLS, " ");
  1444. X            printf ("%s", screen[j].col);
  1445. X        }
  1446. X    }
  1447. #ifndef USE_CLEARSCREEN
  1448. X    CleartoEOS ();
  1449. #endif
  1450. X
  1451. X    if (group_top <= 0) {
  1452. X        info_message (txt_no_groups);
  1453. X        return;
  1454. X    } else if (last_group_on_screen == group_top) {
  1455. X        info_message (txt_end_of_groups);
  1456. X    }
  1457. X    
  1458. X    draw_group_arrow ();
  1459. X
  1460. #endif /* INDEX_DAEMON */
  1461. }
  1462. X
  1463. X
  1464. int prompt_group_num (ch)
  1465. X    char ch;
  1466. {
  1467. X    int num;
  1468. X
  1469. X    clear_message ();
  1470. X
  1471. X    if ((num = prompt_num (ch, txt_select_group)) == -1) {
  1472. X        clear_message ();
  1473. X        return FALSE;
  1474. X    }
  1475. X    num--;        /* index from 0 (internal) vs. 1 (user) */
  1476. X
  1477. X    if (num < 0) {
  1478. X        num = 0;
  1479. X    }
  1480. X    if (num >= group_top) {
  1481. X        num = group_top - 1;
  1482. X    }
  1483. X
  1484. X    if (num >= first_group_on_screen
  1485. X    &&  num < last_group_on_screen) {
  1486. X        erase_group_arrow ();
  1487. X        cur_groupnum = num;
  1488. X        draw_group_arrow ();
  1489. X    } else {
  1490. #ifndef USE_CLEARSCREEN
  1491. X        erase_group_arrow ();
  1492. #endif        
  1493. X        cur_groupnum = num;
  1494. X        group_selection_page ();
  1495. X    }
  1496. X
  1497. X    return TRUE;
  1498. }
  1499. X
  1500. X
  1501. void erase_group_arrow ()
  1502. {
  1503. X    erase_arrow (INDEX_TOP + (cur_groupnum-first_group_on_screen));
  1504. }
  1505. X
  1506. X
  1507. void draw_group_arrow()
  1508. {
  1509. X    draw_arrow (INDEX_TOP + (cur_groupnum-first_group_on_screen));
  1510. }
  1511. X
  1512. X
  1513. int choose_new_group ()
  1514. {
  1515. X    char buf[LEN];
  1516. X    char *p;
  1517. X    int ret;
  1518. X
  1519. X    if (! prompt_string (txt_newsgroup, buf))
  1520. X        return -1;
  1521. X
  1522. X    for (p = buf; *p && (*p == ' ' || *p == '\t'); p++)
  1523. X        continue;
  1524. X    if (*p == '\0')
  1525. X        return -1;
  1526. X
  1527. X    clear_message ();
  1528. X
  1529. X    if ((ret = add_group (p, TRUE)) < 0) {
  1530. X        sprintf (msg, txt_not_in_active_file, p);
  1531. X        info_message (msg);
  1532. X    }
  1533. X
  1534. X    return ret;
  1535. }
  1536. X
  1537. /*
  1538. X *  Add a group to the selection list (my_group[])
  1539. X *  Return the index of my_group[] if group is added or was already
  1540. X *  there.  Return -1 if named group is not in active[].
  1541. X */
  1542. X
  1543. int add_group (s, get_unread)
  1544. X    char *s;
  1545. X    int get_unread;            /* look in .newsrc for sequencer unread info? */
  1546. {
  1547. X    long h;
  1548. X    int i, j;
  1549. X
  1550. X    h = hash_groupname (s);
  1551. X
  1552. X    for (i = group_hash[h]; i >= 0; i = active[i].next) {
  1553. X        if (strcmp (s, active[i].name) == 0) {
  1554. X            for (j = 0; j < group_top; j++) {
  1555. X                if (my_group[j] == i) {
  1556. X                    return j;
  1557. X                }
  1558. X            }
  1559. X
  1560. X            active[i].flag &= ~UNSUBSCRIBED;   /* mark that we got it */
  1561. X            my_group[group_top] = i;
  1562. X
  1563. X            if (get_unread)
  1564. X                unread[group_top] = get_line_unread (s, i);
  1565. X            else
  1566. X                unread[group_top] = -2;
  1567. X
  1568. X            group_top++;
  1569. X            return group_top - 1;
  1570. X        }
  1571. X    }
  1572. X
  1573. X    return -1;
  1574. }
  1575. X
  1576. X
  1577. int reposition_group (group, default_num)
  1578. X    char *group;
  1579. X    int default_num;
  1580. {
  1581. X    char buf[LEN];
  1582. X    char pos[LEN];
  1583. X    int pos_num = 0;
  1584. X
  1585. X    sprintf (buf, txt_newsgroup_position, group);
  1586. X    
  1587. X    if (! prompt_string (buf, pos)) 
  1588. X        return default_num;
  1589. X
  1590. X    if (pos[0] == '\0')
  1591. X        return default_num;
  1592. X        
  1593. X    if (pos[0] == '$') {
  1594. X        pos_num = group_top;
  1595. X    } else {
  1596. X        pos_num = atoi (pos);
  1597. X        if (pos_num > group_top) {
  1598. X            pos_num = group_top;
  1599. X        } else if (pos_num <= 0) {
  1600. X            pos_num = 1;
  1601. X        }
  1602. X    }
  1603. X
  1604. X    wait_message (txt_moving);
  1605. X    
  1606. X    if (pos_group_in_newsrc (group, pos_num)) {
  1607. X        read_newsrc (TRUE);
  1608. X        return (pos_num-1);
  1609. X    } else {
  1610. X        return (default_num);
  1611. X    }
  1612. }
  1613. X
  1614. X
  1615. void catchup_group (goto_next_unread_group)
  1616. X    int goto_next_unread_group;
  1617. {    
  1618. X    int i;
  1619. X    
  1620. X    sprintf (msg, txt_mark_group_read, active[my_group[cur_groupnum]].name);
  1621. X    if (prompt_yn (LINES, msg, 'y')) {
  1622. X        unread[cur_groupnum] = 0;
  1623. X        mark_group_read (active[my_group[cur_groupnum]].name,
  1624. X                        my_group[cur_groupnum]);
  1625. X        if (draw_arrow_mark) {    
  1626. X            MoveCursor (INDEX_TOP+(cur_groupnum - first_group_on_screen), 51);
  1627. X            printf ("     ");
  1628. X            MoveCursor (LINES, 0);
  1629. X            fflush (stdout);
  1630. X        } else {
  1631. X            i = cur_groupnum - first_group_on_screen;
  1632. X            screen[i].col[51] = ' ';
  1633. X            screen[i].col[52] = ' ';
  1634. X            screen[i].col[53] = ' ';
  1635. X            screen[i].col[54] = ' ';
  1636. X            screen[i].col[55] = ' ';
  1637. X        }
  1638. X        if (cur_groupnum+1 < last_group_on_screen) {
  1639. X            erase_group_arrow ();
  1640. X            cur_groupnum++;
  1641. X            draw_group_arrow ();
  1642. X        } else {
  1643. X            cur_groupnum++;
  1644. X            group_selection_page ();
  1645. X        }
  1646. X        if (goto_next_unread_group) {
  1647. X            next_unread_group (FALSE);    
  1648. X        }
  1649. X    }
  1650. }
  1651. X
  1652. X
  1653. void next_unread_group (enter_group)
  1654. X    int enter_group;
  1655. {
  1656. X    int i;
  1657. X    
  1658. X    for (i = cur_groupnum; i < group_top; i++) {
  1659. X        if (unread[i] != 0) {
  1660. X            break;
  1661. X        }
  1662. X    }
  1663. X    if (i >= group_top) {
  1664. X        info_message (txt_no_groups_to_read);
  1665. X        return;
  1666. X    }
  1667. X
  1668. X    erase_group_arrow ();
  1669. X    cur_groupnum = i;
  1670. X    if (cur_groupnum >= last_group_on_screen) {
  1671. X        group_selection_page ();
  1672. X    } else {
  1673. X        draw_group_arrow ();
  1674. X    }
  1675. X    space_mode = pos_first_unread;
  1676. X
  1677. X    if (enter_group) {
  1678. X        clear_message ();
  1679. X        index_point = -1;
  1680. X        do {
  1681. X            group_page (active[my_group[cur_groupnum]].name);
  1682. X        } while (index_point == -3);
  1683. X        group_selection_page ();
  1684. X    }
  1685. }
  1686. SHAR_EOF
  1687. chmod 0600 select.c ||
  1688. echo 'restore of select.c failed'
  1689. Wc_c="`wc -c < 'select.c'`"
  1690. test 20378 -eq "$Wc_c" ||
  1691.     echo 'select.c: original size 20378, current size' "$Wc_c"
  1692. rm -f _shar_wnt_.tmp
  1693. fi
  1694. # ============= signal.c ==============
  1695. if test -f 'signal.c' -a X"$1" != X"-c"; then
  1696.     echo 'x - skipping signal.c (File already exists)'
  1697.     rm -f _shar_wnt_.tmp
  1698. else
  1699. > _shar_wnt_.tmp
  1700. echo 'x - extracting signal.c (Text)'
  1701. sed 's/^X//' << 'SHAR_EOF' > 'signal.c' &&
  1702. /*
  1703. X *  Project   : tin - a threaded Netnews reader
  1704. X *  Module    : signal.c
  1705. X *  Author    : I.Lea
  1706. X *  Created   : 01-04-91
  1707. X *  Updated   : 19-03-92
  1708. X *  Notes     : signal handlers for different modes and window resizing
  1709. X *  Copyright : (c) Copyright 1991-92 by Iain Lea
  1710. X *              You may  freely  copy or  redistribute  this software,
  1711. X *              so  long as there is no profit made from its use, sale
  1712. X *              trade or  reproduction.  You may not change this copy-
  1713. X *              right notice, and it must be included in any copy made
  1714. X */
  1715. X
  1716. #include    "tin.h"
  1717. X
  1718. extern char *glob_art_group;
  1719. extern char *glob_group;
  1720. extern char *glob_page_group;
  1721. extern int glob_respnum;
  1722. extern int reread_active_file;
  1723. X
  1724. #ifdef SIGTSTP
  1725. int do_sigtstp = 0;
  1726. #endif
  1727. X
  1728. #ifdef POSIX_JOB_CONTROL
  1729. struct sigaction art_act;
  1730. struct sigaction group_act;
  1731. struct sigaction kill_act;
  1732. struct sigaction main_act;
  1733. struct sigaction old_act;
  1734. struct sigaction page_act;
  1735. struct sigaction rcfile_act;
  1736. struct sigaction select_act;
  1737. struct sigaction thread_act;
  1738. #endif
  1739. X
  1740. X
  1741. void set_signal_handlers ()
  1742. {
  1743. X    signal (SIGINT, signal_handler);    /* ctrl-C */
  1744. X    signal (SIGQUIT, signal_handler);    /* ctrl-\ */
  1745. X    signal (SIGILL, signal_handler);
  1746. X    signal (SIGBUS, signal_handler);
  1747. X    signal (SIGSEGV, signal_handler);
  1748. X    signal (SIGPIPE, SIG_IGN);
  1749. X
  1750. #ifdef SIGWINCH
  1751. X    if (debug == 2) {
  1752. X        wait_message ("SIGWINCH setting signal...");
  1753. X        sleep (2);
  1754. X    }
  1755. X    signal (SIGWINCH, main_resize);
  1756. #endif
  1757. X
  1758. #if defined(SIGTSTP) && ! defined(MINIX)
  1759. X    {
  1760. X        SIGTYPE (*ptr)();
  1761. X        ptr = signal (SIGTSTP, SIG_DFL);
  1762. X        signal (SIGTSTP, ptr);
  1763. X        if (ptr != SIG_IGN) {
  1764. X            /*
  1765. X             *  SIGTSTP is ignored when starting from shells
  1766. X             *  without job-control
  1767. X             */
  1768. X            do_sigtstp = 1; 
  1769. X            signal (SIGTSTP, main_suspend);
  1770. X        }
  1771. X    }
  1772. #endif
  1773. }
  1774. X
  1775. X
  1776. void set_alarm_signal ()
  1777. {
  1778. #ifndef NO_RESYNC_ACTIVE_FILE
  1779. X    signal (SIGALRM, signal_handler);
  1780. X    alarm (RESYNC_ACTIVE_SECS);
  1781. X    reread_active_file = FALSE;
  1782. #endif
  1783. }
  1784. X
  1785. X
  1786. void signal_handler (sig)
  1787. X    int sig;
  1788. {
  1789. X    char *sigtext;
  1790. X
  1791. X    switch (sig) {
  1792. X        case SIGINT:
  1793. X            if (update) {
  1794. X                sigtext = "SIGINT ";
  1795. X            } else {
  1796. X                signal (SIGINT, signal_handler);
  1797. X                return;
  1798. X            }
  1799. X            break;
  1800. X        case SIGQUIT:
  1801. X            sigtext = "SIGQUIT ";
  1802. X            break;
  1803. X        case SIGBUS:
  1804. X            sigtext = "SIGBUS ";
  1805. X            break;
  1806. X        case SIGSEGV:
  1807. X            sigtext = "SIGSEGV ";
  1808. X            break;
  1809. #ifndef NO_RESYNC_ACTIVE_FILE
  1810. X        case SIGALRM:
  1811. X            set_alarm_signal ();
  1812. X            reread_active_file = TRUE;
  1813. X            return;
  1814. #endif
  1815. X        default:
  1816. X            sigtext = "";
  1817. X            break;
  1818. X    }
  1819. X    Raw (FALSE);
  1820. X    EndWin ();
  1821. X    fprintf (stderr, "\n%s: signal handler caught signal %s(%d).\n",
  1822. X        progname, sigtext, sig);
  1823. X    if (sig != SIGINT && sig != SIGQUIT) {
  1824. X        fprintf (stderr, "%s: send a bug report to %s\n",
  1825. X            progname, BUG_REPORT_ADDRESS);
  1826. X    }
  1827. X    fflush (stderr);
  1828. X    exit (1);
  1829. }
  1830. X
  1831. X
  1832. void set_win_size (num_lines, num_cols)
  1833. X    int *num_lines;
  1834. X    int *num_cols;
  1835. {
  1836. #ifdef TIOCGWINSZ
  1837. X    char buf[64];
  1838. X    int old_lines, old_cols;
  1839. X    struct winsize win;
  1840. X
  1841. X    if (debug == 2) {
  1842. X        old_lines = *num_lines;
  1843. X        old_cols = *num_cols;
  1844. X    }
  1845. #endif
  1846. X
  1847. X    init_screen_array (FALSE);        /* deallocate screen array */
  1848. X
  1849. #ifdef TIOCGWINSZ
  1850. X    if (ioctl (0, TIOCGWINSZ, &win) == 0) {
  1851. X        if (win.ws_row != 0) {
  1852. X            *num_lines = win.ws_row - 1;
  1853. X        }
  1854. X        if (win.ws_col != 0) {
  1855. X            *num_cols = win.ws_col;
  1856. X        }
  1857. X    }
  1858. X
  1859. X    if (debug == 2) {
  1860. X        sprintf (buf, "RESIZED lines %d to %d  cols %d to %d",
  1861. X            old_lines, *num_lines, old_cols, *num_cols);
  1862. X        info_message (buf);
  1863. X    }
  1864. #endif
  1865. X
  1866. X    init_screen_array (TRUE);        /* allocate screen array for resize */
  1867. X
  1868. X    if (show_author == SHOW_FROM_BOTH) {
  1869. X        max_subj = (*num_cols / 2) - 2;
  1870. X    } else {
  1871. X        max_subj = (*num_cols / 2) + 5;
  1872. X    }
  1873. X    max_from = (*num_cols - max_subj) - 17;
  1874. X    RIGHT_POS = *num_cols - 18;
  1875. X    MORE_POS  = *num_cols - 15;
  1876. X    NOTESLINES = *num_lines - INDEX_TOP - 1;
  1877. X    if (NOTESLINES <= 0) {
  1878. X        NOTESLINES = 1;
  1879. X    }
  1880. }
  1881. X
  1882. X
  1883. void set_signals_art ()
  1884. {
  1885. #ifdef SIGTSTP
  1886. X    if (do_sigtstp) {
  1887. #ifdef POSIX_JOB_CONTROL
  1888. X        sigemptyset (&art_act.sa_mask);
  1889. #if defined(SA_RESTART) 
  1890. X        art_act.sa_flags = SA_RESTART | SA_RESETHAND;
  1891. #else
  1892. X        art_act.sa_flags = 0;
  1893. #endif
  1894. X        art_act.sa_handler = art_suspend;
  1895. X        sigaction (SIGTSTP, &art_act, 0L);
  1896. #else
  1897. X        signal (SIGTSTP, art_suspend);
  1898. #endif
  1899. X    }
  1900. #endif
  1901. X
  1902. #ifdef SIGWINCH
  1903. X    signal (SIGWINCH, art_resize);
  1904. #endif
  1905. }
  1906. X
  1907. X
  1908. void set_signals_group ()
  1909. {
  1910. #ifdef SIGTSTP
  1911. X    if (do_sigtstp) {
  1912. #ifdef POSIX_JOB_CONTROL
  1913. X        sigemptyset (&group_act.sa_mask);
  1914. #if defined(SA_RESTART) 
  1915. X        group_act.sa_flags = SA_RESTART | SA_RESETHAND;
  1916. #else
  1917. X        group_act.sa_flags = 0;
  1918. #endif
  1919. X        group_act.sa_handler = group_suspend;
  1920. X        sigaction (SIGTSTP, &group_act, 0L);
  1921. #else
  1922. X        signal (SIGTSTP, group_suspend);
  1923. #endif
  1924. X    }
  1925. #endif
  1926. X
  1927. #ifdef SIGWINCH
  1928. X    signal (SIGWINCH, group_resize);
  1929. #endif
  1930. }
  1931. X
  1932. X
  1933. void set_signals_page ()
  1934. {
  1935. #ifdef SIGTSTP
  1936. X    if (do_sigtstp) {
  1937. #ifdef POSIX_JOB_CONTROL
  1938. X        sigemptyset (&page_act.sa_mask);
  1939. #if defined(SA_RESTART) 
  1940. X        page_act.sa_flags = SA_RESTART | SA_RESETHAND;
  1941. #else
  1942. X        page_act.sa_flags = 0;
  1943. #endif
  1944. X        page_act.sa_handler = page_suspend;
  1945. X        sigaction (SIGTSTP, &page_act, 0L);
  1946. #else
  1947. X        signal (SIGTSTP, page_suspend);
  1948. #endif
  1949. X    }
  1950. #endif
  1951. X
  1952. #ifdef SIGWINCH
  1953. X    signal (SIGWINCH, page_resize);
  1954. #endif
  1955. }
  1956. X
  1957. X
  1958. void set_signals_select ()
  1959. {
  1960. #ifdef SIGTSTP
  1961. X    if (do_sigtstp) {
  1962. #ifdef POSIX_JOB_CONTROL
  1963. X        sigemptyset (&select_act.sa_mask);
  1964. #if defined(SA_RESTART) 
  1965. X        select_act.sa_flags = SA_RESTART | SA_RESETHAND;
  1966. #else
  1967. X        select_act.sa_flags = 0;
  1968. #endif
  1969. X        select_act.sa_handler = select_suspend;
  1970. X        sigaction (SIGTSTP, &select_act, 0L);
  1971. #else
  1972. X        signal (SIGTSTP, select_suspend);
  1973. #endif
  1974. X    }
  1975. #endif
  1976. X
  1977. #ifdef SIGWINCH
  1978. X    signal (SIGWINCH, select_resize);
  1979. #endif
  1980. }
  1981. X
  1982. X
  1983. void set_signals_thread ()
  1984. {
  1985. #ifdef SIGTSTP
  1986. X    if (do_sigtstp) {
  1987. #ifdef POSIX_JOB_CONTROL
  1988. X        sigemptyset (&thread_act.sa_mask);
  1989. #if defined(SA_RESTART) 
  1990. X        thread_act.sa_flags = SA_RESTART | SA_RESETHAND;
  1991. #else
  1992. X        thread_act.sa_flags = 0;
  1993. #endif
  1994. X        thread_act.sa_handler = thread_suspend;
  1995. X        sigaction (SIGTSTP, &thread_act, 0L);
  1996. #else
  1997. X        signal (SIGTSTP, thread_suspend);
  1998. #endif
  1999. X    }
  2000. #endif
  2001. X
  2002. #ifdef SIGWINCH
  2003. X    signal (SIGWINCH, thread_resize);
  2004. #endif
  2005. }
  2006. X
  2007. X
  2008. #ifdef SIGTSTP
  2009. X
  2010. /* ARGSUSED0 */
  2011. void art_suspend (sig)
  2012. X    int sig;
  2013. {
  2014. X    Raw (FALSE);
  2015. X    putchar ('\n');
  2016. X
  2017. #ifdef POSIX_JOB_CONTROL
  2018. X    {
  2019. X        sigset_t stopmask;
  2020. X        sigemptyset (&stopmask);
  2021. X        sigprocmask (SIG_SETMASK, &stopmask, NULL);
  2022. X    }    
  2023. #else
  2024. X    signal(SIGTSTP, SIG_DFL);
  2025. #ifdef BSD
  2026. X    sigsetmask (sigblock(0) & ~(1 << (SIGTSTP -1)));
  2027. #endif
  2028. #endif
  2029. X
  2030. X    kill (0, SIGTSTP);
  2031. X
  2032. #ifdef POSIX_JOB_CONTROL
  2033. X    sigemptyset (&art_act.sa_mask);
  2034. #if defined(SA_RESTART) 
  2035. X        art_act.sa_flags = SA_RESTART | SA_RESETHAND;
  2036. #else
  2037. X        art_act.sa_flags = 0;
  2038. #endif
  2039. X    art_act.sa_handler = art_suspend;
  2040. X    sigaction (SIGTSTP, &art_act, 0L);
  2041. #else
  2042. X    signal (SIGTSTP, art_suspend);
  2043. #endif
  2044. X
  2045. X    if (! update) {
  2046. X        Raw (TRUE);
  2047. X        art_resize (0);        
  2048. X    }
  2049. }
  2050. X
  2051. X
  2052. /* ARGSUSED0 */
  2053. void main_suspend (sig)
  2054. X    int sig;
  2055. {
  2056. X    Raw (FALSE);
  2057. X    putchar ('\n');
  2058. X
  2059. #ifdef POSIX_JOB_CONTROL
  2060. X    {
  2061. X        sigset_t stopmask;
  2062. X        sigemptyset (&stopmask);
  2063. X        sigprocmask (SIG_SETMASK, &stopmask, NULL);
  2064. X    }    
  2065. #else
  2066. X    signal(SIGTSTP, SIG_DFL);
  2067. #ifdef BSD
  2068. X    sigsetmask (sigblock(0) & ~(1 << (SIGTSTP -1)));
  2069. #endif
  2070. #endif
  2071. X
  2072. X    kill (0, SIGTSTP);
  2073. X
  2074. #ifdef POSIX_JOB_CONTROL
  2075. X    sigemptyset (&main_act.sa_mask);
  2076. #if defined(SA_RESTART) 
  2077. X        main_act.sa_flags = SA_RESTART | SA_RESETHAND;
  2078. #else
  2079. X        main_act.sa_flags = 0;
  2080. #endif
  2081. X    main_act.sa_handler = main_suspend;
  2082. X    sigaction (SIGTSTP, &main_act, 0L);
  2083. #else
  2084. X    signal (SIGTSTP, main_suspend);
  2085. #endif
  2086. X
  2087. X    if (! update) {
  2088. X        Raw (TRUE);
  2089. X        main_resize (0);        
  2090. X    }
  2091. }
  2092. X
  2093. X
  2094. /* ARGSUSED0 */
  2095. void select_suspend (sig)
  2096. X    int sig;
  2097. {
  2098. X    Raw (FALSE);
  2099. X
  2100. #ifdef POSIX_JOB_CONTROL
  2101. X    {
  2102. X        sigset_t stopmask;
  2103. X        sigemptyset (&stopmask);
  2104. X        sigprocmask (SIG_SETMASK, &stopmask, NULL);
  2105. X    }    
  2106. #else
  2107. X    signal(SIGTSTP, SIG_DFL);
  2108. #ifdef BSD
  2109. X    sigsetmask (sigblock(0) & ~(1 << (SIGTSTP -1)));
  2110. #endif
  2111. #endif
  2112. X
  2113. X    kill (0, SIGTSTP);
  2114. X
  2115. #ifdef POSIX_JOB_CONTROL
  2116. X    sigemptyset (&select_act.sa_mask);
  2117. #if defined(SA_RESTART) 
  2118. X        select_act.sa_flags = SA_RESTART | SA_RESETHAND;
  2119. #else
  2120. X        select_act.sa_flags = 0;
  2121. #endif
  2122. X    select_act.sa_handler = select_suspend;
  2123. X    sigaction (SIGTSTP, &select_act, 0L);
  2124. #else
  2125. X    signal (SIGTSTP, select_suspend);
  2126. #endif
  2127. X
  2128. X    if (! update) {
  2129. X        Raw (TRUE);
  2130. X    }
  2131. X
  2132. X    select_resize (0);
  2133. }
  2134. X
  2135. X
  2136. /* ARGSUSED0 */
  2137. void group_suspend (sig)
  2138. X    int sig;
  2139. {
  2140. X    Raw (FALSE);
  2141. X    putchar ('\n');
  2142. X
  2143. #ifdef POSIX_JOB_CONTROL
  2144. X    {
  2145. X        sigset_t stopmask;
  2146. X        sigemptyset (&stopmask);
  2147. X        sigprocmask (SIG_SETMASK, &stopmask, NULL);
  2148. X    }    
  2149. #else
  2150. X    signal(SIGTSTP, SIG_DFL);
  2151. #ifdef BSD
  2152. X    sigsetmask (sigblock(0) & ~(1 << (SIGTSTP -1)));
  2153. #endif
  2154. #endif
  2155. X
  2156. X    kill (0, SIGTSTP);
  2157. X
  2158. #ifdef POSIX_JOB_CONTROL
  2159. X    sigemptyset (&group_act.sa_mask);
  2160. #if defined(SA_RESTART) 
  2161. X        group_act.sa_flags = SA_RESTART | SA_RESETHAND;
  2162. #else
  2163. X        group_act.sa_flags = 0;
  2164. #endif
  2165. X    group_act.sa_handler = group_suspend;
  2166. X    sigaction (SIGTSTP, &group_act, 0L);
  2167. #else
  2168. X    signal (SIGTSTP, group_suspend);
  2169. #endif
  2170. X
  2171. X    if (! update) {
  2172. X        Raw (TRUE);
  2173. X    }
  2174. X
  2175. X    group_resize (0);        
  2176. }
  2177. X
  2178. X
  2179. /* ARGSUSED0 */
  2180. void page_suspend (sig)
  2181. X    int sig;
  2182. {
  2183. X
  2184. X    Raw (FALSE);
  2185. X    putchar ('\n');
  2186. X
  2187. #ifdef POSIX_JOB_CONTROL
  2188. X    {
  2189. X        sigset_t stopmask;
  2190. X        sigemptyset (&stopmask);
  2191. X        sigprocmask (SIG_SETMASK, &stopmask, NULL);
  2192. X    }    
  2193. #else
  2194. X    signal(SIGTSTP, SIG_DFL);
  2195. #ifdef BSD
  2196. X    sigsetmask (sigblock(0) & ~(1 << (SIGTSTP -1)));
  2197. #endif
  2198. #endif
  2199. X
  2200. X    kill (0, SIGTSTP);
  2201. X
  2202. #ifdef POSIX_JOB_CONTROL
  2203. X    sigemptyset (&page_act.sa_mask);
  2204. #if defined(SA_RESTART) 
  2205. X        page_act.sa_flags = SA_RESTART | SA_RESETHAND;
  2206. #else
  2207. X        page_act.sa_flags = 0;
  2208. #endif
  2209. X    page_act.sa_handler = page_suspend;
  2210. X    sigaction (SIGTSTP, &page_act, 0L);
  2211. #else
  2212. X    signal (SIGTSTP, page_suspend);
  2213. #endif
  2214. X
  2215. X    mail_setup ();
  2216. X
  2217. X    if (! update) {
  2218. X        Raw (TRUE);
  2219. X    }
  2220. X
  2221. X    page_resize (0);        
  2222. }
  2223. X
  2224. X
  2225. /* ARGSUSED0 */
  2226. void thread_suspend (sig)
  2227. X    int sig;
  2228. {
  2229. X    Raw (FALSE);
  2230. X    putchar ('\n');
  2231. X
  2232. #ifdef POSIX_JOB_CONTROL
  2233. X    {
  2234. X        sigset_t stopmask;
  2235. X        sigemptyset (&stopmask);
  2236. X        sigprocmask (SIG_SETMASK, &stopmask, NULL);
  2237. X    }    
  2238. #else
  2239. X    signal (SIGTSTP, SIG_DFL);
  2240. #ifdef BSD
  2241. X    sigsetmask (sigblock(0) & ~(1 << (SIGTSTP -1)));
  2242. #endif
  2243. #endif
  2244. X
  2245. X    kill (0, SIGTSTP);
  2246. X
  2247. #ifdef POSIX_JOB_CONTROL
  2248. X    sigemptyset (&thread_act.sa_mask);
  2249. #if defined(SA_RESTART) 
  2250. X        thread_act.sa_flags = SA_RESTART | SA_RESETHAND;
  2251. #else
  2252. X        thread_act.sa_flags = 0;
  2253. #endif
  2254. X    thread_act.sa_handler = thread_suspend;
  2255. X    sigaction (SIGTSTP, &thread_act, 0L);
  2256. #else
  2257. X    signal (SIGTSTP, thread_suspend);
  2258. #endif
  2259. X
  2260. X    if (! update) {
  2261. X        Raw (TRUE);
  2262. X    }
  2263. X    
  2264. X    thread_resize (0);        
  2265. }
  2266. X
  2267. X
  2268. /* ARGSUSED0 */
  2269. void rcfile_suspend (sig)
  2270. X    int sig;
  2271. {
  2272. X    Raw (FALSE);
  2273. X    putchar ('\n');
  2274. X
  2275. #ifdef POSIX_JOB_CONTROL
  2276. X    {
  2277. X        sigset_t stopmask;
  2278. X        sigemptyset (&stopmask);
  2279. X        sigprocmask (SIG_SETMASK, &stopmask, NULL);
  2280. X    }    
  2281. #else
  2282. X    signal(SIGTSTP, SIG_DFL);
  2283. #ifdef BSD
  2284. X    sigsetmask (sigblock(0) & ~(1 << (SIGTSTP -1)));
  2285. #endif
  2286. #endif
  2287. X
  2288. X    kill (0, SIGTSTP);
  2289. X
  2290. #ifdef POSIX_JOB_CONTROL
  2291. X    sigemptyset (&rcfile_act.sa_mask);
  2292. #if defined(SA_RESTART) 
  2293. X        rcfile_act.sa_flags = SA_RESTART | SA_RESETHAND;
  2294. #else
  2295. X        rcfile_act.sa_flags = 0;
  2296. #endif
  2297. X    rcfile_act.sa_handler = rcfile_suspend;
  2298. X    sigaction (SIGTSTP, &rcfile_act, 0L);
  2299. #else
  2300. X    signal (SIGTSTP, rcfile_suspend);
  2301. #endif
  2302. X
  2303. X    Raw (TRUE);
  2304. X    show_rcfile_menu ();    
  2305. }
  2306. X
  2307. #endif /* SIGTSTP */    
  2308. X
  2309. X
  2310. /* ARGSUSED0 */
  2311. void art_resize (sig)
  2312. X    int sig;
  2313. {
  2314. X    char buf[LEN];
  2315. X
  2316. #ifdef SIGWINCH
  2317. X    set_win_size (&LINES, &COLS);
  2318. X    signal (SIGWINCH, art_resize);
  2319. #endif
  2320. X    mail_setup ();
  2321. X    ClearScreen ();
  2322. X    sprintf (buf, txt_group, glob_art_group);
  2323. X    wait_message (buf);
  2324. }
  2325. X
  2326. X
  2327. /* ARGSUSED0 */
  2328. void main_resize (sig)
  2329. X    int sig;
  2330. {
  2331. #ifdef SIGWINCH
  2332. X    set_win_size (&LINES, &COLS);
  2333. X    signal (SIGWINCH, main_resize);
  2334. #endif
  2335. X    mail_setup ();
  2336. }
  2337. X
  2338. X
  2339. /* ARGSUSED0 */
  2340. void select_resize (sig)
  2341. X    int sig;
  2342. {
  2343. #ifdef SIGWINCH
  2344. X    set_win_size (&LINES, &COLS);
  2345. X    signal (SIGWINCH, select_resize);
  2346. #endif
  2347. X    
  2348. #ifndef USE_CLEARSCREEN
  2349. X    ClearScreen ();
  2350. #endif
  2351. X    mail_setup ();
  2352. X    group_selection_page ();
  2353. }
  2354. X
  2355. X
  2356. /* ARGSUSED0 */
  2357. void group_resize (sig)
  2358. X    int sig;
  2359. {
  2360. #ifdef SIGWINCH
  2361. X    set_win_size (&LINES, &COLS);
  2362. X    signal (SIGWINCH, group_resize);
  2363. #endif
  2364. X    
  2365. #ifndef USE_CLEARSCREEN
  2366. X    ClearScreen ();
  2367. #endif
  2368. X    mail_setup ();
  2369. X    show_group_page (glob_group);
  2370. }
  2371. X
  2372. X
  2373. /* ARGSUSED0 */
  2374. void page_resize (sig)
  2375. X    int sig;
  2376. {
  2377. #ifdef SIGWINCH
  2378. X    set_win_size (&LINES, &COLS);
  2379. X    signal (SIGWINCH, page_resize);
  2380. #endif
  2381. X    
  2382. #ifndef USE_CLEARSCREEN
  2383. X    ClearScreen ();
  2384. #endif
  2385. X    redraw_page (glob_respnum, glob_page_group);
  2386. }
  2387. X
  2388. X
  2389. /* ARGSUSED0 */
  2390. void thread_resize (sig)
  2391. X    int sig;
  2392. {
  2393. #ifdef SIGWINCH
  2394. X    set_win_size (&LINES, &COLS);
  2395. X    signal (SIGWINCH, thread_resize);
  2396. #endif
  2397. X    
  2398. #ifndef USE_CLEARSCREEN
  2399. X    ClearScreen ();
  2400. #endif
  2401. X    mail_setup ();
  2402. X    show_thread_page ();
  2403. }
  2404. SHAR_EOF
  2405. chmod 0600 signal.c ||
  2406. echo 'restore of signal.c failed'
  2407. Wc_c="`wc -c < 'signal.c'`"
  2408. test 12160 -eq "$Wc_c" ||
  2409.     echo 'signal.c: original size 12160, current size' "$Wc_c"
  2410. rm -f _shar_wnt_.tmp
  2411. fi
  2412. # ============= thread.c ==============
  2413. if test -f 'thread.c' -a X"$1" != X"-c"; then
  2414.     echo 'x - skipping thread.c (File already exists)'
  2415.     rm -f _shar_wnt_.tmp
  2416. else
  2417. > _shar_wnt_.tmp
  2418. echo 'x - extracting thread.c (Text)'
  2419. sed 's/^X//' << 'SHAR_EOF' > 'thread.c' &&
  2420. /*
  2421. X *  Project   : tin - a threaded Netnews reader
  2422. X *  Module    : thread.c
  2423. X *  Author    : I.Lea
  2424. X *  Created   : 01-04-91
  2425. X *  Updated   : 22-03-92
  2426. X *  Notes     :
  2427. X *  Copyright : (c) Copyright 1991-92 by Iain Lea
  2428. X *              You may  freely  copy or  redistribute  this software,
  2429. X *              so  long as there is no profit made from its use, sale
  2430. X *              trade or  reproduction.  You may not change this copy-
  2431. X *              right notice, and it must be included in any copy made
  2432. X */
  2433. X
  2434. #include    "tin.h"
  2435. X
  2436. extern int index_point;
  2437. int threaded_on_subject;
  2438. static int top_thread = 0;
  2439. static int thread_index_point = 0;
  2440. static int thread_basenote = 0;
  2441. SHAR_EOF
  2442. true || echo 'restore of thread.c failed'
  2443. fi
  2444. echo 'End of tin1.1 part 10'
  2445. echo 'File thread.c is continued in part 11'
  2446. echo 11 > _shar_seq_.tmp
  2447. exit 0
  2448.  
  2449. --
  2450. NAME   Iain Lea 
  2451. EMAIL  iain%anl433.uucp@germany.eu.net
  2452. SNAIL  Siemens AG, ANL A433SZ, Gruendlacher Str. 248, 8510 Fuerth, Germany.
  2453. PHONE  +49-911-3089-407 (work) +49-911-331963 (home) +49-911-3089-290 (FAX)  
  2454. -- 
  2455.  Dr. med. dipl.-math Dieter Becker           Tel.: (0 / +49) 6841 - 16 3046
  2456.  Medizinische Universitaets- und Poliklinik  Fax.: (0 / +49) 6841 - 16 3369
  2457.  Innere Medizin III                         
  2458.  D - 6650 Homburg / Saar                     Email: becker@med-in.uni-sb.de
  2459. exit 0 # Just in case...
  2460.