home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume29 / tin / part06 < prev    next >
Text File  |  1992-03-28  |  52KB  |  1,654 lines

  1. Newsgroups: comp.sources.misc
  2. From: iain%anl433.uucp@germany.eu.net (Iain J. Lea)
  3. Subject:  v29i024:  tin - threaded full screen newsreader v1.1P1, Part06/12
  4. Message-ID: <1992Mar27.033648.3312@sparky.imd.sterling.com>
  5. X-Md4-Signature: 025c2da8729ff1b049c954e2c17f9d4e
  6. Date: Fri, 27 Mar 1992 03:36:48 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 24
  11. Archive-name: tin/part06
  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.06 (part 6 of tin1.1)
  17. # do not concatenate these parts, unpack them in order with /bin/sh
  18. # file kill.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" != 6; 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 kill.c'
  34. else
  35. echo 'x - continuing file kill.c'
  36. sed 's/^X//' << 'SHAR_EOF' >> 'kill.c' &&
  37. X        str = "Subject: line only    ";
  38. X        printf ("%s", str);
  39. X        fflush(stdout);
  40. X        do {
  41. X            MoveCursor (INDEX_TOP+2, (int) strlen (txt_kill_text_type));
  42. X            if ((ch    = ReadCh()) == ' ') {
  43. X                counter++;
  44. X                if (counter == KILL_BOTH+1) {
  45. X                    counter = KILL_SUBJ;
  46. X                }
  47. X                switch (counter) {
  48. X                    case KILL_SUBJ:
  49. X                        str = "Subject: line only    ";
  50. X                        break;
  51. X                    case KILL_FROM:
  52. X                        str = "From: line only       ";
  53. X                        break;
  54. X                    case KILL_BOTH:
  55. X                        str = "Subject: & From: lines";
  56. X                        break;
  57. X                }
  58. X                printf ("%s", str);
  59. X                fflush(stdout);
  60. X            }
  61. X        } while (ch != CR && ch != ESC);
  62. X        if (ch == ESC) {
  63. X            return FALSE;
  64. X        }
  65. X    }
  66. X
  67. X    if (! text[0]) {
  68. X        show_menu_help (txt_help_kill_subject);
  69. X        kill_subj_ok = prompt_yn (INDEX_TOP+5, kill_subj, 'y');
  70. X
  71. X        show_menu_help (txt_help_kill_from);
  72. X        kill_from_ok = prompt_yn (INDEX_TOP+7, kill_from, 'n');
  73. X    }
  74. X
  75. X    if (text[0] || kill_subj_ok || kill_from_ok) {
  76. X        show_menu_help (txt_help_kill_group);
  77. X        kill_every_group = FALSE;
  78. X        MoveCursor (INDEX_TOP+10, (int) strlen (txt_kill_group));
  79. X        str = kill_group;
  80. X        printf ("%s", str);
  81. X        fflush (stdout);
  82. X        do {
  83. X            MoveCursor (INDEX_TOP+10, (int) strlen (txt_kill_group));
  84. X            if ((ch    = ReadCh()) == ' ') {
  85. X                kill_every_group = !kill_every_group;
  86. X                if (kill_every_group) {
  87. X                    str = "All groups";
  88. X                } else {
  89. X                    str = kill_group;
  90. X                }
  91. X                CleartoEOLN (); 
  92. X                printf ("%s", str);
  93. X                fflush(stdout);
  94. X            }
  95. X        } while (ch != CR && ch != ESC);
  96. X        if (ch == ESC) {
  97. X            return FALSE;
  98. X        }
  99. X    }
  100. X
  101. X    while (1) {
  102. X        do {
  103. X            sprintf (msg, "%s%c", txt_abort_edit_save_killfile, ch_default);
  104. X            wait_message (msg);
  105. X            MoveCursor(LINES, (int) strlen (txt_abort_edit_save_killfile));
  106. X            if ((ch = ReadCh()) == CR)
  107. X                ch = ch_default;
  108. X        } while (ch != ESC && ch != 'a' && ch != 'e' && ch != 's');
  109. X        switch (ch) {
  110. X            case 'e':
  111. X                start_line_offset = 2;
  112. X                invoke_editor (killfile);
  113. X                unkill_all_articles ();
  114. X                read_kill_file ();
  115. X                reload_index_file (group_name, FALSE);
  116. X                killed = TRUE;
  117. X                goto kill_done;
  118. X
  119. X            case 'a':
  120. X            case ESC:
  121. X                killed = FALSE;
  122. X                goto kill_done;
  123. X            
  124. X            case 's':
  125. X                if (kill_num > max_kill-1) {
  126. X                    expand_kill ();
  127. X                }
  128. X                if (text[0]) {
  129. X                    switch (counter) {
  130. X                        case KILL_SUBJ:
  131. X                            killf[kill_num].kill_subj = str_dup (text);
  132. X                            break;
  133. X                        case KILL_FROM:
  134. X                            killf[kill_num].kill_from = str_dup (text);
  135. X                            break;
  136. X                        case KILL_BOTH:
  137. X                            killf[kill_num].kill_subj = str_dup (text);
  138. X                            killf[kill_num].kill_from = str_dup (text);
  139. X                            break;
  140. X                    }
  141. X                    killf[kill_num].kill_type = counter;
  142. X                    if (kill_every_group) {
  143. X                        killf[kill_num].kill_group= 0L;
  144. X                    } else {
  145. X                        killf[kill_num].kill_group= hash_s (group_name);
  146. X                    }
  147. X                    kill_num++;
  148. X                } else {
  149. X                    if (kill_subj_ok) {
  150. X                        killf[kill_num].kill_type = KILL_SUBJ;
  151. X                        killf[kill_num].kill_subj = str_dup (arts[index].subject);
  152. X                    }
  153. X                    if (kill_from_ok) {
  154. X                        killf[kill_num].kill_type |= KILL_FROM;
  155. X                        if (arts[index].name != (char *) 0) {
  156. X                            sprintf (msg, "%s (%s)", arts[index].from, arts[index].name);
  157. X                        } else {
  158. X                            strcpy (msg, arts[index].from);
  159. X                        }
  160. X                        killf[kill_num].kill_from = str_dup (msg);
  161. X                    }
  162. X                    if (killf[kill_num].kill_type) {        
  163. X                        if (kill_every_group) {
  164. X                            killf[kill_num].kill_group= 0L;
  165. X                        } else {
  166. X                            killf[kill_num].kill_group= hash_s (group_name);
  167. X                        }
  168. X                        kill_num++;
  169. X                    }
  170. X                }
  171. X                write_kill_file ();
  172. X
  173. kill_done:
  174. X
  175. #ifdef SIGTSTP
  176. X                if (do_sigtstp) {
  177. #ifdef POSIX_JOB_CONTROL
  178. X                    sigemptyset (&kill_act.sa_mask);
  179. X                    kill_act.sa_flags = SA_RESTART | SA_RESETHAND;
  180. X                    kill_act.sa_handler = SIG_IGN;
  181. X                    sigaction (SIGTSTP, &old_act, 0L);
  182. #else
  183. X                    signal (SIGTSTP, susp);
  184. #endif
  185. X                }
  186. #endif
  187. X                return (killed);
  188. X        }    
  189. X    }
  190. X    /* NOTREACHED */
  191. }
  192. X
  193. X
  194. int unkill_all_articles ()
  195. {
  196. X    int unkilled = FALSE;
  197. X    register int i;
  198. X
  199. X    for (i=0 ; i < top ; i++) {
  200. X        if (arts[i].killed) {
  201. X            arts[i].killed = FALSE;
  202. X            unkilled = TRUE;
  203. X        }
  204. X    }
  205. X    num_of_killed_files = 0;
  206. X
  207. X    return (unkilled);
  208. }
  209. X
  210. X
  211. int kill_any_articles (group)
  212. X    char *group;
  213. {
  214. X    int killed = FALSE;
  215. X    int run_ok = FALSE;
  216. X    long newsgroup_hash;
  217. X    register int i, j;
  218. X
  219. X    if (! kill_articles) {
  220. X        return killed;
  221. X    }
  222. X
  223. X    if (kill_num) {
  224. X        newsgroup_hash = hash_s (group);
  225. X        for (i=0 ; i < kill_num ; i++) {
  226. X                if (killf[i].kill_group == 0L ||
  227. X                    killf[i].kill_group == newsgroup_hash) {
  228. X                    run_ok = TRUE;    
  229. X                }
  230. X        }
  231. X        if (! run_ok) {
  232. X            return (killed);
  233. X        }
  234. X        if (debug && ! update) {
  235. X            wait_message (txt_killing_arts);
  236. X        }
  237. X        for (i=0 ; i < top ; i++) {
  238. X            for (j=0 ; j < kill_num && ! arts[i].killed ; j++) {
  239. X                if (killf[j].kill_group == 0L ||
  240. X                    killf[j].kill_group == newsgroup_hash) {
  241. X                    switch (killf[j].kill_type) {
  242. X                        case KILL_SUBJ:
  243. #ifdef NO_REGEX 
  244. X                            if (str_str (arts[i].subject, killf[j].kill_subj,
  245. X                                        strlen (killf[j].kill_subj)) != 0) {
  246. #else        
  247. X                            if (wildmat (arts[i].subject, killf[j].kill_subj)) {
  248. #endif        
  249. X                                arts[i].killed = TRUE;
  250. X                                killed = TRUE;
  251. X                            }
  252. X                            break;
  253. X                        case KILL_FROM:
  254. X                            if (arts[i].name != (char *) 0) {
  255. X                                sprintf (msg, "%s (%s)", arts[i].from, arts[i].name);
  256. X                            } else {
  257. X                                strcpy (msg, arts[i].from);
  258. X                            }
  259. #ifdef NO_REGEX 
  260. X                            if (str_str (msg, killf[j].kill_from
  261. X                                        strlen (killf[j].kill_from)) != 0) {
  262. #else        
  263. X                            if (wildmat (msg, killf[j].kill_from)) {
  264. #endif        
  265. X                                arts[i].killed = TRUE;
  266. X                                killed = TRUE;
  267. X                            }
  268. X                            break;
  269. X                        case KILL_BOTH:
  270. #ifdef NO_REGEX 
  271. X                            if (str_str (arts[i].subject, killf[j].kill_subj,
  272. X                                        strlen (killf[j].kill_subj)) != 0) {
  273. #else        
  274. X                            if (wildmat (arts[i].subject, killf[j].kill_subj)) {
  275. #endif        
  276. X                                arts[i].killed = TRUE;
  277. X                                killed = TRUE;
  278. X                            }
  279. X                            if (arts[i].name != (char *) 0) {
  280. X                                sprintf (msg, "%s (%s)", arts[i].from, arts[i].name);
  281. X                            } else {
  282. X                                strcpy (msg, arts[i].from);
  283. X                            }
  284. #ifdef NO_REGEX
  285. X                            if (str_str (msg, killf[j].kill_from,
  286. X                                        strlen (killf[j].kill_from)) != 0) {
  287. #else        
  288. X                            if (wildmat (msg, killf[j].kill_from)) {
  289. #endif        
  290. X                                arts[i].killed = TRUE;
  291. X                                killed = TRUE;
  292. X                            }
  293. X                            break;
  294. X                    }
  295. X                }
  296. X            }
  297. X        }
  298. X    }
  299. X    return (killed);
  300. }
  301. SHAR_EOF
  302. echo 'File kill.c is complete' &&
  303. chmod 0600 kill.c ||
  304. echo 'restore of kill.c failed'
  305. Wc_c="`wc -c < 'kill.c'`"
  306. test 11211 -eq "$Wc_c" ||
  307.     echo 'kill.c: original size 11211, current size' "$Wc_c"
  308. rm -f _shar_wnt_.tmp
  309. fi
  310. # ============= lang.c ==============
  311. if test -f 'lang.c' -a X"$1" != X"-c"; then
  312.     echo 'x - skipping lang.c (File already exists)'
  313.     rm -f _shar_wnt_.tmp
  314. else
  315. > _shar_wnt_.tmp
  316. echo 'x - extracting lang.c (Text)'
  317. sed 's/^X//' << 'SHAR_EOF' > 'lang.c' &&
  318. /*
  319. X *  Project   : tin - a threaded Netnews reader
  320. X *  Module    : lang.c
  321. X *  Author    : I.Lea
  322. X *  Created   : 01-04-91
  323. X *  Updated   : 21-03-92
  324. X *  Notes     :
  325. X *  Copyright : (c) Copyright 1991-92 by Iain Lea
  326. X *              You may  freely  copy or  redistribute  this software,
  327. X *              so  long as there is no profit made from its use, sale
  328. X *              trade or  reproduction.  You may not change this copy-
  329. X *              right notice, and it must be included in any copy made
  330. X */
  331. X
  332. /*
  333. X *  art.c
  334. X */
  335. X
  336. char txt_group[] = "Group %s...";
  337. char txt_cannot_open_art[] = "can't open article %s: ";
  338. char txt_indexing[] = "Indexing %s...";
  339. char txt_indexing_num[] = "Indexing %s...%4d";
  340. char txt_corrupt_index[] = "Index file %s corrupted. error %d on article %d";
  341. char txt_checking_for_news[] = "Checking for news...";
  342. char txt_there_is_no_news[] = "There is no news\n";
  343. char txt_killing_arts[] = "Killing articles...";
  344. char txt_unkilling_arts[] = "Unkilling articles...";
  345. X
  346. /*
  347. X *  feed.c
  348. X */
  349. X
  350. char txt_art_thread_regex_tag[] = " a)rticle, t)hread, r)egex pattern, T)agged articles, e)xit: ";
  351. char txt_post_process_type[] = "Process n)one, s)har, u)udecode, U)udecode & zoo: ";
  352. #ifdef NO_REGEX 
  353. char txt_feed_pattern[] = "Enter pattern [%s]> ";
  354. #else
  355. char txt_feed_pattern[] = "Enter regex pattern [%s]> ";
  356. #endif
  357. char txt_no_command[] = "No command";
  358. char txt_piping[] = "Piping...";
  359. X
  360. /*
  361. X *  group.c
  362. X */
  363. X
  364. char txt_cannot_post[] = "*** Posting not allowed ***";
  365. char txt_tagged_art[] = "tagged article";
  366. char txt_untagged_art[] = "untagged article";
  367. char txt_inverse_on[] = "Inverse video enabled";
  368. char txt_inverse_off[] = "Inverse video disabled";
  369. char txt_subscribed_to[] = "subscribed to %s";
  370. char txt_unsubscribed_to[] = "unsubscribed from %s";
  371. char txt_mark_all_read[] = "Mark all articles as read? (y/n): ";
  372. char txt_no_more_groups[] = "No more groups";
  373. char txt_no_prev_group[] = "No previous group";
  374. char txt_no_arts[] = "*** No Articles ***";
  375. char txt_no_groups[] = "*** No Groups ***";
  376. char txt_end_of_thread[] = "*** End of Thread ***";
  377. char txt_end_of_arts[] = "*** End of Articles ***";
  378. char txt_end_of_groups[] = "*** End of Groups ***";
  379. char txt_no_next_unread_art[] = "No next unread article";
  380. char txt_no_prev_unread_art[] = "No previous unread article";
  381. char txt_no_last_message[] = "No last message";
  382. char txt_bad_command[] = "Bad command.  Type 'h' for help.";
  383. char txt_you_have_mail[] = "    You have mail\n";
  384. /*
  385. char txt_type_h_for_help[] = "Type 'h' for help\n";
  386. */
  387. char txt_type_h_for_help[] = "           h=help\n";
  388. char txt_read_art[] = "Read article> ";
  389. char txt_search_forwards[] = "Search forwards [%s]> ";
  390. char txt_search_backwards[] = "Search backwards [%s]> ";
  391. char txt_author_search_forwards[] = "Author search forwards [%s]> ";
  392. char txt_author_search_backwards[] = "Author search backwards [%s]> ";
  393. char txt_no_search_string[] = "No search string";
  394. char txt_no_match[] = "No match";
  395. char txt_post_subject[] = "Post Subject [%s]> ";
  396. char txt_no_subject[] = "No subject";
  397. char txt_cannot_open[] = "can't open %s";
  398. char txt_posting[] = "Posting...";
  399. char txt_art_posted[] = "-- Article posted --";
  400. char txt_art_rejected[] = "-- Article rejected (saved to %s) --";
  401. char txt_abort_edit_post[] = "a)bort, e)dit, p)ost: ";
  402. char txt_help_i_4[] = "4$       Goto article 4 ($=goto last article)\r\n";
  403. char txt_help_ctrl_k[] = "^K       Kill current article\r\n";
  404. char txt_help_ctrl_l[] = "^L       Redraw page\r\n";
  405. char txt_help_ctrl_d[] = "^D^U     Down (^U=up) a page\r\n";
  406. char txt_help_i_cr[] = "<CR>     Read current article\r\n";
  407. char txt_help_i_tab[] = "<TAB>    Goto next unread article or group\r\n";
  408. char txt_help_d[] = "d        Toggle display of subject only & subject/author\r\n";
  409. char txt_help_l[] = "l        List articles within current thread\r\n";
  410. char txt_help_m[] = "m        Move current group within group selection list\r\n";
  411. char txt_help_M[] = "M        Menu of configurable options\r\n";
  412. char txt_help_a[] = "aA       Author forward (A=backward) search\r\n";
  413. char txt_help_sel_c[] = "cC       Mark group read (C=and goto next unread group)\r\n";
  414. char txt_help_c[] = "c        Mark all articles as read and goto group selection menu\r\n";
  415. char txt_help_g[] = "g        Choose a new group by name\r\n";
  416. char txt_help_I[] = "I        Toggle inverse video\r\n";
  417. char txt_help_K[] = "K        Mark article/thread as read & goto next unread\r\n";
  418. char txt_help_j[] = "jk       Down (k=up) a line\r\n";
  419. char txt_help_i_n[] = "np       Goto next (p=previous) group\r\n";
  420. char txt_help_i_p[] = "NP       Goto next (P=previous) unread article\r\n";
  421. char txt_help_q[] = "q        Quit\r\n";
  422. char txt_help_r[] = "r        Toggle display to show all / only unread articles\r\n";
  423. char txt_help_s[] = "su       Subscribe (u=unsubscribe) to current group\r\n";
  424. char txt_help_S[] = "SU       Subscribe (U=unsubscribe) to groups that match pattern\r\n";
  425. char txt_help_t[] = "t        Return to group selection index\r\n";
  426. char txt_help_T[] = "T        Tag current article for mailing/piping/printing/saving\r\n";
  427. char txt_help_u[] = "u        Toggle display of unthreaded & threaded articles\r\n";
  428. char txt_help_U[] = "U        Untag all tagged articles\r\n";
  429. char txt_help_v[] = "v        Show version information\r\n";
  430. char txt_help_w[] = "w        Post an article to current group\r\n";
  431. char txt_help_i_search[] = "/?       Subject forward (?=backward) search\r\n";
  432. char txt_help_thread[] = "<>       Goto first (>=last) article in current thread";
  433. #ifndef NO_SHELL_ESCAPE
  434. char txt_help_shell[] = "!        Shell escape\r\n";
  435. #endif
  436. char txt_help_dash[] = "-        Show last message\r\n";
  437. #ifdef NO_REGEX 
  438. char txt_save_pattern[] = "Enter save pattern [%s]> ";
  439. #else
  440. char txt_save_pattern[] = "Enter regex save pattern [%s]> ";
  441. #endif
  442. char txt_saved_pattern_to[] = "-- Saved pattern to %s - %s --";
  443. char txt_saved_to_mailbox[] = "-- Saved to mailbox %s --";
  444. char txt_switch_on_kill_art_menu[] = "Kill Article Menu is switched OFF. Select Options Menu to switch it ON.";
  445. X
  446. /* 
  447. X *  help.c:
  448. X */
  449. X
  450. char txt_group_select_com[] = "Group Selection Commands (page %d of %d)";
  451. char txt_index_page_com[] = "Index Page Commands (page %d of %d)";
  452. char txt_thread_com[] = "Thread Commands (page %d of %d)";
  453. char txt_art_pager_com[] = "Article Pager Commands (page %d of %d)";
  454. char txt_hit_space_for_more[] = "PgDn,End,<SPACE>,^D - page down. PgUp,Home,b,^U - page up. <CR>,q - quit";
  455. char txt_post_history_menu[] = "Posted articles history (page %d of %d)";
  456. X
  457. /* 
  458. X *  kill.c:
  459. X */
  460. X
  461. char txt_kill_menu[] = "Kill Article Menu";
  462. char txt_kill_subject[] = "Kill Subject [%-45s] (y/n): ";
  463. char txt_kill_from[] =    "Kill From    [%-45s] (y/n): ";
  464. char txt_kill_text[] = "Kill text pattern : ";
  465. char txt_kill_text_type[] = "Apply pattern to  : ";
  466. char txt_kill_group[] =     "Kill pattern scope: ";
  467. char txt_help_kill_subject[] = "Subject: line to add to kill file. Press backspace key to clear field.";
  468. char txt_help_kill_from[] = "From: line to add to kill file. Press backspace key to clear field.";
  469. char txt_help_kill_text[] = "Enter text pattern to kill if Subject: & From: lines are not what you want.";
  470. char txt_help_kill_text_type[] = "Select where text pattern should be applied. <SPACE> toggles & <CR> sets.";
  471. char txt_help_kill_group[] = "Apply kill to current group only or all groups. <SPACE> toggles & <CR> sets.";
  472. char txt_abort_edit_save_killfile[] = "a)bort e)dit s)ave killfile: ";
  473. X
  474. X
  475. /* 
  476. X *  main.c:
  477. X */
  478. X
  479. char txt_option_not_enabled[] = "Option not enabled. Recompile with %s.\n";
  480. char txt_not_in_active_file[] = "Group %s not found in active file";
  481. char txt_screen_init_failed[] = "%s: Screen initialization failed";
  482. char txt_bad_active_file[] = "Active file corrupt - %s";
  483. X
  484. /*
  485. X *  misc.c
  486. X */
  487. X
  488. char txt_cannot_open_active_file[] = "Cannot open %s. Try %s -r to read news via NNTP.\n";
  489. char txt_reading_active_file[] = "Reading active file...";
  490. char txt_active_file_is_empty[] = "%s contains no newsgroups. Exiting.";
  491. char txt_checking_active_file[] = "Checking for new newsgroups...";
  492. char txt_subscribe_to_new_group[] = "\r\nSubscribe to %s (y/n): ";
  493. char txt_checking[] = "Checking...";
  494. char txt_cannot_find_base_art[] = "Cannot find base article %s";
  495. char txt_out_of_memory[] = "%s: out of memory";
  496. char txt_rename_error[] = "Error: rename %s to %s";
  497. char txt_shell_escape[] = "Enter shell command [%s]> ";
  498. X
  499. /*
  500. X *  newsrc.c
  501. X */
  502. X
  503. char txt_creating_newsrc[] = "Creating .newsrc...\n";
  504. char txt_deleting_from_newsrc[] = "Group %s not in active file. Deleting.";
  505. X
  506. /*
  507. X *  open.c
  508. X */
  509. char txt_connecting[] = "\nConnecting to %s...";
  510. char txt_cannot_get_nntp_server_name[] = "Cannot find NNTP server name";
  511. char txt_server_name_in_file_env_var[] = "Put the server name in the file %s,\nor set the environment variable NNTPSERVER";
  512. char txt_failed_to_connect_to_server[] = "failed to connect to (%s) server";
  513. char txt_rejected_by_nntpserver[] = "rejected by server, nntp error %d";
  514. char txt_connection_to_server_broken[] = "connection to server broken";
  515. char txt_stuff_nntp_cannot_open[] = "stuff_nntp: can't open %s: ";
  516. char txt_nntp_to_fp_cannot_reopen[] = "nntp_to_fp: can't reopen %s: ";
  517. char txt_nntp_to_fd_cannot_reopen[] = "nntp_to_fd: can't reopen %s: ";
  518. X
  519. /*
  520. X *  page.c
  521. X */
  522. X
  523. char txt_quit[] = "Do you really want to quit? (y/n): ";
  524. char txt_art_unavailable[] = "Article %ld unavailable";
  525. char txt_art_marked_as_unread[] = "Article marked as unread";
  526. char txt_thread_marked_as_unread[] = "Thread marked as unread";
  527. char txt_begin_of_art[] = "*** Beginning of article ***";
  528. char txt_next_resp[] = "-- Next response --";
  529. char txt_last_resp[] = "-- Last response --";
  530. char txt_more[] = "--More--";
  531. char txt_more_percent[] = "--More--(%d%%) [%ld/%ld]";
  532. char txt_thread_x_of_n[] = "%sThread %3d of %3d\r\n";
  533. char txt_art[] = "Article %ld  ";
  534. char txt_resp_x_of_n[] = "Respno %3d of %3d\r\n";
  535. char txt_no_resp[] = "No responses\r\n";
  536. char txt_1_resp[] = "1 Response\r\n";
  537. char txt_x_resp[] = "%d Responses\r\n";
  538. char txt_s_at_s[] = "%s at %s";
  539. char txt_thread_resp_page[] = "Thread %d of %d, Resp %d (page %d):  %s";
  540. char txt_thread_page[] = "Thread %d of %d (page %d):  %s";
  541. char txt_read_resp[] = "Read response> ";
  542. char txt_help_p_0[] = "0        Read the base article in current thread\r\n";
  543. char txt_help_p_4[] = "4        Read response 4 in current thread\r\n";
  544. char txt_help_p_cr[] = "<CR>     Goto to next thread\r\n";
  545. char txt_help_p_tab[] = "<TAB>    Goto next unread article\r\n";
  546. char txt_help_b[] = "b<SPACE> Back (<SPACE>=forward) a page\r\n";
  547. char txt_help_bug[] = "B        Mail bug/comment to %s\r\n";
  548. char txt_help_p_f[] = "fF       Post (F=copy text) a followup\r\n";
  549. char txt_help_C[] = "C        Cancel current article that must have been posted by you\r\n";
  550. char txt_help_ctrl_h[] = "^H       Show articles header\r\n";
  551. char txt_help_h[] =      "h        Command help\r\n";
  552. char txt_help_p_i[] = "i        Return to index page\r\n";
  553. char txt_help_p_k[] = "kK       Mark article (K=thread) as read & advance to next unread\r\n";
  554. char txt_help_p_m[] = "m        Mail article/thread/pattern/tagged articles to someone\r\n";
  555. char txt_help_p_n[] = "nN       Goto to the next (N=unread) article\r\n";
  556. char txt_help_o[] = "o        Output article/thread/pattern/tagged articles to printer\r\n";
  557. char txt_help_p_p[] = "pP       Goto the previous (P=unread) article\r\n";
  558. char txt_help_p_r[] = "rR       Reply through mail (R=copy text) to author\r\n";
  559. char txt_help_p_s[] = "s        Save article/thread/pattern/tagged articles to file\r\n";
  560. char txt_help_p_z[] = "zZ       Mark article (Z=thread) as unread\r\n";
  561. char txt_help_p_ctrl_r[] = "^R$      Redisplay first ($=last) page of article\r\n";
  562. char txt_help_p_g[] = "gG       Goto first (G=last) page of article\r\n";
  563. char txt_help_p_d[] = "d        Toggle rot-13 decoding for current article\r\n";
  564. char txt_help_pipe[] = "|        Pipe article/thread/pattern/tagged articles into command\r\n";
  565. char txt_help_p_search[] = "/        Article forward search\r\n";
  566. char txt_mail_art_to[] = "Mail article to [%s]> ";
  567. char txt_no_mail_address[] = "No mail address";
  568. char txt_abort_edit_send[] = "a)bort, e)dit, s)end";
  569. char txt_abort_edit_cancel[] = "a)bort, e)dit, c)ancel";
  570. char txt_cancelling[] = "Cancelling article...";
  571. char txt_art_cancelled[] = "Article cancelled";
  572. char txt_mailing_to[] = "Mailing to %s...";
  573. char txt_message_sent[] = "-- Article(s) Mailed --";
  574. char txt_command_failed_s[] = "Command failed: %s\n";
  575. char txt_in_art_you_write[] = "In article %s you write:\n";
  576. char txt_resp_to_poster[] = "Responses have been directed to the poster. Post anyway? (y/n): ";
  577. char txt_resp_redirect[] = "Responses have been directed to the following newsgroups";
  578. char txt_continue[] = "Continue? (y/n): ";
  579. char txt_writes[] = "%s writes:\n";
  580. char txt_writes_name[] = "%s (%s) writes:\n";
  581. char txt_save_filename[] = "Save filename [%s]> ";
  582. char txt_art_not_saved[] = "-- Article not saved --";
  583. char txt_no_filename[] = "No filename";
  584. char txt_saving[] = "Saving...";
  585. char txt_art_saved_to[] = "-- Article saved to %s --";
  586. char txt_thread_not_saved[] = "-- Thread not saved --";
  587. char txt_thread_saved_to_many[] = "-- Thread saved to %s - %s --";
  588. char txt_thread_saved_to[] = "-- Thread saved to %s --";
  589. char txt_pipe_to_command[] = "Pipe to command [%s]: ";
  590. char txt_printing[] = "Printing...";
  591. char txt_printed[] = "-- Article(s) printed --";
  592. char txt_append_to_file[] = "File %s exists. Append? (y/n): ";
  593. char txt_toggled_rot13[] = "Toggled rot13 encoding";
  594. X
  595. /*
  596. X *  post.c
  597. X */
  598. X
  599. char txt_no_arts_posted[] = "No articles have been posted";
  600. char txt_post_an_article[] = "Post an article...";
  601. char txt_post_a_followup[] = "Post a followup...";
  602. char txt_mail_bug_report[] = "Mail bug report...";
  603. char txt_mail_bug_report_confirm[] = "Mail bug report to %s? (y/n): ";
  604. char txt_reply_to_author[] = "Reply to author...";
  605. X
  606. /*
  607. X *  prompt.c
  608. X */
  609. X
  610. char txt_hit_any_key[] = "-- Press any key to continue --";
  611. X
  612. /*
  613. X *  rcfile.c
  614. X */
  615. char txt_opt_autosave[] = "1. Auto save       : ";
  616. char txt_opt_save_separate[] = "2. Save separate   : ";
  617. char txt_opt_mark_saved_read[] = "3. Mark saved read : ";
  618. char txt_opt_kill_articles[] = "4. Kill articles   : ";
  619. char txt_opt_draw_arrow[] = "5. Draw arrow      : ";
  620. char txt_opt_print_header[] = "6. Print header    : ";
  621. char txt_opt_pos_first_unread[] = "7. Goto 1st unread : ";
  622. char txt_opt_page_scroll[] = "8. Scroll full page: ";
  623. char txt_opt_catchup_groups[] = "9. Catchup on quit : ";
  624. char txt_opt_thread_arts[] =   "10 Thread articles : ";
  625. char txt_opt_show_only_unread[] = "11 Show only unread: ";
  626. char txt_opt_show_author[] = "13 Show author     : ";
  627. char txt_opt_process_type[] = "14 Process type    : ";
  628. char txt_opt_sort_type[] = "15 Sort article by : ";
  629. char txt_opt_savedir[] = "16 Save directory  : ";
  630. char txt_opt_maildir[] = "17 Mail directory  : ";
  631. char txt_opt_printer[] = "18 Printer         : ";
  632. char txt_options_menu[] = "Options Menu";
  633. char txt_show_from_none[] = "None";
  634. char txt_show_from_addr[] = "Addr";
  635. char txt_show_from_name[] = "Name";
  636. char txt_show_from_both[] = "Both";
  637. char txt_post_process_none[] = "None";
  638. char txt_post_process_sh[] = "Shell archive";
  639. char txt_post_process_uudecode[] = "Uudecode";
  640. char txt_post_process_uud_lst_zoo[] = "Uudecode & list zoo archive";
  641. char txt_post_process_uud_ext_zoo[] = "Uudecode & extract zoo archive";
  642. char txt_sort_by_nothing[] = "Nothing";
  643. char txt_sort_by_subj_descend[] = "Subject: field (descending)";
  644. char txt_sort_by_subj_ascend[] = "Subject: field (ascending)";
  645. char txt_sort_by_from_descend[] = "From: field (descending)";
  646. char txt_sort_by_from_ascend[] = "From: field (ascending)";
  647. char txt_sort_by_date_descend[] = "Date: field (descending)";
  648. char txt_sort_by_date_ascend[] = "Date: field (ascending)";
  649. char txt_help_autosave[] = "Auto save article/thread by Archive-name: header. <SPACE> toggles & <CR> sets.";
  650. char txt_help_save_separate[] = "Save articles/threads to separate files. <SPACE> toggles & <CR> sets.";
  651. char txt_help_print_header[] = "By printing print all/part of header. <SPACE> toggles & <CR> sets.";
  652. char txt_help_pos_first_unread[] = "Put cursor at first/last unread art in groups. <SPACE> toggles & <CR> sets.";
  653. char txt_help_show_author[] = "Show Subject & From (author) fields in group menu. <SPACE> toggles & <CR> sets.";
  654. char txt_help_draw_arrow[] = "Draw -> or highlighted bar for selection. <SPACE> toggles & <CR> sets.";
  655. char txt_help_kill_articles[] = "Kill articles that match entries in kill file. <SPACE> toggles & <CR> sets.";
  656. char txt_help_mark_saved_read[] = "Mark saved articles/threads as read. <SPACE> toggles & <CR> sets."; 
  657. char txt_help_page_scroll[] = "Scroll half/full page of groups/articles. <SPACE> toggles & <CR> sets."; 
  658. char txt_help_catchup_groups[] = "Ask to mark groups read when quiting. <SPACE> toggles & <CR> sets."; 
  659. char txt_help_thread_arts[] = "Enable/disable threading of articles in all groups. <SPACE> toggles & <CR> sets."; 
  660. char txt_help_show_only_unread[] = "Show all articles or only unread articles. <SPACE> toggles & <CR> sets."; 
  661. char txt_help_post_proc_type[] = "Post process (ie. unshar) saved article/thread. <SPACE> toggles & <CR> sets."; 
  662. char txt_help_sort_type[] = "Sort articles by Subject, From or Date fields. <SPACE> toggles & <CR> sets.";
  663. char txt_help_savedir[] = "The directory where you want articles/threads saved.";
  664. char txt_help_maildir[] = "The directory where articles/threads are to be saved in mailbox format.";
  665. char txt_help_printer[] = "The printer program with options that is to be used to print articles/threads.";
  666. char txt_select_rcfile_option[] = "Select option by entering number before text. Any other key to save.";
  667. X
  668. /*
  669. X *  save.c
  670. X */
  671. X
  672. char txt_post_processing[] = "Post processing...";
  673. char txt_post_processing_finished[] = "-- post processing completed --";
  674. char txt_deleting[] = "Deleting...";
  675. char txt_uudecoding[] = "Uudecoding...";
  676. X
  677. /*
  678. X *  search.c
  679. X */
  680. X
  681. char txt_searching[] = "Searching...";
  682. X
  683. /*
  684. X *  select.c
  685. X */
  686. X
  687. char txt_moving[] = "Moving...";
  688. #ifdef NO_REGEX
  689. char txt_subscribe_pattern[] = "Enter subscribe pattern> ";
  690. char txt_unsubscribe_pattern[] = "Enter unsubscribe pattern> ";
  691. #else
  692. char txt_subscribe_pattern[] = "Enter regex subscribe pattern> ";
  693. char txt_unsubscribe_pattern[] = "Enter regex unsubscribe pattern> ";
  694. #endif
  695. char txt_subscribing[] = "Subscribing...";
  696. char txt_subscribing_to[] = "Subscribing to %s...";
  697. char txt_unsubscribing[] = "Unsubscribing...";
  698. char txt_unsubscribing_from[] = "Unsubscribing from %s...";
  699. char txt_subscribed_num_groups[] = "subscribed to %d groups";
  700. char txt_unsubscribed_num_groups[] = "unsubscribed from %d groups";
  701. char txt_del_group_in_newsrc[] = "Delete %s from .newsrc? (y/n): ";
  702. char txt_group_deleted[] = "Group %s deleted";
  703. char txt_group_undeleted[] = "Group undeleted";
  704. char txt_mark_group_read[] = "Mark group %s as read? (y/n): ";
  705. char txt_no_groups_to_delete[] = "No groups to delete";
  706. char txt_reset_newsrc[] = "Reset newsrc? (y/n): ";
  707. char txt_post_newsgroup[] = "Post newsgroup> ";
  708. char txt_yanking_all_groups[] = "Yanking in all groups...";
  709. char txt_yanking_sub_groups[] = "Yanking in subscribed to groups...";
  710. char txt_no_groups_to_read[] = "No more groups to read";
  711. char txt_added_groups[] = "Added %d group%s";
  712. char txt_plural[] = "s";
  713. char txt_no_groups_to_yank_in[] = "No more groups to yank in";
  714. char txt_group_selection[] = "Group Selection";
  715. char txt_select_group[] = "Select group> ";
  716. char txt_help_g_4[] = "4$       Select group 4 ($=select last group)\r\n";
  717. char txt_help_g_ctrl_r[] = "^R       Reset .newsrc\r\n";
  718. char txt_help_g_ctrl_k[] = "^KZ      Delete (Z=undelete) group from .newsrc\r\n";
  719. char txt_help_g_cr[] = "<CR>     Read current group\r\n";
  720. char txt_help_g_c[] = "c        Mark group as all read\r\n";
  721. char txt_help_g_tab[] =   "n<TAB>   Goto next group with unread news and enter it\r\n";
  722. char txt_help_n[] = "N        Goto next group with unread news\r\n";
  723. char txt_help_W[] = "W        List articles posted by user\r\n";
  724. char txt_help_g_z[] = "z        Mark current group as unread\r\n";
  725. char txt_help_g_y[] = "y        Yank in unsubscribed groups that are not in .newsrc\r\n";
  726. char txt_help_g_dollar[] = "Y        Yank in subscribed groups from .newsrc\r\n";
  727. char txt_help_g_search[] = "/?       Group forward (?=backward) search\r\n";
  728. char txt_newsgroup[] = "Newsgroup> ";
  729. char txt_newsgroup_position[] = "Position %s in group list [1,2,..,$]> ";
  730. X
  731. /*
  732. X *  signal.c
  733. X */
  734. X
  735. char txt_resizing_window[] = "resizing window";
  736. X
  737. /*
  738. X *  thread.c
  739. X */
  740. X
  741. char txt_no_resps_in_thread[] = "No responses to list in current thread";
  742. char txt_help_t_0[] = "0        Goto the base article in current thread\r\n";
  743. char txt_help_t_4[] = "4$       Goto response 4 ($=goto last response) in current thread\r\n";
  744. char txt_help_t_cr[] = "<CR>     Read current response\r\n";
  745. char txt_help_t_tab[] = "<TAB>    Goto next unread response\r\n";
  746. char txt_help_t_K[] =   "K        Mark thread as read & return\r\n";
  747. SHAR_EOF
  748. chmod 0600 lang.c ||
  749. echo 'restore of lang.c failed'
  750. Wc_c="`wc -c < 'lang.c'`"
  751. test 20905 -eq "$Wc_c" ||
  752.     echo 'lang.c: original size 20905, current size' "$Wc_c"
  753. rm -f _shar_wnt_.tmp
  754. fi
  755. # ============= main.c ==============
  756. if test -f 'main.c' -a X"$1" != X"-c"; then
  757.     echo 'x - skipping main.c (File already exists)'
  758.     rm -f _shar_wnt_.tmp
  759. else
  760. > _shar_wnt_.tmp
  761. echo 'x - extracting main.c (Text)'
  762. sed 's/^X//' << 'SHAR_EOF' > 'main.c' &&
  763. /*
  764. X *  Project   : tin - a threaded Netnews reader
  765. X *  Module    : main.c
  766. X *  Author    : I.Lea & R.Skrenta
  767. X *  Created   : 01-04-91
  768. X *  Updated   : 22-03-92
  769. X *  Notes     :
  770. X *  Copyright : (c) Copyright 1991-92 by Iain Lea & Rich Skrenta
  771. X *              You may  freely  copy or  redistribute  this software,
  772. X *              so  long as there is no profit made from its use, sale
  773. X *              trade or  reproduction.  You may not change this copy-
  774. X *              right notice, and it must be included in any copy made
  775. X */
  776. X
  777. #include    "tin.h"
  778. X
  779. /*
  780. X * OK lets start the ball rolling...
  781. X */
  782. void main (argc, argv)
  783. X    int argc;    
  784. X    char *argv[];
  785. {
  786. X    int created;
  787. X    int start_groupnum = 0;
  788. X    
  789. X    cmd_line = TRUE;
  790. X    debug = 0;    /* debug OFF */
  791. X
  792. X    set_signal_handlers ();
  793. X
  794. X    basename (argv[0], progname);
  795. X
  796. X    sprintf (page_header, "%s %s PL%d", progname, VERSION, PATCHLEVEL);     
  797. X    sprintf (cvers, "%s (c) Copyright 1991-92 Iain Lea.", page_header);
  798. X
  799. #ifdef NNTP_ONLY
  800. X    read_news_via_nntp = TRUE;
  801. #else
  802. X    if (progname[0] == 'r') {    /* rtin so read news remotely via NNTP */
  803. #        ifdef NNTP_ABLE            
  804. X            read_news_via_nntp = TRUE;
  805. #        else
  806. X            error_message (txt_option_not_enabled, "-DNNTP_ABLE");
  807. X            exit (1);
  808. #        endif
  809. X    }
  810. #endif
  811. X
  812. X    tin_uid = geteuid ();
  813. X    tin_gid = getegid ();
  814. X    real_uid = getuid ();
  815. X    real_gid = getgid ();
  816. X
  817. X    /*
  818. X     * we're setuid, so index in /usr/spool/news unless user root
  819. X     */
  820. X    if (tin_uid != real_uid && real_uid != 0) {
  821. X        local_index = FALSE;
  822. X    } else {    /* index in users home directory ~/.tin/.index */
  823. X        local_index = TRUE;
  824. X    }
  825. X
  826. X    /*
  827. X     * set up char *'s: homedir, newsrc, etc. 
  828. X     */
  829. X    init_selfinfo ();
  830. X
  831. X    /*
  832. X     * process command line options
  833. X     */
  834. X    read_cmd_line_options (argc, argv);
  835. X     
  836. X    if (update_fork || (update && verbose) || !update) {
  837. X        wait_message (cvers);
  838. X    }
  839. X
  840. X    /*
  841. X     *  allocate initial array sizes
  842. X     */
  843. X    init_alloc ();
  844. X    hash_init ();
  845. X
  846. X    /*
  847. X     *  if specified connect to nntp server
  848. X     */
  849. X    nntp_startup ();
  850. X    
  851. X    /*
  852. X     *  log username info to local/central logfile (NNTP XUSER)
  853. X     */
  854. X    log_user ();
  855. X
  856. X    if (create_mail_save_dirs ()) {
  857. X        write_rcfile ();
  858. X    }    
  859. X
  860. X    /*
  861. X     *  load the active file into active[]
  862. X     */
  863. X    created = read_active_file ();
  864. X
  865. X    if (optind < argc) {
  866. X        while (optind < argc) {
  867. X            if (add_group (argv[optind], TRUE) < 0) {
  868. X                error_message (txt_not_in_active_file, argv[optind]);
  869. X            }
  870. X            optind++;
  871. X        }
  872. X    } else {
  873. X        backup_newsrc ();
  874. X        read_newsrc (TRUE);
  875. X        mark_unthreaded_groups ();
  876. X    }
  877. X
  878. X    /*
  879. X     *  read in users kill file
  880. X     */
  881. X    if (kill_articles) {
  882. X        read_kill_file ();
  883. X    }
  884. X    
  885. X    /*
  886. X     *  check/start if any new/unread articles
  887. X     */
  888. X    start_groupnum = check_for_any_new_news (check_any_unread, start_any_unread);
  889. X
  890. X    /*
  891. X     *  mail any new articles to specified user
  892. X     *  or
  893. X     *  save any new articles to savedir structure for later reading
  894. X     */
  895. X    save_or_mail_new_news ();
  896. X    
  897. X    /*
  898. X     *  update index files
  899. X     */
  900. X    update_index_files ();
  901. X    
  902. X    if (! InitScreen ()) {
  903. X        error_message (txt_screen_init_failed, progname);
  904. X        exit (1);
  905. X    }
  906. X
  907. X    /*
  908. X     *   get screen size from termcap entry 
  909. X     */
  910. X    ScreenSize (&LINES, &COLS);
  911. X    cmd_line = FALSE;
  912. X    Raw (TRUE);
  913. X
  914. X    /* 
  915. X     *  check & set actual screen size
  916. X     */
  917. X    set_win_size (&LINES, &COLS);
  918. X
  919. X    /*
  920. X     *  check for any newly created newsgroups
  921. X     */
  922. X    if (notify_new_groups && ! created) {
  923. X        notify_groups ();
  924. X    }
  925. X
  926. X    /*
  927. X     *  if first time print welcome screen
  928. X      and auto-subscribe
  929. X     *  to groups specified in /usr/lib/news/subscribe locally
  930. X     *  or via NNTP if reading news remotely (LIST SUBSCRIBE)
  931. X     */
  932. X    if (created_rcdir && update == FALSE) {
  933. X        show_intro_page ();
  934. X    }
  935. X    
  936. X    selection_index (start_groupnum);
  937. X
  938. X    tin_done (0);
  939. }
  940. X
  941. /*
  942. X * process command line options
  943. X */
  944. X
  945. void read_cmd_line_options (argc, argv)
  946. X    int argc;
  947. X    char *argv[];
  948. {
  949. X    int ch;
  950. X
  951. #ifdef INDEX_DAEMON
  952. X    while ((ch = getopt (argc, argv, "D:f:hvV")) != EOF) {
  953. #else
  954. X    while ((ch = getopt (argc, argv, "cD:f:hHm:M:np:rRs:SuUvVzZ")) != EOF) {
  955. #endif
  956. X        switch (ch) {
  957. X            case 'c':
  958. X                catchup = TRUE;
  959. X                update = TRUE;
  960. X                break;
  961. X                
  962. X            case 'D':        /* debug mode 1=NNTP 2=ALL */
  963. #ifdef DEBUG            
  964. X                redirect_output[0] = '\0';
  965. X                debug = atoi (optarg);
  966. #else
  967. X                error_message (txt_option_not_enabled, "-DDEBUG");
  968. X                exit (1);
  969. #endif
  970. X                break;
  971. X
  972. X            case 'f':
  973. X                my_strncpy (newsrc, optarg, LEN);
  974. X                break;
  975. X
  976. X            case 'H':
  977. X                show_intro_page ();
  978. X                exit (1);
  979. X                break;
  980. X
  981. X            case 'm':
  982. X                my_strncpy (maildir, optarg, LEN);
  983. X                break;
  984. X
  985. X            case 'M':    /* mail new news to specified user */
  986. X                my_strncpy (mail_news_user, optarg, LEN);
  987. X                mail_news = TRUE;
  988. X                update = TRUE;
  989. X                catchup = TRUE;
  990. X                break;
  991. X
  992. X            case 'n':
  993. X                notify_new_groups = TRUE;
  994. X                break;
  995. X
  996. X            case 'p':
  997. X                my_strncpy (cmd_line_printer, optarg, LEN);
  998. X                default_printer = FALSE;
  999. X                break;
  1000. X
  1001. X            case 'r':    /* read news remotely from default NNTP server */
  1002. #ifdef NNTP_ABLE            
  1003. X                read_news_via_nntp = TRUE;
  1004. #else
  1005. X                error_message (txt_option_not_enabled, "-DNNTP_ABLE");
  1006. X                exit (1);
  1007. #endif
  1008. X                break;
  1009. X
  1010. X            case 'R':    /* read news saved by -S option */
  1011. X                error_message ("%s: -R option not yet implemented.", progname);
  1012. X                exit (1);
  1013. X                break;
  1014. X
  1015. X            case 's':
  1016. X                my_strncpy (savedir, optarg, LEN);
  1017. X                break;
  1018. X
  1019. X            case 'S':    /* save new news to dir structure */
  1020. X                save_news = TRUE;
  1021. X                update = TRUE;
  1022. X                break;
  1023. X
  1024. #ifndef NNTP_XINDEX    /* index files are maintained on the NNTP server */
  1025. X            case 'u':    /* update index files */
  1026. X                update = TRUE;
  1027. X                break;
  1028. X
  1029. X            case 'U':    /* update index files in background */
  1030. X                update_fork = TRUE;
  1031. X                update = TRUE;
  1032. X                break;
  1033. #endif /* NNTP_XINDEX */
  1034. X
  1035. X            case 'v':    /* verbose mode */
  1036. X                verbose = TRUE;
  1037. X                break;
  1038. X
  1039. X            case 'V':
  1040. #if defined(__DATE__) && defined(__TIME__)            
  1041. X                sprintf (msg, "Version: %s PL%d  %s  %s",
  1042. X                    VERSION, PATCHLEVEL, __DATE__, __TIME__);
  1043. #else
  1044. X                sprintf (msg, "Version: %s PL%d",
  1045. X                    VERSION, PATCHLEVEL);
  1046. #endif                    
  1047. X                error_message (msg, "");
  1048. X                exit (1);
  1049. X                break;
  1050. X
  1051. X            case 'z':
  1052. X                start_any_unread = TRUE;
  1053. X                update = TRUE;
  1054. X                break;
  1055. X
  1056. X            case 'Z':
  1057. X                check_any_unread = TRUE;
  1058. X                update = TRUE;
  1059. X                break;
  1060. X
  1061. X            case 'h':
  1062. X            case '?':
  1063. X            default:
  1064. X                usage (progname);
  1065. X                exit (1);
  1066. X        }
  1067. X    }
  1068. }
  1069. X
  1070. /*
  1071. X * usage
  1072. X */
  1073. X
  1074. void usage (progname)
  1075. X    char *progname;
  1076. {
  1077. #ifndef INDEX_DAEMON
  1078. X    error_message ("%s A threaded Netnews reader.\n", cvers);
  1079. #else
  1080. X    error_message ("%s Tin index file updating daemon.\n", cvers);
  1081. #endif
  1082. X    error_message ("Usage: %s [options] [newsgroups]", progname);
  1083. #ifndef INDEX_DAEMON
  1084. X    error_message ("  -c       mark all news as read in subscribed newsgroups (batch mode)", "");
  1085. #endif /* INDEX_DAEMON */
  1086. X
  1087. X    error_message ("  -f file  subscribed to newsgroups file [default=%s]", newsrc);
  1088. X    error_message ("  -h       help", "");
  1089. #ifndef INDEX_DAEMON
  1090. X    error_message ("  -H       help information about %s", progname);
  1091. X    error_message ("  -m dir   mailbox directory [default=%s]", maildir);
  1092. X    error_message ("  -M user  mail new news to specified user (batch mode)", "");
  1093. X    error_message ("  -n       notify user of any newly created newsgroups", "");
  1094. X    error_message ("  -p file  print program with options [default=%s]", DEFAULT_PRINTER);
  1095. #  if defined(NNTP_ABLE) && !defined(NNTP_ONLY)
  1096. X    if (! read_news_via_nntp) {
  1097. X        error_message ("  -r       read news remotely from default NNTP server", "");
  1098. X    }
  1099. #  endif /* NNTP_ABLE */    
  1100. X    error_message ("  -R       read news saved by -S option (not yet implemented)", "");
  1101. X    error_message ("  -s dir   save news directory [default=%s]", savedir);
  1102. X    error_message ("  -S       save new news for later reading (batch mode)", "");
  1103. #  ifndef NNTP_XINDEX    /* index files are maintained on the NNTP server */
  1104. X    error_message ("  -u       update index files (batch mode)", "");
  1105. X    error_message ("  -U       update index files in the background while reading news", "");
  1106. #  endif /* NNTP_XINDEX */
  1107. #endif /* INDEX_DAEMON */
  1108. X    error_message ("  -v       verbose output for batch mode options", "");
  1109. #ifndef INDEX_DAEMON
  1110. X    error_message ("  -z       start if any unread news", "");
  1111. X    error_message ("  -Z       return status indicating if any unread news (batch mode)", "");
  1112. #endif /* INDEX_DAEMON */
  1113. X    error_message ("\nMail bug reports/comments to %s", BUG_REPORT_ADDRESS);
  1114. }
  1115. X
  1116. /*
  1117. X *  check/start if any new/unread articles
  1118. X */
  1119. X
  1120. int check_for_any_new_news (check_any_unread, start_any_unread)
  1121. X    int check_any_unread;
  1122. X    int start_any_unread;
  1123. {
  1124. X    int i = 0;
  1125. X    
  1126. X    if (check_any_unread) {
  1127. X        i = check_start_save_any_news (CHECK_ANY_NEWS);
  1128. X        exit (i);
  1129. X    }
  1130. X    
  1131. X    if (start_any_unread) {
  1132. X        i = check_start_save_any_news (START_ANY_NEWS);
  1133. X        if (i == -1) {        /* no new/unread news so exit */
  1134. X            exit (0);
  1135. X        }
  1136. X        update = FALSE;
  1137. X    }
  1138. X    return (i);
  1139. }
  1140. X
  1141. /*
  1142. X *  mail any new articles to specified user
  1143. X *  or
  1144. X *  save any new articles to savedir structure for later reading
  1145. X */
  1146. X
  1147. void save_or_mail_new_news ()
  1148. {
  1149. X    int i;
  1150. X    
  1151. X    if (mail_news || save_news) {
  1152. X        i = catchup;            /* set catchup to FALSE */
  1153. X        catchup = FALSE;
  1154. X        do_update ();
  1155. X        catchup = i;            /* set catchup to previous value */
  1156. X        if (mail_news) {
  1157. X            check_start_save_any_news (MAIL_ANY_NEWS);
  1158. X        } else {
  1159. X            check_start_save_any_news (SAVE_ANY_NEWS);
  1160. X        }
  1161. X        tin_done (0);
  1162. X    }
  1163. }
  1164. X
  1165. /*
  1166. X *  update index files
  1167. X */
  1168. X
  1169. void update_index_files ()
  1170. {
  1171. X    int fd;
  1172. X    
  1173. X    if (update || update_fork) {
  1174. X        COLS = DEFAULT_COLS;            /* set because curses has not started */ 
  1175. X        if (update_fork) {
  1176. X            catchup = FALSE;            /* turn off msgs when running forked */ 
  1177. X            verbose = FALSE;
  1178. X            switch (fork ()) {            /* fork child to update indexes in background */
  1179. X                case -1:    /* error forking */    
  1180. X                    error_message ("Failed to start background indexing process", "");
  1181. X                    break;
  1182. X                case 0:        /* child process */    
  1183. X                    process_id = getpid ();
  1184. #ifdef BSD
  1185. X                    setpgrp (0, process_id);    /* reset process group leader to this process */
  1186. #    ifdef TIOCNOTTY
  1187. X                    if ((fd = open ("/dev/tty", O_RDWR)) >= 0) {
  1188. X                        ioctl (fd, TIOCNOTTY, (char *) NULL);
  1189. X                        close (fd);
  1190. X                    }    
  1191. #    endif
  1192. #else
  1193. X                    setpgrp ();
  1194. X                    signal (SIGHUP, SIG_IGN);    /* make immune from process group leader death */
  1195. #endif
  1196. X                    signal (SIGQUIT, SIG_IGN);    /* stop indexing being interrupted */            
  1197. X                    signal (SIGALRM, SIG_IGN);    /* stop indexing resyning active file */            
  1198. X                    nntp_startup ();        /* connect server if we are using nntp */
  1199. X                    thread_arts = FALSE;    /* stop threading to run faster */
  1200. X                    do_update ();
  1201. X                    nntp_finish ();            /* connect server if we are using nntp */
  1202. X                    exit (0);
  1203. X                    break;
  1204. X                default:    /* parent process*/
  1205. X                    break;                    
  1206. X            }    
  1207. X            update = FALSE;
  1208. X        } else {
  1209. X            thread_arts = FALSE;    /* stop threading to run faster */
  1210. X            do_update ();
  1211. X            exit (0);
  1212. X        }
  1213. X    }
  1214. }
  1215. X
  1216. /*
  1217. X *  display page of general info. for first time user.
  1218. X */
  1219. X
  1220. void show_intro_page ()
  1221. {
  1222. X    if (cmd_line) {
  1223. X        printf ("%s", cvers);     
  1224. X    } else {
  1225. X        ClearScreen ();
  1226. X        center_line (0, TRUE, cvers); 
  1227. X        Raw (FALSE);    
  1228. X    }
  1229. X
  1230. X    printf ("\n\nWelcome to tin, a full screen threaded Netnews reader. It can read news locally\n");
  1231. X    printf ("(ie. <spool>/news) or remotely (-r option) from a NNTP  (Network News Transport\n");
  1232. X    printf ("Protocol) server. tin -h lists the available command line options.\n\n");
  1233. X
  1234. X    printf ("Tin has four newsreading levels, the newsgroup selection page,  the group index\n");
  1235. X    printf ("page, the thread listing page and the article viewer. Help is available at each\n");
  1236. X    printf ("level by pressing the 'h' command.\n\n");
  1237. X
  1238. X    printf ("Move up/down by using the terminal arrow keys or 'j' and 'k'.  Use PgUp/PgDn or\n");
  1239. X    printf ("Ctrl-U and Ctrl-D to page up/down. Enter a newsgroup by pressing RETURN.\n\n");
  1240. X
  1241. X    printf ("Articles, threads, tagged articles or articles matching a pattern can be mailed\n");
  1242. X    printf ("('m' command), printed ('o' command), saved ('s' command), piped ('|' command).\n");
  1243. X    printf ("Use the 'w' command  to post  a news  article,  the 'f'/'F' commands to  post a\n");
  1244. X    printf ("follow-up  to  an existing  news article and the 'r'/'R' commands to  reply via\n");
  1245. X    printf ("mail to an existing news articles author.  The 'M' command allows the operation\n");
  1246. X    printf ("of tin to be configured via a menu.\n\n");
  1247. X
  1248. X    printf ("For more in depth information please read  the supplied manual page and README.\n\n");
  1249. X    printf ("Please send bug reports/comments to the programs author with the 'B' command.\n");
  1250. X    fflush (stdout);
  1251. X
  1252. X    if (! cmd_line) {
  1253. X        Raw (TRUE);    
  1254. X        continue_prompt ();
  1255. X    }
  1256. }
  1257. X
  1258. SHAR_EOF
  1259. chmod 0600 main.c ||
  1260. echo 'restore of main.c failed'
  1261. Wc_c="`wc -c < 'main.c'`"
  1262. test 12102 -eq "$Wc_c" ||
  1263.     echo 'main.c: original size 12102, current size' "$Wc_c"
  1264. rm -f _shar_wnt_.tmp
  1265. fi
  1266. # ============= memory.c ==============
  1267. if test -f 'memory.c' -a X"$1" != X"-c"; then
  1268.     echo 'x - skipping memory.c (File already exists)'
  1269.     rm -f _shar_wnt_.tmp
  1270. else
  1271. > _shar_wnt_.tmp
  1272. echo 'x - extracting memory.c (Text)'
  1273. sed 's/^X//' << 'SHAR_EOF' > 'memory.c' &&
  1274. /*
  1275. X *  Project   : tin - a threaded Netnews reader
  1276. X *  Module    : memory.c
  1277. X *  Author    : I.Lea & R.Skrenta
  1278. X *  Created   : 01-04-91
  1279. X *  Updated   : 16-02-92
  1280. X *  Notes     :
  1281. X *  Copyright : (c) Copyright 1991-92 by Iain Lea & Rich Skrenta
  1282. X *              You may  freely  copy or  redistribute  this software,
  1283. X *              so  long as there is no profit made from its use, sale
  1284. X *              trade or  reproduction.  You may not change this copy-
  1285. X *              right notice, and it must be included in any copy made
  1286. X */
  1287. X
  1288. #include    "tin.h"
  1289. X
  1290. int *my_group;                    /* .newsrc --> active[] */
  1291. int *unread;                    /* highest art read in group */
  1292. long *base;
  1293. struct group_t *active;            /* active file */
  1294. struct article_t *arts;
  1295. X
  1296. /*
  1297. X *  Dynamic table management
  1298. X *  These settings are memory conservative:  small initial allocations
  1299. X *  and a 50% expansion on table overflow.  A fast vm system with
  1300. X *  much memory might want to start with higher initial allocations
  1301. X *  and a 100% expansion on overflow, especially for the arts[] array.
  1302. X */
  1303. X
  1304. void init_alloc ()
  1305. {
  1306. X    max_active = DEFAULT_ACTIVE_NUM;
  1307. X    max_art = DEFAULT_ARTICLE_NUM;
  1308. X
  1309. X    active = (struct group_t *) my_malloc ((unsigned) sizeof(*active) * max_active);
  1310. X    my_group = (int *) my_malloc ((unsigned) sizeof(int) * max_active);
  1311. X    unread = (int *) my_malloc ((unsigned) sizeof(int) * max_active);
  1312. X
  1313. X    arts = (struct article_t *) my_malloc ((unsigned) sizeof(*arts) * max_art);
  1314. X    base = (long *) my_malloc ((unsigned) sizeof(long) * max_art);
  1315. X
  1316. X    max_kill = DEFAULT_KILL_NUM;
  1317. X    
  1318. X    killf = (struct kill_t *) my_malloc ((unsigned) sizeof(*killf) * max_kill);
  1319. X
  1320. X    max_save = DEFAULT_SAVE_NUM;
  1321. X    
  1322. X    save = (struct save_t *) my_malloc ((unsigned) sizeof(*save) * max_save);
  1323. X
  1324. X    screen = (struct screen_t *) 0;
  1325. }
  1326. X
  1327. X
  1328. void expand_art()
  1329. {
  1330. X    max_art += max_art / 2;        /* increase by 50% */
  1331. X
  1332. X    arts = (struct article_t *) my_realloc ((char *) arts, (unsigned) sizeof(*arts) * max_art);
  1333. X    base = (long *) my_realloc ((char *) base, (unsigned) sizeof(long) * max_art);
  1334. }
  1335. X
  1336. X
  1337. void expand_active()
  1338. {
  1339. X    max_active += max_active / 2;        /* increase by 50% */
  1340. X
  1341. X    if (active == (struct group_t *) 0) {
  1342. X        active = (struct group_t *) my_malloc ((unsigned) sizeof(*active) * max_active);
  1343. X        my_group = (int *) my_malloc ((unsigned) sizeof(int) * max_active);
  1344. X        unread = (int *) my_malloc ((unsigned) sizeof(int) * max_active);
  1345. X    } else {
  1346. X        active = (struct group_t *) my_realloc((char *) active,
  1347. X                 (unsigned) sizeof(*active) * max_active);
  1348. X        my_group = (int *) my_realloc((char *) my_group, (unsigned) sizeof(int) * max_active);
  1349. X        unread = (int *) my_realloc((char *) unread, (unsigned) sizeof(int) * max_active);
  1350. X    }
  1351. }
  1352. X
  1353. X
  1354. void expand_kill()
  1355. {
  1356. X    max_kill += max_kill / 2;        /* increase by 50% */
  1357. X
  1358. X    killf = (struct kill_t *) my_realloc((char *) killf, (unsigned) sizeof(struct kill_t) * max_kill);
  1359. }
  1360. X
  1361. X
  1362. void expand_save()
  1363. {
  1364. X    max_save += max_save / 2;        /* increase by 50% */
  1365. X
  1366. X    save = (struct save_t *) my_realloc((char *) save, (unsigned) sizeof(struct save_t) * max_save);
  1367. }
  1368. X
  1369. X
  1370. void init_screen_array (allocate)
  1371. X    int allocate;
  1372. {
  1373. X    int i;
  1374. X
  1375. X    if (allocate) {
  1376. X        screen = (struct screen_t *) my_malloc((unsigned) sizeof(*screen) * LINES);
  1377. X
  1378. X        for (i=0 ; i < LINES ; i++) {
  1379. X            screen[i].col = (char *) my_malloc ((unsigned) COLS+1);
  1380. X        }
  1381. X    } else {
  1382. X        if (screen != (struct screen_t *) 0) {
  1383. X            for (i=0 ; i < LINES ; i++) {
  1384. X                if (screen[i].col != (char *) 0) {
  1385. X                    free ((char *) screen[i].col);
  1386. X                    screen[i].col = (char *) 0;
  1387. X                }
  1388. X            }    
  1389. X
  1390. X            free ((char *) screen);
  1391. X            screen = (struct screen_t *) 0;
  1392. X        }
  1393. X    }
  1394. }
  1395. X
  1396. X
  1397. void free_all_arrays ()
  1398. {
  1399. X    hash_reclaim ();
  1400. X    
  1401. X    init_screen_array (FALSE);
  1402. X
  1403. X    free_art_array ();
  1404. X
  1405. X    if (arts != (struct article_t *) 0) {
  1406. X        free ((char *) arts);
  1407. X        arts = (struct article_t *) 0;
  1408. X    }
  1409. X
  1410. X    free_active_arrays ();
  1411. X
  1412. X    if (base != (long *) 0) {
  1413. X        free ((char *) base);
  1414. X        base = (long *) 0;
  1415. X    }
  1416. X
  1417. X    if (killf != (struct kill_t *) 0) {
  1418. X        free_kill_array ();
  1419. X        if (killf != (struct kill_t *) 0) {
  1420. X            free ((char *) killf);
  1421. X            killf = (struct kill_t *) 0;
  1422. X        }
  1423. X    }
  1424. X
  1425. X    if (save != (struct save_t *) 0) {
  1426. X        free_save_array ();
  1427. X        if (save != (struct save_t *) 0) {
  1428. X            free ((char *) save);
  1429. X            save = (struct save_t *) 0;
  1430. X        }
  1431. X    }
  1432. }
  1433. X
  1434. X
  1435. void free_art_array ()
  1436. {
  1437. X    register int i;
  1438. X
  1439. X    for (i=0 ; i < top ; i++) {
  1440. X        arts[i].artnum = 0L;
  1441. X        arts[i].thread = ART_EXPIRED;
  1442. X        arts[i].inthread = FALSE;
  1443. X        arts[i].unread = ART_UNREAD;
  1444. X        arts[i].tagged = FALSE;
  1445. X        if (arts[i].part != (char *) 0) {
  1446. X            free ((char *) arts[i].part);
  1447. X            arts[i].part = (char *) 0;
  1448. X        }
  1449. X        if (arts[i].patch != (char *) 0) {
  1450. X            free ((char *) arts[i].patch);
  1451. X            arts[i].patch = (char *) 0;
  1452. X        }
  1453. X    }
  1454. }
  1455. X
  1456. X
  1457. void free_active_arrays ()
  1458. {
  1459. X    register int i;
  1460. X    
  1461. X    if (my_group != (int *) 0) {            /* my_group[] */
  1462. X        free ((char *) my_group);
  1463. X        my_group = (int *) 0;
  1464. X    }
  1465. X
  1466. X    if (unread != (int *) 0) {                /* unread[] */
  1467. X        free ((char *) unread);
  1468. X        unread = (int *) 0;
  1469. X    }
  1470. X
  1471. X    if (active != (struct group_t *) 0) {    /* active[] */
  1472. X        for (i=0 ; i < max_active ; i++) {
  1473. X            if (active[i].name != (char *) 0) {
  1474. X                free ((char *) active[i].name);
  1475. X                active[i].name = (char *) 0;
  1476. X            }
  1477. X        }
  1478. X        if (active != (struct group_t *) 0) {
  1479. X            free ((char *) active);
  1480. X            active = (struct group_t *) 0;
  1481. X        }
  1482. X    }
  1483. }
  1484. X
  1485. X
  1486. void free_kill_array ()
  1487. {
  1488. X    int i;
  1489. X    
  1490. X    for (i=0 ; i < kill_num ; i++) {
  1491. X        if (killf[i].kill_subj != (char *) 0) {
  1492. X            free ((char *) killf[i].kill_subj);
  1493. X            killf[i].kill_subj = (char *) 0;
  1494. X        }
  1495. X        if (killf[i].kill_from != (char *) 0) {
  1496. X            free ((char *) killf[i].kill_from);
  1497. X            killf[i].kill_from = (char *) 0;
  1498. X        }
  1499. X    }
  1500. }
  1501. X
  1502. X
  1503. /*
  1504. X *  reset save list array to 0 and free's all its allocated memory
  1505. X */
  1506. void free_save_array ()
  1507. {
  1508. X    int i;
  1509. X    
  1510. X    for (i=0 ; i < save_num ; i++) {
  1511. X        if (save[i].subject != (char *) 0) {
  1512. X            free ((char *) save[i].subject);
  1513. X            save[i].subject = (char *) 0;
  1514. X        }
  1515. X        if (save[i].archive != (char *) 0) {
  1516. X            free ((char *) save[i].archive);
  1517. X            save[i].archive = (char *) 0;
  1518. X        }
  1519. X        if (save[i].dir != (char *) 0) {
  1520. X            free ((char *) save[i].dir);
  1521. X            save[i].dir = (char *) 0;
  1522. X        }
  1523. X        if (save[i].file != (char *) 0) {
  1524. X            free ((char *) save[i].file);
  1525. X            save[i].file = (char *) 0;
  1526. X        }
  1527. X        if (save[i].part != (char *) 0) {
  1528. X            free ((char *) save[i].part);
  1529. X            save[i].part = (char *) 0;
  1530. X        }
  1531. X        if (save[i].patch != (char *) 0) {
  1532. X            free ((char *) save[i].patch);
  1533. X            save[i].patch = (char *) 0;
  1534. X        }
  1535. X        save[i].index   = -1;
  1536. X        save[i].saved   = FALSE;
  1537. X        save[i].is_mailbox = FALSE;
  1538. X    }
  1539. X    
  1540. X    save_num = 0;
  1541. }
  1542. X
  1543. X
  1544. char *my_malloc (size)
  1545. X    unsigned size;
  1546. {
  1547. X    char *p;
  1548. X
  1549. X    if ((p = (char *) calloc (1, (int) size)) == NULL) {
  1550. X        error_message (txt_out_of_memory, progname);
  1551. X        tin_done (1);
  1552. X    }
  1553. X    return p;
  1554. }
  1555. X
  1556. X
  1557. char *my_realloc (p, size)
  1558. X    char *p;
  1559. X    unsigned size;
  1560. {
  1561. X    if (! p) {
  1562. X        p = (char *) calloc (1, (int) size);
  1563. X    } else {
  1564. X        p = (char *) realloc (p, (int) size);
  1565. X    }
  1566. X
  1567. X    if (! p) {
  1568. X        error_message (txt_out_of_memory, progname);
  1569. X        tin_done (1);
  1570. X    }
  1571. X    return p;
  1572. }
  1573. SHAR_EOF
  1574. chmod 0600 memory.c ||
  1575. echo 'restore of memory.c failed'
  1576. Wc_c="`wc -c < 'memory.c'`"
  1577. test 6765 -eq "$Wc_c" ||
  1578.     echo 'memory.c: original size 6765, current size' "$Wc_c"
  1579. rm -f _shar_wnt_.tmp
  1580. fi
  1581. # ============= misc.c ==============
  1582. if test -f 'misc.c' -a X"$1" != X"-c"; then
  1583.     echo 'x - skipping misc.c (File already exists)'
  1584.     rm -f _shar_wnt_.tmp
  1585. else
  1586. > _shar_wnt_.tmp
  1587. echo 'x - extracting misc.c (Text)'
  1588. sed 's/^X//' << 'SHAR_EOF' > 'misc.c' &&
  1589. /*
  1590. X *  Project   : tin - a threaded Netnews reader
  1591. X *  Module    : misc.c
  1592. X *  Author    : I.Lea & R.Skrenta
  1593. X *  Created   : 01-04-91
  1594. X *  Updated   : 21-03-92
  1595. X *  Notes     :
  1596. X *  Copyright : (c) Copyright 1991-92 by Iain Lea & Rich Skrenta
  1597. X *              You may  freely  copy or  redistribute  this software,
  1598. X *              so  long as there is no profit made from its use, sale
  1599. X *              trade or  reproduction.  You may not change this copy-
  1600. X *              right notice, and it must be included in any copy made
  1601. X */
  1602. X
  1603. #include    "tin.h"
  1604. X
  1605. static char *mailbox_name = (char *) 0;
  1606. static int  mailbox_size;
  1607. X
  1608. X
  1609. void asfail (file, line, cond)
  1610. X    char    *file;
  1611. X    int    line;
  1612. X    char    *cond;
  1613. {
  1614. #ifdef POSIX_JOB_CONTROL
  1615. X    struct sigaction sa;
  1616. #endif
  1617. X      fprintf (stderr, "%s: assertion failure: %s (%d): %s\n",
  1618. X          progname, file, line, cond);
  1619. X      fflush (stderr);
  1620. X      
  1621. X     /*
  1622. X      * create a core dump
  1623. X      */
  1624. #ifdef POSIX_JOB_CONTROL
  1625. X    sigemptyset (&sa.sa_mask);
  1626. X    art_act.sa_flags = 0;
  1627. X     art_act.sa_handler = SIG_DFL;
  1628. X     sigaction (SIGABRT, &sa, (struct sigaction *) 0);
  1629. #else
  1630. SHAR_EOF
  1631. true || echo 'restore of misc.c failed'
  1632. fi
  1633. echo 'End of tin1.1 part 6'
  1634. echo 'File misc.c is continued in part 7'
  1635. echo 7 > _shar_seq_.tmp
  1636. exit 0
  1637.  
  1638. --
  1639. NAME   Iain Lea 
  1640. EMAIL  iain%anl433.uucp@germany.eu.net
  1641. SNAIL  Siemens AG, ANL A433SZ, Gruendlacher Str. 248, 8510 Fuerth, Germany.
  1642. PHONE  +49-911-3089-407 (work) +49-911-331963 (home) +49-911-3089-290 (FAX)  
  1643. -- 
  1644.  Dr. med. dipl.-math Dieter Becker           Tel.: (0 / +49) 6841 - 16 3046
  1645.  Medizinische Universitaets- und Poliklinik  Fax.: (0 / +49) 6841 - 16 3369
  1646.  Innere Medizin III                         
  1647.  D - 6650 Homburg / Saar                     Email: becker@med-in.uni-sb.de
  1648. exit 0 # Just in case...
  1649.