home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume23 / tin / part06 < prev    next >
Encoding:
Text File  |  1991-09-25  |  49.6 KB  |  2,142 lines

  1. Newsgroups: comp.sources.misc
  2. From: iain@estevax.uucp (Iain J. Lea)
  3. Subject:  v23i020:  tin - threaded full screen newsreader v1.0 PL2, Part06/09
  4. Message-ID: <1991Sep25.205241.2122@sparky.imd.sterling.com>
  5. X-Md4-Signature: 4f4146a2f69dee28cd7e6a7e74733ca8
  6. Date: Wed, 25 Sep 1991 20:52:41 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: iain@estevax.uucp (Iain J. Lea)
  10. Posting-number: Volume 23, Issue 20
  11. Archive-name: tin/part06
  12. Environment: BSD, SCO, ISC, SUNOS, SYSVR3, SYSVR4, ULTRIX, XENIX
  13.  
  14. #!/bin/sh
  15. # this is tin.shar.06 (part 6 of tin1.02)
  16. # do not concatenate these parts, unpack them in order with /bin/sh
  17. # file page.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" != 6; 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 page.c"
  36. sed 's/^X//' << 'SHAR_EOF' >> page.c &&
  37. X                    } else {
  38. X                        reload_index_file (group, FALSE);    /* unkill arts */
  39. X                    }
  40. X                    return find_new_pos (old_top, old_artnum, respnum);
  41. X                }
  42. X                return (which_base (respnum));
  43. X
  44. X            case 'I':    /* toggle inverse video */
  45. X                inverse_okay = !inverse_okay;
  46. X                if (inverse_okay) {
  47. X                    info_message (txt_inverse_on);
  48. X                } else {
  49. X                    draw_arrow_mark = TRUE;
  50. X                    info_message (txt_inverse_off);
  51. X                }
  52. X                redraw_page (respnum, group);
  53. X                break;
  54. X
  55. X            case 'k':
  56. X                if (note_page == NOTE_UNAVAIL) {
  57. X                    n = next_unread (next_response(respnum));
  58. X                    if (n == -1)
  59. X                        return (which_base (respnum));
  60. X                } else {
  61. X                    note_cleanup ();
  62. X                    n = next_unread (next_response (respnum));
  63. X                    if (n == -1)
  64. X                        return (which_base (respnum));
  65. X                }
  66. X                respnum = n;
  67. X                goto restart;
  68. X                /* NOTREACHED */
  69. X
  70. X            case 'K':    /* mark rest of thread as read */
  71. X                for (n = respnum; n >= 0; n = arts[n].thread)
  72. X                    arts[n].unread = ART_READ;
  73. X                n = next_unread (next_response (respnum));
  74. X                if (n == -1)
  75. X                    goto return_to_index;
  76. X                note_cleanup ();
  77. X                respnum = n;
  78. X                goto restart;
  79. X                /* NOTREACHED */
  80. X
  81. X            case 'm':    /* mail article/thread/tagged articles to somebody */
  82. X                feed_articles (FEED_MAIL, PAGE_LEVEL, "Mail", respnum, group_path);
  83. X                break;
  84. X
  85. X            case 'M':    /* options menu */
  86. X                if (change_rcfile (group, FALSE) == KILLING) {
  87. X                    kill_state = KILLING;
  88. X                } 
  89. X                redraw_page (respnum, group);
  90. X                break;
  91. X
  92. X            case 'n':    /* skip to next article */
  93. X                note_cleanup ();
  94. X                n = next_response (respnum);
  95. X                if (n == -1)
  96. X                    return (which_base(respnum));
  97. X
  98. X                respnum = n;
  99. X                goto restart;
  100. X                /* NOTREACHED */
  101. X                
  102. X            case 'N':    /* next unread article */
  103. X                n = next_unread(next_response(respnum));
  104. X                if (n == -1)
  105. X                    info_message(txt_no_next_unread_art);
  106. X                else {
  107. X                    note_cleanup();
  108. X                    respnum = n;
  109. X                    goto restart;
  110. X                }
  111. X                break;
  112. X
  113. X            case 'o':    /* output art/thread/tagged arts to printer */
  114. X                feed_articles (FEED_PRINT, PAGE_LEVEL, "Print", respnum, group_path);
  115. X                break;
  116. X
  117. X            case 'p':    /* previous article */
  118. X                note_cleanup ();
  119. X                n = prev_response (respnum);
  120. X                if (n == -1)
  121. X                    return (which_resp (respnum));
  122. X
  123. X                respnum = n;
  124. X                goto restart;
  125. X
  126. X            case 'P':    /* previous unread article */
  127. X                n = prev_unread (prev_response (respnum));
  128. X                if (n == -1)
  129. X                    info_message (txt_no_prev_unread_art);
  130. X                else {
  131. X                    note_cleanup ();
  132. X                    respnum = n;
  133. X                    goto restart;
  134. X                }
  135. X                break;
  136. X
  137. X            case 'q':    /* quit */
  138. X                if (prompt_yn (LINES, txt_quit, 'y')) {
  139. X                    return -2;
  140. X                }
  141. X                break;
  142. X    
  143. X            case 'r':    /* reply to author through mail */
  144. X                mail_to_author (FALSE);
  145. X                redraw_page (respnum, group);
  146. X                break;
  147. X
  148. X            case 'R':    /* reply to author, copy text */
  149. X                mail_to_author (TRUE);
  150. X                redraw_page (respnum, group);
  151. X                break;
  152. X
  153. X            case 's':    /* save article/thread/tagged articles */
  154. X                feed_articles (FEED_SAVE, PAGE_LEVEL, "Save", respnum, group_path);
  155. X                break;
  156. X
  157. X            case 't':    /* return to group selection page */
  158. X                note_cleanup ();
  159. X                if (kill_state == KILLING) {
  160. X                    if (kill_articles) {
  161. X                        kill_any_articles (group);
  162. X                        reload_index_file (group, TRUE);    /* kill arts */
  163. X                    } else {
  164. X                        reload_index_file (group, FALSE);    /* unkill arts */
  165. X                    }
  166. X                }
  167. X                update_newsrc (group, my_group[cur_groupnum], FALSE);
  168. X                fix_new_highest (cur_groupnum);
  169. X                return -1;
  170. X
  171. X            case 'T':    /* tag/untag article for saving */
  172. X                if (arts[respnum].tagged) {
  173. X                    arts[respnum].tagged = 0;
  174. X                    info_message (txt_untagged_art);
  175. X                } else {
  176. X                    arts[respnum].tagged = ++num_of_tagged_files;
  177. X                    info_message (txt_tagged_art);
  178. X                }
  179. X                break;
  180. X
  181. X            case 'v':
  182. X                info_message (cvers);
  183. X                break;
  184. X
  185. X            case 'w':    /* post a basenote */
  186. X                if (post_base (group)) {
  187. X                    update_newsrc (group, my_group[cur_groupnum], FALSE);
  188. X                    index_group (group, group_path);
  189. X                    read_newsrc_line (group);
  190. X                    redraw_page (respnum, group);
  191. X                }
  192. X                break;
  193. X
  194. X            case 'W':    /* display messages posted by user */
  195. X                if (user_posted_messages ()) {
  196. X                    redraw_page(respnum, group);
  197. X                }
  198. X                break;
  199. X
  200. X            case 'z':    /* mark article as unread (to return) */
  201. X                arts[respnum].unread = ART_WILL_RETURN;
  202. X                info_message(txt_art_marked_as_unread);
  203. X                break;
  204. X
  205. X            default:
  206. X                info_message(txt_bad_command);
  207. X        }
  208. X    }
  209. X}
  210. X
  211. X
  212. Xvoid redraw_page (respnum, group)
  213. X    int respnum;
  214. X    char *group;
  215. X{
  216. X
  217. X    if (note_page == NOTE_UNAVAIL) {
  218. X        ClearScreen ();
  219. X        printf (txt_art_unavailable, arts[respnum].artnum);
  220. X        fflush (stdout);
  221. X    } else if (note_page > 0) {
  222. X        note_page--;
  223. X        fseek (note_fp, note_mark[note_page], 0);
  224. X        show_note_page (respnum, group);
  225. X    }
  226. X}
  227. X
  228. X
  229. Xvoid show_note_page (respnum, group)
  230. X    int respnum;
  231. X    char *group;
  232. X{
  233. X    char buf[LEN+1];
  234. X    char buf2[LEN+50];
  235. X    char *p, *q;
  236. X    int i, j;
  237. X    int ctrl_L;        /* form feed character detected */
  238. X
  239. X    ClearScreen();
  240. X
  241. X    note_line = 1;
  242. X
  243. X    if (note_page == 0)
  244. X        show_first_header (respnum, group);
  245. X    else
  246. X        show_cont_header (respnum);
  247. X
  248. X    ctrl_L = FALSE;
  249. X    while (note_line < LINES) {
  250. X        if (fgets(buf, sizeof buf, note_fp) == NULL) {
  251. X            note_end = TRUE;
  252. X            break;
  253. X        }
  254. X
  255. X        buf[LEN-1] = '\0';
  256. X        if (rotate)
  257. X            for (p = buf, q = buf2;
  258. X                    *p && *p != '\n' && q<&buf2[LEN]; p++) {
  259. X                if (*p == '\b' && q > buf2) {
  260. X                    q--;
  261. X                } else if (*p == 12) {        /* ^L */
  262. X                    *q++ = '^';
  263. X                    *q++ = 'L';
  264. X                    ctrl_L = TRUE;
  265. X                } else if (*p == '\t') {
  266. X                    i = q - buf2;
  267. X                    j = (i|7) + 1;
  268. X
  269. X                    while (i++ < j)
  270. X                        *q++ = ' ';
  271. X                } else if (((*p) & 0x7F) < 32) {
  272. X                    *q++ = '^';
  273. X                    *q++ = ((*p) & 0x7F) + '@';
  274. X                } else if (*p >= 'A' && *p <= 'Z')
  275. X                    *q++ = 'A' + (*p - 'A' + rotate) % 26;
  276. X                else if (*p >= 'a' && *p <= 'z')
  277. X                    *q++ = 'a' + (*p - 'a' + rotate) % 26;
  278. X                else
  279. X                    *q++ = *p;
  280. X            }
  281. X        else
  282. X            for (p = buf, q = buf2;
  283. X                    *p && *p != '\n' && q<&buf2[LEN]; p++) {
  284. X                if (*p == '\b' && q > buf2) {
  285. X                    q--;
  286. X                } else if (*p == 12) {        /* ^L */
  287. X                    *q++ = '^';
  288. X                    *q++ = 'L';
  289. X                    ctrl_L = TRUE;
  290. X                } else if (*p == '\t') {
  291. X                    i = q - buf2;
  292. X                    j = (i|7) + 1;
  293. X
  294. X                    while (i++ < j)
  295. X                        *q++ = ' ';
  296. X                } else if (((*p) & 0x7F) < 32) {
  297. X                    *q++ = '^';
  298. X                    *q++ = ((*p) & 0x7F) + '@';
  299. X                } else
  300. X                    *q++ = *p;
  301. X            }
  302. X
  303. X        *q = '\0';
  304. X
  305. X        printf("%s\r\n", buf2);
  306. X
  307. X        note_line += ((int) strlen (buf2) / COLS) + 1;
  308. X
  309. X        if (ctrl_L) {
  310. X            break;
  311. X        }
  312. X    }
  313. X
  314. X    note_mark[++note_page] = ftell(note_fp);
  315. X
  316. X    if (note_end) {
  317. X        MoveCursor (LINES, MORE_POS-(5+BLANK_PAGE_COLS));
  318. X        StartInverse ();    
  319. X        if (arts[respnum].thread != -1) {
  320. X            printf (txt_next_resp);
  321. X            fflush (stdout);
  322. X        } else {
  323. X            printf (txt_last_resp);
  324. X            fflush (stdout);
  325. X        }
  326. X        EndInverse ();
  327. X    } else {
  328. X        if (note_size > 0) {
  329. X            draw_percent_mark ((int) note_mark[note_page], note_size);
  330. X        } else {
  331. X            MoveCursor (LINES, MORE_POS-BLANK_PAGE_COLS);
  332. X            StartInverse ();    
  333. X            printf (txt_more);
  334. X            fflush (stdout);
  335. X            EndInverse ();
  336. X        }
  337. X    }
  338. X    MoveCursor (LINES, 0);
  339. X}
  340. X
  341. X
  342. Xvoid show_first_header (respnum, group)
  343. X    int respnum;
  344. X    char *group;
  345. X{
  346. X    int whichresp;
  347. X    int x_resp;
  348. X    char buf[LEN+1];
  349. X    char tmp[LEN+1];
  350. X    int pos, i;
  351. X    int n;
  352. X
  353. X    whichresp = which_resp (respnum);
  354. X    x_resp = nresp (which_base (respnum));
  355. X
  356. X    ClearScreen ();
  357. X
  358. X    strcpy (buf, note_h_date);
  359. X    pos = (COLS - (int) strlen (group)) / 2;
  360. X    for (i = strlen(buf); i < pos; i++)
  361. X        buf[i] = ' ';
  362. X    buf[i] = '\0';
  363. X
  364. X    strcat (buf, group);
  365. X
  366. X    for (i = strlen(buf); i < RIGHT_POS ; i++)
  367. X        buf[i] = ' ';
  368. X    buf[i] = '\0';
  369. X
  370. X    printf (txt_thread_x_of_n, buf, which_base (respnum) + 1, top_base);
  371. X
  372. X    sprintf (buf, txt_art, arts[respnum].artnum);
  373. X    n = strlen (buf);
  374. X    fputs (buf, stdout);
  375. X
  376. X    strcpy (buf, note_h_subj);
  377. X    buf[RIGHT_POS - 5 - n] = '\0';
  378. X
  379. X    pos = ((COLS - (int) strlen (buf)) / 2) - 2;
  380. X
  381. X    if (pos > n) {
  382. X        MoveCursor (1, pos);
  383. X    } else {
  384. X        MoveCursor (1, n);
  385. X    }
  386. X
  387. X    StartInverse ();
  388. X    fputs (buf, stdout);
  389. X    EndInverse ();
  390. X
  391. X    MoveCursor (1, RIGHT_POS);
  392. X    if (whichresp)
  393. X        printf (txt_resp_x_of_n, whichresp, x_resp);
  394. X    else {
  395. X        if (x_resp == 0)
  396. X            printf (txt_no_resp);
  397. X        else if (x_resp == 1)
  398. X            printf (txt_1_resp);
  399. X        else
  400. X            printf (txt_x_resp, x_resp);
  401. X    }
  402. X
  403. X    if (*note_h_org)
  404. X        sprintf (tmp, txt_s_at_s, note_full_name, note_h_org);
  405. X    else
  406. X        strcpy (tmp, note_full_name);
  407. X
  408. X    tmp[LEN] = '\0';
  409. X
  410. X    sprintf (buf, "%s  ", note_from_addr);
  411. X
  412. X    pos = COLS - 1 - (int) strlen(tmp);
  413. X    if ((int) strlen (buf) + (int) strlen (tmp) >= COLS - 1) {
  414. X        strncat (buf, tmp, COLS - 1 - (int) strlen(buf));
  415. X        buf[COLS - 1] = '\0';
  416. X    } else {
  417. X        for (i = strlen(buf); i < pos; i++)
  418. X            buf[i] = ' ';
  419. X        buf[i] = '\0';
  420. X        strcat (buf, tmp);
  421. X    }
  422. X    printf ("%s\r\n\r\n", buf);
  423. X
  424. X    note_line += 4;
  425. X}
  426. X
  427. X
  428. Xvoid show_cont_header (respnum)
  429. X    int respnum;
  430. X{
  431. X    int whichresp;
  432. X    int whichbase;
  433. X    char buf[LEN+1];
  434. X
  435. X    whichresp = which_resp (respnum);
  436. X    whichbase = which_base (respnum);
  437. X
  438. X    assert (whichbase < top_base);
  439. X
  440. X    if (whichresp)
  441. X        sprintf(buf, txt_thread_resp_page,
  442. X            whichbase + 1,
  443. X            top_base,
  444. X            whichresp,
  445. X            note_page + 1,
  446. X            note_h_subj);
  447. X    else
  448. X        sprintf(buf, txt_thread_page,
  449. X            whichbase + 1,
  450. X            top_base,
  451. X            note_page + 1,
  452. X            note_h_subj);
  453. X
  454. X    buf[COLS] = '\0';
  455. X    printf("%s\r\n\r\n", buf);
  456. X
  457. X    note_line += 2;
  458. X}
  459. X
  460. X
  461. Xvoid open_note (art, group_path)
  462. X    long art;
  463. X    char *group_path;
  464. X{
  465. X    char buf[1025];
  466. X    char *p;
  467. X
  468. X    note_page = 0;
  469. X
  470. X    if ((note_fp = open_art_fp (group_path, art)) == NULL) {
  471. X        note_page = NOTE_UNAVAIL;
  472. X        return;
  473. X    }
  474. X
  475. X    note_h_from[0] = '\0';
  476. X    note_h_path[0] = '\0';
  477. X    note_h_subj[0] = '\0';
  478. X    note_h_org[0] = '\0';
  479. X    note_h_date[0] = '\0';
  480. X    note_h_newsgroups[0] = '\0';
  481. X    note_h_messageid[0] = '\0';
  482. X    note_h_distrib[0] = '\0';
  483. X    note_h_followup[0] = '\0';
  484. X
  485. X    while (fgets(buf, sizeof buf, note_fp) != NULL) {
  486. X        buf[1024] = '\0';
  487. X
  488. X        for (p=buf ; *p && *p != '\n' ; p++) {
  489. X            if (((*p) & 0x7F) < 32)
  490. X                *p = ' ';
  491. X        }
  492. X        *p = '\0';
  493. X        
  494. X        if (*buf == '\0')
  495. X            break;
  496. X
  497. X        if (strncmp(buf, "From: ", 6) == 0) {
  498. X            strcpy(note_h_from, &buf[6]);
  499. X            note_h_from[LEN-1] = '\0';
  500. X        } else if (strncmp(buf, "Path: ", 6) == 0) {
  501. X            strcpy(note_h_path, &buf[6]);
  502. X            note_h_path[LEN-1] = '\0';
  503. X        } else if (strncmp(buf, "Subject: ", 9) == 0) {
  504. X            strcpy(note_h_subj, &buf[9]);
  505. X            note_h_subj[LEN-1] = '\0';
  506. X        } else if (strncmp(buf, "Organization: ", 14) == 0) {
  507. X            strcpy(note_h_org, &buf[14]);
  508. X            note_h_org[LEN-1] = '\0';
  509. X        } else if (strncmp(buf, "Date: ", 6) == 0) {
  510. X            strcpy(note_h_date, &buf[6]);
  511. X            note_h_date[LEN-1] = '\0';
  512. X        } else if (strncmp(buf, "Newsgroups: ", 12) == 0) {
  513. X            strcpy(note_h_newsgroups, &buf[12]);
  514. X            note_h_newsgroups[LEN-1] = '\0';
  515. X        } else if (strncmp(buf, "Message-ID: ", 12) == 0) {
  516. X            strcpy(note_h_messageid, &buf[12]);
  517. X            note_h_messageid[LEN-1] = '\0';
  518. X        } else if (strncmp(buf, "Distribution: ", 14) == 0) {
  519. X            strcpy(note_h_distrib, &buf[14]);
  520. X            note_h_distrib[LEN-1] = '\0';
  521. X        } else if (strncmp(buf, "Followup-To: ", 13) == 0) {
  522. X            strcpy(note_h_followup, &buf[13]);
  523. X            note_h_followup[LEN-1] = '\0';
  524. X        }
  525. X    }
  526. X
  527. X    note_page = 0;
  528. X    note_mark[0] = ftell (note_fp);
  529. X
  530. X    parse_from (note_h_from, note_from_addr, note_full_name);
  531. X    note_end = FALSE;
  532. X
  533. X    return;
  534. X}
  535. X
  536. X
  537. Xvoid note_cleanup()
  538. X{
  539. X    if (note_page != NOTE_UNAVAIL)
  540. X        fclose(note_fp);
  541. X}
  542. X
  543. X
  544. Xint prompt_response(ch, respnum)
  545. X    int respnum;
  546. X{
  547. X    int num;
  548. X
  549. X    clear_message ();
  550. X
  551. X    if ((num = parse_num (ch, txt_read_resp)) == -1) {
  552. X        clear_message ();
  553. X        return -1;
  554. X    }
  555. X
  556. X    return choose_resp (which_base (respnum), num);
  557. X}
  558. X
  559. X/*
  560. X *  return response number n from thread i
  561. X */
  562. X
  563. Xint choose_resp (i, n)
  564. X    int i;
  565. X    int n;
  566. X{
  567. X    int j;
  568. X
  569. X    j = base[i];
  570. X
  571. X    while (n-- && arts[j].thread >= 0) {
  572. X        j = arts[j].thread;
  573. X    }
  574. X
  575. X    return j;
  576. X}
  577. X
  578. X
  579. X/*
  580. X *  Parse various From: lines into the component mail addresses and
  581. X *  real names
  582. X */
  583. X
  584. Xvoid parse_from (str, addr, name)
  585. X    char *str;
  586. X    char *addr;
  587. X    char *name;
  588. X{
  589. X    char *p;
  590. X    
  591. X    for (p=str ; *p ; p++) {
  592. X        if (((*p) & 0x7F) < 32)
  593. X            *p = ' ';
  594. X    }
  595. X
  596. X    while (*str && *str != ' ')
  597. X        *addr++ = *str++;
  598. X    *addr = '\0';
  599. X    if (*str++ == ' ') {
  600. X        if (*str++ == '(') {
  601. X            if (*str == '"')
  602. X                str++;  /* Kill "quotes around names"         */
  603. X                    /* But don't touch quotes inside the  */
  604. X                    /* Name (that's what that nonsense    */
  605. X                    /* below is for                  */
  606. X            while (*str && *str != ')' && !(*str=='"'&&str[1]==')'))
  607. X                *name++ = *str++;
  608. X        }
  609. X    }
  610. X    *name = '\0';
  611. X}
  612. X
  613. X
  614. X/*
  615. X *  Find the previous response.  Go to the last response in the previous
  616. X *  thread if we go past the beginning of this thread.
  617. X */
  618. X
  619. Xint prev_response (n)
  620. X    int n;
  621. X{
  622. X    int resp;
  623. X    int i;
  624. X
  625. X    resp = which_resp (n);
  626. X
  627. X    if (resp > 0)
  628. X        return choose_resp (which_base (n), resp-1);
  629. X
  630. X    i = which_base (n) - 1;
  631. X
  632. X    if (i < 0)
  633. X        return -1;
  634. X
  635. X    return choose_resp (i, nresp (i));
  636. X}
  637. X
  638. X
  639. X/*
  640. X *  Find the next response.  Go to the next basenote if there
  641. X *  are no more responses in this thread
  642. X */
  643. X
  644. Xint next_response (n)
  645. X    int n;
  646. X{
  647. X    int i;
  648. X
  649. X    if (arts[n].thread >= 0)
  650. X        return arts[n].thread;
  651. X
  652. X    i = which_base (n) + 1;
  653. X
  654. X    if (i >= top_base)
  655. X        return -1;
  656. X
  657. X    return base[i];
  658. X}
  659. X
  660. X
  661. X/*
  662. X *  Given a respnum (index into arts[]), find the respnum of the
  663. X *  next basenote
  664. X */
  665. X
  666. Xint next_basenote (n)
  667. X    int n;
  668. X{
  669. X    int i;
  670. X
  671. X    i = which_base (n) + 1;
  672. X    if (i >= top_base)
  673. X        return -1;
  674. X
  675. X    return base[i];
  676. X}
  677. X
  678. X
  679. Xvoid yank_to_addr (orig, addr)
  680. X    char *orig;
  681. X    char *addr;
  682. X{
  683. X    char *p;
  684. X
  685. X    for (p = orig; *p; p++)
  686. X        if (((*p) & 0x7F) < 32)
  687. X            *p = ' ';
  688. X
  689. X    while (*addr)
  690. X        addr++;
  691. X
  692. X    while (*orig) {
  693. X        while (*orig && (*orig == ' ' || *orig == '"' || *orig == ','))
  694. X            orig++;
  695. X        *addr++ = ' ';
  696. X        while (*orig && (*orig != ' ' && *orig != ',' && *orig != '"'))
  697. X            *addr++ = *orig++;
  698. X        while (*orig && (*orig == ' ' || *orig == '"' || *orig == ','))
  699. X            orig++;
  700. X        if (*orig == '(') {
  701. X            while (*orig && *orig != ')')
  702. X                orig++;
  703. X            if (*orig == ')')
  704. X                orig++;
  705. X        }
  706. X    }
  707. X    *addr = '\0';
  708. X}
  709. X
  710. X
  711. Xint show_last_page ()
  712. X{
  713. X    char buf[LEN+1];
  714. X    char buf2[LEN+50];
  715. X    char *p, *q;
  716. X    int ctrl_L;        /* form feed character detected */
  717. X    int i, j;
  718. X    
  719. X    if (note_end) {
  720. X        return FALSE;
  721. X    }
  722. X
  723. X    while (! note_end) {
  724. X        note_line = 1;
  725. X        ctrl_L = FALSE;
  726. X
  727. X        if (note_page == 0) {
  728. X            note_line += 4;
  729. X        } else {
  730. X            note_line += 2;
  731. X        }
  732. X        while (note_line < LINES) {
  733. X            if (fgets(buf, sizeof buf, note_fp) == NULL) {
  734. X                note_end = TRUE;
  735. X                break;
  736. X            }
  737. X            buf[LEN-1] = '\0';
  738. X            for (p = buf, q = buf2;    *p && *p != '\n' && q<&buf2[LEN]; p++) {
  739. X                if (*p == '\b' && q > buf2) {
  740. X                    q--;
  741. X                } else if (*p == 12) {        /* ^L */
  742. X                    *q++ = '^';
  743. X                    *q++ = 'L';
  744. X                    ctrl_L = TRUE;
  745. X                } else if (*p == '\t') {
  746. X                    i = q - buf2;
  747. X                    j = (i|7) + 1;
  748. X
  749. X                    while (i++ < j) {
  750. X                        *q++ = ' ';
  751. X                    }
  752. X                } else if (((*p) & 0x7F) < 32) {
  753. X                    *q++ = '^';
  754. X                    *q++ = ((*p) & 0x7F) + '@';
  755. X                } else {
  756. X                    *q++ = *p;
  757. X                }
  758. X            }
  759. X            *q = '\0';
  760. X            note_line += ((int) strlen (buf2) / COLS) + 1;
  761. X
  762. X            if (ctrl_L) {
  763. X                break;
  764. X            }
  765. X        }
  766. X        if (! note_end) {
  767. X            note_mark[++note_page] = ftell(note_fp);
  768. X        }
  769. X    }
  770. X    fseek (note_fp, note_mark[note_page], 0);
  771. X    return TRUE;
  772. X}
  773. SHAR_EOF
  774. echo "File page.c is complete" &&
  775. $TOUCH -am 0924082391 page.c &&
  776. chmod 0600 page.c ||
  777. echo "restore of page.c failed"
  778. set `wc -c page.c`;Wc_c=$1
  779. if test "$Wc_c" != "24185"; then
  780.     echo original size 24185, current size $Wc_c
  781. fi
  782. # ============= post.c ==============
  783. echo "x - extracting post.c (Text)"
  784. sed 's/^X//' << 'SHAR_EOF' > post.c &&
  785. X/*
  786. X *  Project   : tin - a visual threaded usenet newsreader
  787. X *  Module    : post.c
  788. X *  Author    : I.Lea
  789. X *  Created   : 01-04-91
  790. X *  Updated   : 22-09-91
  791. X *  Release   : 1.0
  792. X *  Notes     : mailing/posting/replying/followup & cancel article routines
  793. X *  Copyright : (c) Copyright 1991 by Rich Skrenta & Iain Lea
  794. X *                You may  freely  copy or  redistribute  this software,
  795. X *              so  long as there is no profit made from its use, sale
  796. X *              trade or  reproduction.  You may not change this copy-
  797. X *              right notice, and it must be included in any copy made
  798. X */
  799. X
  800. X#include    "tin.h"
  801. X
  802. Xextern char note_h_distrib[LEN+1];        /* Distribution: */
  803. Xextern char note_h_followup[LEN+1];        /* Followup-To: */
  804. Xextern char note_h_from[LEN+1];            /* From:    */
  805. Xextern char note_h_messageid[LEN+1];    /* Message-ID:    */
  806. Xextern char note_h_newsgroups[LEN+1];    /* Newsgroups:    */
  807. Xextern char note_h_subj[LEN+1];            /* Subject:    */
  808. X
  809. Xextern char note_from_addr[100];
  810. Xextern char note_full_name[100];
  811. X
  812. Xextern FILE *note_fp;                    /* the body of the current article */
  813. X
  814. Xextern long note_mark[MAX_PAGES];        /* ftells on beginnings of pages */
  815. X
  816. Xstruct posted_t *posted;
  817. X
  818. X
  819. Xint user_posted_messages ()
  820. X{
  821. X    char buf[LEN];
  822. X    FILE *fp;
  823. X    int i, j, k;
  824. X    int no_of_lines = 0;
  825. X
  826. X    set_real_uid_gid ();
  827. X        
  828. X    if ((fp = fopen (postfile, "r")) == NULL) {
  829. X        clear_message ();
  830. X        set_tin_uid_gid ();
  831. X        return FALSE;
  832. X    } else {
  833. X        while (fgets (buf, sizeof (buf), fp) != NULL) {
  834. X            no_of_lines++;
  835. X        }
  836. X        if (! no_of_lines) {
  837. X            fclose (fp);
  838. X            info_message (txt_no_arts_posted);
  839. X            return FALSE;
  840. X        }
  841. X        rewind (fp);
  842. X        posted = (struct posted_t *) my_malloc ((no_of_lines+1) * sizeof (struct posted_t));
  843. X        for (i=0 ; fgets (buf, sizeof (buf), fp) != NULL ; i++) {
  844. X            for (j=0 ; buf[j] != '|' && buf[j] != '\n' ; j++) {
  845. X                posted[i].date[j] = buf[j];        /* posted date */
  846. X            }
  847. X            if (buf[j] == '\n') {    
  848. X                error_message ("Corrupted file %s", postfile);
  849. X                sleep (1);
  850. X                fclose (fp);
  851. X                clear_message ();
  852. X                return FALSE;
  853. X            }
  854. X            posted[i].date[j++] = '\0';
  855. X            for (k=j,j=0 ; buf[k] != '|' && buf[k] != ',' ; k++, j++) {
  856. X                posted[i].group[j] = buf[k];
  857. X            }
  858. X            if (buf[k] == ',') {
  859. X                while (buf[k] != '|' && buf[k] != '\n') {
  860. X                    k++;
  861. X                }
  862. X                posted[i].group[j++] = ',';
  863. X                posted[i].group[j++] = '.';
  864. X                posted[i].group[j++] = '.';
  865. X                posted[i].group[j++] = '.';
  866. X            }
  867. X            posted[i].group[j++] = '\0';
  868. X            k++;
  869. X            for (j=k,k=0 ; buf[j] != '\n' ; j++, k++) {
  870. X                posted[i].subj[k] = buf[j];
  871. X            }
  872. X            posted[i].subj[k++] = '\0';
  873. X        }
  874. X        fclose (fp);
  875. X        set_tin_uid_gid ();
  876. X
  877. X        show_info_page (POST_INFO, (char *) 0, txt_post_history_menu);
  878. X        return TRUE;
  879. X    }
  880. X}
  881. X
  882. X
  883. Xvoid update_art_posted_file (group, subj)
  884. X    char *group;
  885. X    char *subj;
  886. X{
  887. X    char buf[LEN+1];
  888. X    char tmp_post[LEN+1];
  889. X    FILE *fp, *tmp_fp;
  890. X    long epoch;
  891. X    struct tm *tm;
  892. X
  893. X    sprintf (tmp_post, "%s.%d", postfile, getpid ());
  894. X
  895. X    set_real_uid_gid ();
  896. X
  897. X    if ((tmp_fp = fopen (tmp_post, "w")) != NULL) {
  898. X        time (&epoch);
  899. X        tm = localtime (&epoch);
  900. X        fprintf (tmp_fp, "%02d-%02d-%02d|%s|%s\n",
  901. X            tm->tm_mday, tm->tm_mon+1, tm->tm_year, group, subj);
  902. X        fclose (tmp_fp);
  903. X    }
  904. X
  905. X    if ((tmp_fp = fopen (tmp_post, "a+")) != NULL) {
  906. X        if ((fp = fopen (postfile, "r")) != NULL) {
  907. X            while (fgets (buf, sizeof buf, fp) != NULL) {
  908. X                fprintf (tmp_fp, "%s", buf);
  909. X            }    
  910. X            fclose (fp);
  911. X            rename_file (tmp_post, postfile);
  912. X        }
  913. X        fclose (tmp_fp);
  914. X    }
  915. X    set_tin_uid_gid ();
  916. X}
  917. X
  918. X/*
  919. X *  Post an original article (not a followup)
  920. X */
  921. X
  922. Xint post_base (group)
  923. X    char *group;
  924. X{
  925. X    FILE *fp;
  926. X    char ch;
  927. X    char ch_default = 'p';
  928. X    char subj[LEN+1];
  929. X    char buf[LEN+1];
  930. X    int redraw_screen = FALSE;
  931. X
  932. X    start_line_offset = 4;
  933. X    
  934. X    if (! parse_string (txt_post_subject, subj)) {
  935. X        clear_message ();
  936. X        return (redraw_screen);
  937. X    }    
  938. X    if (subj[0] == '\0') {
  939. X        info_message (txt_no_subject);
  940. X        return (redraw_screen);
  941. X    }
  942. X
  943. X    set_real_uid_gid ();
  944. X
  945. X    if ((fp = fopen (article, "w")) == NULL) {
  946. X        error_message (txt_cannot_open, article);
  947. X        set_tin_uid_gid ();
  948. X        return (redraw_screen);
  949. X    }
  950. X    chmod (article, 0600);
  951. X
  952. X    fprintf (fp, "Subject: %s\n", subj);
  953. X    fprintf (fp, "Newsgroups: %s\n", group);
  954. X    fprintf (fp, "Distribution: \n");
  955. X    if (*my_org) {
  956. X        fprintf (fp, "Organization: %s\n", my_org);
  957. X        start_line_offset++;
  958. X    }
  959. X    if (*reply_to) {
  960. X        fprintf (fp, "Reply-To: %s\n", reply_to);
  961. X        start_line_offset++;
  962. X    }
  963. X    fprintf (fp, "\n");
  964. X
  965. X    add_signature (fp, FALSE);
  966. X    fclose (fp);
  967. X
  968. X    ch = 'e';
  969. X    while (1) {
  970. X        switch (ch) {
  971. X        case 'e':
  972. X            invoke_editor (article);
  973. X            redraw_screen = TRUE;
  974. X            break;
  975. X
  976. X        case 'a':
  977. X            unlink (article);
  978. X            clear_message ();
  979. X            set_tin_uid_gid ();
  980. X            return (redraw_screen);
  981. X
  982. X        case 'p':
  983. X            wait_message (txt_posting);
  984. X            if (debug) {
  985. X                sprintf (buf, "%s/inews -h < %s", INEWSDIR, article);
  986. X            } else {
  987. X                sprintf (buf, "%s/inews -h < %s > /dev/null 2>&1",
  988. X                    INEWSDIR, article);
  989. X            }
  990. X            if (invoke_cmd (buf)) {
  991. X                unlink (article);
  992. X                info_message (txt_art_posted);
  993. X                goto post_base_done;
  994. X            } else {
  995. X                rename_file (article, dead_article);
  996. X                sprintf (buf, txt_art_rejected, dead_article);
  997. X                info_message (buf);
  998. X                sleep (3);
  999. X                set_tin_uid_gid ();
  1000. X                return (redraw_screen);
  1001. X            }
  1002. X        }
  1003. X
  1004. X        do {
  1005. X            sprintf (msg, "%s%c", txt_abort_edit_post, ch_default);
  1006. X            wait_message (msg);
  1007. X            MoveCursor (LINES, (int) strlen (txt_abort_edit_post));
  1008. X            if ((ch = ReadCh ()) == CR)
  1009. X                ch = ch_default;
  1010. X        } while (ch != 'a' && ch != 'e' && ch != 'p');
  1011. X    }
  1012. X
  1013. Xpost_base_done:
  1014. X    set_tin_uid_gid ();
  1015. X    update_art_posted_file (group, subj);
  1016. X    return (redraw_screen);
  1017. X}
  1018. X
  1019. X
  1020. Xint post_response (group, respnum)
  1021. X    char *group;
  1022. X    int respnum;
  1023. X{
  1024. X    FILE *fp;
  1025. X    char ch, *ptr;
  1026. X    char ch_default = 'p';
  1027. X    char buf[LEN+1];
  1028. X    int redraw_screen = FALSE;
  1029. X
  1030. X    start_line_offset = 4;
  1031. X
  1032. X    if (*note_h_followup && strcmp (note_h_followup, "poster") == 0) {
  1033. X        clear_message ();
  1034. X        if (! prompt_yn (LINES, txt_resp_to_poster, 'y')) {
  1035. X            return (redraw_screen);
  1036. X        }
  1037. X        *note_h_followup = '\0';
  1038. X    } else if (*note_h_followup && strcmp(note_h_followup, group) != 0) {
  1039. X        MoveCursor (LINES/2, 0);
  1040. X        CleartoEOS ();
  1041. X        center_line ((LINES/2)+2, TRUE, txt_resp_redirect);
  1042. X        MoveCursor ((LINES/2)+4, 0);
  1043. X
  1044. X        printf ("    ");
  1045. X        ptr = note_h_followup;
  1046. X        while (*ptr) {
  1047. X            if (*ptr != ',') {
  1048. X                putc (*ptr, stdout);
  1049. X            } else {
  1050. X                printf ("\r\n    ");
  1051. X            }
  1052. X            fflush (stdout);
  1053. X            ptr++;
  1054. X        }
  1055. X
  1056. X        if (! prompt_yn (LINES, txt_continue, 'y')) {
  1057. X            return (redraw_screen);
  1058. X        }
  1059. X    }
  1060. X
  1061. X    set_real_uid_gid ();
  1062. X
  1063. X    if ((fp = fopen (article, "w")) == NULL) {
  1064. X        error_message (txt_cannot_open, article);
  1065. X        set_tin_uid_gid ();
  1066. X        return (redraw_screen);
  1067. X    }
  1068. X    chmod (article, 0600);
  1069. X
  1070. X    fprintf (fp, "Subject: Re: %s\n", eat_re (note_h_subj));
  1071. X
  1072. X    if (*note_h_followup && strcmp(note_h_followup, "poster") != 0) {
  1073. X        fprintf (fp, "Newsgroups: %s\n", note_h_followup);
  1074. X    } else {
  1075. X        fprintf (fp, "Newsgroups: %s\n", note_h_newsgroups);
  1076. X    }
  1077. X    if (note_h_distrib != '\0') {
  1078. X        fprintf (fp, "Distribution: %s\n", note_h_distrib);
  1079. X        start_line_offset++;
  1080. X    }
  1081. X    fprintf (fp, "References: %s\n", note_h_messageid);
  1082. X
  1083. X    if (*my_org) {
  1084. X        fprintf (fp, "Organization: %s\n", my_org);
  1085. X        start_line_offset++;
  1086. X    }
  1087. X    if (*reply_to) {
  1088. X        fprintf (fp, "Reply-To: %s\n", reply_to);
  1089. X        start_line_offset++;
  1090. X    }
  1091. X    fprintf (fp, "\n");
  1092. X
  1093. X    if (respnum) {        /* if "copy_text" */
  1094. X        if (note_h_from[0]) {     
  1095. X            fprintf (fp, txt_writes, note_h_from);
  1096. X        }
  1097. X        fseek (note_fp, note_mark[0], 0);
  1098. X        copy_fp (note_fp, fp, DEFAULT_COMMENT);
  1099. X    }
  1100. X
  1101. X    add_signature (fp, FALSE);
  1102. X    fclose (fp);
  1103. X
  1104. X    ch = 'e';
  1105. X    while (1) {
  1106. X        switch (ch) {
  1107. X        case 'e':
  1108. X            invoke_editor (article);
  1109. X            redraw_screen = TRUE;
  1110. X            break;
  1111. X
  1112. X        case 'a':
  1113. X            unlink (article);
  1114. X            clear_message ();
  1115. X            set_tin_uid_gid ();
  1116. X            return (redraw_screen);
  1117. X
  1118. X        case 'p':
  1119. X            wait_message (txt_posting);
  1120. X            if (debug) {
  1121. X                sprintf (buf, "%s/inews -h < %s", INEWSDIR, article);
  1122. X            } else {
  1123. X                sprintf (buf, "%s/inews -h < %s > /dev/null 2>&1",
  1124. X                    INEWSDIR, article);
  1125. X            }
  1126. X            if (invoke_cmd (buf)) {
  1127. X                unlink (article);
  1128. X                info_message (txt_art_posted);
  1129. X                goto post_response_done;
  1130. X            } else {
  1131. X                rename_file (article, dead_article);
  1132. X                sprintf (buf, txt_art_rejected, dead_article);
  1133. X                info_message (buf);
  1134. X                sleep (3);
  1135. X                set_tin_uid_gid ();
  1136. X                return (redraw_screen);
  1137. X            }
  1138. X        }
  1139. X
  1140. X        do {
  1141. X            sprintf (msg, "%s%c", txt_abort_edit_post, ch_default);
  1142. X            wait_message (msg);
  1143. X            MoveCursor(LINES, (int) strlen (txt_abort_edit_post));
  1144. X            if ((ch = ReadCh()) == CR)
  1145. X                ch = ch_default;
  1146. X        } while (ch != 'a' && ch != 'e' && ch != 'p');
  1147. X    }
  1148. X
  1149. Xpost_response_done:
  1150. X    set_tin_uid_gid ();
  1151. X
  1152. X    if (*note_h_followup && strcmp(note_h_followup, "poster") != 0)
  1153. X        update_art_posted_file (note_h_followup, note_h_subj);
  1154. X    else
  1155. X        update_art_posted_file (note_h_newsgroups, note_h_subj);
  1156. X
  1157. X    return (redraw_screen);
  1158. X}
  1159. X
  1160. X
  1161. Xint mail_to_someone (address)
  1162. X    char *address;
  1163. X{
  1164. X    char nam[100];
  1165. X    char ch, ch_default = 's';
  1166. X    char buf[LEN+1];
  1167. X    char mail_to[LEN+1];
  1168. X    FILE *fp;
  1169. X    int redraw_screen = FALSE;
  1170. X
  1171. X    start_line_offset = 4;
  1172. X    
  1173. X    strcpy (mail_to, address);
  1174. X    clear_message ();
  1175. X    
  1176. X    set_real_uid_gid ();
  1177. X
  1178. X    sprintf (nam, "%s/.letter", homedir);
  1179. X    if ((fp = fopen (nam, "w")) == NULL) {
  1180. X        error_message (txt_cannot_open, nam);
  1181. X        set_tin_uid_gid ();
  1182. X        return (redraw_screen);
  1183. X    }
  1184. X    chmod (nam, 0600);
  1185. X
  1186. X    fprintf (fp, "To: %s\n", mail_to);
  1187. X    fprintf (fp, "Subject: %s\n", note_h_subj);
  1188. X    if (*note_h_followup) {
  1189. X        fprintf (fp, "Newsgroups: %s\n\n", note_h_followup);
  1190. X    } else {
  1191. X        fprintf (fp, "Newsgroups: %s\n", note_h_newsgroups);
  1192. X    }
  1193. X    if (*my_org) {
  1194. X        fprintf (fp, "Organization: %s\n", my_org);
  1195. X        start_line_offset++;
  1196. X    }
  1197. X    if (*reply_to) {
  1198. X        fprintf (fp, "Reply-To: %s\n", reply_to);
  1199. X        start_line_offset++;
  1200. X    }
  1201. X    fputs ("\n", fp);
  1202. X    
  1203. X    fseek (note_fp, 0L, 0);
  1204. X    copy_fp (note_fp, fp, "");
  1205. X
  1206. X    add_signature (fp, TRUE);
  1207. X    fclose (fp);
  1208. X    
  1209. X    while (1) {
  1210. X        do {
  1211. X            my_strncpy (buf, note_h_subj, COLS-30);
  1212. X            sprintf (msg, "%s [%s]: %c", txt_abort_edit_send, buf, ch_default);
  1213. X            wait_message (msg);
  1214. X            MoveCursor (LINES, (int) strlen (msg)-1);
  1215. X            if ((ch = ReadCh ()) == CR)
  1216. X                ch = ch_default;
  1217. X        } while (ch != 'a' && ch != 'e' && ch != 's');
  1218. X
  1219. X        switch (ch) {
  1220. X        case 'e':
  1221. X            invoke_editor (nam);
  1222. X            redraw_screen = TRUE;
  1223. X            break;
  1224. X
  1225. X        case 'a':
  1226. X            unlink (nam);
  1227. X            clear_message ();
  1228. X            set_tin_uid_gid ();
  1229. X            return (redraw_screen);
  1230. X
  1231. X        case 's':
  1232. X/*
  1233. X *  Open letter and get the To: line in case they changed it with
  1234. X *  the editor
  1235. X */
  1236. X            find_new_to (nam, mail_to);
  1237. X            sprintf (msg, txt_mailing_to, mail_to);
  1238. X            wait_message (msg);
  1239. X            sprintf (buf, "%s \"%s\" < %s", mailer, mail_to, nam);
  1240. X            if (invoke_cmd (buf)) {
  1241. X                info_message (txt_message_sent);
  1242. X                goto mail_to_someone_done;
  1243. X            } else {
  1244. X                error_message (txt_command_failed_s, buf);
  1245. X                break;
  1246. X            }
  1247. X        }
  1248. X    }
  1249. X
  1250. Xmail_to_someone_done:
  1251. X    unlink (nam);
  1252. X    set_tin_uid_gid ();
  1253. X
  1254. X    return (redraw_screen);
  1255. X}
  1256. X
  1257. X
  1258. Xint mail_bug_report ()
  1259. X{
  1260. X    char nam[100];
  1261. X    FILE *fp;
  1262. X    char ch;
  1263. X    char ch_default = 's';
  1264. X    char buf[LEN+1];
  1265. X    char mail_to[LEN+1];
  1266. X
  1267. X    start_line_offset = 5;
  1268. X    
  1269. X    set_real_uid_gid ();
  1270. X
  1271. X    sprintf (nam, "%s/.bugreport", homedir);
  1272. X    if ((fp = fopen (nam, "w")) == NULL) {
  1273. X        error_message (txt_cannot_open, nam);
  1274. X        set_tin_uid_gid ();
  1275. X        return FALSE;
  1276. X    }
  1277. X    chmod(nam, 0600);
  1278. X
  1279. X    fprintf (fp, "To: %s\n", bug_addr);
  1280. X    fprintf (fp, "Subject: BUG REPORT %s %s PL%d %s\n",    progname,
  1281. X        version, PATCHLEVEL, (compiled_with_nntp ? "(NNTP)" : ""));
  1282. X    if (*my_org) {
  1283. X        fprintf (fp, "Organization: %s\n", my_org);
  1284. X        start_line_offset++;
  1285. X    }
  1286. X    if (*reply_to) {
  1287. X        fprintf (fp, "Reply-To: %s\n", reply_to);
  1288. X        start_line_offset++;
  1289. X    }
  1290. X    fprintf (fp, "\nPlease enter the following information:\n");
  1291. X    fprintf (fp, "1) machine:\n");
  1292. X    fprintf (fp, "2) os type:\n");
  1293. X    fprintf (fp, "\nPlease enter bug/gripe/comment report:\n");
  1294. X
  1295. X    add_signature (fp, TRUE);
  1296. X    fclose (fp);
  1297. X    
  1298. X    ch = 'e';
  1299. X    while (1) {
  1300. X        switch (ch) {
  1301. X        case 'e':
  1302. X            invoke_editor (nam);
  1303. X            break;
  1304. X
  1305. X        case 'a':
  1306. X            unlink (nam);
  1307. X            clear_message ();
  1308. X            set_tin_uid_gid ();
  1309. X            return TRUE;
  1310. X
  1311. X        case 's':
  1312. X            strcpy (mail_to, bug_addr);
  1313. X            find_new_to (nam, mail_to);
  1314. X            sprintf (msg, txt_mailing_to, mail_to);
  1315. X            wait_message (msg);
  1316. X            sprintf (buf, "%s \"%s\" < %s", mailer, mail_to, nam);
  1317. X            if (invoke_cmd (buf)) {
  1318. X                info_message (txt_message_sent);
  1319. X                goto mail_bug_report_done;
  1320. X            } else {
  1321. X                error_message (txt_command_failed_s, buf);
  1322. X                break;
  1323. X            }
  1324. X        }
  1325. X
  1326. X        do {
  1327. X            sprintf (msg, "%s: %c", txt_abort_edit_send, ch_default);
  1328. X            wait_message (msg);
  1329. X            MoveCursor (LINES, (int) strlen (msg)-1);
  1330. X            if ((ch = ReadCh ()) == CR)
  1331. X                ch = ch_default;
  1332. X        } while (ch != 'a' && ch != 'e' && ch != 's');
  1333. X    }
  1334. X
  1335. Xmail_bug_report_done:
  1336. X    unlink (nam);
  1337. X    set_tin_uid_gid ();
  1338. X
  1339. X    return TRUE;
  1340. X}
  1341. X
  1342. X
  1343. Xint mail_to_author (copy_text)
  1344. X    int copy_text;
  1345. X{
  1346. X    char buf[LEN+1];
  1347. X    char nam[100];
  1348. X    char mail_to[LEN+1];
  1349. X    char ch, ch_default = 's';
  1350. X    FILE *fp;
  1351. X    int redraw_screen = FALSE;
  1352. X
  1353. X    start_line_offset = 4;
  1354. X    
  1355. X    set_real_uid_gid ();
  1356. X
  1357. X    sprintf (nam, "%s/.letter", homedir);
  1358. X    if ((fp = fopen (nam, "w")) == NULL) {
  1359. X        error_message (txt_cannot_open, nam);
  1360. X        set_tin_uid_gid ();
  1361. X        return (redraw_screen);
  1362. X    }
  1363. X    chmod (nam, 0600);
  1364. X
  1365. X    fprintf (fp, "To: %s%s (%s)\n", note_from_addr, add_addr, note_full_name);
  1366. X    fprintf (fp, "Subject: Re: %s\n", eat_re(note_h_subj) );
  1367. X    fprintf (fp, "Newsgroups: %s\n", note_h_newsgroups);
  1368. X    if (*my_org) {
  1369. X        fprintf (fp, "Organization: %s\n", my_org);
  1370. X        start_line_offset++;
  1371. X    }
  1372. X    if (*reply_to) {
  1373. X        fprintf (fp, "Reply-To: %s\n", reply_to);
  1374. X        start_line_offset++;
  1375. X    }
  1376. X    fputs ("\n", fp);
  1377. X
  1378. X    if (copy_text) {        /* if "copy_text" */
  1379. X        fprintf (fp, txt_in_art_you_write, note_h_messageid);
  1380. X        fseek (note_fp, note_mark[0], 0);
  1381. X        copy_fp (note_fp, fp, DEFAULT_COMMENT);
  1382. X    }
  1383. X
  1384. X    add_signature (fp, TRUE);
  1385. X    fclose (fp);
  1386. X
  1387. X    ch = 'e';
  1388. X    while (1) {
  1389. X        switch (ch) {
  1390. X        case 'e':
  1391. X            invoke_editor (nam);
  1392. X            redraw_screen = TRUE;
  1393. X            break;
  1394. X
  1395. X        case 'a':
  1396. X            unlink (nam);
  1397. X            clear_message ();
  1398. X            set_tin_uid_gid ();
  1399. X            return (redraw_screen);
  1400. X
  1401. X        case 's':
  1402. X            strcpy (mail_to, note_from_addr);
  1403. X            find_new_to (nam, mail_to);
  1404. X            sprintf (msg, txt_mailing_to, mail_to);
  1405. X            wait_message (msg);
  1406. X            sprintf (buf, "%s \"%s\" < %s", mailer, mail_to, nam);
  1407. X            if (invoke_cmd (buf)) {
  1408. X                info_message (txt_message_sent);
  1409. X                goto mail_to_author_done;
  1410. X            } else {
  1411. X                error_message (txt_command_failed_s, buf);
  1412. X                break;
  1413. X            }
  1414. X        }
  1415. X
  1416. X        do {
  1417. X            sprintf (msg, "%s: %c", txt_abort_edit_send, ch_default);
  1418. X            wait_message (msg);
  1419. X            MoveCursor (LINES, (int) strlen (msg)-1);
  1420. X            if ((ch = ReadCh ()) == CR)
  1421. X                ch = ch_default;
  1422. X        } while (ch != 'a' && ch != 'e' && ch != 's');
  1423. X    }
  1424. X
  1425. Xmail_to_author_done:
  1426. X    unlink (nam);
  1427. X    set_tin_uid_gid ();
  1428. X
  1429. X    return (redraw_screen);
  1430. X}
  1431. X
  1432. X/*
  1433. X *  Read a file grabbing the address given for To: and
  1434. X *  sticking it in mail_to
  1435. X */
  1436. X
  1437. Xvoid find_new_to (nam, mail_to)
  1438. X    char *nam;
  1439. X    char *mail_to;
  1440. X{
  1441. X    FILE *fp;
  1442. X    char buf[LEN+1];
  1443. X    char buf2[LEN+1];
  1444. X    char new_mail_to[LEN+1];
  1445. X    char *p;
  1446. X
  1447. X    *new_mail_to = '\0';
  1448. X
  1449. X    if ((fp = fopen(nam, "r")) == NULL) {
  1450. X        fprintf(stderr, txt_cannot_open, nam);
  1451. X        return;
  1452. X    }
  1453. X
  1454. X    while (fgets(buf, 1024, fp) != NULL) {
  1455. X        for (p = buf; *p && *p != '\n'; p++)
  1456. X            continue;
  1457. X        *p = '\0';
  1458. X
  1459. X        if (*buf == '\0')
  1460. X            break;
  1461. X
  1462. X        if (strncmp(buf, "To: ", 4) == 0) {
  1463. X            strncpy(buf2, &buf[4], LEN);
  1464. X            buf2[LEN-1] = '\0';
  1465. X            yank_to_addr(buf2, new_mail_to);
  1466. X        } else if (strncmp(buf, "Cc: ", 4) == 0) {
  1467. X            strncpy(buf2, &buf[4], LEN);
  1468. X            buf2[LEN-1] = '\0';
  1469. X            yank_to_addr(buf2, new_mail_to);
  1470. X        }
  1471. X    }
  1472. X
  1473. X    fclose (fp);
  1474. X    if (new_mail_to[0] == ' ')
  1475. X        my_strncpy (mail_to, &new_mail_to[1], LEN);
  1476. X    else
  1477. X        my_strncpy (mail_to, new_mail_to, LEN);
  1478. X}
  1479. X
  1480. X
  1481. Xint cancel_article ()
  1482. X{
  1483. X    char ch, ch_default = 'c';
  1484. X    char buf[LEN];
  1485. X    char cancel[LEN];
  1486. X    FILE *fp;
  1487. X    int redraw_screen = FALSE;
  1488. X
  1489. X    start_line_offset = 4;
  1490. X    
  1491. X    clear_message ();
  1492. X    
  1493. X    set_real_uid_gid ();
  1494. X
  1495. X    sprintf (cancel, "%s/.cancel", homedir);
  1496. X    if ((fp = fopen (cancel, "w")) == NULL) {
  1497. X        error_message (txt_cannot_open, cancel);
  1498. X        set_tin_uid_gid ();
  1499. X        return (redraw_screen);
  1500. X    }
  1501. X    chmod (cancel, 0600);
  1502. X
  1503. X    fprintf (fp, "Subject: cancel %s\n", note_h_messageid);
  1504. X    if (*note_h_followup) {
  1505. X        fprintf (fp, "Newsgroups: %s\n", note_h_followup);
  1506. X    } else {
  1507. X        fprintf (fp, "Newsgroups: %s\n", note_h_newsgroups);
  1508. X    }
  1509. X    fprintf (fp, "Control: cancel %s\n", note_h_messageid);
  1510. X    if (*my_org) { 
  1511. X        fprintf (fp, "Organization: %s\n", my_org);
  1512. X        start_line_offset++;    
  1513. X    }
  1514. X    if (*reply_to) {
  1515. X        fprintf (fp, "Reply-To: %s\n", reply_to);
  1516. X        start_line_offset++;    
  1517. X    }
  1518. X    fputs ("\n", fp);
  1519. X
  1520. X    fprintf (fp, "Article cancelled from within tin\n");
  1521. X    
  1522. X    add_signature (fp, TRUE);
  1523. X    fclose (fp);
  1524. X    
  1525. X    while (1) {
  1526. X        do {
  1527. X            my_strncpy (buf, note_h_subj, COLS-30);
  1528. X            sprintf (msg, "%s [%s]: %c", txt_abort_edit_cancel, buf, ch_default);
  1529. X            wait_message (msg);
  1530. X            MoveCursor (LINES, (int) strlen (msg)-1);
  1531. X            if ((ch = ReadCh ()) == CR)
  1532. X                ch = ch_default;
  1533. X        } while (ch != 'a' && ch != 'e' && ch != 'c');
  1534. X
  1535. X        switch (ch) {
  1536. X        case 'e':
  1537. X            invoke_editor (cancel);
  1538. X            redraw_screen = TRUE;
  1539. X            break;
  1540. X
  1541. X        case 'a':
  1542. X            unlink (cancel);
  1543. X            clear_message ();
  1544. X            set_tin_uid_gid ();
  1545. X            return (redraw_screen);
  1546. X
  1547. X        case 'c':
  1548. X            wait_message (txt_cancelling);
  1549. X            sprintf (buf, "%s/inews -h < %s", INEWSDIR, cancel);
  1550. X            if (invoke_cmd (buf)) {
  1551. X                info_message (txt_art_cancelled);
  1552. X                goto cancel_article_done;
  1553. X            } else {
  1554. X                error_message (txt_command_failed_s, buf);
  1555. X                break;
  1556. X            }
  1557. X        }
  1558. X    }
  1559. X
  1560. Xcancel_article_done:
  1561. X    unlink (cancel);
  1562. X    set_tin_uid_gid ();
  1563. X
  1564. X    return (redraw_screen);
  1565. X}
  1566. SHAR_EOF
  1567. $TOUCH -am 0923175591 post.c &&
  1568. chmod 0600 post.c ||
  1569. echo "restore of post.c failed"
  1570. set `wc -c post.c`;Wc_c=$1
  1571. if test "$Wc_c" != "17061"; then
  1572.     echo original size 17061, current size $Wc_c
  1573. fi
  1574. # ============= prompt.c ==============
  1575. echo "x - extracting prompt.c (Text)"
  1576. sed 's/^X//' << 'SHAR_EOF' > prompt.c &&
  1577. X/*
  1578. X *  Project   : tin - a visual threaded usenet newsreader
  1579. X *  Module    : prompt.c
  1580. X *  Author    : R.Skrenta / I.Lea
  1581. X *  Created   : 01-04-91
  1582. X *  Updated   : 10-08-91
  1583. X *  Release   : 1.0
  1584. X *  Notes     :
  1585. X *  Copyright : (c) Copyright 1991 by Rich Skrenta & Iain Lea
  1586. X *                You may  freely  copy or  redistribute  this software,
  1587. X *              so  long as there is no profit made from its use, sale
  1588. X *              trade or  reproduction.  You may not change this copy-
  1589. X *              right notice, and it must be included in any copy made
  1590. X */
  1591. X
  1592. X#include    "tin.h"
  1593. X
  1594. X/*
  1595. X *  parse_num
  1596. X *  get a number from the user
  1597. X *  Return -1 if missing or bad number typed
  1598. X */
  1599. X
  1600. Xint parse_num (ch, prompt)
  1601. X    char ch;
  1602. X    char *prompt;
  1603. X{
  1604. X    char buf[40];
  1605. X    int len;
  1606. X    int i;
  1607. X    int num;
  1608. X
  1609. X    MoveCursor (LINES,0);
  1610. X    printf ("%s %c",prompt,ch);
  1611. X    fflush (stdout);
  1612. X    buf[0] = ch;
  1613. X    buf[1] = '\0';
  1614. X    len = 1;
  1615. X    ch = ReadCh ();
  1616. X    while (ch != '\n' && ch != '\r') {
  1617. X        if (ch == 8 || ch == 127) {
  1618. X            if (len) {
  1619. X                len--;
  1620. X                buf[len] = '\0';
  1621. X                putchar ('\b');
  1622. X                putchar (' ');
  1623. X                putchar ('\b');
  1624. X            } else {
  1625. X                MoveCursor (LINES, 0);
  1626. X                CleartoEOLN ();
  1627. X                return (-1);
  1628. X            }
  1629. X        } else if (ch == 21) {    /* control-U    */
  1630. X            for (i = len ; i>0 ; i--) {
  1631. X                putchar ('\b');
  1632. X                putchar (' ');
  1633. X                putchar ('\b');
  1634. X            }
  1635. X            buf[0] = '\0';
  1636. X            len = 0;
  1637. X        } else if (ch >= '0' && ch <= '9' && len < 4) {
  1638. X            buf[len++] = ch;
  1639. X            buf[len] = '\0';
  1640. X            putchar (ch);
  1641. X        } else
  1642. X            putchar (7);
  1643. X        fflush (stdout);
  1644. X        ch = ReadCh ();
  1645. X    }
  1646. X
  1647. X    MoveCursor (LINES, 0);
  1648. X    CleartoEOLN ();
  1649. X
  1650. X    if (len) {
  1651. X        num = atoi (buf);
  1652. X        return (num);
  1653. X    } else
  1654. X        return(-1);
  1655. X}
  1656. X
  1657. X
  1658. X/*
  1659. X *  parse_string
  1660. X *  get a string from the user
  1661. X *  Return TRUE if a valid string was typed, FALSE otherwise
  1662. X */
  1663. X
  1664. Xint parse_string (prompt, buf)
  1665. X    char *prompt;
  1666. X    char *buf;
  1667. X{
  1668. X    int len;
  1669. X    int i;
  1670. X    char ch;
  1671. X
  1672. X    clear_message();
  1673. X    MoveCursor(LINES,0);
  1674. X    printf("%s", prompt);
  1675. X    fflush(stdout);
  1676. X
  1677. X    buf[0] = '\0';
  1678. X    len = 0;
  1679. X    ch = ReadCh();
  1680. X    while (ch != '\n' && ch != '\r') {
  1681. X        if (ch == 8 || ch == 127) {
  1682. X            if (len) {
  1683. X                len--;
  1684. X                buf[len] = '\0';
  1685. X                putchar('\b');
  1686. X                putchar(' ');
  1687. X                putchar('\b');
  1688. X            } else {
  1689. X                MoveCursor(LINES, 0);
  1690. X                CleartoEOLN();
  1691. X                return(FALSE);
  1692. X            }
  1693. X        } else if (ch == 21) {    /* control-U    */
  1694. X            for (i = len;i>0;i--) {
  1695. X                putchar('\b');
  1696. X                putchar(' ');
  1697. X                putchar('\b');
  1698. X            }
  1699. X            buf[0] = '\0';
  1700. X            len = 0;
  1701. X        } else if (ch >= ' ' && len < 60) {
  1702. X            buf[len++] = ch;
  1703. X            buf[len] = '\0';
  1704. X            putchar (ch);
  1705. X        } else
  1706. X            putchar(7);
  1707. X        fflush(stdout);
  1708. X        ch = ReadCh();
  1709. X    }
  1710. X    MoveCursor(LINES,0);
  1711. X    CleartoEOLN();
  1712. X
  1713. X    return TRUE;
  1714. X}
  1715. X
  1716. X
  1717. Xint prompt_yn (line, prompt, default_ch)
  1718. X    int line;
  1719. X    char *prompt;
  1720. X    char default_ch;
  1721. X{
  1722. X    char ch;
  1723. X
  1724. X    MoveCursor (line, 0);
  1725. X    CleartoEOLN ();
  1726. X    printf ("%s%c", prompt, default_ch);
  1727. X    fflush (stdout);
  1728. X    MoveCursor (line, (int) strlen (prompt));
  1729. X
  1730. X    if ((ch = ReadCh()) == CR) {
  1731. X        ch = default_ch;
  1732. X    }    
  1733. X
  1734. X    if (line == LINES) {
  1735. X        clear_message();
  1736. X    } else {
  1737. X        MoveCursor (line, (int) strlen (prompt));
  1738. X        printf ("%c", ch);
  1739. X        fflush (stdout);
  1740. X    }
  1741. X
  1742. X    return (ch == 'y' ? TRUE : FALSE);
  1743. X}
  1744. X
  1745. X
  1746. Xvoid continue_prompt()
  1747. X{
  1748. X    info_message(txt_hit_any_key);
  1749. X    ReadCh();
  1750. X}
  1751. X
  1752. X
  1753. SHAR_EOF
  1754. $TOUCH -am 0923175591 prompt.c &&
  1755. chmod 0600 prompt.c ||
  1756. echo "restore of prompt.c failed"
  1757. set `wc -c prompt.c`;Wc_c=$1
  1758. if test "$Wc_c" != "3098"; then
  1759.     echo original size 3098, current size $Wc_c
  1760. fi
  1761. # ============= rcfile.c ==============
  1762. echo "x - extracting rcfile.c (Text)"
  1763. sed 's/^X//' << 'SHAR_EOF' > rcfile.c &&
  1764. X/*
  1765. X *  Project   : tin - a visual threaded usenet newsreader
  1766. X *  Module    : rcfile.c
  1767. X *  Author    : I.Lea
  1768. X *  Created   : 01-04-91
  1769. X *  Updated   : 16-09-91
  1770. X *  Release   : 1.0
  1771. X *  Notes     :
  1772. X *  Copyright : (c) Copyright 1991 by Iain Lea
  1773. X *                You may  freely  copy or  redistribute  this software,
  1774. X *              so  long as there is no profit made from its use, sale
  1775. X *              trade or  reproduction.  You may not change this copy-
  1776. X *              right notice, and it must be included in any copy made
  1777. X */
  1778. X
  1779. X#include    "tin.h"
  1780. X
  1781. X#define COL2    COLS/2
  1782. X
  1783. Xextern char index_file[LEN+1];
  1784. X
  1785. X/*
  1786. X *  read_rcfile - read defaults from ~/.tin/tinrc
  1787. X */
  1788. X
  1789. Xint read_rcfile ()
  1790. X{
  1791. X    char buf[LEN+1];
  1792. X    FILE *fp;
  1793. X
  1794. X    if ((fp = fopen (rcfile, "r")) != NULL) {
  1795. X        while (fgets (buf, sizeof buf, fp) != NULL) {
  1796. X            if (buf[0] != '#') { 
  1797. X                if (strncmp (buf, "save_archive=", 13) == 0) {
  1798. X                    save_archive_name = (strncmp (&buf[13], "ON", 2) == 0 ? TRUE : FALSE);
  1799. X                } else if (strncmp (buf, "save_separate=", 14) == 0) {
  1800. X                    save_separate = (strncmp (&buf[14], "ON", 2) == 0 ? TRUE : FALSE);
  1801. X                } else if (strncmp (buf, "mark_saved_read=", 16) == 0) {
  1802. X                    mark_saved_read = (strncmp (&buf[16], "ON", 2) == 0 ? TRUE : FALSE);
  1803. X                } else if (strncmp (buf, "kill_articles=", 14) == 0) {
  1804. X                    kill_articles = (strncmp (&buf[14], "ON", 2) == 0 ? TRUE : FALSE);
  1805. X                } else if (strncmp (buf, "show_author=", 12) == 0) {
  1806. X                    show_author = (strncmp (&buf[12], "ON", 2) == 0 ? TRUE : FALSE);
  1807. X                } else if (strncmp (buf, "draw_arrow=", 11) == 0) {
  1808. X                    draw_arrow_mark = (strncmp (&buf[11], "ON", 2) == 0 ? TRUE : FALSE);
  1809. X                    if (draw_arrow_mark == FALSE && inverse_okay == FALSE) {
  1810. X                        inverse_okay = TRUE;
  1811. X                    }
  1812. X                } else if (strncmp (buf, "print_header=", 13) == 0) {
  1813. X                    print_header = (strncmp (&buf[13], "ON", 2) == 0 ? TRUE : FALSE);
  1814. X                } else if (strncmp (buf, "pos_first_unread=", 17) == 0) {
  1815. X                    pos_first_unread = (strncmp (&buf[17], "ON", 2) == 0 ? TRUE : FALSE);
  1816. X                } else if (strncmp (buf, "post_process_type=", 18) == 0) {
  1817. X                    post_proc_type = atoi (&buf[18]);
  1818. X                    switch (post_proc_type) {
  1819. X                        case POST_PROC_NONE:
  1820. X                            proc_ch_default = 'n';
  1821. X                            break;
  1822. X                        case POST_PROC_SHAR:
  1823. X                            proc_ch_default = 's';
  1824. X                            break;
  1825. X                        case POST_PROC_UUDECODE:
  1826. X                            proc_ch_default = 'u';
  1827. X                            break;
  1828. X                        case POST_PROC_UUD_LST_ZOO:
  1829. X                            proc_ch_default = 'U';
  1830. X                            break;
  1831. X                        case POST_PROC_UUD_EXT_ZOO:
  1832. X                            proc_ch_default = 'U';
  1833. X                            break;
  1834. X                        case POST_PROC_PATCH:
  1835. X                            proc_ch_default = 'p';
  1836. X                            break;
  1837. X                    }
  1838. X                } else if (strncmp (buf, "sort_article_type=", 18) == 0) {
  1839. X                    sort_art_type = atoi (&buf[18]);
  1840. X                } else if (strncmp (buf, "savedir=", 8) == 0) {
  1841. X                    strncpy (savedir, &buf[8], LEN);
  1842. X                    savedir[strlen (savedir) - 1] = '\0';
  1843. X                    if (savedir[0] == '.' && strlen (savedir) == 1) {
  1844. X#ifdef BSD
  1845. X                        getwd (buf);    
  1846. X#else
  1847. X                        getcwd (buf, LEN);
  1848. X#endif
  1849. X                        my_strncpy (savedir, buf, LEN);
  1850. X                    }
  1851. X                } else if (strncmp (buf, "maildir=", 8) == 0) {
  1852. X                    strncpy (maildir, &buf[8], LEN);
  1853. X                    maildir[strlen (maildir) - 1] = '\0';
  1854. X                } else if (strncmp (buf, "printer=", 8) == 0) {
  1855. X                    strncpy (printer, &buf[8], LEN);
  1856. X                    printer[strlen (printer) - 1] = '\0';
  1857. X                } else if (strncmp (buf, "spooldir=", 9) == 0) {
  1858. X                    strncpy (spooldir, &buf[9], LEN);
  1859. X                    spooldir[strlen (spooldir) - 1] = '\0';
  1860. X                } else if (strncmp (buf, "signature=", 10) == 0) {
  1861. X                    strncpy (signature, &buf[10], LEN);
  1862. X                    signature[strlen (signature) - 1] = '\0';
  1863. X                } else if (strncmp (buf, "sig=", 4) == 0) {
  1864. X                    strncpy (sig, &buf[4], LEN);
  1865. X                    sig[strlen (sig) - 1] = '\0';
  1866. X                }
  1867. X            }
  1868. X        }
  1869. X        fclose (fp);
  1870. X        return TRUE;        
  1871. X    }
  1872. X    return FALSE;        
  1873. X}
  1874. X
  1875. X/*
  1876. X *  write_rcfile - write defaults to ~/.tin/tinrc
  1877. X */
  1878. X
  1879. Xvoid write_rcfile ()
  1880. X{
  1881. X    FILE *fp;
  1882. X
  1883. X    set_real_uid_gid ();
  1884. X    
  1885. X    if ((fp = fopen (rcfile, "w")) != NULL) {
  1886. X        wait_message (txt_saving);
  1887. X
  1888. X        fprintf (fp, "# if ON articles/threads with Archive-name: in mail header will\n");
  1889. X        fprintf (fp, "# be automatically saved with the Archive-name & part/patch no.\n");
  1890. X        fprintf (fp, "save_archive=%s\n\n", (save_archive_name ? "ON" : "OFF"));
  1891. X        fprintf (fp, "# if ON articles of a threads will be saved to separate files\n");
  1892. X        fprintf (fp, "# otherwise the whole thread will be saved to one file\n");
  1893. X        fprintf (fp, "save_separate=%s\n\n", (save_separate ? "ON" : "OFF"));
  1894. X        fprintf (fp, "# if ON mark articles that are saved as read\n");
  1895. X        fprintf (fp, "mark_saved_read=%s\n\n", (mark_saved_read ? "ON" : "OFF"));
  1896. X        fprintf (fp, "# if ON show Subject & From otherwise just Subject\n");
  1897. X        fprintf (fp, "show_author=%s\n\n", (show_author ? "ON" : "OFF"));
  1898. X        fprintf (fp, "# if ON use -> otherwise highlighted bar for selection\n");
  1899. X        fprintf (fp, "draw_arrow=%s\n\n", (draw_arrow_mark ? "ON" : "OFF"));
  1900. X        fprintf (fp, "# if ON kill articles that match kill file\n");
  1901. X        fprintf (fp, "kill_articles=%s\n\n", (kill_articles ? "ON" : "OFF"));
  1902. X        fprintf (fp, "# if ON print all of mail header otherwise Subject: & From: lines\n");
  1903. X        fprintf (fp, "print_header=%s\n\n", (print_header ? "ON" : "OFF"));
  1904. X        fprintf (fp, "# if ON put cursor at first unread art in group otherwise last art\n");
  1905. X        fprintf (fp, "pos_first_unread=%s\n\n", (pos_first_unread ? "ON" : "OFF"));
  1906. X        fprintf (fp, "# type of post processing to perform after saving articles.\n");
  1907. X        fprintf (fp, "# 0) none 1) shar 2) uudecode 3) uud & list zoo 4) uud & extract zoo 5) patch.\n");
  1908. X        fprintf (fp, "post_process_type=%d\n\n", post_proc_type);
  1909. X        fprintf (fp, "# sort articles by 0) nothing 1) Subject (descending) 2) Subject (ascending)\n");
  1910. X        fprintf (fp, "# 3) From (descend) 4) From (ascend) 5) Date (descend) 6) Date (ascend)\n");
  1911. X        fprintf (fp, "sort_article_type=%d\n\n", sort_art_type);
  1912. X        fprintf (fp, "# (-d) directory where articles/threads are saved\n");
  1913. X        fprintf (fp, "savedir=%s\n\n", savedir);
  1914. X        fprintf (fp, "# (-M) directory where articles/threads are saved in mailbox format\n");    
  1915. X        fprintf (fp, "maildir=%s\n\n", maildir);    
  1916. X        fprintf (fp, "# (-p) print program with parameters used to print articles/threads\n");
  1917. X        fprintf (fp, "printer=%s\n\n", printer);
  1918. X        fprintf (fp, "# (-S) directory where news is spooled\n");
  1919. X        fprintf (fp, "spooldir=%s\n\n", spooldir);
  1920. X
  1921. X        fprintf (fp, "# .signature file used for replies, followups\n");
  1922. X        fprintf (fp, "signature=%s\n\n", signature);
  1923. X        fprintf (fp, "# .Sig file used for postings\n");
  1924. X        fprintf (fp, "sig=%s\n\n", sig);
  1925. X
  1926. X        fclose (fp);
  1927. X        chmod (rcfile, 0600);
  1928. X    }
  1929. X    set_tin_uid_gid ();
  1930. X}
  1931. X
  1932. X/*
  1933. X *  options menu so that the user can dynamically change parameters
  1934. X */
  1935. Xint change_rcfile (group, kill_at_once)
  1936. X    char *group;
  1937. X    int kill_at_once;
  1938. X{
  1939. X    char *str;
  1940. X    int ch;
  1941. X    int kill_changed = FALSE;
  1942. X    int orig_kill_state;
  1943. X    int option;
  1944. X    int ret_code = NO_KILLING;
  1945. X#ifdef SIGTSTP
  1946. X    void (*susp)();
  1947. X
  1948. X    if (do_sigtstp) {
  1949. X#ifdef POSIX_JOB_CONTROL
  1950. X        sigemptyset (&rcfile_act.sa_mask);
  1951. X        rcfile_act.sa_flags = SA_RESTART | SA_RESETHAND;
  1952. X        rcfile_act.sa_handler = SIG_DFL;
  1953. X        sigaction (SIGTSTP, &rcfile_act, &old_act);
  1954. X#else
  1955. X        susp = signal (SIGTSTP, SIG_DFL);
  1956. X#endif
  1957. X    }
  1958. X#endif
  1959. X
  1960. X    show_rcfile_menu ();
  1961. X
  1962. X    while (1) {
  1963. X
  1964. X#ifdef SIGTSTP
  1965. X        if (do_sigtstp) {
  1966. X#ifdef POSIX_JOB_CONTROL
  1967. X            sigemptyset (&rcfile_act.sa_mask);
  1968. X            rcfile_act.sa_flags = SA_RESTART | SA_RESETHAND;
  1969. X            rcfile_act.sa_handler = rcfile_suspend;
  1970. X            sigaction (SIGTSTP, &rcfile_act, 0L);
  1971. X#else
  1972. X            signal (SIGTSTP, rcfile_suspend);
  1973. X#endif
  1974. X        }
  1975. X#endif
  1976. X        MoveCursor (LINES, 0);
  1977. X        ch = ReadCh ();
  1978. X        if (ch >= '1' && ch <= '9') {
  1979. X            option = parse_num (ch, "Enter option number> ");
  1980. X        } else {
  1981. X            option = 0;
  1982. X        }
  1983. X#ifdef SIGTSTP
  1984. X        if (do_sigtstp) {
  1985. X#ifdef POSIX_JOB_CONTROL
  1986. X            sigemptyset (&rcfile_act.sa_mask);
  1987. X            rcfile_act.sa_flags = SA_RESTART | SA_RESETHAND;
  1988. X            rcfile_act.sa_handler = SIG_IGN;
  1989. X            sigaction (SIGTSTP, &rcfile_act, 0L);
  1990. X#else
  1991. X            signal (SIGTSTP, SIG_IGN);
  1992. X#endif
  1993. X        }
  1994. X#endif
  1995. X        switch (option) {
  1996. X            case 0:
  1997. X                write_rcfile ();
  1998. X                if (kill_changed) {
  1999. X                    if (kill_at_once) {
  2000. X                        if (kill_articles) {
  2001. X                            read_kill_file ();
  2002. X                            if (kill_any_articles (group)) {
  2003. X                                reload_index_file (group, TRUE);    /* kill arts */
  2004. X                            }
  2005. X                        } else {
  2006. X                            reload_index_file (group, FALSE);    /* add killed arts */
  2007. X                        }
  2008. X                    }
  2009. X                    ret_code = KILLING;
  2010. X                }
  2011. X                clear_note_area ();
  2012. X#ifdef SIGTSTP
  2013. X                if (do_sigtstp) {
  2014. X#ifdef POSIX_JOB_CONTROL
  2015. X                    sigemptyset (&rcfile_act.sa_mask);
  2016. X                    rcfile_act.sa_flags = SA_RESTART | SA_RESETHAND;
  2017. X                    rcfile_act.sa_handler = SIG_IGN;
  2018. X                    sigaction (SIGTSTP, &old_act, 0L);
  2019. X#else
  2020. X                    signal (SIGTSTP, susp);
  2021. X#endif
  2022. X                }
  2023. X#endif
  2024. X                return ret_code;
  2025. X            
  2026. X            case 1:        /* auto save */
  2027. X                show_menu_help (txt_help_autosave);
  2028. X                do {
  2029. X                    MoveCursor (INDEX_TOP, (int) strlen (txt_opt_autosave));
  2030. X                    if ((ch = ReadCh()) == ' ') {
  2031. X                        save_archive_name = !save_archive_name;
  2032. X                        printf ("%s", (save_archive_name ? "ON " : "OFF"));
  2033. X                        fflush(stdout);
  2034. X                    }
  2035. X                } while (ch != CR);
  2036. X                break;
  2037. X
  2038. X            case 2:        /* save sperate */
  2039. X                show_menu_help (txt_help_save_separate);
  2040. X                do {
  2041. X                    MoveCursor (INDEX_TOP, COL2 + (int) strlen (txt_opt_save_separate));
  2042. X                    if ((ch = ReadCh()) == ' ') {
  2043. X                        save_separate = !save_separate;
  2044. X                        printf ("%s", (save_separate ? "ON " : "OFF"));
  2045. X                        fflush(stdout);
  2046. X                    }
  2047. X                } while (ch != CR);
  2048. X                break;
  2049. X            
  2050. X            case 3:        /* mark saved articles read */
  2051. X                show_menu_help (txt_help_mark_saved_read);
  2052. X                do {
  2053. X                    MoveCursor (INDEX_TOP+2, (int) strlen (txt_opt_mark_saved_read));
  2054. X                    if ((ch = ReadCh()) == ' ') {
  2055. X                        mark_saved_read = !mark_saved_read;
  2056. X                        printf ("%s", (mark_saved_read ? "ON " : "OFF"));
  2057. X                        fflush(stdout);
  2058. X                    }
  2059. X                } while (ch != CR);
  2060. X                break;
  2061. X
  2062. X            case 4:        /* kill articles */
  2063. X                orig_kill_state = kill_articles;
  2064. X                show_menu_help (txt_help_kill_articles);
  2065. X                do {
  2066. X                    MoveCursor (INDEX_TOP+2, COL2 + (int) strlen (txt_opt_kill_articles));
  2067. X                    if ((ch = ReadCh()) == ' ') {
  2068. X                        kill_articles = !kill_articles;
  2069. X                        kill_changed = (kill_articles != orig_kill_state ? TRUE : FALSE);
  2070. X                        printf ("%s", (kill_articles ? "ON " : "OFF"));
  2071. X                        fflush(stdout);
  2072. X                    }
  2073. X                } while (ch != CR);
  2074. X                break;
  2075. X
  2076. X            case 5:        /* show subject & author / subject only */
  2077. X                show_menu_help (txt_help_show_author);
  2078. X                do {
  2079. X                    MoveCursor (INDEX_TOP+4, (int) strlen (txt_opt_show_author));
  2080. X                    if ((ch = ReadCh()) == ' ') {
  2081. X                        show_author = !show_author;
  2082. X                        printf ("%s", (show_author ? "ON " : "OFF"));
  2083. X                        fflush(stdout);    
  2084. X                    }
  2085. X                } while (ch != CR);
  2086. X                break;
  2087. X            
  2088. X            case 6:        /* draw -> / highlighted bar */
  2089. X                show_menu_help (txt_help_draw_arrow);
  2090. X                do {
  2091. X                    MoveCursor (INDEX_TOP+4, COL2 + (int) strlen (txt_opt_draw_arrow));
  2092. X                    if ((ch = ReadCh()) == ' ') {
  2093. X                        draw_arrow_mark = !draw_arrow_mark;
  2094. X                        printf ("%s", (draw_arrow_mark ? "ON " : "OFF"));
  2095. X                        fflush(stdout);
  2096. X                    }
  2097. X                } while (ch != CR);
  2098. X                if (draw_arrow_mark == FALSE && inverse_okay == FALSE) {
  2099. X                    inverse_okay = TRUE;
  2100. X                }
  2101. X                break;
  2102. X
  2103. X            case 7:        /* print header */
  2104. X                show_menu_help (txt_help_print_header);
  2105. X                do {
  2106. X                    MoveCursor (INDEX_TOP+6, (int) strlen (txt_opt_print_header));
  2107. X                    if ((ch = ReadCh()) == ' ') {
  2108. X                        print_header = !print_header;
  2109. X                        printf ("%s", (print_header ? "ON " : "OFF"));
  2110. X                        fflush(stdout);
  2111. X                    }
  2112. X                } while (ch != CR);
  2113. X                break;
  2114. X            
  2115. X            case 8:        /* position cursor at first / last unread art */
  2116. X                show_menu_help (txt_help_pos_first_unread);
  2117. X                do {
  2118. X                    MoveCursor (INDEX_TOP+6, COL2 + (int) strlen (txt_opt_pos_first_unread));
  2119. X                    if ((ch = ReadCh()) == ' ') {
  2120. X                        pos_first_unread = !pos_first_unread;
  2121. X                        printf ("%s", (pos_first_unread ? "ON " : "OFF"));
  2122. X                        fflush(stdout);
  2123. X                    }
  2124. X                } while (ch != CR);
  2125. X                break;
  2126. X
  2127. X            case 9:
  2128. X                show_menu_help (txt_help_post_proc_type);
  2129. SHAR_EOF
  2130. echo "End of tin1.02 part 6"
  2131. echo "File rcfile.c is continued in part 7"
  2132. echo "7" > shar3_seq_.tmp
  2133. exit 0
  2134.  
  2135. exit 0 # Just in case...
  2136. -- 
  2137. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  2138. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  2139. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  2140. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  2141.