home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #31 / NN_1992_31.iso / spool / de / comp / sources / os9 / 13 < prev    next >
Encoding:
Internet Message Format  |  1992-12-24  |  25.3 KB

  1. Xref: sparky de.comp.sources.os9:13 comp.os.os9:1558
  2. Path: sparky!uunet!elroy.jpl.nasa.gov!ames!sun-barr!news2me.EBay.Sun.COM!seven-up.East.Sun.COM!sungy!stasys!stasys!not-for-mail
  3. From: frank.kaefer@stasys.sta.sub.org (Frank Kaefer)
  4. Newsgroups: de.comp.sources.os9,comp.os.os9
  5. Subject: Tass for OS-9 Part03/03
  6. Message-ID: <1hccjhINN778@stasys.sta.sub.org>
  7. Date: 24 Dec 92 13:05:53 GMT
  8. Sender: news@stasys.sta.sub.org
  9. Followup-To: de.comp.sources.d
  10. Organization: Stasys News Server, Starnberg, Germany
  11. Lines: 1217
  12. Approved: frank.kaefer@stasys.sta.sub.org (Frank Kaefer)
  13. NNTP-Posting-Host: stasys.sta.sub.org
  14.  
  15. Submitted-by: Ulrich Dessauer <ud@Nightmare.ddt.sub.org>
  16. Archive-name: tass/part03
  17.  
  18. : ----- Cut here ----- Cut here ----- Cut here ----- Cut here -----
  19. : Use  sh filename  to extract shell archive
  20. : This shell archive contains following files:
  21. :     'prompt.c                                     2308 bytes'
  22. :     'screen.c                                      729 bytes'
  23. :     'select.c                                    13169 bytes'
  24. :     'sigs.c                                       1277 bytes'
  25. :     'tass.h                                       3575 bytes'
  26. :     'time.c                                       1094 bytes'
  27. if test -f 'prompt.c' ; then
  28.   echo 'File prompt.c already exists, overwriting it'
  29.   del 'prompt.c'
  30. fi
  31. echo Extracting \"'prompt.c'\"
  32. sed "s/^X//" >'prompt.c' <<'__END__OF__THIS__FILE__'
  33. X
  34. X#include    <stdio.h>
  35. X#include    "tass.h"
  36. X
  37. X
  38. X/*
  39. X *  parse_num
  40. X *  get a number from the user
  41. X *  Return -1 if missing or bad number typed
  42. X */
  43. X
  44. Xparse_num(ch, prompt)
  45. Xchar ch;
  46. Xchar *prompt;
  47. X{
  48. X    char buf[40];
  49. X    int len;
  50. X    int i;
  51. X    int num;
  52. X
  53. X    MoveCursor(LINES,0);
  54. X    printf("%s %c",prompt,ch);
  55. X    fflush(stdout);
  56. X    buf[0] = ch;
  57. X    buf[1] = '\0';
  58. X    len = 1;
  59. X    ch = ReadCh();
  60. X    while (ch != '\n'&& ch != '\r') {
  61. X        if (ch >= '0' && ch <= '9' && len < 4) {
  62. X            buf[len++] = ch;
  63. X            buf[len] = '\0';
  64. X            putchar(ch);
  65. X        } else if (ch == 8 || ch == 127) {
  66. X            if (len) {
  67. X                len--;
  68. X                buf[len] = '\0';
  69. X                putchar('\b');
  70. X                putchar(' ');
  71. X                putchar('\b');
  72. X            } else {
  73. X                MoveCursor(LINES, 0);
  74. X                CleartoEOLN();
  75. X                return(-1);
  76. X            }
  77. X        } else if (ch == 21) {    /* control-U    */
  78. X            for (i = len;i>0;i--) {
  79. X                putchar('\b');
  80. X                putchar(' ');
  81. X                putchar('\b');
  82. X            }
  83. X            buf[0] = '\0';
  84. X            len = 0;
  85. X        } else
  86. X            putchar(7);
  87. X        fflush(stdout);
  88. X        ch = ReadCh();
  89. X    }
  90. X
  91. X    MoveCursor(LINES, 0);
  92. X    CleartoEOLN();
  93. X
  94. X    if (len) {
  95. X        num = atoi(buf);
  96. X        return(num);
  97. X    } else
  98. X        return(-1);
  99. X}
  100. X
  101. X
  102. X/*
  103. X *  parse_string
  104. X *  get a string from the user
  105. X *  Return TRUE if a valid string was typed, FALSE otherwise
  106. X */
  107. X
  108. Xparse_string(prompt, buf)
  109. Xchar *prompt;
  110. Xchar *buf;
  111. X{
  112. Xint len;
  113. Xint i;
  114. Xchar ch;
  115. X
  116. X    clear_message();
  117. X    MoveCursor(LINES,0);
  118. X    printf("%s", prompt);
  119. X    fflush(stdout);
  120. X    buf[0] = '\0';
  121. X    len = 0;
  122. X    ch = ReadCh();
  123. X    while (ch != '\n' && ch != '\r') {
  124. X        if (ch >= ' ' && len < 60) {
  125. X            buf[len++] = ch;
  126. X            buf[len] = '\0';
  127. X            putchar(ch);
  128. X        } else if (ch == 8 || ch == 127) {
  129. X            if (len) {
  130. X                len--;
  131. X                buf[len] = '\0';
  132. X                putchar('\b');
  133. X                putchar(' ');
  134. X                putchar('\b');
  135. X            } else {
  136. X                MoveCursor(LINES, 0);
  137. X                CleartoEOLN();
  138. X                return(FALSE);
  139. X            }
  140. X        } else if (ch == 21) {    /* control-U    */
  141. X            for (i = len;i>0;i--) {
  142. X                putchar('\b');
  143. X                putchar(' ');
  144. X                putchar('\b');
  145. X            }
  146. X            buf[0] = '\0';
  147. X            len = 0;
  148. X        } else
  149. X            putchar(7);
  150. X        fflush(stdout);
  151. X        ch = ReadCh();
  152. X    }
  153. X    MoveCursor(LINES,0);
  154. X    CleartoEOLN();
  155. X
  156. X    return TRUE;
  157. X}
  158. X
  159. X
  160. Xprompt_yn(prompt)
  161. Xchar *prompt;
  162. X{
  163. X    char ch;
  164. X
  165. X    clear_message();
  166. X    MoveCursor(LINES,0);
  167. X    printf("%s", prompt);
  168. X    fflush(stdout);
  169. X
  170. X    ch = ReadCh();
  171. X    clear_message();
  172. X
  173. X    if (ch == 'y' || ch == 'Y')
  174. X        return TRUE;
  175. X
  176. X    return FALSE;
  177. X}
  178. X
  179. X
  180. Xcontinue_prompt() {
  181. X
  182. X    printf("-Hit return to continue-");
  183. X    fflush(stdout);
  184. X    while (ReadCh() != '\n') ;
  185. X}
  186. X
  187. X
  188. __END__OF__THIS__FILE__
  189. if test -f 'screen.c' ; then
  190.   echo 'File screen.c already exists, overwriting it'
  191.   del 'screen.c'
  192. fi
  193. echo Extracting \"'screen.c'\"
  194. sed "s/^X//" >'screen.c' <<'__END__OF__THIS__FILE__'
  195. X
  196. X#include    <stdio.h>
  197. X#include    "tass.h"
  198. X
  199. X
  200. X
  201. Xinfo_message(msg)
  202. Xchar *msg;
  203. X{
  204. X    clear_message();      /* Clear any old messages hanging around */
  205. X    center_line(LINES, msg);  /* center the message at screen bottom  */
  206. X    MoveCursor(LINES, 0);
  207. X}
  208. X
  209. X
  210. Xclear_message()
  211. X{
  212. X    MoveCursor(LINES, 0);
  213. X    CleartoEOLN();
  214. X}
  215. X
  216. X
  217. Xcenter_line(line, str)
  218. Xint line;
  219. Xchar *str;
  220. X{
  221. Xint pos;
  222. X
  223. X    pos = (COLS - strlen(str)) / 2;
  224. X    MoveCursor(line, pos);
  225. X    printf("%s", str);
  226. X    fflush(stdout);
  227. X}
  228. X
  229. X
  230. Xdraw_arrow(line)
  231. Xint line;
  232. X{
  233. X    MoveCursor(line, 0);
  234. X    printf("->");
  235. X    fflush(stdout);
  236. X    MoveCursor(LINES, 0);
  237. X}
  238. X
  239. Xerase_arrow(line)
  240. Xint line;
  241. X{
  242. X    MoveCursor(line, 0);
  243. X    printf("  ");
  244. X    fflush(stdout);
  245. X}
  246. X
  247. X#ifdef    REGEXP
  248. Xvoid
  249. Xregerror (s)
  250. Xchar *s;
  251. X{
  252. X    info_message (s);
  253. X}
  254. X#endif    /* REGEXP */
  255. X
  256. __END__OF__THIS__FILE__
  257. if test -f 'select.c' ; then
  258.   echo 'File select.c already exists, overwriting it'
  259.   del 'select.c'
  260. fi
  261. echo Extracting \"'select.c'\"
  262. sed "s/^X//" >'select.c' <<'__END__OF__THIS__FILE__'
  263. X
  264. X#include    <stdio.h>
  265. X#include    <signal.h>
  266. X#ifdef    REGEXP
  267. X#include    <regexp.h>
  268. X#endif    /* REGEXP */
  269. X#include    "tass.h"
  270. X
  271. X
  272. Xint first_group_on_screen;
  273. Xint last_group_on_screen;
  274. Xint cur_groupnum = 0;
  275. Xextern int index_point;
  276. Xint space_mode;
  277. Xextern char *cvers;
  278. X
  279. Xchar group_search_string[LEN+1];
  280. X
  281. X
  282. X
  283. X#ifdef SIGTSTP
  284. Xvoid
  285. Xselect_susp(i)
  286. Xint i;
  287. X{
  288. X
  289. X    Raw(FALSE);
  290. X    putchar('\n');
  291. X    signal(SIGTSTP, SIG_DFL);
  292. X    kill(0, SIGTSTP);
  293. X
  294. X    signal(SIGTSTP, select_susp);
  295. X    Raw(TRUE);
  296. X    mail_setup();
  297. X    group_selection_page(-1, FALSE);
  298. X}
  299. X#endif
  300. X
  301. X
  302. Xselection_index()
  303. X{
  304. X    char ch;
  305. X    int n;
  306. X    int i;
  307. X    char buf[200];
  308. X
  309. X    group_selection_page(-1, FALSE);    /* display group selection page */
  310. X
  311. X    while (1) {
  312. X        if ((n = ReadCh()) == EOF)
  313. X            longjmp (jmp_buffer, 1);
  314. X        ch = (char) n;
  315. X    
  316. X        if (ch > '0' && ch <= '9') {
  317. X            prompt_group_num(ch);
  318. X        } else switch (ch) {
  319. X            case 'c':    /* catchup--mark all articles as read */
  320. X                if (prompt_yn("Mark group as read? (y/n): ")) {
  321. X                unread[cur_groupnum] = 0;
  322. X                mark_group_read(
  323. X                        active[my_group[cur_groupnum]].name,
  324. X                        my_group[cur_groupnum]);
  325. X                group_selection_page(cur_groupnum, TRUE);
  326. X                }
  327. X                break;
  328. X
  329. X            case ctrl('K'):
  330. X                if (local_top <= 0) {
  331. X                    info_message("No groups to delete");
  332. X                    break;
  333. X                }
  334. X
  335. X                delete_group(
  336. X                    active[my_group[cur_groupnum]].name);
  337. X                active[my_group[cur_groupnum]].flag = NOTGOT;
  338. X
  339. X                local_top--;
  340. X                for (i = cur_groupnum; i < local_top; i++) {
  341. X                    my_group[i] = my_group[i+1];
  342. X                    unread[i] = unread[i+1];
  343. X                }
  344. X                if (cur_groupnum >= local_top)
  345. X                    cur_groupnum = local_top - 1;
  346. X
  347. X                group_selection_page(cur_groupnum, FALSE);
  348. X                break;
  349. X
  350. X            case ctrl('Y'):
  351. X                undel_group();
  352. X                group_selection_page(cur_groupnum, FALSE);
  353. X                break;
  354. X
  355. X            case 'I':        /* toggle inverse video */
  356. X                inverse_okay = !inverse_okay;
  357. X                if (inverse_okay)
  358. X                    info_message("Inverse video enabled");
  359. X                else
  360. X                    info_message("Inverse video disabled");
  361. X                break;
  362. X
  363. X            case ctrl('R'):    /* reset .newsrc */
  364. X                if (prompt_yn("Reset newsrc? (y/n): ")) {
  365. X                reset_newsrc();
  366. X                cur_groupnum = 0;
  367. X                group_selection_page(-1, FALSE);
  368. X                }
  369. X                break;
  370. X
  371. X            case '$':    /* reread .newsrc, no unsub groups */
  372. X                cur_groupnum = 0;
  373. X                local_top = 0;
  374. X                for (i = 0; i < num_active; i++)
  375. X                    active[i].flag = NOTGOT;
  376. X                read_newsrc(TRUE);
  377. X                group_selection_page(-1, FALSE);
  378. X                break;
  379. X
  380. X            case 's':    /* subscribe to current group */
  381. X                MoveCursor(INDEX_TOP +
  382. X                (cur_groupnum-first_group_on_screen), 3);
  383. X                putchar(' ');
  384. X                fflush(stdout);
  385. X                MoveCursor(LINES, 0);
  386. X
  387. X                subscribe(active[my_group[cur_groupnum]].name,
  388. X                    ':', my_group[cur_groupnum], FALSE);
  389. X                sprintf(buf, "subscribed to %s",
  390. X                    active[my_group[cur_groupnum]].name);
  391. X                info_message(buf);
  392. X                break;
  393. X
  394. X            case 'u':    /* unsubscribe to current group */
  395. X                MoveCursor(INDEX_TOP +
  396. X                (cur_groupnum-first_group_on_screen), 3);
  397. X                putchar('u');
  398. X                fflush(stdout);
  399. X                MoveCursor(LINES, 0);
  400. X
  401. X                subscribe(active[my_group[cur_groupnum]].name,
  402. X                    '!', my_group[cur_groupnum], FALSE);
  403. X                sprintf(buf, "unsubscribed to %s",
  404. X                    active[my_group[cur_groupnum]].name);
  405. X                info_message(buf);
  406. X                break;
  407. X
  408. X            case ' ':
  409. X                clear_message();
  410. X                break;
  411. X
  412. X            case '\t':
  413. X                for (i = cur_groupnum; i < local_top; i++)
  414. X                    if (unread[i] != 0)
  415. X                        break;
  416. X                if (i >= local_top) {
  417. X                    info_message("No more groups to read");
  418. X                    break;
  419. X                }
  420. X
  421. X                erase_group_arrow();
  422. X                cur_groupnum = i;
  423. X                if (cur_groupnum >= last_group_on_screen)
  424. X                    group_selection_page(-1, FALSE);
  425. X                else
  426. X                    draw_group_arrow();
  427. X                space_mode = TRUE;
  428. X                goto go_into_group;
  429. X
  430. X            case 'g':    /* prompt for a new group name */
  431. X                n = choose_new_group();
  432. X                if (n >= 0) {
  433. X                    erase_group_arrow();
  434. X                    cur_groupnum = n;
  435. X                    if (cur_groupnum < first_group_on_screen
  436. X                    || cur_groupnum >= last_group_on_screen)
  437. X                        group_selection_page(-1, FALSE);
  438. X                    else
  439. X                        draw_group_arrow();
  440. X                }
  441. X                break;
  442. X
  443. X#ifdef    USE_ARROW
  444. X            case 27:    /* (ESC) common arrow keys */
  445. X                ch = ReadCh();
  446. X                if (ch == '[' || ch == 'O')
  447. X                    ch = ReadCh();
  448. X                switch (ch) {
  449. X                case 'A':
  450. X                case 'D':
  451. X                case 'i':
  452. X                    goto select_up;
  453. X
  454. X                case 'B':
  455. X                case 'I':
  456. X                case 'C':
  457. X                    goto select_down;
  458. X                }
  459. X                break;
  460. X#endif    /* USE_ARROW */
  461. X
  462. X            case 'y':    /* pull in rest of groups from active */
  463. X                n = local_top;
  464. X                for (i = 0; i < num_active; i++)
  465. X                    active[i].flag = NOTGOT;
  466. X                read_newsrc(FALSE);
  467. X                for (i = 0; i < num_active; i++)
  468. X                    if (active[i].flag & NOTGOT) {
  469. X                        active[i].flag &= ~NOTGOT;
  470. X                        my_group[local_top] = i;
  471. X                        unread[local_top] = -1;
  472. X                        local_top++;
  473. X                    }
  474. X                if (n < local_top) {
  475. X                    sprintf(buf, "Added %d group%s",
  476. X                        local_top - n,
  477. X                        local_top - n == 1 ? "" : "s");
  478. X                    group_selection_page(-1, FALSE);
  479. X                    info_message(buf);
  480. X                } else
  481. X                    info_message("No more groups to yank in");
  482. X                break;
  483. X
  484. X            case ctrl('U'):        /* page up */
  485. X            case ctrl('Z'):        /* full page up */
  486. X                erase_group_arrow();
  487. X                cur_groupnum -= (ch == ctrl('Z')) ?
  488. X                        NOTESLINES :
  489. X                        NOTESLINES / 2;
  490. X                if (cur_groupnum < 0)
  491. X                    cur_groupnum = 0;
  492. X                if (cur_groupnum < first_group_on_screen
  493. X                ||  cur_groupnum >= last_group_on_screen)
  494. X                    group_selection_page(-1, FALSE);
  495. X                else
  496. X                    draw_group_arrow();
  497. X                break;
  498. X
  499. X            case ctrl('D'):        /* page down */
  500. X            case ctrl('V'):        /* full page down */
  501. X                erase_group_arrow();
  502. X                cur_groupnum += (ch == ctrl ('V')) ?
  503. X                        NOTESLINES :
  504. X                        NOTESLINES / 2;
  505. X                if (cur_groupnum >= local_top)
  506. X                    cur_groupnum = local_top - 1;
  507. X
  508. X                if (cur_groupnum <= first_group_on_screen
  509. X                ||  cur_groupnum >= last_group_on_screen)
  510. X                    group_selection_page(-1, FALSE);
  511. X                else
  512. X                    draw_group_arrow();
  513. X                break;
  514. X
  515. X            case '!':
  516. X                shell_escape();
  517. X                group_selection_page(-1, FALSE);
  518. X                break;
  519. X
  520. X            case 'v':
  521. X                info_message(cvers);
  522. X                break;
  523. X
  524. X            case ctrl('N'):        /* line down */
  525. X            case 'j':
  526. X#ifdef    USE_ARROW
  527. Xselect_down:
  528. X#endif    /* USE_ARROW */
  529. X                if (cur_groupnum + 1 >= local_top)
  530. X                    break;
  531. X
  532. X                if (cur_groupnum + 1 >= last_group_on_screen) {
  533. X                    cur_groupnum++;
  534. X                    group_selection_page(-1, FALSE);
  535. X                } else {
  536. X                    erase_group_arrow();
  537. X                    cur_groupnum++;
  538. X                    draw_group_arrow();
  539. X                }
  540. X                break;
  541. X
  542. X            case ctrl('P'):        /* line up */
  543. X            case 'k':
  544. X#ifdef    USE_ARROW
  545. Xselect_up:
  546. X#endif    /* USE_ARROW */
  547. X                if (!cur_groupnum)
  548. X                    break;
  549. X
  550. X                if (cur_groupnum <= first_group_on_screen) {
  551. X                    cur_groupnum--;
  552. X                    group_selection_page(-1, FALSE);
  553. X                } else {
  554. X                    erase_group_arrow();
  555. X                    cur_groupnum--;
  556. X                    draw_group_arrow();
  557. X                }
  558. X                break;
  559. X
  560. X            case 't':        /* redraw */
  561. X            case ctrl('W'):
  562. X            case ctrl('L'):
  563. X                group_selection_page(-1, FALSE);
  564. X                break;
  565. X
  566. X#ifndef    OSK
  567. X            case '\r':    /* go into group */
  568. X#else    /* OSK */
  569. X            case '\l':    /* go into group */
  570. X#endif    /* OSK */
  571. X            case '\n':
  572. X            case ctrl('F'):    /* cursor key */
  573. X                space_mode = FALSE;
  574. Xgo_into_group:
  575. X                clear_message();
  576. X                index_point = -1;
  577. X                do {
  578. X                    group_page(
  579. X                      active[my_group[cur_groupnum]].name);
  580. X                } while (index_point == -3);
  581. X                group_selection_page(-1, FALSE);
  582. X                break;
  583. X
  584. X            case '/':    /* search forward */
  585. X                search_group(TRUE);
  586. X                break;
  587. X
  588. X            case '?':    /* search backward */
  589. X                search_group(FALSE);
  590. X                break;
  591. X
  592. X            case 'q':    /* quit */
  593. X            case ctrl('B'):    /* cursor key */
  594. X                tass_done(0);
  595. X
  596. X            case 'h':
  597. X                tass_select_help();
  598. X                group_selection_page(-1, FALSE);
  599. X                break;
  600. X
  601. X            default:
  602. X                info_message("Bad command.  Type 'h' for help.");
  603. X        }
  604. X    }
  605. X}
  606. X
  607. X
  608. Xgroup_selection_page(ind, justone) 
  609. Xint ind;
  610. Xint justone;
  611. X{
  612. X    int i;
  613. X    int n;
  614. X    char new[10];
  615. X    char subs;
  616. X
  617. X#ifdef SIGTSTP
  618. X    signal(SIGTSTP, select_susp);
  619. X#endif
  620. X
  621. X    if (ind < 0) {
  622. X        ClearScreen();
  623. X        printf("%s\r\012", nice_time()); /* print time in upper left */
  624. X    }
  625. X
  626. X    show_mail ();
  627. X
  628. X    if (ind < 0)
  629. X        center_line(1, "Group Selection");
  630. X    MoveCursor(INDEX_TOP, 0);
  631. X
  632. X    first_group_on_screen = (cur_groupnum / NOTESLINES) * NOTESLINES;
  633. X
  634. X    last_group_on_screen = first_group_on_screen + NOTESLINES;
  635. X    if (last_group_on_screen >= local_top)
  636. X        last_group_on_screen = local_top;
  637. X
  638. X    for (i = first_group_on_screen; i < last_group_on_screen; i++) {
  639. X        if ((ind >= 0) && (ind > i))
  640. X            continue;
  641. X        switch (unread[i]) {
  642. X        case -2:
  643. X            strcpy(new, "?   ");
  644. X            break;
  645. X
  646. X        case -1:
  647. X            strcpy(new, "-   ");
  648. X            break;
  649. X
  650. X        case 0:
  651. X            strcpy(new, "    ");
  652. X            break;
  653. X
  654. X        default:
  655. X            sprintf(new, "%-4d", unread[i]);
  656. X        }
  657. X
  658. X        n = my_group[i];
  659. X        if (active[n].flag & SUBS)    /* subscribed? */
  660. X            subs = ' ';
  661. X        else
  662. X            subs = 'u';    /* u next to unsubscribed groups */
  663. X
  664. X        MoveCursor (INDEX_TOP + i - first_group_on_screen, 3);
  665. X        printf("%c %4d", subs, i+1);
  666. X        if (!justone)
  667. X            printf (" %s", active[n].name);
  668. X        MoveCursor (INDEX_TOP + i - first_group_on_screen, COLS - 8);
  669. X        printf (" %s", new);
  670. X        CleartoEOLN ();
  671. X        if ((ind >= 0) && justone && (ind == i))
  672. X            break;
  673. X    }
  674. X
  675. X    if (last_group_on_screen < first_group_on_screen + NOTESLINES) {
  676. X        MoveCursor (INDEX_TOP + last_group_on_screen + 1 - first_group_on_screen, 0);
  677. X        CleartoEOLN ();
  678. X    }
  679. X
  680. X    draw_group_arrow();
  681. X}
  682. X
  683. X
  684. Xprompt_group_num(ch)
  685. Xchar ch;
  686. X{
  687. Xint num;
  688. X
  689. X    clear_message();
  690. X
  691. X    if ((num = parse_num(ch, "Select group> ")) == -1) {
  692. X        clear_message();
  693. X        return FALSE;
  694. X    }
  695. X    num--;        /* index from 0 (internal) vs. 1 (user) */
  696. X
  697. X    if (num >= local_top)
  698. X        num = local_top - 1;
  699. X
  700. X    if (num >= first_group_on_screen
  701. X    &&  num < last_group_on_screen) {
  702. X        erase_group_arrow();
  703. X        cur_groupnum = num;
  704. X        draw_group_arrow();
  705. X    } else {
  706. X        cur_groupnum = num;
  707. X        group_selection_page(-1, FALSE);
  708. X    }
  709. X
  710. X    return TRUE;
  711. X}
  712. X
  713. Xerase_group_arrow() {
  714. X    erase_arrow(INDEX_TOP + (cur_groupnum-first_group_on_screen) );
  715. X}
  716. X
  717. Xdraw_group_arrow() {
  718. X    draw_arrow(INDEX_TOP + (cur_groupnum-first_group_on_screen) );
  719. X}
  720. X
  721. Xvoid
  722. Xsearch_group(forward)
  723. Xint forward;
  724. X{
  725. X    char buf[LEN+1];
  726. X    int i;
  727. X#ifndef    REGEXP
  728. X    extern char *regcmp();
  729. X    extern char *regex();
  730. X    char *re;
  731. X#else    /* REGEXP */
  732. X    regexp *re;
  733. X#endif    /* REGEXP */
  734. X    char *prompt;
  735. X
  736. X    clear_message();
  737. X
  738. X    if (forward)
  739. X        prompt = "/";
  740. X    else
  741. X        prompt = "?";
  742. X
  743. X    if (!parse_string(prompt, buf))
  744. X        return;
  745. X
  746. X    if (strlen(buf))
  747. X        strcpy(group_search_string, buf);
  748. X    else if (!strlen(group_search_string)) {
  749. X        info_message("No search pattern");
  750. X        return;
  751. X    }
  752. X
  753. X    i = cur_groupnum;
  754. X
  755. X    glob_name(group_search_string, buf);
  756. X
  757. X#ifndef    REGEXP
  758. X    if ((re = regcmp(buf, NULL)) == NULL) {
  759. X#else    /* REGEXP */
  760. X    if ((re = regcomp (buf)) == NULL) {
  761. X#endif    /* REGEXP */
  762. X        info_message("Bad search pattern");
  763. X        return;
  764. X    }
  765. X
  766. X    do {
  767. X        if (forward)
  768. X            i++;
  769. X        else
  770. X            i--;
  771. X
  772. X        if (i >= local_top)
  773. X            i = 0;
  774. X        if (i < 0)
  775. X            i = local_top - 1;
  776. X
  777. X#ifndef    REGEXP
  778. X        if (regex(re, active[my_group[i]].name) != NULL) {
  779. X#else    /* REGEXP */
  780. X        if (regexec (re, active[my_group[i]].name)) {
  781. X#endif    /* REGEXP */
  782. X            if (i >= first_group_on_screen
  783. X            &&  i < last_group_on_screen) {
  784. X                erase_group_arrow();
  785. X                cur_groupnum = i;
  786. X                draw_group_arrow();
  787. X            } else {
  788. X                cur_groupnum = i;
  789. X                group_selection_page(-1, FALSE);
  790. X            }
  791. X            return;
  792. X        }
  793. X    } while (i != cur_groupnum);
  794. X
  795. X    info_message("No match");
  796. X}
  797. X
  798. X
  799. Xtass_select_help() {
  800. X
  801. X    ClearScreen();
  802. X    center_line(0, TASS_HEADER);
  803. X    center_line(1, "Group Selection Commands");
  804. X
  805. X    MoveCursor(3, 0);
  806. X
  807. X    printf("4        Select group 4\r\012");
  808. X    printf("^D, ^V   half / full Page down\r\012");
  809. X    printf("^R       Reset .newsrc\r\012");
  810. X    printf("^U, ^Z   half / full Page up\r\012");
  811. X    printf("^K       Delete group\r\012");
  812. X    printf("^Y       Undelete group\r\012");
  813. X    printf("<CR>     Read current group\r\012");
  814. X    printf("<TAB>    View next unread group\r\012");
  815. X    printf("c        Mark group as all read\r\012");
  816. X    printf("g        Choose a new group by name\r\012");
  817. X    printf("j        Down a line\r\012");
  818. X    printf("k        Up a line\r\012");
  819. X    printf("q        Quit\r\012");
  820. X    printf("s        Subscribe to current group\r\012");
  821. X    printf("u        Unsubscribe to current group\r\012");
  822. X    printf("y        Yank in groups that are not in the .newsrc\r\012");
  823. X    printf("$        Reread group list from .newsrc\r\012");
  824. X    printf("/        Search forward for group\r\012");
  825. X    printf("?        Search backward for group\r\012");
  826. X
  827. X    center_line(LINES, "-- hit any key --");
  828. X    ReadCh();
  829. X}
  830. X
  831. X
  832. Xchoose_new_group() {
  833. X    char buf[LEN+1];
  834. X    char *p;
  835. X    int ret;
  836. X
  837. X    if (!parse_string("Newsgroup> ", buf))
  838. X        return -1;
  839. X
  840. X    for (p = buf; *p && (*p == ' ' || *p == '\t'); p++) ;
  841. X    if (*p == '\0')
  842. X        return -1;
  843. X
  844. X    ret = add_group(p, TRUE);
  845. X    if (ret < 0)
  846. X        info_message("Group not found in active file");
  847. X
  848. X    return ret;
  849. X}
  850. X
  851. X
  852. X/*
  853. X *  Add a group to the selection list (my_group[])
  854. X *  Return the index of my_group[] if group is added or was already
  855. X *  there.  Return -1 if named group is not in active[].
  856. X */
  857. X
  858. Xadd_group(s, get_unread)
  859. Xchar *s;
  860. Xint get_unread;            /* look in .newsrc for sequencer unread info? */
  861. X{
  862. X    long h;
  863. X    int i, j;
  864. X
  865. X    {            /* find the hash of the group name */
  866. X        char *t = s;
  867. X
  868. X        h = *t++;
  869. X        while (*t)
  870. X            h = (h * 64 + *t++) % TABLE_SIZE;
  871. X    }
  872. X
  873. X    for (i = group_hash[h]; i >= 0; i = active[i].next)
  874. X        if (strcmp(s, active[i].name) == 0) {
  875. X            for (j = 0; j < local_top; j++)
  876. X                if (my_group[j] == i)
  877. X                    return j;
  878. X
  879. X            active[i].flag &= ~NOTGOT;   /* mark that we got it */
  880. X            my_group[local_top] = i;
  881. X
  882. X            if (get_unread)
  883. X                unread[local_top] = get_line_unread(s, i);
  884. X            else
  885. X                unread[local_top] = -2;
  886. X
  887. X            local_top++;
  888. X            return local_top - 1;
  889. X        }
  890. X
  891. X    return -1;
  892. X}
  893. X
  894. X
  895. __END__OF__THIS__FILE__
  896. if test -f 'sigs.c' ; then
  897.   echo 'File sigs.c already exists, overwriting it'
  898.   del 'sigs.c'
  899. fi
  900. echo Extracting \"'sigs.c'\"
  901. sed "s/^X//" >'sigs.c' <<'__END__OF__THIS__FILE__'
  902. X#include    <stdio.h>
  903. X#include    "tass.h"
  904. X
  905. X#ifdef    APPEND_SIG
  906. X#ifdef    RAND_SIG
  907. Xstatic void
  908. Xrandom_signature (buf, fpo, cnt)
  909. Xchar *buf;
  910. XFILE *fpo;
  911. Xint cnt;
  912. X{
  913. X    static int    first = 1;
  914. X    FILE        *fp;
  915. X    char        inp[130];
  916. X    int        n;
  917. X
  918. X    sprintf (buf, "%s/.randsig", homedir);
  919. X    if (! (fp = fopen (buf, "r")))
  920. X        return;
  921. X    if (first) {
  922. X        srandom (time (0));
  923. X        first = 0;
  924. X    }
  925. X    n = _gs_size (fileno (fp));
  926. X    n = random () % 
  927. X        ((n > (1 << 9)) ?
  928. X            (n >> 7) :
  929. X            ((n > (1 << 5)) ?
  930. X                (n >> 3) :
  931. X                10));
  932. X    while (n-- > 0) {
  933. X        while (fgets (inp, 128, fp))
  934. X            if (! strcmp (inp, "%%\n"))
  935. X                break;
  936. X        if (feof (fp)) {
  937. X            clearerr (fp);
  938. X            cleareof (fp);
  939. X            rewind (fp);
  940. X            continue;
  941. X        }
  942. X    }
  943. X    while (fgets (inp, 128, fp) && (cnt-- > 0))
  944. X        if (strcmp (inp, "%%\n"))
  945. X            fputs (inp, fpo);
  946. X        else
  947. X            break;
  948. X    fclose (fp);
  949. X}
  950. X#endif    /* RAND_SIG */
  951. X        
  952. Xvoid
  953. Xadd_signature (fp)
  954. XFILE *fp;
  955. X{
  956. X    extern char    *malloc ();
  957. X    static char    *fn = NULL;
  958. X    FILE        *fpi;
  959. X    int        cnt;
  960. X
  961. X    if (!fn) {
  962. X        if (!(fn = malloc (250)))
  963. X            return;
  964. X    }
  965. X    sprintf (fn, "%s/.signature", homedir);
  966. X    cnt = 4 * 400;
  967. X    if (fpi = fopen (fn, "r")) {
  968. X        putc ('\n', fp);
  969. X        while (fgets (fn, 200, fpi) && (cnt-- > 0))
  970. X            fputs (fn, fp);
  971. X        fclose (fpi);
  972. X    }
  973. X#ifdef    RAND_SIG
  974. X    if (cnt > 0)
  975. X        random_signature (fn, fp, cnt);
  976. X#endif    /* RAND_SIG */
  977. X}
  978. X#endif    /* APPEND_SIG */
  979. X
  980. X
  981. __END__OF__THIS__FILE__
  982. if test -f 'tass.h' ; then
  983.   echo 'File tass.h already exists, overwriting it'
  984.   del 'tass.h'
  985. fi
  986. echo Extracting \"'tass.h'\"
  987. sed "s/^X//" >'tass.h' <<'__END__OF__THIS__FILE__'
  988. X#include    <setjmp.h>
  989. X
  990. X#ifndef        OSK
  991. X#define        LIBDIR        "/usr/lib/news"
  992. X#define        SPOOLDIR    "/usr/spool/news"
  993. X#define        MAILER        "/bin/rmail"
  994. X#else        /* OSK */
  995. X#define        LIBDIR        "/h0/USR/LIB/NEWS"
  996. X#define        SPOOLDIR    "/h0/SPOOL/NEWS"
  997. X#define        MAILER        "rmail"
  998. X#ifdef        USE_UID
  999. X#define        setgid(n)    /* */
  1000. X#endif        /* USE_UID */
  1001. X#endif        /* OSK */
  1002. X
  1003. X#ifndef        TRUE
  1004. X#define        TRUE        1
  1005. X#define        FALSE        0
  1006. X#endif        /* TRUE */
  1007. X
  1008. X#define        LEN        200
  1009. X
  1010. X#define        INDEX_TOP        4
  1011. X#define        NOTESLINES        (LINES - INDEX_TOP - 2)
  1012. X#define        RIGHT_POS        (COLS - 16)
  1013. X#define        MORE_POS        (COLS - 20)
  1014. X
  1015. X#define        MAX_FROM    25
  1016. X#define        MAX_SUBJ    38
  1017. X#define        TABLE_SIZE    1409
  1018. X
  1019. X/* #define        MAX_SUBJ    (COLS - 42)    */
  1020. X
  1021. X
  1022. Xstruct header {
  1023. X    long artnum;
  1024. X    char subject[MAX_SUBJ];
  1025. X    char *nore;        /* pointer into subject after Re: */
  1026. X    char from[MAX_FROM];
  1027. X    int thread;
  1028. X    long hash;
  1029. X    int inthread;
  1030. X    int unread;        /* has this article been read? */
  1031. X                /* 0 = read, 1 = unread, 2 = will return */
  1032. X};
  1033. X
  1034. X/*
  1035. X *  header.artnum:
  1036. X *    article number in spool directory for group
  1037. X *
  1038. X *  header.nore
  1039. X *    pointer into header.subject after the Re:'s.
  1040. X *
  1041. X *  header.hash:
  1042. X *    hash of the subject minus the re's.  For fast subject comparison
  1043. X *
  1044. X *  header.thread:
  1045. X *    initially -1
  1046. X *    points to another arts[] (struct header): zero and up
  1047. X *    -2 means article has expired (wasn't found in file search
  1048. X *    of spool directory for the group)
  1049. X *
  1050. X *  header.inthread:
  1051. X *    FALSE for the first article in a thread, TRUE for all
  1052. X *    following articles in thread
  1053. X *
  1054. X *  header.read:
  1055. X *    boolean, has this article been read or not
  1056. X */
  1057. X
  1058. Xstruct group_ent {
  1059. X    char *name;
  1060. X    long max;
  1061. X    long min;
  1062. X    int next;        /* next active entry in hash chain */
  1063. X    int flag;
  1064. X};
  1065. X
  1066. X#define        NOTGOT        0x01    /* haven't put in my_group yet */
  1067. X#define        SUBS        0x02    /* subscribed to */
  1068. X
  1069. X
  1070. Xextern int top;
  1071. Xextern struct header *arts;
  1072. Xextern long *base;
  1073. Xextern int max_art;
  1074. X
  1075. Xextern char userid[LEN];
  1076. Xextern char homedir[LEN];
  1077. Xextern char indexdir[LEN];
  1078. Xextern char my_org[LEN];
  1079. Xextern char active_file[LEN];
  1080. X#ifdef    OSK
  1081. Xextern char spooldir[LEN];
  1082. X#endif    /* OSK */
  1083. X#ifdef    INCSTR
  1084. Xextern char *incstr;
  1085. X#endif    /* INCSTR */
  1086. Xextern char newsrc[LEN];
  1087. Xextern char newnewsrc[LEN];
  1088. Xextern char delgroups[LEN];
  1089. Xextern int top_base;
  1090. Xextern int LINES, COLS;
  1091. Xextern char *str_save();
  1092. Xextern char *my_malloc();
  1093. Xextern char *my_realloc();
  1094. Xextern int group_hash[TABLE_SIZE];
  1095. X
  1096. Xextern int num_active;
  1097. Xextern struct group_ent *active;
  1098. Xextern int *my_group;
  1099. Xextern int *unread;
  1100. Xextern int max_active;
  1101. X
  1102. Xextern int local_top;
  1103. Xextern char *eat_re();
  1104. Xextern char *nice_time();
  1105. Xextern int update;
  1106. Xextern int inverse_okay;
  1107. X
  1108. X#ifdef    USE_UID
  1109. Xextern int tass_uid;
  1110. Xextern int tass_gid;
  1111. Xextern int real_uid;
  1112. Xextern int real_gid;
  1113. X#endif    /* USE_UID */
  1114. Xextern int local_index;
  1115. Xextern int do_mail_check;
  1116. Xextern int omask;
  1117. X
  1118. Xextern jmp_buf jmp_buffer;
  1119. X
  1120. Xextern char *strcpy();
  1121. Xextern char *strncat();
  1122. Xextern char *strncpy();
  1123. Xextern long atol();
  1124. X
  1125. X
  1126. X#define        ctrl(c)            ((c) & 0x1F)
  1127. X
  1128. X/*
  1129. X *  Assertion verifier
  1130. X */
  1131. X
  1132. X#ifdef __STDC__
  1133. X#define    assert(p)    if(! (p)) asfail(__FILE__, __LINE__, #p); else
  1134. X#else
  1135. X#define    assert(p)    if(! (p)) asfail(__FILE__, __LINE__, "p"); else
  1136. X#endif
  1137. X
  1138. X#define        TASS_HEADER    "Tass 3.0"
  1139. X
  1140. Xextern void    dump_index();
  1141. Xextern void    load_index();
  1142. Xextern void    find_local_index();
  1143. Xextern void    search_subject();
  1144. Xextern void    tass_group_help();
  1145. Xextern void    read_newsrc();
  1146. Xextern void    print_seq();
  1147. Xextern void    mark_group_read();
  1148. Xextern void    cancel_article();
  1149. Xextern void    save_art_to_file();
  1150. Xextern void    save_thread_to_file();
  1151. Xextern void    pipe_article();
  1152. Xextern void    open_note();
  1153. Xextern void    tass_page_help();
  1154. Xextern void    find_new_to();
  1155. Xextern void    search_group();
  1156. __END__OF__THIS__FILE__
  1157. if test -f 'time.c' ; then
  1158.   echo 'File time.c already exists, overwriting it'
  1159.   del 'time.c'
  1160. fi
  1161. echo Extracting \"'time.c'\"
  1162. sed "s/^X//" >'time.c' <<'__END__OF__THIS__FILE__'
  1163. X
  1164. X#include    <sys/types.h>
  1165. X#include    <time.h>
  1166. X
  1167. X
  1168. Xnicedate(timestr, newstr)
  1169. Xchar *timestr, *newstr;
  1170. X{
  1171. X    int i;
  1172. X
  1173. X    for (i = 0; i <= 7; i++)
  1174. X        *newstr++ = timestr[i];
  1175. X    if (timestr[8] != ' ')
  1176. X        *newstr++ = timestr[8];
  1177. X    *newstr++ = timestr[9];
  1178. X    *newstr++ = ',';
  1179. X    *newstr++ = ' ';
  1180. X    for (i = 20;i <= 23; i++)
  1181. X        *newstr++ = timestr[i];
  1182. X    *newstr++ = '\0';
  1183. X}
  1184. X
  1185. Xnicetime(timestr, newstr)
  1186. Xchar *timestr, *newstr;
  1187. X{
  1188. X    int hours;
  1189. X    char dayornite[3];
  1190. X
  1191. X    if (timestr[11] == ' ')
  1192. X        hours = timestr[12] - '0';
  1193. X    else
  1194. X        hours = (timestr[11]-'0')*10 + (timestr[12]-'0');
  1195. X    if (hours < 12)
  1196. X        strcpy(dayornite, "am");
  1197. X    else
  1198. X        strcpy(dayornite, "pm");
  1199. X    if (hours >= 13)
  1200. X        hours -= 12;
  1201. X    if (!hours)
  1202. X        hours = 12;
  1203. X    sprintf(newstr, "%d:%c%c%s", hours, timestr[14],
  1204. X                    timestr[15], dayornite);
  1205. X}
  1206. X
  1207. Xchar *nice_time() {
  1208. X    char *timestr;
  1209. X    char the_date[17];
  1210. X    char the_time[8];
  1211. X#ifndef    OSK
  1212. X    extern char *ctime();
  1213. X#endif    /* OSK */
  1214. X    long time_now;
  1215. X    static char buf[25];
  1216. X
  1217. X    time(&time_now);
  1218. X    timestr = ctime(&time_now);
  1219. X    nicedate(timestr, the_date);
  1220. X    nicetime(timestr, the_time);
  1221. X    sprintf(buf,"%s  %s", the_date, the_time);
  1222. X    return(buf);
  1223. X}
  1224. X
  1225. __END__OF__THIS__FILE__
  1226. exit 0
  1227. : end of shell archive
  1228.  
  1229. -- 
  1230. Frank Kaefer # fkk@stasys.sta.sub.org # Starnberg, Germany
  1231.