home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume28 / tin / part08 < prev    next >
Text File  |  1992-02-23  |  52KB  |  2,011 lines

  1. Newsgroups: comp.sources.misc
  2. From: iain%estevax.uucp@unido.Informatik.Uni-Dortmund.DE (Iain Lea)
  3. Subject:  v28i052:  tin - threaded full screen newsreader v1.1, Part08/11
  4. Message-ID: <1992Feb18.043839.13302@sparky.imd.sterling.com>
  5. X-Md4-Signature: 05fb4670b12dfc17c86e0bbfe255ff33
  6. Date: Tue, 18 Feb 1992 04:38:39 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: iain%estevax.uucp@unido.Informatik.Uni-Dortmund.DE (Iain Lea)
  10. Posting-number: Volume 28, Issue 52
  11. Archive-name: tin/part08
  12. Environment: BSD, SCO, ISC, SUNOS, SYSVR3, SYSVR4, ULTRIX, XENIX
  13. Supersedes: tin: Volume 23, Issue 15-23
  14.  
  15. #!/bin/sh
  16. # this is tin.shar.08 (part 8 of tin1.1)
  17. # do not concatenate these parts, unpack them in order with /bin/sh
  18. # file post.c continued
  19. #
  20. if test ! -r _shar_seq_.tmp; then
  21.     echo 'Please unpack part 1 first!'
  22.     exit 1
  23. fi
  24. (read Scheck
  25.  if test "$Scheck" != 8; then
  26.     echo Please unpack part "$Scheck" next!
  27.     exit 1
  28.  else
  29.     exit 0
  30.  fi
  31. ) < _shar_seq_.tmp || exit 1
  32. if test ! -f _shar_wnt_.tmp; then
  33.     echo 'x - still skipping post.c'
  34. else
  35. echo 'x - continuing file post.c'
  36. sed 's/^X//' << 'SHAR_EOF' >> 'post.c' &&
  37. X
  38. X    start_line_offset = 4;
  39. X    
  40. X    strcpy (mail_to, address);
  41. X    clear_message ();
  42. X    
  43. X    set_real_uid_gid ();
  44. X
  45. X    sprintf (nam, "%s/.letter", homedir);
  46. X    if ((fp = fopen (nam, "w")) == NULL) {
  47. X        error_message (txt_cannot_open, nam);
  48. X        set_tin_uid_gid ();
  49. X        return (redraw_screen);
  50. X    }
  51. X    chmod (nam, 0600);
  52. X
  53. X    fprintf (fp, "To: %s\n", mail_to);
  54. X    fprintf (fp, "Subject: (fwd) %s\n", note_h_subj);
  55. X    if (*note_h_followup) {
  56. X        fprintf (fp, "Newsgroups: %s\n\n", note_h_followup);
  57. X    } else {
  58. X        fprintf (fp, "Newsgroups: %s\n", note_h_newsgroups);
  59. X    }
  60. X    if (*my_org) {
  61. X        fprintf (fp, "Organization: %s\n", my_org);
  62. X        start_line_offset++;
  63. X    }
  64. X    if (*reply_to) {
  65. X        fprintf (fp, "Reply-To: %s\n", reply_to);
  66. X        start_line_offset++;
  67. X    }
  68. X    fputs ("\n", fp);
  69. X    
  70. X    fseek (note_fp, 0L, 0);
  71. X    copy_fp (note_fp, fp, (char *) 0);
  72. X
  73. X    add_signature (fp, TRUE);
  74. X    fclose (fp);
  75. X    
  76. X    while (1) {
  77. X        do {
  78. X            my_strncpy (buf, note_h_subj, COLS-30);
  79. X            sprintf (msg, "%s [%s]: %c", txt_abort_edit_send, buf, ch_default);
  80. X            wait_message (msg);
  81. X            MoveCursor (LINES, (int) strlen (msg)-1);
  82. X            if ((ch = (char) ReadCh ()) == CR)
  83. X                ch = ch_default;
  84. X        } while (ch != ESC && ch != 'a' && ch != 'e' && ch != 's');
  85. X
  86. X        switch (ch) {
  87. X        case 'e':
  88. X            invoke_editor (nam);
  89. X            set_real_uid_gid ();
  90. X            redraw_screen = TRUE;
  91. X            break;
  92. X
  93. X        case 'a':
  94. X        case ESC:
  95. X            unlink (nam);
  96. X            clear_message ();
  97. X            set_tin_uid_gid ();
  98. X            return (redraw_screen);
  99. X
  100. X        case 's':
  101. X            /*
  102. X             *  Open letter and get the To: line in case they changed
  103. X             *  it with the editor
  104. X             */
  105. X            find_mail_header (HEADER_TO, nam, mail_to);
  106. X            sprintf (msg, txt_mailing_to, mail_to);
  107. X            wait_message (msg);
  108. X            sprintf (buf, "%s \"%s\" < %s", mailer, mail_to, nam);
  109. X            if (invoke_cmd (buf)) {
  110. X                info_message (txt_message_sent);
  111. X                goto mail_to_someone_done;
  112. X            } else {
  113. X                error_message (txt_command_failed_s, buf);
  114. X                break;
  115. X            }
  116. X        }
  117. X    }
  118. X
  119. mail_to_someone_done:
  120. X    set_real_uid_gid ();
  121. X    unlink (nam);
  122. X    set_tin_uid_gid ();
  123. X
  124. X    return (redraw_screen);
  125. }
  126. X
  127. X
  128. int mail_bug_report ()
  129. {
  130. X    char nam[100];
  131. X    FILE *fp;
  132. X    FILE *fp_uname;
  133. X    char ch;
  134. X    char ch_default = 's';
  135. X    char buf[LEN];
  136. X    char mail_to[LEN];
  137. X
  138. X    start_line_offset = 5;
  139. X    
  140. X    wait_message (txt_mail_bug_report);
  141. X    
  142. X    set_real_uid_gid ();
  143. X
  144. X    sprintf (nam, "%s/.bugreport", homedir);
  145. X    if ((fp = fopen (nam, "w")) == NULL) {
  146. X        error_message (txt_cannot_open, nam);
  147. X        set_tin_uid_gid ();
  148. X        return FALSE;
  149. X    }
  150. X    chmod(nam, 0600);
  151. X
  152. X    fprintf (fp, "To: %s\n", bug_addr);
  153. X    fprintf (fp, "Subject: BUG REPORT %s %s PL%d %s\n",    progname,
  154. X        VERSION, PATCHLEVEL, (compiled_with_nntp ? "(NNTP)" : ""));
  155. X    if (*my_org) {
  156. X        fprintf (fp, "Organization: %s\n", my_org);
  157. X        start_line_offset++;
  158. X    }
  159. X    if (*reply_to) {
  160. X        fprintf (fp, "Reply-To: %s\n", reply_to);
  161. X        start_line_offset++;
  162. X    }
  163. X
  164. X    if ((fp_uname = popen ("uname -a", "r")) != NULL) {
  165. X        fprintf (fp, "\n");
  166. X        start_line_offset++;
  167. X        while (fgets (buf, sizeof (buf), fp_uname) != NULL) {
  168. X            fprintf (fp, "%s", buf);
  169. X            start_line_offset++;
  170. X        }
  171. X        fclose (fp_uname);
  172. X    } else {
  173. X        fprintf (fp, "\nPlease enter the following information:\n");
  174. X        fprintf (fp, "1) machine:\n");
  175. X        fprintf (fp, "2) os type:\n");
  176. X    }
  177. X    fprintf (fp, "\nPlease enter bug report/gripe/comment:\n");
  178. X
  179. X    add_signature (fp, TRUE);
  180. X    fclose (fp);
  181. X    
  182. X    ch = 'e';
  183. X    while (1) {
  184. X        switch (ch) {
  185. X        case 'e':
  186. X            invoke_editor (nam);
  187. X            set_real_uid_gid ();
  188. X            break;
  189. X
  190. X        case 'a':
  191. X        case ESC:
  192. X            unlink (nam);
  193. X            clear_message ();
  194. X            set_tin_uid_gid ();
  195. X            return TRUE;
  196. X
  197. X        case 's':
  198. X            strcpy (mail_to, bug_addr);
  199. X            find_mail_header (HEADER_TO, nam, mail_to);
  200. X            sprintf (msg, txt_mailing_to, mail_to);
  201. X            wait_message (msg);
  202. X            sprintf (buf, "%s \"%s\" < %s", mailer, mail_to, nam);
  203. X            if (invoke_cmd (buf)) {
  204. X                info_message (txt_message_sent);
  205. X                goto mail_bug_report_done;
  206. X            } else {
  207. X                error_message (txt_command_failed_s, buf);
  208. X                break;
  209. X            }
  210. X        }
  211. X
  212. X        do {
  213. X            sprintf (msg, "%s: %c", txt_abort_edit_send, ch_default);
  214. X            wait_message (msg);
  215. X            MoveCursor (LINES, (int) strlen (msg)-1);
  216. X            if ((ch = (char) ReadCh ()) == CR)
  217. X                ch = ch_default;
  218. X        } while (ch != ESC && ch != 'a' && ch != 'e' && ch != 's');
  219. X    }
  220. X
  221. mail_bug_report_done:
  222. X    set_real_uid_gid ();
  223. X    unlink (nam);
  224. X    set_tin_uid_gid ();
  225. X
  226. X    return TRUE;
  227. }
  228. X
  229. X
  230. int mail_to_author (respnum, copy_text)
  231. X    int respnum;
  232. X    int copy_text;
  233. {
  234. X    char buf[LEN];
  235. X    char nam[100];
  236. X    char mail_to[LEN];
  237. X    char ch, ch_default = 's';
  238. X    FILE *fp;
  239. X    int redraw_screen = FALSE;
  240. X
  241. X    start_line_offset = 4;
  242. X    
  243. X    wait_message (txt_reply_to_author);
  244. X
  245. X    set_real_uid_gid ();
  246. X
  247. X    sprintf (nam, "%s/.letter", homedir);
  248. X    if ((fp = fopen (nam, "w")) == NULL) {
  249. X        error_message (txt_cannot_open, nam);
  250. X        set_tin_uid_gid ();
  251. X        return (redraw_screen);
  252. X    }
  253. X    chmod (nam, 0600);
  254. X
  255. X    fprintf (fp, "To: %s%s (%s)\n",
  256. X        arts[respnum].from, add_addr, arts[respnum].name);
  257. X    fprintf (fp, "Subject: Re: %s\n", eat_re(note_h_subj) );
  258. X    fprintf (fp, "Newsgroups: %s\n", note_h_newsgroups);
  259. X    if (*my_org) {
  260. X        fprintf (fp, "Organization: %s\n", my_org);
  261. X        start_line_offset++;
  262. X    }
  263. X    if (*reply_to) {
  264. X        fprintf (fp, "Reply-To: %s\n", reply_to);
  265. X        start_line_offset++;
  266. X    }
  267. X    fputs ("\n", fp);
  268. X
  269. X    if (copy_text) {        /* if "copy_text" */
  270. X        fprintf (fp, txt_in_art_you_write, note_h_messageid);
  271. X        fseek (note_fp, note_mark[0], 0);
  272. X        copy_fp (note_fp, fp, DEFAULT_COMMENT);
  273. X    }
  274. X
  275. X    add_signature (fp, TRUE);
  276. X    fclose (fp);
  277. X
  278. X    ch = 'e';
  279. X    while (1) {
  280. X        switch (ch) {
  281. X        case 'e':
  282. X            invoke_editor (nam);
  283. X            set_real_uid_gid ();
  284. X            redraw_screen = TRUE;
  285. X            break;
  286. X
  287. X        case 'a':
  288. X        case ESC:
  289. X            unlink (nam);
  290. X            clear_message ();
  291. X            set_tin_uid_gid ();
  292. X            return (redraw_screen);
  293. X
  294. X        case 's':
  295. X            strcpy (mail_to, arts[respnum].from);
  296. X            find_mail_header (HEADER_TO, nam, mail_to);
  297. X            sprintf (msg, txt_mailing_to, mail_to);
  298. X            wait_message (msg);
  299. X            sprintf (buf, "%s \"%s\" < %s", mailer, mail_to, nam);
  300. X            if (invoke_cmd (buf)) {
  301. X                info_message (txt_message_sent);
  302. X                goto mail_to_author_done;
  303. X            } else {
  304. X                error_message (txt_command_failed_s, buf);
  305. X                break;
  306. X            }
  307. X        }
  308. X
  309. X        do {
  310. X            sprintf (msg, "%s: %c", txt_abort_edit_send, ch_default);
  311. X            wait_message (msg);
  312. X            MoveCursor (LINES, (int) strlen (msg)-1);
  313. X            if ((ch = (char) ReadCh ()) == CR)
  314. X                ch = ch_default;
  315. X        } while (ch != ESC && ch != 'a' && ch != 'e' && ch != 's');
  316. X    }
  317. X
  318. mail_to_author_done:
  319. X    set_real_uid_gid ();
  320. X    unlink (nam);
  321. X    set_tin_uid_gid ();
  322. X
  323. X    return (redraw_screen);
  324. }
  325. X
  326. /*
  327. X *  Read a file grabbing the value of the specified mail header line
  328. X */
  329. X
  330. void find_mail_header (header, file, value)
  331. X    int header;
  332. X    char *file;
  333. X    char *value;
  334. {
  335. X    FILE *fp;
  336. X    char buf[LEN];
  337. X    char buf2[LEN];
  338. X    char new_value[LEN];
  339. X    char *p;
  340. X
  341. X    *new_value = '\0';
  342. X
  343. X    if ((fp = fopen (file, "r")) == NULL) {
  344. X        error_message (txt_cannot_open, file);
  345. X        return;
  346. X    }
  347. X
  348. X    while (fgets (buf, sizeof (buf), fp) != NULL) {
  349. X        for (p = buf; *p && *p != '\n'; p++)
  350. X            continue;
  351. X        *p = '\0';
  352. X
  353. X        if (*buf == '\0')
  354. X            break;
  355. X
  356. X        switch (header) {
  357. X            case HEADER_TO:
  358. X                if (strncmp (buf, "To: ", 4) == 0) {
  359. X                    my_strncpy (buf2, &buf[4], LEN);
  360. X                    buf2[LEN-1] = '\0';
  361. X                    yank_to_addr (buf2, new_value);
  362. X                } else if (strncmp (buf, "Cc: ", 4) == 0) {
  363. X                    my_strncpy (buf2, &buf[4], LEN);
  364. X                    buf2[LEN-1] = '\0';
  365. X                    yank_to_addr (buf2, new_value);
  366. X                } 
  367. X                break;
  368. X
  369. X            case HEADER_SUBJECT:
  370. X                if (strncmp (buf, "Subject: ", 9) == 0) {
  371. X                    my_strncpy (new_value, &buf[9], LEN);
  372. X                    new_value[LEN-1] = '\0';
  373. X                }
  374. X                break;
  375. X        }
  376. X    }
  377. X
  378. X    fclose (fp);
  379. X
  380. X    if (new_value[0] == ' ') {
  381. X        my_strncpy (value, &new_value[1], LEN);
  382. X    } else {
  383. X        my_strncpy (value, new_value, LEN);
  384. X    }
  385. }
  386. X
  387. X
  388. int cancel_article ()
  389. {
  390. X    char ch, ch_default = 'c';
  391. X    char buf[LEN];
  392. X    char cancel[LEN];
  393. X    FILE *fp;
  394. X    int redraw_screen = FALSE;
  395. X
  396. X    start_line_offset = 4;
  397. X    
  398. X    clear_message ();
  399. X    
  400. X    set_real_uid_gid ();
  401. X
  402. X    sprintf (cancel, "%s/.cancel", homedir);
  403. X    if ((fp = fopen (cancel, "w")) == NULL) {
  404. X        error_message (txt_cannot_open, cancel);
  405. X        set_tin_uid_gid ();
  406. X        return (redraw_screen);
  407. X    }
  408. X    chmod (cancel, 0600);
  409. X
  410. X    fprintf (fp, "Subject: cancel %s\n", note_h_messageid);
  411. X    if (*note_h_followup) {
  412. X        fprintf (fp, "Newsgroups: %s\n", note_h_followup);
  413. X    } else {
  414. X        fprintf (fp, "Newsgroups: %s\n", note_h_newsgroups);
  415. X    }
  416. X    fprintf (fp, "Control: cancel %s\n", note_h_messageid);
  417. X    if (*my_org) { 
  418. X        fprintf (fp, "Organization: %s\n", my_org);
  419. X        start_line_offset++;    
  420. X    }
  421. X    if (*reply_to) {
  422. X        fprintf (fp, "Reply-To: %s\n", reply_to);
  423. X        start_line_offset++;    
  424. X    }
  425. X    fputs ("\n", fp);
  426. X
  427. X    fprintf (fp, "Article cancelled from within tin\n");
  428. X    
  429. X    fclose (fp);
  430. X    
  431. X    while (1) {
  432. X        do {
  433. X            my_strncpy (buf, note_h_subj, COLS-30);
  434. X            sprintf (msg, "%s [%s]: %c", txt_abort_edit_cancel, buf, ch_default);
  435. X            wait_message (msg);
  436. X            MoveCursor (LINES, (int) strlen (msg)-1);
  437. X            if ((ch = (char) ReadCh ()) == CR)
  438. X                ch = ch_default;
  439. X        } while (ch != ESC && ch != 'a' && ch != 'e' && ch != 'c');
  440. X
  441. X        switch (ch) {
  442. X        case 'e':
  443. X            invoke_editor (cancel);
  444. X             set_real_uid_gid ();
  445. X            redraw_screen = TRUE;
  446. X            break;
  447. X
  448. X        case 'a':
  449. X        case ESC:
  450. X            unlink (cancel);
  451. X            clear_message ();
  452. X            set_tin_uid_gid ();
  453. X            return (redraw_screen);
  454. X
  455. X        case 'c':
  456. X            wait_message (txt_cancelling);
  457. X            if (submit_file (cancel)) {
  458. X                info_message (txt_art_cancelled);
  459. X                goto cancel_article_done;
  460. X            } else {
  461. X                error_message (txt_command_failed_s, buf);
  462. X                break;
  463. X            }
  464. X        }
  465. X    }
  466. X
  467. cancel_article_done:
  468. X    set_real_uid_gid ();
  469. X    unlink (cancel);
  470. X    set_tin_uid_gid ();
  471. X
  472. X    return (redraw_screen);
  473. }
  474. X
  475. X
  476. int submit_file(name)
  477. X    char *name;
  478. {
  479. X    char    buf[LEN];
  480. X    char*    cp = buf;
  481. X
  482. #ifdef INEWSDIR
  483. X    strcpy(buf, INEWSDIR);
  484. X    strcat(buf, "/");
  485. X    cp = &buf[strlen(buf)];
  486. #endif
  487. X
  488. X    sprintf (cp, "inews -h < %s %s", name, redirect_output);
  489. X    
  490. X    if (invoke_cmd(buf)) {
  491. X         set_real_uid_gid ();
  492. X        return TRUE;
  493. X    }
  494. X    set_real_uid_gid ();
  495. X    return FALSE;
  496. }
  497. X
  498. X
  499. void add_signature (fp, flag)
  500. X    FILE *fp;
  501. X    int flag;
  502. {
  503. X    FILE *sigf;
  504. X
  505. X    if ((sigf = fopen (signature, "r")) != NULL) {
  506. X        if (flag) {
  507. X            fprintf (fp, "\n--\n");
  508. X            copy_fp (sigf, fp, (char *) 0);
  509. X        }
  510. X        fclose (sigf);
  511. X        return;
  512. X    }
  513. X
  514. X    if ((sigf = fopen (sig, "r")) != NULL) {
  515. X        fprintf (fp, "\n--\n");
  516. X        copy_fp (sigf, fp, (char *) 0);
  517. X        fclose (sigf);
  518. X    }
  519. }
  520. SHAR_EOF
  521. echo 'File post.c is complete' &&
  522. chmod 0600 post.c ||
  523. echo 'restore of post.c failed'
  524. Wc_c="`wc -c < 'post.c'`"
  525. test 19458 -eq "$Wc_c" ||
  526.     echo 'post.c: original size 19458, current size' "$Wc_c"
  527. rm -f _shar_wnt_.tmp
  528. fi
  529. # ============= prompt.c ==============
  530. if test -f 'prompt.c' -a X"$1" != X"-c"; then
  531.     echo 'x - skipping prompt.c (File already exists)'
  532.     rm -f _shar_wnt_.tmp
  533. else
  534. > _shar_wnt_.tmp
  535. echo 'x - extracting prompt.c (Text)'
  536. sed 's/^X//' << 'SHAR_EOF' > 'prompt.c' &&
  537. /*
  538. X *  Project   : tin - a threaded Netnews reader
  539. X *  Module    : prompt.c
  540. X *  Author    : I.Lea
  541. X *  Created   : 01-04-91
  542. X *  Updated   : 25-11-91
  543. X *  Notes     :
  544. X *  Copyright : (c) Copyright 1991-92 by Rich Skrenta & Iain Lea
  545. X *              You may  freely  copy or  redistribute  this software,
  546. X *              so  long as there is no profit made from its use, sale
  547. X *              trade or  reproduction.  You may not change this copy-
  548. X *              right notice, and it must be included in any copy made
  549. X */
  550. X
  551. #include    "tin.h"
  552. X
  553. /*
  554. X *  prompt_num
  555. X *  get a number from the user
  556. X *  Return -1 if missing or bad number typed
  557. X */
  558. X
  559. int prompt_num (ch, prompt)
  560. X    char ch;
  561. X    char *prompt;
  562. {
  563. X    char *p;
  564. X    int num;
  565. X
  566. X    clear_message ();
  567. X
  568. X    sprintf (msg, "%c", ch);
  569. X
  570. X    if ((p = getline (prompt, TRUE, msg)) != (char *) 0) {
  571. X        strcpy (msg, p);
  572. X        num = atoi (msg);
  573. X    } else {
  574. X        num = -1;
  575. X    }
  576. X
  577. X    clear_message ();
  578. X    return (num);
  579. }
  580. X
  581. /*
  582. X *  prompt_string
  583. X *  get a string from the user
  584. X *  Return TRUE if a valid string was typed, FALSE otherwise
  585. X */
  586. X
  587. int prompt_string (prompt, buf)
  588. X    char *prompt;
  589. X    char *buf;
  590. {
  591. X    char *p;
  592. X
  593. X    clear_message ();
  594. X
  595. X    if ((p = getline (prompt, FALSE, (char *) 0)) == (char *) 0) {
  596. X        buf[0] = '\0';
  597. X        clear_message ();
  598. X        return FALSE;
  599. X    }
  600. X    strcpy (buf, p);
  601. X    
  602. X    clear_message ();
  603. X
  604. X    return TRUE;
  605. }
  606. X
  607. /*
  608. X *  prompt_menu_string
  609. X *  get a string from the user
  610. X *  Return TRUE if a valid string was typed, FALSE otherwise
  611. X */
  612. X
  613. int prompt_menu_string (line, col, var)
  614. X    int line;
  615. X    int col;
  616. X    char *var;
  617. {
  618. X    char *p;
  619. X
  620. X    MoveCursor (line, col);
  621. X
  622. X    if ((p = getline ((char *) 0, FALSE, var)) == (char *) 0) {
  623. X        return FALSE;
  624. X    }
  625. X    strcpy (var, p);
  626. X    
  627. X    return TRUE;
  628. X
  629. #ifdef XXX
  630. X    char buf[LEN];
  631. X    char ch;
  632. X    int i, len;
  633. X    int max_len;
  634. X
  635. X    MoveCursor (line, col);
  636. X    buf[0] = '\0';
  637. X    len = 0;
  638. X    max_len = (COLS - col)-2;
  639. X    ch = (char) ReadCh();
  640. X
  641. X    while (ch != '\n' && ch != '\r') {
  642. X        if (ch == ESC) {        /* Esc pressed so abort */
  643. X            return FALSE;
  644. X        }
  645. X        if (ch == 8 || ch == 127) {
  646. X            if (len) {
  647. X                len--;
  648. X                buf[len] = '\0';
  649. X                putchar('\b');
  650. X                putchar(' ');
  651. X                putchar('\b');
  652. X            } else {
  653. X                strcpy (var, buf);
  654. X                MoveCursor(line, col);
  655. X                CleartoEOLN();
  656. X            }
  657. X        } else if (ch == 21) {    /* control-U    */
  658. X            for (i = len; i > 0; i--) {
  659. X                putchar('\b');
  660. X                putchar(' ');
  661. X                putchar('\b');
  662. X            }
  663. X            buf[0] = '\0';
  664. X            len = 0;
  665. X        } else if (ch >= ' ' && len < max_len) {
  666. X            buf[len++] = ch;
  667. X            buf[len] = '\0';
  668. X            putchar (ch);
  669. X        } else
  670. X            putchar(7);
  671. X        fflush(stdout);
  672. X        ch = (char) ReadCh();
  673. X        if(ch == EOF)
  674. X            return FALSE;
  675. X        ch &= 0xFF;
  676. X    }
  677. X
  678. X    if (buf[0]) {
  679. X        strcpy (var, buf);
  680. X    }
  681. X    return TRUE;
  682. #endif
  683. }
  684. X
  685. X
  686. int prompt_yn (line, prompt, default_ch)
  687. X    int line;
  688. X    char *prompt;
  689. X    char default_ch;
  690. {
  691. X    char ch;
  692. X
  693. X    MoveCursor (line, 0);
  694. X    CleartoEOLN ();
  695. X    printf ("%s%c", prompt, default_ch);
  696. X    fflush (stdout);
  697. X    MoveCursor (line, (int) strlen (prompt));
  698. X
  699. X    if ((ch = (char) ReadCh()) == CR) {
  700. X        ch = default_ch;
  701. X    }    
  702. X
  703. X    if (line == LINES) {
  704. X        clear_message();
  705. X    } else {
  706. X        MoveCursor (line, (int) strlen (prompt));
  707. X        if (ch == ESC) {
  708. X            printf ("%c", default_ch);
  709. X        } else {
  710. X            printf ("%c", ch);
  711. X        }
  712. X        fflush (stdout);
  713. X    }
  714. X
  715. X    return (ch == 'y' ? TRUE : FALSE);
  716. }
  717. X
  718. X
  719. void prompt_on_off (row, col, var, help_text, prompt_text)
  720. X    int row;
  721. X    int col;
  722. X    int *var;
  723. X    char *help_text;
  724. X    char *prompt_text;
  725. {
  726. X    int ch, var_orig;
  727. X
  728. X    var_orig = *var;
  729. X
  730. X    show_menu_help (help_text);
  731. X    do {
  732. X        MoveCursor (row, col + (int) strlen (prompt_text));
  733. X        if ((ch = (char) ReadCh ()) == ' ') {
  734. X            *var = !*var;
  735. X            printf ("%s", (*var ? "ON " : "OFF"));
  736. X            fflush (stdout);
  737. X        }
  738. X    } while (ch != CR && ch != ESC);
  739. X
  740. X    if (ch == ESC) {
  741. X        *var = var_orig;
  742. X        printf ("%s", (*var ? "ON " : "OFF"));
  743. X        fflush (stdout);
  744. X    }
  745. }
  746. X
  747. X
  748. void continue_prompt ()
  749. {
  750. X    char ch;
  751. X    
  752. X    info_message (txt_hit_any_key);
  753. X    ch = (char) ReadCh ();
  754. }
  755. X
  756. X
  757. SHAR_EOF
  758. chmod 0600 prompt.c ||
  759. echo 'restore of prompt.c failed'
  760. Wc_c="`wc -c < 'prompt.c'`"
  761. test 3748 -eq "$Wc_c" ||
  762.     echo 'prompt.c: original size 3748, current size' "$Wc_c"
  763. rm -f _shar_wnt_.tmp
  764. fi
  765. # ============= rcfile.c ==============
  766. if test -f 'rcfile.c' -a X"$1" != X"-c"; then
  767.     echo 'x - skipping rcfile.c (File already exists)'
  768.     rm -f _shar_wnt_.tmp
  769. else
  770. > _shar_wnt_.tmp
  771. echo 'x - extracting rcfile.c (Text)'
  772. sed 's/^X//' << 'SHAR_EOF' > 'rcfile.c' &&
  773. /*
  774. X *  Project   : tin - a threaded Netnews reader
  775. X *  Module    : rcfile.c
  776. X *  Author    : I.Lea
  777. X *  Created   : 01-04-91
  778. X *  Updated   : 23-01-92
  779. X *  Notes     :
  780. X *  Copyright : (c) Copyright 1991-92 by Iain Lea
  781. X *                You may  freely  copy or  redistribute  this software,
  782. X *              so  long as there is no profit made from its use, sale
  783. X *              trade or  reproduction.  You may not change this copy-
  784. X *              right notice, and it must be included in any copy made
  785. X */
  786. X
  787. #include    "tin.h"
  788. X
  789. extern char index_file[LEN];
  790. extern int index_point;
  791. X
  792. static int COL1;
  793. static int COL2;
  794. static int COL3;
  795. X
  796. /*
  797. X *  read_rcfile - read defaults from ~/.tin/tinrc
  798. X */
  799. X
  800. int read_rcfile ()
  801. {
  802. X    char buf[LEN];
  803. X    FILE *fp;
  804. X
  805. X    if ((fp = fopen (rcfile, "r")) != NULL) {
  806. X        while (fgets (buf, sizeof buf, fp) != NULL) {
  807. X            if (buf[0] != '#') { 
  808. X                if (strncmp (buf, "save_archive=", 13) == 0) {
  809. X                    save_archive_name = (strncmp (&buf[13], "ON", 2) == 0 ? TRUE : FALSE);
  810. X                } else if (strncmp (buf, "save_separate=", 14) == 0) {
  811. X                    save_separate = (strncmp (&buf[14], "ON", 2) == 0 ? TRUE : FALSE);
  812. X                } else if (strncmp (buf, "mark_saved_read=", 16) == 0) {
  813. X                    mark_saved_read = (strncmp (&buf[16], "ON", 2) == 0 ? TRUE : FALSE);
  814. X                } else if (strncmp (buf, "kill_articles=", 14) == 0) {
  815. X                    kill_articles = (strncmp (&buf[14], "ON", 2) == 0 ? TRUE : FALSE);
  816. X                } else if (strncmp (buf, "draw_arrow=", 11) == 0) {
  817. X                    draw_arrow_mark = (strncmp (&buf[11], "ON", 2) == 0 ? TRUE : FALSE);
  818. X                    if (draw_arrow_mark == FALSE && inverse_okay == FALSE) {
  819. X                        inverse_okay = TRUE;
  820. X                    }
  821. X                } else if (strncmp (buf, "print_header=", 13) == 0) {
  822. X                    print_header = (strncmp (&buf[13], "ON", 2) == 0 ? TRUE : FALSE);
  823. X                } else if (strncmp (buf, "pos_first_unread=", 17) == 0) {
  824. X                    pos_first_unread = (strncmp (&buf[17], "ON", 2) == 0 ? TRUE : FALSE);
  825. X                } else if (strncmp (buf, "full_page_scroll=", 17) == 0) {
  826. X                    full_page_scroll = (strncmp (&buf[17], "ON", 2) == 0 ? TRUE : FALSE);
  827. X                } else if (strncmp (buf, "catchup_read_groups=", 20) == 0) {
  828. X                    catchup_read_groups = (strncmp (&buf[20], "ON", 2) == 0 ? TRUE : FALSE);
  829. X                } else if (strncmp (buf, "thread_articles=", 16) == 0) {
  830. X                    thread_arts = (strncmp (&buf[16], "ON", 2) == 0 ? TRUE : FALSE);
  831. X                } else if (strncmp (buf, "show_only_unread=", 17) == 0) {
  832. X                    show_only_unread = (strncmp (&buf[17], "ON", 2) == 0 ? TRUE : FALSE);
  833. X                } else if (strncmp (buf, "show_author=", 12) == 0) {
  834. X                    default_show_author = atoi (&buf[12]);
  835. X                } else if (strncmp (buf, "post_process_type=", 18) == 0) {
  836. X                    post_proc_type = atoi (&buf[18]);
  837. X                    switch (post_proc_type) {
  838. X                        case POST_PROC_NONE:
  839. X                            proc_ch_default = 'n';
  840. X                            break;
  841. X                        case POST_PROC_SHAR:
  842. X                            proc_ch_default = 's';
  843. X                            break;
  844. X                        case POST_PROC_UUDECODE:
  845. X                            proc_ch_default = 'u';
  846. X                            break;
  847. X                        case POST_PROC_UUD_LST_ZOO:
  848. X                            proc_ch_default = 'U';
  849. X                            break;
  850. X                        case POST_PROC_UUD_EXT_ZOO:
  851. X                            proc_ch_default = 'U';
  852. X                            break;
  853. X                    }
  854. X                } else if (strncmp (buf, "sort_article_type=", 18) == 0) {
  855. X                    sort_art_type = atoi (&buf[18]);
  856. X                } else if (strncmp (buf, "savedir=", 8) == 0) {
  857. X                    strncpy (savedir, &buf[8], LEN);
  858. X                    savedir[strlen (savedir) - 1] = '\0';
  859. X                    if (savedir[0] == '.' && strlen (savedir) == 1) {
  860. #if defined(BSD) && ! defined(SINIX)
  861. X                        getwd (buf);    
  862. #else
  863. X                        getcwd (buf, LEN);
  864. #endif
  865. X                        my_strncpy (savedir, buf, LEN);
  866. X                    }
  867. X                } else if (strncmp (buf, "maildir=", 8) == 0) {
  868. X                    strncpy (maildir, &buf[8], LEN);
  869. X                    maildir[strlen (maildir) - 1] = '\0';
  870. X                } else if (strncmp (buf, "printer=", 8) == 0) {
  871. X                    strncpy (printer, &buf[8], LEN);
  872. X                    printer[strlen (printer) - 1] = '\0';
  873. X                } else if (strncmp (buf, "spooldir=", 9) == 0) {
  874. X                    strncpy (spooldir, &buf[9], LEN);
  875. X                    spooldir[strlen (spooldir) - 1] = '\0';
  876. X                } else if (strncmp (buf, "signature=", 10) == 0) {
  877. X                    strncpy (signature, &buf[10], LEN);
  878. X                    signature[strlen (signature) - 1] = '\0';
  879. X                } else if (strncmp (buf, "sig=", 4) == 0) {
  880. X                    strncpy (sig, &buf[4], LEN);
  881. X                    sig[strlen (sig) - 1] = '\0';
  882. X                }
  883. X            }
  884. X        }
  885. X        fclose (fp);
  886. X        return TRUE;        
  887. X    }
  888. X    return FALSE;        
  889. }
  890. X
  891. /*
  892. X *  write_rcfile - write defaults to ~/.tin/tinrc
  893. X */
  894. X
  895. void write_rcfile ()
  896. {
  897. X    FILE *fp;
  898. X
  899. X    set_real_uid_gid ();
  900. X    
  901. X    if ((fp = fopen (rcfile, "w")) != NULL) {
  902. X        wait_message (txt_saving);
  903. X
  904. X        fprintf (fp, "# if ON articles/threads with Archive-name: in mail header will\n");
  905. X        fprintf (fp, "# be automatically saved with the Archive-name & part/patch no.\n");
  906. X        fprintf (fp, "save_archive=%s\n\n", (save_archive_name ? "ON" : "OFF"));
  907. X        fprintf (fp, "# if ON articles of a threads will be saved to separate files\n");
  908. X        fprintf (fp, "# otherwise the whole thread will be saved to one file\n");
  909. X        fprintf (fp, "save_separate=%s\n\n", (save_separate ? "ON" : "OFF"));
  910. X        fprintf (fp, "# if ON mark articles that are saved as read\n");
  911. X        fprintf (fp, "mark_saved_read=%s\n\n", (mark_saved_read ? "ON" : "OFF"));
  912. X        fprintf (fp, "# if ON use -> otherwise highlighted bar for selection\n");
  913. X        fprintf (fp, "draw_arrow=%s\n\n", (draw_arrow_mark ? "ON" : "OFF"));
  914. X        fprintf (fp, "# if ON kill articles that match kill file\n");
  915. X        fprintf (fp, "kill_articles=%s\n\n", (kill_articles ? "ON" : "OFF"));
  916. X        fprintf (fp, "# if ON print all of mail header otherwise Subject: & From: lines\n");
  917. X        fprintf (fp, "print_header=%s\n\n", (print_header ? "ON" : "OFF"));
  918. X        fprintf (fp, "# if ON put cursor at first unread art in group otherwise last art\n");
  919. X        fprintf (fp, "pos_first_unread=%s\n\n", (pos_first_unread ? "ON" : "OFF"));
  920. X        fprintf (fp, "# if ON scroll full page of groups/articles otherwise half a page\n");
  921. X        fprintf (fp, "full_page_scroll=%s\n\n", (full_page_scroll ? "ON" : "OFF"));
  922. X        fprintf (fp, "# if ON ask user if read groups should all be marked read\n");
  923. X        fprintf (fp, "catchup_read_groups=%s\n\n", (catchup_read_groups ? "ON" : "OFF"));
  924. X        fprintf (fp, "# part of from field to display 0) none 1) address 2) full name 3) both\n");
  925. X        fprintf (fp, "show_author=%d\n\n", default_show_author);
  926. X        fprintf (fp, "# type of post processing to perform after saving articles.\n");
  927. X        fprintf (fp, "# 0) none 1) shar 2) uudecode 3) uud & list zoo 4) uud & extract zoo 5) patch.\n");
  928. X        fprintf (fp, "post_process_type=%d\n\n", post_proc_type);
  929. X        fprintf (fp, "# if ON and group not in ~/.tin/unthread articles will be threaded.\n");
  930. X        fprintf (fp, "thread_articles=%s\n\n", (thread_arts ? "ON" : "OFF"));
  931. X        fprintf (fp, "# if ON show only new/unread articles otherwise show all.\n");
  932. X        fprintf (fp, "show_only_unread=%s\n\n", (show_only_unread ? "ON" : "OFF"));
  933. X        fprintf (fp, "# sort articles by 0) nothing 1) Subject (descending) 2) Subject (ascending)\n");
  934. X        fprintf (fp, "# 3) From (descend) 4) From (ascend) 5) Date (descend) 6) Date (ascend)\n");
  935. X        fprintf (fp, "sort_article_type=%d\n\n", sort_art_type);
  936. X        fprintf (fp, "# (-d) directory where articles/threads are saved\n");
  937. X        fprintf (fp, "savedir=%s\n\n", savedir);
  938. X        fprintf (fp, "# (-M) directory where articles/threads are saved in mailbox format\n");    
  939. X        fprintf (fp, "maildir=%s\n\n", maildir);    
  940. X        fprintf (fp, "# (-p) print program with parameters used to print articles/threads\n");
  941. X        fprintf (fp, "printer=%s\n\n", printer);
  942. X        fprintf (fp, "# (-s) directory where news is spooled\n");
  943. X        fprintf (fp, "spooldir=%s\n\n", spooldir);
  944. X
  945. X        fprintf (fp, "# .signature file used for replies, followups\n");
  946. X        fprintf (fp, "signature=%s\n\n", signature);
  947. X        fprintf (fp, "# .Sig file used for postings\n");
  948. X        fprintf (fp, "sig=%s\n\n", sig);
  949. X
  950. X        fclose (fp);
  951. X        chmod (rcfile, 0600);
  952. X    }
  953. X    set_tin_uid_gid ();
  954. }
  955. X
  956. /*
  957. X *  options menu so that the user can dynamically change parameters
  958. X */
  959. int change_rcfile (group, kill_at_once)
  960. X    char *group;
  961. X    int kill_at_once;
  962. {
  963. X    char *str;
  964. X    int ch, i;
  965. X    int kill_changed = FALSE;
  966. X    int orig_kill_state;
  967. X    int orig_show_only_unread;
  968. X    int orig_thread_arts;
  969. X    int option;
  970. X    int ret_code = NO_KILLING;
  971. X    int var_orig;
  972. X    
  973. #ifdef SIGTSTP
  974. X    SIGTYPE (*susp)();
  975. X
  976. X    if (do_sigtstp) {
  977. #ifdef POSIX_JOB_CONTROL
  978. X        sigemptyset (&rcfile_act.sa_mask);
  979. X        rcfile_act.sa_flags = SA_RESTART | SA_RESETHAND;
  980. X        rcfile_act.sa_handler = SIG_DFL;
  981. X        sigaction (SIGTSTP, &rcfile_act, &old_act);
  982. #else
  983. X        susp = signal (SIGTSTP, SIG_DFL);
  984. #endif
  985. X    }
  986. #endif
  987. X
  988. X    COL1 = 0;
  989. X    COL2 = ((COLS / 3) * 1) + 1;
  990. X    COL3 = ((COLS / 3) * 2) + 2;
  991. X
  992. X    show_rcfile_menu ();
  993. X
  994. X    while (1) {
  995. X
  996. #ifdef SIGTSTP
  997. X        if (do_sigtstp) {
  998. #ifdef POSIX_JOB_CONTROL
  999. X            sigemptyset (&rcfile_act.sa_mask);
  1000. X            rcfile_act.sa_flags = SA_RESTART | SA_RESETHAND;
  1001. X            rcfile_act.sa_handler = rcfile_suspend;
  1002. X            sigaction (SIGTSTP, &rcfile_act, 0L);
  1003. #else
  1004. X            signal (SIGTSTP, rcfile_suspend);
  1005. #endif
  1006. X        }
  1007. #endif
  1008. X        MoveCursor (LINES, 0);
  1009. X        ch = ReadCh ();
  1010. X        if (ch >= '1' && ch <= '9') {
  1011. X            option = prompt_num (ch, "Enter option number> ");
  1012. X        } else {
  1013. X            if (ch == 'q' || ch == ESC) {
  1014. X                option = -1;
  1015. X            } else {
  1016. X                option = 0;
  1017. X            }
  1018. X        }
  1019. #ifdef SIGTSTP
  1020. X        if (do_sigtstp) {
  1021. #ifdef POSIX_JOB_CONTROL
  1022. X            sigemptyset (&rcfile_act.sa_mask);
  1023. X            rcfile_act.sa_flags = SA_RESTART | SA_RESETHAND;
  1024. X            rcfile_act.sa_handler = SIG_IGN;
  1025. X            sigaction (SIGTSTP, &rcfile_act, 0L);
  1026. #else
  1027. X            signal (SIGTSTP, SIG_IGN);
  1028. #endif
  1029. X        }
  1030. #endif
  1031. X        switch (option) {
  1032. X            case -1:
  1033. X                clear_note_area ();
  1034. X                return ret_code;
  1035. X                /*NOTREACHED*/                
  1036. X            case 0:
  1037. X                write_rcfile ();
  1038. X                if (kill_changed) {
  1039. X                    if (kill_at_once) {
  1040. X                        if (kill_articles) {
  1041. X                            read_kill_file ();
  1042. X                            if (kill_any_articles (group)) {
  1043. X                                reload_index_file (group, TRUE);    /* kill arts */
  1044. X                            }
  1045. X                        } else {
  1046. X                            reload_index_file (group, FALSE);    /* add killed arts */
  1047. X                        }
  1048. X                    }
  1049. X                    ret_code = KILLING;
  1050. X                }
  1051. X                clear_note_area ();
  1052. #ifdef SIGTSTP
  1053. X                if (do_sigtstp) {
  1054. #ifdef POSIX_JOB_CONTROL
  1055. X                    sigemptyset (&rcfile_act.sa_mask);
  1056. X                    rcfile_act.sa_flags = SA_RESTART | SA_RESETHAND;
  1057. X                    rcfile_act.sa_handler = SIG_IGN;
  1058. X                    sigaction (SIGTSTP, &old_act, 0L);
  1059. #else
  1060. X                    signal (SIGTSTP, susp);
  1061. #endif
  1062. X                }
  1063. #endif
  1064. X                return ret_code;
  1065. X            
  1066. X            case 1:        /* auto save */
  1067. X                prompt_on_off (INDEX_TOP, COL1, &save_archive_name, 
  1068. X                    txt_help_autosave, txt_opt_autosave);
  1069. X                break;
  1070. X
  1071. X            case 2:        /* save sperate */
  1072. X                prompt_on_off (INDEX_TOP, COL2, &save_separate, 
  1073. X                    txt_help_save_separate, txt_opt_save_separate);
  1074. X                break;
  1075. X            
  1076. X            case 3:        /* mark saved articles read */
  1077. X                prompt_on_off (INDEX_TOP, COL3, &mark_saved_read, 
  1078. X                    txt_help_mark_saved_read, txt_opt_mark_saved_read);
  1079. X                break;
  1080. X
  1081. X            case 4:        /* kill articles */
  1082. X                orig_kill_state = kill_articles;
  1083. X                show_menu_help (txt_help_kill_articles);
  1084. X                do {
  1085. X                    MoveCursor (INDEX_TOP+2, COL1 + (int) strlen (txt_opt_kill_articles));
  1086. X                    if ((ch = ReadCh()) == ' ') {
  1087. X                        kill_articles = !kill_articles;
  1088. X                        kill_changed = (kill_articles != orig_kill_state ? TRUE : FALSE);
  1089. X                        printf ("%s", (kill_articles ? "ON " : "OFF"));
  1090. X                        fflush (stdout);
  1091. X                    }
  1092. X                } while (ch != CR && ch != ESC);
  1093. X                break;
  1094. X
  1095. X            case 5:        /* draw -> / highlighted bar */
  1096. X                prompt_on_off (INDEX_TOP+2, COL2, &draw_arrow_mark, 
  1097. X                    txt_help_draw_arrow, txt_opt_draw_arrow);
  1098. X                if (draw_arrow_mark == FALSE && inverse_okay == FALSE) {
  1099. X                    inverse_okay = TRUE;
  1100. X                }
  1101. X                break;
  1102. X
  1103. X            case 6:        /* print header */
  1104. X                prompt_on_off (INDEX_TOP+2, COL3, &print_header, 
  1105. X                    txt_help_print_header, txt_opt_print_header);
  1106. X                break;
  1107. X            
  1108. X            case 7:        /* position cursor at first / last unread art */
  1109. X                prompt_on_off (INDEX_TOP+4, COL1, &pos_first_unread, 
  1110. X                    txt_help_pos_first_unread, txt_opt_pos_first_unread);
  1111. X                break;
  1112. X
  1113. X            case 8:        /* scroll half/full page of groups/articles */
  1114. X                prompt_on_off (INDEX_TOP+4, COL2, &full_page_scroll, 
  1115. X                    txt_help_page_scroll, txt_opt_page_scroll);
  1116. X                break;
  1117. X
  1118. X            case 9:        /* catchup read groups when quitting */
  1119. X                prompt_on_off (INDEX_TOP+4, COL3, &catchup_read_groups, 
  1120. X                    txt_help_catchup_groups, txt_opt_catchup_groups);
  1121. X                break;
  1122. X
  1123. X            case 10:    /* thread/unthread all groups except those in ~/.tin/unthreaded */
  1124. X                orig_thread_arts = thread_arts;    
  1125. X                prompt_on_off (INDEX_TOP+6, COL1, &thread_arts, 
  1126. X                    txt_help_thread_arts, txt_opt_thread_arts);
  1127. X                if (thread_arts != orig_thread_arts || group != (char *) 0) {
  1128. X                    make_threads (TRUE);
  1129. X                    find_base (show_only_unread);
  1130. X                }
  1131. X                break;
  1132. X
  1133. X            case 11:    /* show all arts or just new/unread arts */
  1134. X                orig_show_only_unread = show_only_unread;    
  1135. X                prompt_on_off (INDEX_TOP+6, COL2, &show_only_unread, 
  1136. X                    txt_help_show_only_unread, txt_opt_show_only_unread);
  1137. X                if (show_only_unread != orig_show_only_unread || group != (char *) 0) {
  1138. X                    make_threads (TRUE);
  1139. X                    find_base (show_only_unread);
  1140. X                    if (space_mode) {
  1141. X                        for (i = 0; i < top_base; i++) {
  1142. X                            if (new_responses (i)) {
  1143. X                                break;
  1144. X                            }
  1145. X                        }
  1146. X                        if (i < top_base) {
  1147. X                            index_point = i;
  1148. X                        } else {
  1149. X                            index_point = top_base - 1;
  1150. X                        }
  1151. X                    } else {
  1152. X                        index_point = top_base - 1;
  1153. X                    }
  1154. X                }
  1155. X                break;
  1156. X
  1157. X            case 13:        /* show subject & author / subject only */
  1158. X                var_orig = show_author;
  1159. X                show_menu_help (txt_help_show_author);
  1160. X                do {
  1161. X                    MoveCursor (INDEX_TOP+8, COL1 + (int) strlen (txt_opt_show_author));
  1162. X                    if ((ch    = ReadCh()) == ' ') {
  1163. X                        if (show_author + 1 > SHOW_FROM_BOTH) {
  1164. X                            show_author = SHOW_FROM_NONE;
  1165. X                        } else {
  1166. X                            show_author++;
  1167. X                        }
  1168. X                        switch (show_author) {
  1169. X                            case SHOW_FROM_NONE:
  1170. X                                str = txt_show_from_none;
  1171. X                                break;
  1172. X                            case SHOW_FROM_ADDR:
  1173. X                                str = txt_show_from_addr;
  1174. X                                break;
  1175. X                            case SHOW_FROM_NAME:
  1176. X                                str = txt_show_from_name;
  1177. X                                break;
  1178. X                            case SHOW_FROM_BOTH:
  1179. X                                str = txt_show_from_both;
  1180. X                                break;
  1181. X                        }
  1182. X                        printf ("%s", str);
  1183. X                        fflush (stdout);
  1184. X                    }
  1185. X                } while (ch != CR && ch != ESC);
  1186. X
  1187. X                if (ch == ESC) {    /* restore original value */
  1188. X                    show_author = var_orig;
  1189. X                    switch (show_author) {
  1190. X                        case SHOW_FROM_NONE:
  1191. X                            str = txt_show_from_none;
  1192. X                            break;
  1193. X                        case SHOW_FROM_ADDR:
  1194. X                            str = txt_show_from_addr;
  1195. X                            break;
  1196. X                        case SHOW_FROM_NAME:
  1197. X                            str = txt_show_from_name;
  1198. X                            break;
  1199. X                        case SHOW_FROM_BOTH:
  1200. X                            str = txt_show_from_both;
  1201. X                            break;
  1202. X                    }
  1203. X                    printf ("%s", str);
  1204. X                    fflush (stdout);
  1205. X                } else {
  1206. X                    default_show_author = show_author;    
  1207. X                    if (show_author == SHOW_FROM_BOTH) {
  1208. X                        max_subj = (COLS / 2) - 2;
  1209. X                    } else {
  1210. X                        max_subj = (COLS / 2) + 5;
  1211. X                    }
  1212. X                    max_from = (COLS - max_subj) - 17;
  1213. X                }
  1214. X                break;
  1215. X
  1216. X            case 14:
  1217. X                var_orig = post_proc_type;
  1218. X                show_menu_help (txt_help_post_proc_type);
  1219. X                do {
  1220. X                    MoveCursor (INDEX_TOP+8, COL2 + (int) strlen (txt_opt_process_type));
  1221. X                    if ((ch    = ReadCh()) == ' ') {
  1222. X                        if (post_proc_type + 1 > POST_PROC_UUD_EXT_ZOO) {
  1223. X                            post_proc_type = POST_PROC_NONE;
  1224. X                        } else {
  1225. X                            post_proc_type++;
  1226. X                        }
  1227. X                        switch (post_proc_type) {
  1228. X                            case POST_PROC_NONE:
  1229. X                                str = txt_post_process_none;
  1230. X                                proc_ch_default = 'n';
  1231. X                                break;
  1232. X                            case POST_PROC_SHAR:
  1233. X                                str = txt_post_process_sh;
  1234. X                                proc_ch_default = 's';
  1235. X                                break;
  1236. X                            case POST_PROC_UUDECODE:
  1237. X                                str = txt_post_process_uudecode;
  1238. X                                proc_ch_default = 'u';
  1239. X                                break;
  1240. X                            case POST_PROC_UUD_LST_ZOO:
  1241. X                                str = txt_post_process_uud_lst_zoo;
  1242. X                                proc_ch_default = 'U';
  1243. X                                break;
  1244. X                            case POST_PROC_UUD_EXT_ZOO:
  1245. X                                str = txt_post_process_uud_ext_zoo;
  1246. X                                proc_ch_default = 'U';
  1247. X                                break;
  1248. X                        }
  1249. X                        CleartoEOLN (); 
  1250. X                        printf ("%s", str);
  1251. X                        fflush (stdout);
  1252. X                    }
  1253. X                } while (ch != CR && ch != ESC);
  1254. X
  1255. X                if (ch == ESC) {    /* restore original value */
  1256. X                    post_proc_type = var_orig;
  1257. X                    switch (post_proc_type) {
  1258. X                        case POST_PROC_NONE:
  1259. X                            str = txt_post_process_none;
  1260. X                            proc_ch_default = 'n';
  1261. X                            break;
  1262. X                        case POST_PROC_SHAR:
  1263. X                            str = txt_post_process_sh;
  1264. X                            proc_ch_default = 's';
  1265. X                            break;
  1266. X                        case POST_PROC_UUDECODE:
  1267. X                            str = txt_post_process_uudecode;
  1268. X                            proc_ch_default = 'u';
  1269. X                            break;
  1270. X                        case POST_PROC_UUD_LST_ZOO:
  1271. X                            str = txt_post_process_uud_lst_zoo;
  1272. X                            proc_ch_default = 'U';
  1273. X                            break;
  1274. X                        case POST_PROC_UUD_EXT_ZOO:
  1275. X                            str = txt_post_process_uud_ext_zoo;
  1276. X                            proc_ch_default = 'U';
  1277. X                            break;
  1278. X                    }
  1279. X                    CleartoEOLN (); 
  1280. X                    printf ("%s", str);
  1281. X                    fflush (stdout);
  1282. X                }
  1283. X                break;
  1284. X
  1285. X            case 15:
  1286. X                var_orig = sort_art_type;
  1287. X                show_menu_help (txt_help_sort_type);
  1288. X                do {
  1289. X                    MoveCursor (INDEX_TOP+10, COL1 + (int) strlen (txt_opt_sort_type));
  1290. X                    if ((ch    = ReadCh()) == ' ') {
  1291. X                        if (sort_art_type + 1 > SORT_BY_DATE_ASCEND) {
  1292. X                            sort_art_type = SORT_BY_NOTHING;
  1293. X                        } else {
  1294. X                            sort_art_type++;
  1295. X                        }
  1296. X                        switch (sort_art_type) {
  1297. X                            case SORT_BY_NOTHING:
  1298. X                                str = txt_sort_by_nothing;
  1299. X                                break;
  1300. X                            case SORT_BY_SUBJ_DESCEND:
  1301. X                                str = txt_sort_by_subj_descend;
  1302. X                                break;
  1303. X                            case SORT_BY_SUBJ_ASCEND:
  1304. X                                str = txt_sort_by_subj_ascend;
  1305. X                                break;
  1306. X                            case SORT_BY_FROM_DESCEND:
  1307. X                                str = txt_sort_by_from_descend;
  1308. X                                break;
  1309. X                            case SORT_BY_FROM_ASCEND:
  1310. X                                str = txt_sort_by_from_ascend;
  1311. X                                break;
  1312. X                            case SORT_BY_DATE_DESCEND:
  1313. X                                str = txt_sort_by_date_descend;
  1314. X                                break;
  1315. X                            case SORT_BY_DATE_ASCEND:
  1316. X                                str = txt_sort_by_date_ascend;
  1317. X                                break;
  1318. X                        }
  1319. X                        CleartoEOLN (); 
  1320. X                        printf ("%s", str);
  1321. X                        fflush (stdout);
  1322. X                    }
  1323. X                } while (ch != CR && ch != ESC);
  1324. X
  1325. X                if (ch == ESC) {    /* restore original value */
  1326. X                    sort_art_type = var_orig;
  1327. X                    switch (sort_art_type) {
  1328. X                        case SORT_BY_NOTHING:
  1329. X                            str = txt_sort_by_nothing;
  1330. X                            break;
  1331. X                        case SORT_BY_SUBJ_DESCEND:
  1332. X                            str = txt_sort_by_subj_descend;
  1333. X                            break;
  1334. X                        case SORT_BY_SUBJ_ASCEND:
  1335. X                            str = txt_sort_by_subj_ascend;
  1336. X                            break;
  1337. X                        case SORT_BY_FROM_DESCEND:
  1338. X                            str = txt_sort_by_from_descend;
  1339. X                            break;
  1340. X                        case SORT_BY_FROM_ASCEND:
  1341. X                            str = txt_sort_by_from_ascend;
  1342. X                            break;
  1343. X                        case SORT_BY_DATE_DESCEND:
  1344. X                            str = txt_sort_by_date_descend;
  1345. X                            break;
  1346. X                        case SORT_BY_DATE_ASCEND:
  1347. X                            str = txt_sort_by_date_ascend;
  1348. X                            break;
  1349. X                    }
  1350. X                    CleartoEOLN (); 
  1351. X                    printf ("%s", str);
  1352. X                    fflush (stdout);
  1353. X                }
  1354. X                break;
  1355. X
  1356. X            case 16:
  1357. X                show_menu_help (txt_help_savedir);
  1358. X                prompt_menu_string (INDEX_TOP+12, COL1 + (int) strlen (txt_opt_savedir), savedir);
  1359. X                expand_rel_abs_pathname (INDEX_TOP+12, COL1 + (int) strlen (txt_opt_savedir), savedir);
  1360. X                break;
  1361. X
  1362. X            case 17:
  1363. X                show_menu_help (txt_help_maildir);
  1364. X                prompt_menu_string (INDEX_TOP+14, COL1 + (int) strlen (txt_opt_maildir), maildir);
  1365. X                expand_rel_abs_pathname (INDEX_TOP+14, COL1 + (int) strlen (txt_opt_maildir), maildir);
  1366. X                break;
  1367. X
  1368. X            case 18:
  1369. X                show_menu_help (txt_help_printer);
  1370. X                prompt_menu_string (INDEX_TOP+16, COL1 + (int) strlen (txt_opt_printer), printer);
  1371. X                expand_rel_abs_pathname (INDEX_TOP+16, COL1 + (int) strlen (txt_opt_printer), printer);
  1372. X                break;
  1373. X        }
  1374. X        show_menu_help (txt_select_rcfile_option);
  1375. X    }
  1376. }
  1377. X
  1378. X
  1379. void show_rcfile_menu ()
  1380. {
  1381. X    char *str;
  1382. X
  1383. X    ClearScreen ();
  1384. X
  1385. X    center_line (0, TRUE, txt_options_menu);
  1386. X    
  1387. X    MoveCursor (INDEX_TOP, 0);
  1388. X    printf ("%s%s\r\n\r\n", txt_opt_autosave, (save_archive_name ? "ON " : "OFF"));
  1389. X    printf ("%s%s\r\n\r\n", txt_opt_kill_articles, (kill_articles ? "ON " : "OFF"));
  1390. X    printf ("%s%s\r\n\r\n", txt_opt_pos_first_unread, (pos_first_unread ? "ON " : "OFF"));
  1391. X    printf ("%s%s", txt_opt_thread_arts, (thread_arts ? "ON " : "OFF"));
  1392. X
  1393. X    MoveCursor(INDEX_TOP, COL2);
  1394. X    printf ("%s%s", txt_opt_save_separate, (save_separate ? "ON " : "OFF"));
  1395. X    MoveCursor(INDEX_TOP+2, COL2);
  1396. X    printf ("%s%s", txt_opt_draw_arrow, (draw_arrow_mark ? "ON " : "OFF"));
  1397. X    MoveCursor(INDEX_TOP+4, COL2);
  1398. X    printf ("%s%s", txt_opt_page_scroll, (full_page_scroll ? "ON " : "OFF"));
  1399. X    MoveCursor(INDEX_TOP+6, COL2);
  1400. X    printf ("%s%s", txt_opt_show_only_unread, (show_only_unread ? "ON " : "OFF"));
  1401. X
  1402. X    MoveCursor(INDEX_TOP, COL3);
  1403. X    printf ("%s%s", txt_opt_mark_saved_read, (mark_saved_read ? "ON " : "OFF"));
  1404. X    MoveCursor(INDEX_TOP+2, COL3);
  1405. X    printf ("%s%s", txt_opt_print_header, (print_header ? "ON " : "OFF"));
  1406. X    MoveCursor(INDEX_TOP+4, COL3);
  1407. X    printf ("%s%s", txt_opt_catchup_groups, (catchup_read_groups ? "ON " : "OFF"));
  1408. X
  1409. X    MoveCursor(INDEX_TOP+8, COL1);
  1410. X    switch (show_author) {
  1411. X        case SHOW_FROM_NONE:
  1412. X            str = txt_show_from_none;
  1413. X            break;
  1414. X        case SHOW_FROM_ADDR:
  1415. X            str = txt_show_from_addr;
  1416. X            break;
  1417. X        case SHOW_FROM_NAME:
  1418. X            str = txt_show_from_name;
  1419. X            break;
  1420. X        case SHOW_FROM_BOTH:
  1421. X            str = txt_show_from_both;
  1422. X            break;
  1423. X        }
  1424. X    printf ("%s%s", txt_opt_show_author, str);
  1425. X    MoveCursor(INDEX_TOP+8, COL2);
  1426. X    switch (post_proc_type) {
  1427. X        case POST_PROC_NONE:
  1428. X            str = txt_post_process_none;
  1429. X            break;
  1430. X        case POST_PROC_SHAR:
  1431. X            str = txt_post_process_sh;
  1432. X            break;
  1433. X        case POST_PROC_UUDECODE:
  1434. X            str = txt_post_process_uudecode;
  1435. X            break;
  1436. X        case POST_PROC_UUD_LST_ZOO:
  1437. X            str = txt_post_process_uud_lst_zoo;
  1438. X            break;
  1439. X        case POST_PROC_UUD_EXT_ZOO:
  1440. X            str = txt_post_process_uud_ext_zoo;
  1441. X            break;
  1442. X    }
  1443. X    printf ("%s%s\r\n\r\n", txt_opt_process_type, str);
  1444. X    
  1445. X    MoveCursor(INDEX_TOP+10, COL1);
  1446. X    switch (sort_art_type) {
  1447. X        case SORT_BY_NOTHING:
  1448. X            str = txt_sort_by_nothing;
  1449. X            break;
  1450. X        case SORT_BY_SUBJ_DESCEND:
  1451. X            str = txt_sort_by_subj_descend;
  1452. X            break;
  1453. X        case SORT_BY_SUBJ_ASCEND:
  1454. X            str = txt_sort_by_subj_ascend;
  1455. X            break;
  1456. X        case SORT_BY_FROM_DESCEND:
  1457. X            str = txt_sort_by_from_descend;
  1458. X            break;
  1459. X        case SORT_BY_FROM_ASCEND:
  1460. X            str = txt_sort_by_from_ascend;
  1461. X            break;
  1462. X        case SORT_BY_DATE_DESCEND:
  1463. X            str = txt_sort_by_date_descend;
  1464. X            break;
  1465. X        case SORT_BY_DATE_ASCEND:
  1466. X            str = txt_sort_by_date_ascend;
  1467. X            break;
  1468. X    }
  1469. X    printf ("%s%s\r\n\r\n", txt_opt_sort_type, str);
  1470. X
  1471. X    printf ("%s%s\r\n\r\n", txt_opt_savedir, savedir);
  1472. X    printf ("%s%s\r\n\r\n", txt_opt_maildir, maildir);
  1473. X    printf ("%s%s\r\n\r\n", txt_opt_printer, printer);
  1474. X    fflush(stdout);
  1475. X
  1476. X    show_menu_help (txt_select_rcfile_option);
  1477. X    MoveCursor (LINES, 0);
  1478. }
  1479. X
  1480. /*
  1481. X *  expand ~/News to /usr/username/News and print to screen
  1482. X */
  1483. void expand_rel_abs_pathname (line, col, str)
  1484. X    int line;
  1485. X    int col;
  1486. X    char *str;
  1487. {
  1488. X    char buf[LEN];
  1489. X    
  1490. X    if (str[0] == '~') {
  1491. X        if (strlen (str) == 1) {
  1492. X            strcpy (str, homedir);
  1493. X        } else {
  1494. X            sprintf (buf, "%s%s", homedir, str+1);
  1495. X            strcpy (str, buf);
  1496. X        }
  1497. X    }
  1498. X    MoveCursor (line, col);
  1499. X    CleartoEOLN ();
  1500. X    puts (str);
  1501. X    fflush (stdout);
  1502. }
  1503. X
  1504. /*
  1505. X *  show_menu_help
  1506. X */
  1507. void show_menu_help (help_message)
  1508. X    char *help_message;
  1509. {
  1510. X     MoveCursor (LINES-2, 0);
  1511. X     CleartoEOLN ();
  1512. X     center_line (LINES-2, FALSE, help_message);
  1513. }
  1514. SHAR_EOF
  1515. chmod 0600 rcfile.c ||
  1516. echo 'restore of rcfile.c failed'
  1517. Wc_c="`wc -c < 'rcfile.c'`"
  1518. test 22451 -eq "$Wc_c" ||
  1519.     echo 'rcfile.c: original size 22451, current size' "$Wc_c"
  1520. rm -f _shar_wnt_.tmp
  1521. fi
  1522. # ============= save.c ==============
  1523. if test -f 'save.c' -a X"$1" != X"-c"; then
  1524.     echo 'x - skipping save.c (File already exists)'
  1525.     rm -f _shar_wnt_.tmp
  1526. else
  1527. > _shar_wnt_.tmp
  1528. echo 'x - extracting save.c (Text)'
  1529. sed 's/^X//' << 'SHAR_EOF' > 'save.c' &&
  1530. /*
  1531. X *  Project   : tin - a threaded Netnews reader
  1532. X *  Module    : save.c
  1533. X *  Author    : R.Skrenta / I.Lea
  1534. X *  Created   : 01-04-91
  1535. X *  Updated   : 15-12-91
  1536. X *  Notes     :
  1537. X *  Copyright : (c) Copyright 1991-92 by Rich Skrenta & Iain Lea
  1538. X *                You may  freely  copy or  redistribute  this software,
  1539. X *              so  long as there is no profit made from its use, sale
  1540. X *              trade or  reproduction.  You may not change this copy-
  1541. X *              right notice, and it must be included in any copy made
  1542. X */
  1543. X
  1544. #include    "tin.h"
  1545. X
  1546. #define    INITIAL        1
  1547. #define MIDDLE        2
  1548. #define OFF            3
  1549. #define END            4
  1550. X
  1551. int create_subdir = TRUE;
  1552. X
  1553. struct save_t *save;
  1554. int save_num=0;
  1555. int max_save;
  1556. X
  1557. /*
  1558. X * types of archive programs
  1559. X * 0=archiver, 1=extension, 2=extract option, 3=list option
  1560. X */
  1561. struct archiver_t { 
  1562. X    char *name;
  1563. X    char *ext;
  1564. X    char *extract;
  1565. X    char *list;
  1566. };
  1567. X
  1568. struct archiver_t archiver[] = {
  1569. X    { "",            "",            "",            "" },
  1570. X    { "",            "",            "",            "" },
  1571. X    { "",            "",            "",            "" },
  1572. X    { "zoo",        "zoo",        "-extract",    "-list" },
  1573. X    { (char *) 0,    (char *) 0,    (char *) 0,    (char *) 0 }
  1574. };
  1575. X
  1576. extern char *glob_group;
  1577. extern char note_h_path[LEN];    /* Path:    */
  1578. extern char note_h_date[LEN];    /* Date:    */
  1579. extern FILE    *note_fp;            /* the body of the current article */
  1580. extern int index_point;
  1581. extern int note_end;
  1582. extern int note_page;
  1583. extern long note_mark[MAX_PAGES];
  1584. X
  1585. X
  1586. /*
  1587. X *  Check for articles and say how many new/unread in each group.
  1588. X *  or
  1589. X *  Start if new/unread articles and return first group with new/unread.
  1590. X *  or
  1591. X *  Save any new articles to savedir and mark arts read and mail user
  1592. X *  and inform how many arts in which groups were saved.
  1593. X *  or
  1594. X *  Mail any new articles to specified user and mark arts read and mail
  1595. X *  user and inform how many arts in which groups were mailed.
  1596. X */
  1597. X
  1598. int check_start_save_any_news (check_start_save)
  1599. X    int check_start_save;
  1600. {
  1601. X    char buf[LEN], logfile[LEN], *p;
  1602. X    char group_path[LEN];
  1603. X    char savefile[LEN];
  1604. X    extern FILE *note_fp;
  1605. X    FILE *fp, *fp_log;
  1606. X    int i, j, print_group;
  1607. X    int check_arts = 0;
  1608. X    int    log_opened = TRUE;
  1609. X    int print_first = TRUE;
  1610. X    int saved_arts = 0;
  1611. X    int saved_groups = 0;
  1612. X    int unread_news = FALSE;    
  1613. X    long epoch;
  1614. X
  1615. X    switch (check_start_save) {
  1616. X        case CHECK_ANY_NEWS:
  1617. X            if (verbose) {
  1618. X                wait_message (txt_checking_for_news);
  1619. X            }
  1620. X            break;
  1621. X        case START_ANY_NEWS:
  1622. X            wait_message (txt_checking_for_news);
  1623. X            break;
  1624. X        case MAIL_ANY_NEWS:
  1625. X        case SAVE_ANY_NEWS:
  1626. X            sprintf (logfile, "%s/log", rcdir);
  1627. X            if ((fp_log = fopen (logfile, "w")) == NULL) {
  1628. X                error_message (txt_cannot_open, logfile);
  1629. X                fp_log = stdout;
  1630. X                verbose = FALSE;
  1631. X                log_opened = FALSE;
  1632. X            }
  1633. X            time (&epoch);
  1634. X            fprintf (fp_log, "To: %s\n", userid);
  1635. X            fprintf (fp_log, "Subject: NEWS LOG %s\n", ctime (&epoch));
  1636. X            break;
  1637. X    }
  1638. X    
  1639. X    for (i = 0; i < group_top; i++) {
  1640. X        strcpy (group_path, active[my_group[i]].name);
  1641. X        for (p = group_path; *p; p++) {
  1642. X            if (*p == '.') {
  1643. X                *p = '/';
  1644. X            }
  1645. X        }
  1646. X        
  1647. X        index_group (active[my_group[i]].name, group_path);
  1648. X        read_newsrc_line (active[my_group[i]].name);
  1649. X        print_group = TRUE;
  1650. X        check_arts = 0;
  1651. X
  1652. X        for (j = 0; j < top; j++) {
  1653. X            if (arts[j].unread == ART_UNREAD)  {
  1654. X                switch (check_start_save) {
  1655. X                    case CHECK_ANY_NEWS:
  1656. X                        if (print_first && verbose) {
  1657. X                            putchar ('\n');
  1658. X                            print_first = FALSE;
  1659. X                        }
  1660. X                        check_arts++;
  1661. X                        break;
  1662. X                    case START_ANY_NEWS:
  1663. X                        return i;    /* return first group with unread news */ 
  1664. X                        /* NOTREACHED */
  1665. X                    case MAIL_ANY_NEWS:
  1666. X                    case SAVE_ANY_NEWS:
  1667. X                        if (print_group) {    
  1668. X                            sprintf (buf, "Saved %s...\n", active[my_group[i]].name);
  1669. X                            fprintf (fp_log, "%s", buf);
  1670. X                            if (verbose) {
  1671. X                                wait_message (buf);
  1672. X                            }
  1673. X                            print_group = FALSE;
  1674. X                            saved_groups++;
  1675. X                            if (check_start_save == SAVE_ANY_NEWS) {
  1676. X                                sprintf (buf, "%s/dummy", group_path);
  1677. X                                create_path (buf);
  1678. X                            }
  1679. X                        }
  1680. X                        sprintf (buf, "[%5ld]  %s\n", arts[j].artnum, arts[j].subject);
  1681. X                        fprintf (fp_log, "%s", buf);
  1682. X                        if (verbose) {
  1683. X                            wait_message (buf);
  1684. X                        }
  1685. X                        saved_arts++;
  1686. X
  1687. X                        if (check_start_save == MAIL_ANY_NEWS) {
  1688. X                            sprintf (savefile, "/tmp/tin.%d", getpid ());
  1689. X                        } else {
  1690. X                            sprintf (savefile, "%s/%s/%ld", savedir,
  1691. X                                     group_path, arts[j].artnum);
  1692. X                        }
  1693. X
  1694. X                        if ((fp = fopen (savefile, "w")) == NULL) {
  1695. X                            fprintf (fp_log, txt_cannot_open, savefile);
  1696. X                            if (verbose) {
  1697. X                                error_message (txt_cannot_open, savefile);
  1698. X                            }
  1699. X                            continue;
  1700. X                        }
  1701. X                
  1702. X                        if (check_start_save == MAIL_ANY_NEWS) {
  1703. X                            fprintf (fp, "To: %s\n", mail_news_user);
  1704. X                        }
  1705. X
  1706. X                        art_open (arts[j].artnum, group_path);    
  1707. X                        fseek (note_fp, 0L, 0);
  1708. X                        copy_fp (note_fp, fp, (char *) 0);
  1709. X                        art_close ();
  1710. X                        fclose (fp);
  1711. X
  1712. X                        if (check_start_save == MAIL_ANY_NEWS) {
  1713. X                            sprintf (buf, "%s \"%s\" < %s", mailer,
  1714. X                                    mail_news_user, savefile);
  1715. X                            if (! invoke_cmd (buf)) {
  1716. X                                error_message (txt_command_failed_s, buf);
  1717. X                            }
  1718. X                            unlink (savefile);
  1719. X                        }
  1720. X                        if (catchup) {
  1721. X                            arts[j].unread = ART_READ;
  1722. X                        }
  1723. X                        break;
  1724. X                }
  1725. X            }
  1726. X        }
  1727. X        
  1728. X        if (check_start_save == MAIL_ANY_NEWS ||
  1729. X            check_start_save == SAVE_ANY_NEWS) {
  1730. X            if (catchup) {
  1731. X                update_newsrc (active[my_group[i]].name, my_group[i], FALSE);
  1732. X            }
  1733. X        } else {
  1734. X            if (check_arts) {
  1735. X                if (verbose) {
  1736. X                    sprintf (buf, "%4d unread articles in %s\n",
  1737. X                        check_arts, active[my_group[i]].name);
  1738. X                    wait_message (buf);     
  1739. X                }
  1740. X                unread_news = TRUE;    
  1741. X            }
  1742. X        }
  1743. X    }
  1744. X    switch (check_start_save) {
  1745. X        case CHECK_ANY_NEWS:
  1746. X            if (unread_news) {
  1747. X                return 2;
  1748. X            } else {
  1749. X                if (verbose) {
  1750. X                    wait_message (txt_there_is_no_news);
  1751. X                }
  1752. X                return 0;
  1753. X            }
  1754. X            /* NOTREACHED */ 
  1755. X        case START_ANY_NEWS:
  1756. X            wait_message (txt_there_is_no_news);
  1757. X            return -1;
  1758. X            /* NOTREACHED */ 
  1759. X        case MAIL_ANY_NEWS:
  1760. X        case SAVE_ANY_NEWS:
  1761. X            sprintf (buf, "\n%s %d article(s) from %d group(s)\n", 
  1762. X                (check_start_save == MAIL_ANY_NEWS ? "Mailed" : "Saved"),
  1763. X                saved_arts, saved_groups);
  1764. X            fprintf (fp_log, "%s", buf);
  1765. X            if (verbose) {
  1766. X                wait_message (buf);
  1767. X            }
  1768. X            if (log_opened) {
  1769. X                fclose (fp_log);
  1770. X                if (verbose) {
  1771. X                    sprintf (buf, "Mailing log to %s\n",
  1772. X                        (check_start_save == MAIL_ANY_NEWS ? mail_news_user : userid));
  1773. X                    wait_message (buf);
  1774. X                }
  1775. X                sprintf (buf, "%s \"%s\" < %s", mailer,
  1776. X                    (check_start_save == MAIL_ANY_NEWS ? mail_news_user : userid),
  1777. X                    logfile);
  1778. X                if (! invoke_cmd (buf)) {
  1779. X                    error_message (txt_command_failed_s, buf);
  1780. X                }
  1781. X            }
  1782. X            break;
  1783. X    }
  1784. X    return 0;
  1785. }
  1786. X
  1787. X
  1788. int save_art_to_file (respnum, index, mailbox, filename)
  1789. X    int respnum;
  1790. X    int index;
  1791. X    int mailbox;
  1792. X    char *filename;
  1793. {
  1794. X    char file[LEN];
  1795. X    char save_art_info[LEN];
  1796. X    FILE *fp;
  1797. X    int is_mailbox = FALSE;
  1798. X    int i = 0, ret_code = FALSE;
  1799. X    long epoch;
  1800. X    
  1801. X    if (filename) {
  1802. X        my_strncpy (file, filename, LEN);
  1803. X        is_mailbox = mailbox;
  1804. X        i = index;
  1805. X    } else if (save_archive_name && arts[respnum].archive) {
  1806. X            my_strncpy (file, arts[respnum].archive, LEN);
  1807. X    }
  1808. X
  1809. X    if (! append_to_existing_file (i)) {
  1810. X        save[i].saved = FALSE;
  1811. X        info_message (txt_art_not_saved);
  1812. X        sleep (1);
  1813. X        return (ret_code);
  1814. X    }
  1815. X
  1816. X    set_real_uid_gid ();
  1817. X
  1818. X    if ((fp = fopen (save_filename (i), "a+")) == NULL) {
  1819. X        save[i].saved = FALSE;
  1820. X        info_message (txt_art_not_saved);
  1821. X        set_tin_uid_gid ();
  1822. X        return (ret_code);
  1823. X    }
  1824. X
  1825. X     time (&epoch);
  1826. X     fprintf (fp, "From %s %s", note_h_path, ctime (&epoch));
  1827. X
  1828. X    if (fseek (note_fp, 0L, 0) == -1) {
  1829. X        error_message ("fseek() error on [%s]", arts[respnum].subject);
  1830. X    }
  1831. X    copy_fp (note_fp, fp, (char *) 0);
  1832. X    fputs ("\n", fp);
  1833. X    fclose (fp);
  1834. X    fseek (note_fp, note_mark[note_page], 0);
  1835. X
  1836. X    save[i].saved = TRUE;
  1837. X
  1838. X    set_tin_uid_gid ();
  1839. X
  1840. X    if (filename == (char *) 0) {
  1841. X        if (is_mailbox) {
  1842. X            sprintf (save_art_info, txt_saved_to_mailbox, get_first_savefile ());
  1843. X        } else {
  1844. X            sprintf (save_art_info, txt_art_saved_to, get_first_savefile ());
  1845. X        }
  1846. X        info_message(save_art_info);
  1847. X    }
  1848. X    return TRUE;
  1849. }
  1850. X
  1851. X
  1852. int save_thread_to_file (is_mailbox, group_path)
  1853. X    int is_mailbox;
  1854. X    char *group_path;
  1855. {
  1856. X    char buf[LEN];
  1857. X    char save_thread_info[LEN];
  1858. X    char *first_savefile;
  1859. X    int count = 0;
  1860. X    int i, ret_code = FALSE;
  1861. X    long epoch;
  1862. X
  1863. X    set_real_uid_gid ();
  1864. X
  1865. X    for (i=0 ; i < save_num ; i++) {
  1866. X        sprintf (msg, "%s%d", txt_saving, ++count);
  1867. X        wait_message (msg);
  1868. X
  1869. X        if (is_mailbox) {
  1870. X            buf[0] = 0;
  1871. X        }else {
  1872. X            sprintf (buf, "%s.%02d", save[i].file, i+1);
  1873. X        }
  1874. X
  1875. X        art_open (arts[save[i].index].artnum, group_path);
  1876. X        ret_code = save_art_to_file (save[i].index, i, is_mailbox, buf);
  1877. X        art_close ();            
  1878. X    }
  1879. X    set_tin_uid_gid ();
  1880. X    
  1881. X    first_savefile = get_first_savefile ();
  1882. X
  1883. X    if (first_savefile == (char *) 0) {
  1884. X        info_message (txt_thread_not_saved);
  1885. X    } else {
  1886. X        if (is_mailbox) {
  1887. X            sprintf (save_thread_info, txt_saved_to_mailbox, first_savefile);
  1888. X        } else {
  1889. X            if (save_num == 1) {
  1890. X                sprintf (save_thread_info, txt_art_saved_to, first_savefile);
  1891. X            } else {
  1892. X                if (save_separate) {
  1893. X                    sprintf (save_thread_info, txt_thread_saved_to_many,
  1894. X                        first_savefile, get_last_savefile ());
  1895. X                } else {
  1896. X                    sprintf (save_thread_info, txt_thread_saved_to,
  1897. X                        first_savefile);
  1898. X                }
  1899. X            }
  1900. X            if (first_savefile != (char *) 0) {
  1901. X                free (first_savefile);
  1902. X                first_savefile = (char *) 0;
  1903. X            }
  1904. X        }
  1905. X        info_message (save_thread_info);
  1906. X    }
  1907. X    return TRUE;
  1908. }
  1909. X
  1910. X
  1911. int save_regex_arts (is_mailbox, group_path)
  1912. X    int is_mailbox;
  1913. X    char *group_path;
  1914. {
  1915. X    char buf[LEN];
  1916. X    int i, ret_code;     
  1917. X    
  1918. X    for (i=0 ; i < save_num ; i++) {
  1919. X        sprintf(msg, "%s%d", txt_saving, i+1);
  1920. X        wait_message (msg);
  1921. X
  1922. X        if (is_mailbox) {
  1923. X            buf[0] = 0;
  1924. X        }else {
  1925. X            sprintf (buf, "%s.%02d", save[i].file, i+1);
  1926. X        }
  1927. X
  1928. X        art_open (arts[save[i].index].artnum, group_path);
  1929. X        ret_code = save_art_to_file (save[i].index, i, is_mailbox, buf);
  1930. X        art_close ();            
  1931. X    }
  1932. X
  1933. X    if (! save_num) {    
  1934. X        info_message (txt_no_match);
  1935. X    } else {
  1936. X        if (is_mailbox) {
  1937. X            sprintf (buf, txt_saved_to_mailbox, get_first_savefile ());
  1938. X        } else {
  1939. X            sprintf (buf,txt_saved_pattern_to,
  1940. X                get_first_savefile (), get_last_savefile ());
  1941. X        }
  1942. X        info_message (buf);
  1943. X    }
  1944. X    return (ret_code);
  1945. }
  1946. X
  1947. X
  1948. int append_to_existing_file (i)
  1949. X    int i;
  1950. {
  1951. X    char buf[LEN];
  1952. X    char *file;
  1953. X    struct stat st;
  1954. X
  1955. X    if (! save[i].is_mailbox && save_separate) {
  1956. X        file = save_filename (i);
  1957. X        if (stat(file, &st) != -1) {    
  1958. X            sprintf (buf, txt_append_to_file, file); 
  1959. X            if (! prompt_yn (LINES, buf, 'n')) {
  1960. X                if (file != (char *) 0) {
  1961. X                    free (file);
  1962. X                    file = (char *) 0;
  1963. X                }
  1964. X                return FALSE;
  1965. X            }
  1966. X        }
  1967. X        if (file != (char *) 0) {
  1968. X            free (file);
  1969. X            file = (char *) 0;
  1970. X        }
  1971. X    }
  1972. X    
  1973. X    return TRUE;
  1974. }
  1975. X
  1976. X
  1977. int create_path (path)
  1978. X    char *path;
  1979. {
  1980. X    char buf[LEN];
  1981. X    char group[LEN];
  1982. X    char *env;
  1983. X    int i, j, len;
  1984. X    struct stat st;
  1985. X    
  1986. X    /*
  1987. X     * save in mailbox format to ~/Mail/<group.name>
  1988. SHAR_EOF
  1989. true || echo 'restore of save.c failed'
  1990. fi
  1991. echo 'End of tin1.1 part 8'
  1992. echo 'File save.c is continued in part 9'
  1993. echo 9 > _shar_seq_.tmp
  1994. exit 0
  1995.  
  1996. --
  1997. NAME   Iain Lea
  1998. EMAIL  iain%estevax.uucp@unido.Informatik.Uni-Dortmund.DE
  1999. SNAIL  Bruecken Strasse 12, 8500 Nuernberg 90, Germany
  2000. PHONE  +49-911-331963 (home)  +49-911-3089-407 (work)
  2001. -- 
  2002.  Dr. med. dipl.-math Dieter Becker           Tel.: (0 / +49) 6841 - 16 3046
  2003.  Medizinische Universitaets- und Poliklinik  Fax.: (0 / +49) 6841 - 16 3369
  2004.  Innere Medizin III                         
  2005.  D - 6650 Homburg / Saar                     Email: becker@med-in.uni-sb.de
  2006. exit 0 # Just in case...
  2007.