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

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