home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume29 / tin / part09 < prev    next >
Encoding:
Text File  |  1992-03-27  |  50.4 KB  |  1,970 lines

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