home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3963 < prev    next >
Encoding:
Internet Message Format  |  1991-09-04  |  49.7 KB

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