home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume30 / tin / part13 < prev    next >
Encoding:
Text File  |  1992-05-19  |  53.7 KB  |  2,252 lines

  1. Newsgroups: comp.sources.misc
  2. From: iain%anl433.uucp@germany.eu.net (Iain J. Lea)
  3. Subject:  v30i013:  tin - threaded full screen newsreader, Part13/14
  4. Message-ID: <1992May20.173027.160@sparky.imd.sterling.com>
  5. X-Md4-Signature: ea90556dc2396504de011f1d8ba61bdc
  6. Date: Wed, 20 May 1992 17:30:27 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 30, Issue 13
  11. Archive-name: tin/part13
  12. Environment: BSD, SCO, ISC, SUNOS, SYSVR3, SYSVR4, ULTRIX, XENIX
  13. Supersedes: tin: Volume 29, Issue 19-30
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then feed it
  17. # into a shell via "sh file" or similar.  To overwrite existing files,
  18. # type "sh file -c".
  19. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  20. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  21. # Contents:  INSTALL active.c getline.c memory.c nntplib.h signal.c
  22. # Wrapped by kent@sparky on Tue May 19 13:38:06 1992
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. echo If this archive is complete, you will see the following message:
  25. echo '          "shar: End of archive 13 (of 14)."'
  26. if test -f 'INSTALL' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'INSTALL'\"
  28. else
  29.   echo shar: Extracting \"'INSTALL'\" \(8397 characters\)
  30.   sed "s/^X//" >'INSTALL' <<'END_OF_FILE'
  31. XCompilation and installation notes for tin - 13-05-92 
  32. X-----------------------------------------------------
  33. X
  34. XTin has been compiled on a wide range of Un*x machines with cc and gcc.
  35. XA list of these machines can be found at the end of this file.
  36. X
  37. XThis file is long (so was the yellow brick road) but please read it all
  38. Xas it could save you problems later and we don't want an unhappy ending
  39. Xdo we? :-)  
  40. X
  41. XTin can be compiled to read news in any of the following ways:
  42. X
  43. X  o  locally from your machines news spool dir (default /usr/spool/news).
  44. X
  45. X  o  locally and remotely (rtin or tin -r option) (-DNNTP_ABLE).
  46. X
  47. X  o  remotely from another machine via NNTP but creating tin index files
  48. X     on local machine for each user in $HOME/.tin/.index (-DNNTP_ONLY).
  49. X
  50. X  o  remotely from another machine via NNTP and also retreiving tin index
  51. X     files from remote machine via NNTP (-DNNTP_ONLY -DNNTP_EXTS). This
  52. X     option requires that MY NNTP XUSER & XINDEX patches be applied to
  53. X     your NNTP server nntpd. On the NNTP server the index daemon of tin
  54. X     'tind' needs to be run from cron to update the index files at 
  55. X     regular inetervals.
  56. X
  57. X  o  locally from you machines news spool dir (defult /usr/spool/news)
  58. X     and via CD-ROM using pseudo NNTP library with XSPOOLDIR command.
  59. X     (-DCDROM_ABLE) must be defined and tin must be linked with the
  60. X     pseudo NNTP CD-ROM library libcllib.a.
  61. X  o  via CD-ROM only using pseudo NNTP library with XSPOOLDIR command.
  62. X     (-DCDROM_ONLY) must be defined and tin must be linked with the
  63. X     pseudo NNTP CD-ROM library libcllib.a.
  64. XThe -DNNTP_ABLE or -DNNTP_ONLY define must be added to CFLAGS in 
  65. XMakefile and the correct libraries need to be linked to produce
  66. Xan NNTP aware tin.
  67. X
  68. XIf -DCDROM_ABLE is defined tin will not work with normal NNTP. This
  69. Xmay change as the CD-ROM library is further developed.
  70. X
  71. XBuilding Tin (Normal & Daemon versions) 
  72. X---------------------------------------
  73. X
  74. XNormal version
  75. X1)  Type 'make' and a few system types will be displayed.
  76. X2)  Edit Makefile if you want to add/change -D<defines>.
  77. X3)  Type 'make <system type>' to compile for your system.
  78. X4)  Type 'make install' / 'make install_setuid' to install.
  79. X
  80. XNote1: If you want to retreive tin index files from your NNTP server
  81. X      you will have to compile the tind index file daemon so do the
  82. X      following steps:
  83. X
  84. X  1)  Build 'Normal version' of tin as specified by the above 4 points.
  85. X  2)  The tind index daemon needs to be installed on your NNTP server.
  86. X  3)  Apply my NNTP XUSER & XINDEX patches to your nntpd server or this
  87. X      will not work!!!. (If you want tind locally read Note3).  
  88. X  4)  Edit the Makefile and add -DINDEX_DAEMON to your CFLAGS entry and
  89. X      remove any -DNNTP_* defines. Also remove any -lcurses screen type
  90. X      libs as tind does not need to be linked with curses and it will
  91. X      save a good 30-50K on the size of tind.
  92. X  5)  Type 'make <system type>' to compile tind daemon for your NNTP server.
  93. X  6)  Type 'make install_daemon' to install tind daemon on your NNTP server.
  94. X  7)  Add the following line to your system cron to run tind every 30 mins:
  95. X        00,30 * * * * su news -c '/usr/lib/news/tind'
  96. X        
  97. X  Note2: tind must be run as user 'news' and the normal tin must have 
  98. X         the correct permissions to read the central index files!
  99. X  Note3: tind can also be used to update a copy of all index files
  100. X         centrally so each user does not have duplicate files.
  101. X    
  102. XCompiler flags (-D<name> define directives)
  103. X-------------------------------------------
  104. XNews directory structure
  105. X------------------------
  106. X
  107. XLIBDIR
  108. XDefine if news software is not in /usr/lib/news.
  109. X
  110. XINEWSDIR
  111. XDefine if bnews/cnews program 'inews' is not in LIBDIR.
  112. X
  113. XSPOOLDIR
  114. XDefine if news articles are not in /usr/spool/news.
  115. X
  116. X
  117. XReading/posting news via NNTP
  118. X----------------------------- 
  119. X
  120. XNNTP_ABLE
  121. XDefine if you wish to read news locally and remotely via an NNTP server.
  122. X
  123. XNNTP_ONLY
  124. XDefine if you [want to | can] ONLY read news remotely via an NNTP server.
  125. X
  126. XNNTP_INEWS
  127. XDefine if you want to use my builtin NNTP POST routine so that you no
  128. Xlonger have to rely on the mini-inews from NNTP to be installed on each
  129. Xclient machine. Also check that NNTP_INEWS_GATEWAY & NNTP_INEWS_DOMAIN 
  130. Xare correctly set to produce correct From: headers for your site.
  131. X
  132. XNNTP_INEWS_GATEWAY
  133. XDefines the name of your news gateway machine. Useful if you don't want 
  134. Xyour internal network visable to the outside world.
  135. XExample: I use this define to make all my net postings appear from our news
  136. Xgateway machine 'anl433' even though I post from my own workstation 'sony01'
  137. X
  138. XNNTP_INEWS_DOMAIN
  139. XDefines the name of your network domain. 
  140. XExample: I use this define to add our uucp domain '.uucp' to our news 
  141. Xgateways machine address 'anl433.uucp'.
  142. X
  143. XNNTP_SERVER_FILE
  144. XOnly define if your nntpserver file is other than /etc/nntpserver.
  145. X
  146. XNETLIBS
  147. XContains the networking libraries needed to link with clientlib.o file.
  148. X
  149. X
  150. XReading news via CD-ROM
  151. X-----------------------
  152. X
  153. XCDROM_ABLE
  154. XDefine if you wish to read news locally and from CD-ROM.
  155. X
  156. XCDROM_ONLY
  157. XDefine if you [want to | can] ONLY read news from CD-ROM.
  158. X
  159. X
  160. XDaemon options
  161. X--------------
  162. X
  163. XINDEX_DAEMON
  164. XDefine to make an index file updating daemon version of tin. Note that
  165. Xno -lcurses or screen libraries need to be linked with tin when this
  166. X#define is specified. If defined this will automatically undefine all
  167. XNNTP_* defines as the daemon has to be installed on the NNTP server.
  168. X
  169. X
  170. XMiscellaneous options
  171. X---------------------
  172. X
  173. XSIGTYPE=[void | int]
  174. XDefine only if incorrect pointer type warnings occur during compilition.
  175. XSIGTYPE is already defined in tin.h for most compilers signal() call.
  176. XBy defining this you will override the default action in tin.h.
  177. XPOSIX_JOB_CONTROL
  178. XDefine if your machine uses Posix style sigaction() signal handling.
  179. X
  180. XUSE_MKDIR
  181. XDefine if your machine does not have the mkdir() system call.
  182. X
  183. XUSE_LONG_FILENAMES
  184. XDefine if your machines filesystem supports filenames longer than 14
  185. Xchars (default for BSD type systems).
  186. X
  187. XUSE_INVERSE_HACK
  188. XDefine if you want inverse video and highlighted bar disabled. (default
  189. Xfor SCO Unix & SysVR4).  Can be toggled in tin by the 'I' command and
  190. Xhighlight bar by 'M' command.
  191. X
  192. XUSE_CLEARSCREEN
  193. XDefine if the you wish screen to use ClearScreen() and not MoveCursor()
  194. Xand CleartoEOLN(). This is perhaps faster on slow terminals but I have
  195. Xnot really run any speed tests recently.
  196. X
  197. XSLOW_SCREEN_UPDATE
  198. XDefine if running over a low speed connection (ie. 2400baud). It stops
  199. Xthe percentage info being shown at bottom of select and group menus and
  200. Xstops the groupname being displayed at the bottom of the screen as it is
  201. Xsubscribed/unsubscribed.
  202. X
  203. XSMALL_MEMORY_MACHINE
  204. XDefine if you are running a machine with little memory (<4MB). Tin will
  205. Xrun slightly slower but be more efficent in how memory is allocated and
  206. Xreclaimed.
  207. XNO_REGEX
  208. XDefine if you do not want to use regular expression pattern matching.
  209. X
  210. XNO_SHELL_ESCAPE
  211. XDo not allow shell escapes.
  212. X
  213. XNO_POSTING
  214. XDo not allow posting/followup of articles.
  215. X
  216. XNO_RESYNC_ACTIVE_FILE
  217. XDo not reread active every RESYNC_ACTIVE_SECS.
  218. X
  219. XLOG_USER
  220. XLog username & info to /tmp/.tin_log for usage statistics. If reading via
  221. XNNTP the NNTP XUSER extended command will log user info to NNTP server.
  222. XIf -DNNTP_XUSER is defined it will define LOG_USER automatically.
  223. X
  224. XDEBUG
  225. XDefine if you want tin to log debug info. to files in /tmp. Activated
  226. Xby tin -Dn where n is 1 for NNTP only debug logging and n is 2 for 
  227. Xlogging all debug info. Debug files written to /tmp are ARTS, ACTIVE,
  228. XBASE and NNTP.
  229. X
  230. X
  231. XCompiled & installed on the following machines
  232. X----------------------------------------------
  233. X
  234. X1) * 386 PC & Xenix 2.3.2/SCO SysVR3.2/ISC SysVR3.2/ATT SysVr4.0
  235. X2) * Sony News & NewsOS 4.1
  236. X3) * SNI MX300/MX500 & Sinix 5.22/5.23/5.24/5.4
  237. X4) * Sun 3/4/IPC/SS1/SS2 & SunOS 4.0.3/4.1/4.1.1 
  238. X5) * Dec 5000/Vax & Ultrix 4.1/4.2
  239. X6) * Vax 11/785 & BSD 4.3
  240. X7) * DG Aviion 300 & DG-UX 4.30
  241. X8) * Apollo DN4500 & DomainOS 10.3
  242. X9)   ICL DRS6000 & SysVR4.0 
  243. X10)  Apricot VX/FT & SCO 3.2.2
  244. X11)  DIAB DS90 & D-NIX 5.3
  245. X12)  Amdahl & SysVR3
  246. X13)  HP 720/845 & HP-UX 7.0
  247. X14)  IBM RS/6000 & AIX 3.1.5
  248. X15)  NCR Tower & SysV
  249. X16)  Atari STe & Minix 1.5.10.3b
  250. X17)  Powerbook 140 & MacMinix
  251. X18)  386 PC & Minix 386
  252. X19)  Sequent S81 & PTX 1.3 / Dynix
  253. X20)  Convex C220 & Convex Un*x
  254. X21)  Harris HCX & CX/UX
  255. X22)  SGI 4D/35 & IRIX 4.0.1
  256. X
  257. X* = compiled, installed and used by author 
  258. END_OF_FILE
  259.   if test 8397 -ne `wc -c <'INSTALL'`; then
  260.     echo shar: \"'INSTALL'\" unpacked with wrong size!
  261.   fi
  262.   # end of 'INSTALL'
  263. fi
  264. if test -f 'active.c' -a "${1}" != "-c" ; then 
  265.   echo shar: Will not clobber existing file \"'active.c'\"
  266. else
  267.   echo shar: Extracting \"'active.c'\" \(8546 characters\)
  268.   sed "s/^X//" >'active.c' <<'END_OF_FILE'
  269. X/*
  270. X *  Project   : tin - a threaded Netnews reader
  271. X *  Module    : active.c
  272. X *  Author    : I.Lea
  273. X *  Created   : 16-02-92
  274. X *  Updated   : 02-05-92
  275. X *  Notes     :
  276. X *  Copyright : (c) Copyright 1991-92 by Iain Lea
  277. X *              You may  freely  copy or  redistribute  this software,
  278. X *              so  long as there is no profit made from its use, sale
  279. X *              trade or  reproduction.  You may not change this copy-
  280. X *              right notice, and it must be included in any copy made
  281. X */
  282. X
  283. X#include    "tin.h"
  284. X
  285. Xint group_hash[TABLE_SIZE];            /* group name --> active[] */
  286. Xint reread_active_file = FALSE;
  287. X
  288. X
  289. X/*
  290. X *  Resync active file when SIGALRM signal received that
  291. X *  is triggered by alarm (RESYNC_ACTIVE_SECS) call.
  292. X */
  293. X
  294. Xvoid resync_active_file ()
  295. X{
  296. X    if (reread_active_file) {
  297. X        free_active_arrays ();
  298. X        max_active = DEFAULT_ACTIVE_NUM;
  299. X        expand_active ();
  300. X        read_active_file ();
  301. X        read_newsrc (TRUE);
  302. X        set_alarm_signal ();
  303. X        group_selection_page ();
  304. X    }
  305. X}
  306. X
  307. X/*
  308. X *  Load the active file into active[] and create copy of active ~/.tin/active
  309. X */
  310. X
  311. Xint read_active_file ()
  312. X{
  313. X    FILE *fp;
  314. X    char *p, *q, *r;
  315. X    char buf[LEN];
  316. X    char moderated = 'y';
  317. X    int created, i;
  318. X    long h;
  319. X    
  320. X    num_active = 0;
  321. X
  322. X    if (! update) {
  323. X        wait_message (txt_reading_active_file);
  324. X    }
  325. X
  326. X    if ((fp = open_active_fp ()) == NULL) {
  327. X        if (compiled_with_nntp) {
  328. X            sprintf (msg, txt_cannot_open_active_file, active_file, progname);
  329. X            wait_message (msg);
  330. X        } else {
  331. X            fputc ('\n', stderr);
  332. X            fprintf (stderr, txt_cannot_open, active_file);
  333. X            fputc ('\n', stderr);
  334. X            fflush (stderr);
  335. X        }
  336. X        exit (1);
  337. X    }
  338. X
  339. X    for (i = 0; i < TABLE_SIZE; i++) {
  340. X        group_hash[i] = -1;
  341. X    }
  342. X
  343. X    while (fgets (buf, sizeof (buf), fp) != NULL) {
  344. X        for (p = buf; *p && *p != ' '; p++)
  345. X            continue;
  346. X        if (*p != ' ') {
  347. X            error_message (txt_bad_active_file, buf);
  348. X            continue;
  349. X        }
  350. X        *p++ = '\0';
  351. X
  352. X        if (num_active >= max_active) {
  353. X            debug_nntp ("read_active_file", "EXPANDING active file");
  354. X            expand_active ();
  355. X        }
  356. X
  357. X        h = hash_groupname (buf);
  358. X
  359. X        if (group_hash[h] == -1) {
  360. X            group_hash[h] = num_active;
  361. X        } else {                /* hash linked list chaining */
  362. X            for (i=group_hash[h]; active[i].next >= 0; i=active[i].next) {
  363. X                if (strcmp(active[i].name, buf) == 0) {
  364. X                    goto read_active_continue;        /* kill dups */
  365. X                }
  366. X            }
  367. X            if (strcmp(active[i].name, buf) == 0)
  368. X                goto read_active_continue;
  369. X            active[i].next = num_active;
  370. X        }
  371. X
  372. X        for (q = p; *q && *q != ' '; q++)
  373. X            continue;
  374. X        if (*q != ' ') {
  375. X            error_message (txt_bad_active_file, buf);
  376. X            continue;
  377. X        }
  378. X        *q++ = '\0';
  379. X
  380. X        for (r = q; *r && *r != '\n'; r++) {
  381. X            if (*r == 'y' || *r == 'm') {
  382. X                moderated = *r;
  383. X                break;
  384. X            }
  385. X        }
  386. X
  387. X        /*
  388. X         * Group info.
  389. X         */
  390. X        active[num_active].name = str_dup (buf);
  391. X        active[num_active].max = (long) atol (p);
  392. X        active[num_active].min = (long) atol (q);
  393. X        active[num_active].moderated = moderated;
  394. X        active[num_active].next = -1;            /* hash chaining */
  395. X        active[num_active].flag = UNSUBSCRIBED;    /* not in my_group[] yet */
  396. X        /*
  397. X         * Per group attributes
  398. X         */
  399. X        active[num_active].attribute.server  = (char *) 0;
  400. X        active[num_active].attribute.maildir = default_maildir;
  401. X        active[num_active].attribute.savedir = default_savedir;
  402. X        active[num_active].attribute.sigfile = default_sigfile;
  403. X        active[num_active].attribute.read    = FALSE;    /* read/unread */
  404. X        active[num_active].attribute.showall = show_only_unread;
  405. X        active[num_active].attribute.thread  = thread_arts;
  406. X        active[num_active].attribute.sortby  = sort_art_type;
  407. X        active[num_active].attribute.author  = show_author;
  408. X        active[num_active].attribute.autosave= save_archive_name;
  409. X        active[num_active].attribute.process = post_proc_type; 
  410. X
  411. X        num_active++;
  412. X
  413. Xread_active_continue:;
  414. X
  415. X    }
  416. X    fclose (fp);
  417. X
  418. X    /*
  419. X     *  exit if active file is empty
  420. X     */
  421. X    if (! num_active) {
  422. X        error_message (txt_active_file_is_empty, active_file);
  423. X        exit (1);
  424. X    }
  425. X
  426. X    /*
  427. X     *  create backup of LIBDIR/active for use by -n option to notify new groups 
  428. X     */
  429. X    created = backup_active (TRUE);
  430. X
  431. X    debug_print_active ();
  432. X
  433. X    if (cmd_line && (read_news_via_nntp && update == FALSE)) {
  434. X        if (! (update && ! verbose)) {
  435. X            wait_message ("\n");
  436. X        }
  437. X    }
  438. X
  439. X    return (created);
  440. X}
  441. X
  442. X/*
  443. X *  create ~/.tin/active from LIBDIR/active if it does not exist 
  444. X */
  445. X
  446. Xint backup_active (create)
  447. X    int create;
  448. X{
  449. X    char buf[LEN];
  450. X    FILE *fp;
  451. X    int created = FALSE;
  452. X    int i;
  453. X    struct stat sb;
  454. X    
  455. X    sprintf (buf, "%s/active", rcdir);
  456. X    
  457. X    if (create) {
  458. X        if (stat (buf, &sb) != -1) {
  459. X            goto backup_active_done;
  460. X        }
  461. X    }
  462. X    
  463. X    if ((fp = fopen (buf, "w")) != NULL) {
  464. X        for (i = 0; i < num_active ; i++) {    /* for each group */
  465. X            fprintf (fp, "%s\n", active[i].name);
  466. X        }
  467. X        fclose (fp);
  468. X        chmod (buf, 0644);
  469. X        created = TRUE;
  470. X    }
  471. X
  472. Xbackup_active_done:
  473. X    return (created);
  474. X}
  475. X
  476. X/*
  477. X *  Option -n to check for any newly created newsgroups.
  478. X */
  479. X
  480. Xvoid notify_groups ()
  481. X{
  482. X    char buf[LEN];
  483. X    FILE *fp;
  484. X    int group_not_found;
  485. X    int index;
  486. X    int num = 0;
  487. X    int update_old_active = FALSE;
  488. X    int max_old_active;
  489. X    register int i, j;
  490. X    struct notify_t {
  491. X        char name[LEN];
  492. X        int len;
  493. X        int visited;
  494. X    } *old_active = (struct notify_t *) 0;
  495. X    
  496. X    sprintf (buf, "%s/active", rcdir);
  497. X    
  498. X    if ((fp = fopen (buf, "r")) == NULL) {
  499. X        perror_message (txt_cannot_open, buf);
  500. X        goto notify_groups_done;
  501. X    }
  502. X
  503. X    Raw (TRUE);
  504. X    
  505. X    wait_message (txt_checking_active_file);
  506. X
  507. X    max_old_active = num_active;
  508. X    
  509. X    old_active = (struct notify_t *) my_malloc ((unsigned) sizeof (struct notify_t) * max_old_active);
  510. X    if (old_active == (struct notify_t *) 0) {
  511. X        error_message (txt_out_of_memory, progname);
  512. X        goto notify_groups_done;
  513. X    }
  514. X    
  515. X    while (fgets (old_active[num].name, sizeof (old_active[num].name), fp) != NULL) {
  516. X        old_active[num].len = strlen (old_active[num].name)-1;
  517. X        old_active[num].name[old_active[num].len] = '\0';
  518. X        old_active[num].visited = FALSE;
  519. X        num++;
  520. X        if (num >= max_old_active) {
  521. X            max_old_active= max_old_active + (max_old_active / 2);
  522. X            old_active= (struct notify_t*) my_realloc(
  523. X                (char *) old_active, 
  524. X                (unsigned) sizeof(struct notify_t) * max_old_active);
  525. X            if (old_active == (struct notify_t *) 0) {
  526. X                error_message (txt_out_of_memory, progname);
  527. X                goto notify_groups_done;
  528. X            }
  529. X        }
  530. X    }
  531. X
  532. X    for (i = 0 ; i < num_active ; i++) {    
  533. X        group_not_found = TRUE;
  534. X        for (j=0; j < num ; j++) {
  535. X            if (strcmp (old_active[j].name, active[i].name) == 0) {
  536. X                group_not_found = FALSE;    /* found it so read in next group */
  537. X                old_active[j].visited = TRUE;
  538. X                break;
  539. X            }
  540. X        }
  541. X
  542. X        if (group_not_found == FALSE) {
  543. X            continue;
  544. X        }    
  545. X
  546. X        update_old_active = TRUE;
  547. X        do {
  548. X            fputc ('\r', stdout);
  549. X            CleartoEOLN();
  550. X            printf (txt_subscribe_to_new_group, active[i].name);
  551. X            fflush (stdout);
  552. X            buf[0] = ReadCh();
  553. X        } while (buf[0] != 'y' && buf[0] != 'n');
  554. X            
  555. X        if (buf[0] == 'y') {
  556. X            index = add_group (active[i].name, TRUE);
  557. X            subscribe (active[my_group[index]].name, ':',
  558. X                   my_group[index], FALSE);
  559. X        }
  560. X        printf ("\r\n%s", txt_checking);
  561. X        fflush (stdout);
  562. X    }
  563. X    fclose (fp);
  564. X    fputc ('\r', stdout);
  565. X    fflush (stdout);
  566. X    CleartoEOLN();
  567. X
  568. X    /*
  569. X     * Look for bogus groups 
  570. X     */
  571. X    for (j = 0 ; j < num ; j++)  {
  572. X        if (old_active[j].visited) {
  573. X            continue;
  574. X        }
  575. X        do {    
  576. X            update_old_active= 1;
  577. X            fputc ('\r', stdout);
  578. X            CleartoEOLN ();
  579. X            printf (txt_delete_bogus_group, old_active[j].name);
  580. X            fflush (stdout);
  581. X            buf[0] = ReadCh ();
  582. X        } while (buf[0] != 'y' && buf[0] != 'n');
  583. X        if (buf[0] == 'y') {
  584. X            delete_group (old_active[j].name);
  585. X        }
  586. X        printf ("\r\n");
  587. X    }
  588. X    
  589. X    Raw (TRUE);
  590. X
  591. X    /*
  592. X     *  write active[] to ~/.tin/active
  593. X     */
  594. X    if (update_old_active) {
  595. X        backup_active (FALSE);
  596. X    }
  597. X
  598. Xnotify_groups_done:
  599. X    if (old_active != (struct notify_t *) 0) {
  600. X        free ((char *) old_active);
  601. X        old_active = (struct notify_t *) 0;
  602. X    }
  603. X}
  604. X
  605. X/*
  606. X *  Mark any groups in my_group[] that are in ~/.tin/unthread so they
  607. X *  will not be threaded
  608. X */
  609. Xvoid mark_unthreaded_groups ()
  610. X{
  611. X    FILE *fp;
  612. X    char buf[LEN];
  613. X    int i, len;
  614. X    long h;
  615. X
  616. X#ifndef INDEX_DAEMON
  617. X
  618. X    if ((fp = fopen (unthreadfile, "r")) == NULL) {
  619. X        perror_message (txt_cannot_open, unthreadfile);
  620. X        return;
  621. X    }
  622. X
  623. X    while (fgets (buf, sizeof (buf), fp) != NULL) {
  624. X        buf[strlen (buf)-1] = '\0'; 
  625. X        h = hash_groupname (buf);
  626. X        sprintf (msg, "Unthreading %s...\n", buf);
  627. X        wait_message (msg);
  628. X        
  629. X        i = group_hash[h];
  630. X        
  631. X        if (active[i].next == -1) {
  632. X            len = strlen (active[i].name);
  633. X            if (strncmp (active[i].name, buf, len) == 0) {
  634. X                active[i].attribute.thread = FALSE;
  635. X            }
  636. X        
  637. X        } else {
  638. X            for (i=group_hash[h]; active[i].next >= 0; i=active[i].next) {
  639. X                len = strlen (active[i].name);
  640. X                if (strncmp (active[i].name, buf, len) == 0) {
  641. X                    active[i].attribute.thread = FALSE;
  642. X                    break;
  643. X                }
  644. X            }
  645. X        }    
  646. X    }
  647. X
  648. X    fclose (fp);
  649. X#endif /* INDEX_DAEMON */
  650. X}
  651. X
  652. END_OF_FILE
  653.   if test 8546 -ne `wc -c <'active.c'`; then
  654.     echo shar: \"'active.c'\" unpacked with wrong size!
  655.   fi
  656.   # end of 'active.c'
  657. fi
  658. if test -f 'getline.c' -a "${1}" != "-c" ; then 
  659.   echo shar: Will not clobber existing file \"'getline.c'\"
  660. else
  661.   echo shar: Extracting \"'getline.c'\" \(11458 characters\)
  662.   sed "s/^X//" >'getline.c' <<'END_OF_FILE'
  663. X/*
  664. X *  Project   : tin - a threaded Netnews reader
  665. X *  Module    : getline.c
  666. X *  Author    : Chris Thewalt & Iain Lea 
  667. X *  Created   : 09-11-91
  668. X *  Updated   : 29-03-92
  669. X *  Notes     : emacs style line editing input package.  
  670. X *  Copyright : (c) Copyright 1991-92 by Chris Thewalt & Iain Lea
  671. X *              Permission to use, copy, modify, and distribute this
  672. X *              software for any purpose and without fee is hereby
  673. X *              granted, provided that the above copyright notices
  674. X *              appear in all copies and that both the copyright
  675. X *              notice and this permission notice appear in supporting
  676. X *              documentation. This software is provided "as is" without
  677. X *              express or implied warranty.
  678. X */
  679. X
  680. X#include "tin.h"
  681. X
  682. Xextern int      isatty ();    
  683. X
  684. X#define BUF_SIZE    1024
  685. X#define SCROLL        30
  686. X#define TABSIZE        4
  687. X#ifndef HIST_SIZE
  688. X#define HIST_SIZE    100
  689. X#endif
  690. X
  691. X#define CTRL_A    '\001'
  692. X#define CTRL_B    '\002'
  693. X#define CTRL_D    '\004'
  694. X#define CTRL_E    '\005'
  695. X#define CTRL_F    '\006'
  696. X#define CTRL_H    '\010'
  697. X#define CTRL_K    '\013'
  698. X#define CTRL_L    '\014'
  699. X#define CTRL_R    '\022'
  700. X#define CTRL_N    '\016'
  701. X#define CTRL_P    '\020'
  702. X#define TAB        '\t'
  703. X#define DEL        '\177'
  704. X
  705. Xchar    *hist_buf[HIST_SIZE];
  706. Xint        hist_pos, hist_last;
  707. Xstatic char gl_buf[BUF_SIZE];       /* input buffer */
  708. Xstatic char *gl_prompt;                /* to save the prompt string */
  709. Xstatic int  gl_init_done = 0;        /* -1 is terminal, 1 is batch  */
  710. Xstatic int  gl_width = 0;            /* net size available for input */
  711. Xstatic int  gl_pos, gl_cnt = 0;     /* position and size of input */
  712. X
  713. X#if __STDC__
  714. X
  715. Xstatic int      gl_tab (char *, int, int *);
  716. Xstatic void        gl_redraw (void);
  717. Xstatic void     gl_addchar (int);
  718. Xstatic void     gl_newline (void);
  719. Xstatic void     gl_fixup (int, int);
  720. Xstatic void     gl_del (int);
  721. Xstatic void     gl_kill (void);
  722. Xstatic void     hist_add (void);
  723. Xstatic void     hist_init (void);
  724. Xstatic void     hist_next (void);
  725. Xstatic void     hist_prev (void);
  726. X
  727. Xint     (*gl_in_hook)(char *) = 0;
  728. Xint     (*gl_out_hook)(char *) = 0;
  729. Xint     (*gl_tab_hook)(char *, int, int *) = gl_tab;
  730. X
  731. X#else
  732. X
  733. Xstatic int      gl_tab ();
  734. Xstatic void        gl_redraw ();
  735. Xstatic void     gl_addchar ();
  736. Xstatic void     gl_newline ();
  737. Xstatic void     gl_fixup ();
  738. Xstatic void     gl_del ();
  739. Xstatic void     gl_kill ();
  740. Xstatic void     hist_add ();
  741. Xstatic void     hist_init ();
  742. Xstatic void     hist_next ();
  743. Xstatic void     hist_prev ();
  744. X
  745. Xint     (*gl_in_hook)() = 0;
  746. Xint     (*gl_out_hook)() = 0;
  747. Xint     (*gl_tab_hook)() = gl_tab;
  748. X
  749. X#endif
  750. X
  751. X
  752. X#if __STDC__
  753. Xchar *getline (char *prompt, int number_only, char *str)
  754. X#else
  755. Xchar *getline (prompt, number_only, str)
  756. X    char *prompt;
  757. X    int number_only;
  758. X    char *str;
  759. X#endif
  760. X{
  761. X    int c, i, loc, tmp;
  762. X
  763. X    if (! gl_init_done) {
  764. X        gl_init_done = 1;
  765. X        hist_init ();
  766. X    }
  767. X
  768. X    if (prompt == (char *) 0) {    
  769. X        prompt = "";
  770. X    }
  771. X    gl_buf[0] = 0;        /* used as end of input indicator */
  772. X    gl_fixup (-1, 0);    /* this resets gl_fixup */
  773. X    gl_width = COLS - strlen (prompt);
  774. X    gl_prompt = prompt;
  775. X    gl_pos = gl_cnt = 0;
  776. X
  777. X    fputs (prompt, stdout);
  778. X    fflush (stdout);
  779. X    
  780. X    if (gl_in_hook) {
  781. X        loc = gl_in_hook (gl_buf);
  782. X        if (loc >= 0)
  783. X            gl_fixup (0, BUF_SIZE);
  784. X    }
  785. X    if (str != (char *) 0) {
  786. X        for (i=0 ; str[i] ; i++) 
  787. X            gl_addchar (str[i]);
  788. X    }
  789. X    while ((c = ReadCh ()) != EOF) {
  790. X        c &= 0xff;    
  791. X        if (isprint (c)) {
  792. X            if (number_only) {
  793. X                if (isdigit (c) && gl_cnt < 6) {    /* num < 100000 */
  794. X                    gl_addchar (c);
  795. X                } else {
  796. X                    ring_bell ();
  797. X                }
  798. X            } else {
  799. X                gl_addchar (c);
  800. X            }
  801. X        } else {
  802. X            switch (c) {
  803. X                case ESC:             /* abort */
  804. X                    return (char *) 0;
  805. X                    break;
  806. X                case '\n':             /* newline */
  807. X                case '\r':
  808. X                    gl_newline ();
  809. X                    return gl_buf;
  810. X                    break;
  811. X                case CTRL_A:
  812. X                    gl_fixup (-1, 0);
  813. X                    break;
  814. X                case CTRL_B:
  815. X                    gl_fixup (-1, gl_pos-1);
  816. X                    break;
  817. X                case CTRL_D:
  818. X                    if (gl_cnt == 0) {
  819. X                        gl_buf[0] = 0;
  820. X                        fputc ('\n', stdout);
  821. X                        return gl_buf;
  822. X                    } else {
  823. X                        gl_del (0);
  824. X                    }
  825. X                    break;
  826. X                case CTRL_E:
  827. X                    gl_fixup (-1, gl_cnt);
  828. X                    break;
  829. X                case CTRL_F:
  830. X                    gl_fixup (-1, gl_pos+1);
  831. X                    break;
  832. X                case CTRL_H:
  833. X                case DEL:
  834. X                    gl_del (-1);
  835. X                    break;
  836. X                case TAB:
  837. X                    if (gl_tab_hook) {
  838. X                        tmp = gl_pos;
  839. X                        loc = gl_tab_hook (gl_buf, strlen (gl_prompt), &tmp);
  840. X                        if (loc >= 0 || tmp != gl_pos)
  841. X                            gl_fixup (loc, tmp);
  842. X                    }
  843. X                    break;
  844. X                case CTRL_K:
  845. X                    gl_kill ();
  846. X                    break;
  847. X                case CTRL_L:
  848. X                case CTRL_R:
  849. X                    gl_redraw ();
  850. X                    break;
  851. X                case CTRL_N:
  852. X                    hist_next ();
  853. X                    break;
  854. X                case CTRL_P:
  855. X                    hist_prev ();
  856. X                    break;
  857. X                default:
  858. X                    ring_bell ();
  859. X                    break;
  860. X            }
  861. X        }
  862. X    }
  863. X    return gl_buf;
  864. X}
  865. X
  866. X/*
  867. X * adds the character c to the input buffer at current location if
  868. X * the character is in the allowed template of characters
  869. X */
  870. X
  871. X#if __STDC__
  872. Xstatic void gl_addchar (int c)
  873. X#else
  874. Xstatic void gl_addchar (c)
  875. X    int c;
  876. X#endif
  877. X{
  878. X    int  i;
  879. X
  880. X    if (gl_cnt >= BUF_SIZE - 1) {
  881. X        error_message ("getline: input buffer overflow", "");
  882. X        exit (1);
  883. X    }
  884. X    
  885. X    for (i=gl_cnt; i >= gl_pos; i--) {
  886. X        gl_buf[i+1] = gl_buf[i];
  887. X    }
  888. X    gl_buf[gl_pos] = c;
  889. X    gl_fixup (gl_pos, gl_pos+1);
  890. X}
  891. X
  892. X/*
  893. X * Cleans up entire line before returning to caller. A \n is appended.
  894. X * If line longer than screen, we redraw starting at beginning
  895. X */
  896. X
  897. Xstatic void gl_newline ()
  898. X{
  899. X    int change = gl_cnt;
  900. X    int len = gl_cnt;
  901. X    int loc = gl_width - 5;    /* shifts line back to start position */
  902. X
  903. X    if (gl_cnt >= BUF_SIZE - 1) {
  904. X        error_message ("getline: input buffer overflow", "");
  905. X        exit (1);
  906. X    }
  907. X    hist_add ();            /* only adds if nonblank */
  908. X    if (gl_out_hook) {
  909. X        change = gl_out_hook (gl_buf);
  910. X        len = strlen (gl_buf);
  911. X    } 
  912. X    if (loc > len)
  913. X        loc = len;
  914. X    gl_fixup (change, loc);    /* must do this before appending \n */
  915. X    gl_buf[len] = '\0';
  916. X}
  917. X
  918. X/*
  919. X * Delete a character.  The loc variable can be:
  920. X *    -1 : delete character to left of cursor
  921. X *     0 : delete character under cursor
  922. X */
  923. X
  924. X#if __STDC__
  925. Xstatic void gl_del (int loc)
  926. X#else
  927. Xstatic void gl_del (loc)
  928. X    int loc;
  929. X#endif
  930. X{
  931. X    int i;
  932. X
  933. X    if ((loc == -1 && gl_pos > 0) || (loc == 0 && gl_pos < gl_cnt)) {
  934. X        for (i=gl_pos+loc; i < gl_cnt; i++)
  935. X            gl_buf[i] = gl_buf[i+1];
  936. X        gl_fixup (gl_pos+loc, gl_pos+loc);
  937. X    } else {
  938. X        ring_bell ();
  939. X    }
  940. X}
  941. X
  942. X/*
  943. X * delete from current position to the end of line
  944. X */
  945. Xstatic void gl_kill ()
  946. X{
  947. X    if (gl_pos < gl_cnt) {
  948. X        gl_buf[gl_pos] = '\0';
  949. X        gl_fixup (gl_pos, gl_pos);
  950. X    } else {
  951. X        ring_bell ();
  952. X    }
  953. X}
  954. X
  955. X/*
  956. X * emit a newline, reset and redraw prompt and current input line
  957. X */
  958. X
  959. Xstatic void gl_redraw ()
  960. X{
  961. X    if (gl_init_done == -1) {
  962. X        fputc ('\n', stdout);
  963. X        fputs (gl_prompt, stdout);
  964. X        gl_pos = 0;
  965. X        gl_fixup (0, BUF_SIZE);
  966. X    }
  967. X}
  968. X
  969. X/*
  970. X * This function is used both for redrawing when input changes or for
  971. X * moving within the input line.  The parameters are:
  972. X *   change : the index of the start of changes in the input buffer,
  973. X *            with -1 indicating no changes.
  974. X *   cursor : the desired location of the cursor after the call.
  975. X *            A value of BUF_SIZE can be used to indicate the cursor
  976. X *            should move just past the end of the input line.
  977. X */
  978. X
  979. X#if __STDC__
  980. Xstatic void gl_fixup (int change, int cursor)
  981. X#else
  982. Xstatic void gl_fixup (change, cursor)
  983. X    int change;
  984. X    int cursor;
  985. X#endif
  986. X{
  987. X    static int   gl_shift;    /* index of first on screen character */
  988. X    static int   off_right;    /* true if more text right of screen */
  989. X    static int   off_left;    /* true if more text left of screen */
  990. X    int          left = 0, right = -1;        /* bounds for redraw */
  991. X    int          pad;        /* how much to erase at end of line */
  992. X    int          backup;        /* how far to backup before fixing */
  993. X    int          new_shift;     /* value of shift based on cursor */
  994. X    int          extra;         /* adjusts when shift (scroll) happens */
  995. X    int          i;
  996. X
  997. X    if (change == -1 && cursor == 0 && gl_buf[0] == 0) {   /* reset */
  998. X        gl_shift = off_right = off_left = 0;
  999. X        return;
  1000. X    }
  1001. X    pad = (off_right) ? gl_width - 1 : gl_cnt - gl_shift;   /* old length */
  1002. X    backup = gl_pos - gl_shift;
  1003. X    if (change >= 0) {
  1004. X        gl_cnt = strlen (gl_buf);
  1005. X        if (change > gl_cnt)
  1006. X            change = gl_cnt;
  1007. X    }
  1008. X    if (cursor > gl_cnt) {
  1009. X        if (cursor != BUF_SIZE)        /* BUF_SIZE means end of line */
  1010. X            ring_bell ();
  1011. X            cursor = gl_cnt;
  1012. X    }
  1013. X    if (cursor < 0) {
  1014. X        ring_bell ();
  1015. X        cursor = 0;
  1016. X    }
  1017. X    if (off_right || off_left && (cursor < gl_shift + gl_width - SCROLL / 2))
  1018. X        extra = 2;            /* shift the scrolling boundary */
  1019. X    else 
  1020. X        extra = 0;
  1021. X    new_shift = cursor + extra + SCROLL - gl_width;
  1022. X    if (new_shift > 0) {
  1023. X        new_shift /= SCROLL;
  1024. X        new_shift *= SCROLL;
  1025. X    } else
  1026. X        new_shift = 0;
  1027. X    if (new_shift != gl_shift) {    /* scroll occurs */
  1028. X        gl_shift = new_shift;
  1029. X        off_left = (gl_shift) ? 1 : 0;
  1030. X        off_right = (gl_cnt > gl_shift + gl_width - 1)? 1 : 0;
  1031. X        left = gl_shift;
  1032. X        right = (off_right) ? gl_shift + gl_width - 2 : gl_cnt;
  1033. X    } else if (change >= 0) {        /* no scroll, but text changed */
  1034. X        if (change < gl_shift + off_left) {
  1035. X            left = gl_shift;
  1036. X        } else {
  1037. X            left = change;
  1038. X            backup = gl_pos - change;
  1039. X        }
  1040. X        off_right = (gl_cnt > gl_shift + gl_width - 1)? 1 : 0;
  1041. X        right = (off_right) ? gl_shift + gl_width - 2 : gl_cnt;
  1042. X    }
  1043. X    pad -= (off_right) ? gl_width - 1 : gl_cnt - gl_shift;
  1044. X    pad = (pad < 0)? 0 : pad;
  1045. X    if (left <= right) {        /* clean up screen */
  1046. X        for (i=0; i < backup; i++)
  1047. X            fputc ('\b', stdout);
  1048. X        if (left == gl_shift && off_left) {
  1049. X            fputc ('$', stdout);
  1050. X            left++;
  1051. X        }
  1052. X        for (i=left; i < right; i++)
  1053. X            fputc (gl_buf[i], stdout);
  1054. X        if (off_right) {
  1055. X            fputc ('$', stdout);
  1056. X            gl_pos = right + 1;
  1057. X        } else { 
  1058. X            for (i=0; i < pad; i++)    /* erase remains of prev line */
  1059. X                fputc (' ', stdout);
  1060. X            gl_pos = right + pad;
  1061. X        }
  1062. X    }
  1063. X    i = gl_pos - cursor;        /* move to final cursor location */
  1064. X    if (i > 0) {
  1065. X        while (i--)
  1066. X            fputc ('\b', stdout);
  1067. X    } else {
  1068. X        for (i=gl_pos; i < cursor; i++)
  1069. X            fputc (gl_buf[i], stdout);
  1070. X    }
  1071. X    fflush (stdout);
  1072. X    gl_pos = cursor;
  1073. X}
  1074. X    
  1075. X/*
  1076. X * default tab handler, acts like tabstops every TABSIZE cols
  1077. X */
  1078. X
  1079. X#if __STDC__
  1080. Xstatic int gl_tab (char *buf, int offset, int *loc)
  1081. X#else
  1082. Xstatic int gl_tab (buf, offset, loc)
  1083. X    char *buf;
  1084. X    int offset;
  1085. X    int *loc;
  1086. X#endif
  1087. X{
  1088. X    int i, count, len;
  1089. X    
  1090. X    len = strlen (buf);
  1091. X    count = TABSIZE - (offset + *loc) % TABSIZE;
  1092. X    for (i=len; i >= *loc; i--)
  1093. X        buf[i+count] = buf[i];
  1094. X    for (i=0; i < count; i++)
  1095. X        buf[*loc+i] = ' ';
  1096. X    i = *loc;
  1097. X    *loc = i + count;
  1098. X    return i;
  1099. X}
  1100. X
  1101. X/*
  1102. X * History functions
  1103. X */
  1104. X
  1105. Xstatic void hist_init ()
  1106. X{
  1107. X    int i;
  1108. X    
  1109. X    for (i=0; i < HIST_SIZE; i++)
  1110. X        hist_buf[i] = (char *) 0;
  1111. X}
  1112. X
  1113. X
  1114. Xstatic void hist_add ()
  1115. X{
  1116. X    char *p = gl_buf;
  1117. X
  1118. X    while (*p == ' ' || *p == '\t')    /* only save nonblank line */
  1119. X        p++;
  1120. X    if (*p) {
  1121. X        hist_buf[hist_last] = str_dup (gl_buf);
  1122. X        hist_last = (hist_last + 1) % HIST_SIZE;
  1123. X        if (hist_buf[hist_last]) {    /* erase next location */
  1124. X            free(hist_buf[hist_last]);
  1125. X            hist_buf[hist_last] = (char *) 0;
  1126. X        }
  1127. X    }
  1128. X    hist_pos = hist_last;
  1129. X}
  1130. X
  1131. X/*
  1132. X * loads previous hist entry into input buffer, sticks on first
  1133. X */
  1134. Xstatic void hist_prev ()
  1135. X{
  1136. X    int   next;
  1137. X
  1138. X    next = (hist_pos - 1 + HIST_SIZE) % HIST_SIZE;
  1139. X    if (next != hist_last) {
  1140. X        if (hist_buf[next]) {
  1141. X            hist_pos = next;
  1142. X            strcpy (gl_buf, hist_buf[hist_pos]);
  1143. X        } else {
  1144. X            ring_bell ();
  1145. X        }
  1146. X    } else {
  1147. X        ring_bell ();
  1148. X    }
  1149. X    if (gl_in_hook)
  1150. X        gl_in_hook (gl_buf);
  1151. X    gl_fixup (0, BUF_SIZE);
  1152. X}
  1153. X
  1154. X/*
  1155. X * loads next hist entry into input buffer, clears on last
  1156. X */
  1157. Xstatic void hist_next ()
  1158. X{
  1159. X    if (hist_pos != hist_last) {
  1160. X        hist_pos = (hist_pos + 1) % HIST_SIZE;
  1161. X        if (hist_buf[hist_pos]) {
  1162. X            strcpy (gl_buf, hist_buf[hist_pos]);
  1163. X        } else {
  1164. X            gl_buf[0] = 0;
  1165. X        }
  1166. X    } else {
  1167. X        ring_bell ();
  1168. X    }
  1169. X    if (gl_in_hook) 
  1170. X        gl_in_hook (gl_buf);
  1171. X    gl_fixup (0, BUF_SIZE);
  1172. X}
  1173. END_OF_FILE
  1174.   if test 11458 -ne `wc -c <'getline.c'`; then
  1175.     echo shar: \"'getline.c'\" unpacked with wrong size!
  1176.   fi
  1177.   # end of 'getline.c'
  1178. fi
  1179. if test -f 'memory.c' -a "${1}" != "-c" ; then 
  1180.   echo shar: Will not clobber existing file \"'memory.c'\"
  1181. else
  1182.   echo shar: Extracting \"'memory.c'\" \(7630 characters\)
  1183.   sed "s/^X//" >'memory.c' <<'END_OF_FILE'
  1184. X/*
  1185. X *  Project   : tin - a threaded Netnews reader
  1186. X *  Module    : memory.c
  1187. X *  Author    : I.Lea & R.Skrenta
  1188. X *  Created   : 01-04-91
  1189. X *  Updated   : 15-05-92
  1190. X *  Notes     :
  1191. X *  Copyright : (c) Copyright 1991-92 by Iain Lea & Rich Skrenta
  1192. X *              You may  freely  copy or  redistribute  this software,
  1193. X *              so  long as there is no profit made from its use, sale
  1194. X *              trade or  reproduction.  You may not change this copy-
  1195. X *              right notice, and it must be included in any copy made
  1196. X */
  1197. X
  1198. X#include    "tin.h"
  1199. X
  1200. Xint *my_group;                    /* .newsrc --> active[] */
  1201. Xint *unread;                    /* highest art read in group */
  1202. Xlong *base;
  1203. Xstruct group_t *active;            /* active file */
  1204. Xstruct article_t *arts;
  1205. X
  1206. X/*
  1207. X *  Dynamic table management
  1208. X *  These settings are memory conservative:  small initial allocations
  1209. X *  and a 50% expansion on table overflow.  A fast vm system with
  1210. X *  much memory might want to start with higher initial allocations
  1211. X *  and a 100% expansion on overflow, especially for the arts[] array.
  1212. X */
  1213. X
  1214. Xvoid init_alloc ()
  1215. X{
  1216. X    max_active = DEFAULT_ACTIVE_NUM;
  1217. X    max_art = DEFAULT_ARTICLE_NUM;
  1218. X
  1219. X    active = (struct group_t *) my_malloc ((unsigned) sizeof(*active) * max_active);
  1220. X    my_group = (int *) my_malloc ((unsigned) sizeof(int) * max_active);
  1221. X    unread = (int *) my_malloc ((unsigned) sizeof(int) * max_active);
  1222. X
  1223. X    arts = (struct article_t *) my_malloc ((unsigned) sizeof(*arts) * max_art);
  1224. X    base = (long *) my_malloc ((unsigned) sizeof(long) * max_art);
  1225. X
  1226. X    max_kill = DEFAULT_KILL_NUM;
  1227. X    
  1228. X    killf = (struct kill_t *) my_malloc ((unsigned) sizeof(*killf) * max_kill);
  1229. X
  1230. X    max_save = DEFAULT_SAVE_NUM;
  1231. X    
  1232. X    save = (struct save_t *) my_malloc ((unsigned) sizeof(*save) * max_save);
  1233. X
  1234. X    screen = (struct screen_t *) 0;
  1235. X}
  1236. X
  1237. X
  1238. Xvoid expand_art()
  1239. X{
  1240. X    max_art += max_art / 2;        /* increase by 50% */
  1241. X
  1242. X    arts = (struct article_t *) my_realloc ((char *) arts, (unsigned) sizeof(*arts) * max_art);
  1243. X    base = (long *) my_realloc ((char *) base, (unsigned) sizeof(long) * max_art);
  1244. X}
  1245. X
  1246. X
  1247. Xvoid expand_active()
  1248. X{
  1249. X    max_active += max_active / 2;        /* increase by 50% */
  1250. X
  1251. X    if (active == (struct group_t *) 0) {
  1252. X        active = (struct group_t *) my_malloc ((unsigned) sizeof(*active) * max_active);
  1253. X        my_group = (int *) my_malloc ((unsigned) sizeof(int) * max_active);
  1254. X        unread = (int *) my_malloc ((unsigned) sizeof(int) * max_active);
  1255. X    } else {
  1256. X        active = (struct group_t *) my_realloc((char *) active,
  1257. X                 (unsigned) sizeof(*active) * max_active);
  1258. X        my_group = (int *) my_realloc((char *) my_group, (unsigned) sizeof(int) * max_active);
  1259. X        unread = (int *) my_realloc((char *) unread, (unsigned) sizeof(int) * max_active);
  1260. X    }
  1261. X}
  1262. X
  1263. X
  1264. Xvoid expand_kill()
  1265. X{
  1266. X    max_kill += max_kill / 2;        /* increase by 50% */
  1267. X
  1268. X    killf = (struct kill_t *) my_realloc((char *) killf, (unsigned) sizeof(struct kill_t) * max_kill);
  1269. X}
  1270. X
  1271. X
  1272. Xvoid expand_save()
  1273. X{
  1274. X    max_save += max_save / 2;        /* increase by 50% */
  1275. X
  1276. X    save = (struct save_t *) my_realloc((char *) save, (unsigned) sizeof(struct save_t) * max_save);
  1277. X}
  1278. X
  1279. X
  1280. Xvoid init_screen_array (allocate)
  1281. X    int allocate;
  1282. X{
  1283. X    int i;
  1284. X
  1285. X    if (allocate) {
  1286. X        screen = (struct screen_t *) my_malloc(
  1287. X            (unsigned) sizeof(struct screen_t) * LINES+1);
  1288. X
  1289. X        for (i=0 ; i < LINES ; i++) {
  1290. X            screen[i].col = (char *) my_malloc ((unsigned) COLS+2);
  1291. X        }
  1292. X    } else {
  1293. X        if (screen != (struct screen_t *) 0) {
  1294. X            for (i=0 ; i < LINES ; i++) {
  1295. X                if (screen[i].col != (char *) 0) {
  1296. X                    free ((char *) screen[i].col);
  1297. X                    screen[i].col = (char *) 0;
  1298. X                }
  1299. X            }    
  1300. X
  1301. X            free ((char *) screen);
  1302. X            screen = (struct screen_t *) 0;
  1303. X        }
  1304. X    }
  1305. X}
  1306. X
  1307. X
  1308. Xvoid free_all_arrays ()
  1309. X{
  1310. X    hash_reclaim ();
  1311. X    
  1312. X    init_screen_array (FALSE);
  1313. X
  1314. X    free_art_array ();
  1315. X
  1316. X    if (arts != (struct article_t *) 0) {
  1317. X        free ((char *) arts);
  1318. X        arts = (struct article_t *) 0;
  1319. X    }
  1320. X
  1321. X    free_active_arrays ();
  1322. X
  1323. X    if (base != (long *) 0) {
  1324. X        free ((char *) base);
  1325. X        base = (long *) 0;
  1326. X    }
  1327. X
  1328. X    if (killf != (struct kill_t *) 0) {
  1329. X        free_kill_array ();
  1330. X        if (killf != (struct kill_t *) 0) {
  1331. X            free ((char *) killf);
  1332. X            killf = (struct kill_t *) 0;
  1333. X        }
  1334. X    }
  1335. X
  1336. X    if (save != (struct save_t *) 0) {
  1337. X        free_save_array ();
  1338. X        if (save != (struct save_t *) 0) {
  1339. X            free ((char *) save);
  1340. X            save = (struct save_t *) 0;
  1341. X        }
  1342. X    }
  1343. X}
  1344. X
  1345. X
  1346. Xvoid free_art_array ()
  1347. X{
  1348. X    register int i;
  1349. X
  1350. X    for (i=0 ; i < top ; i++) {
  1351. X        arts[i].artnum = 0L;
  1352. X        arts[i].thread = ART_EXPIRED;
  1353. X        arts[i].inthread = FALSE;
  1354. X        arts[i].unread = ART_UNREAD;
  1355. X        arts[i].killed = FALSE;
  1356. X        arts[i].tagged = FALSE;
  1357. X        arts[i].hot = FALSE;
  1358. X        arts[i].date[0] = '\0';
  1359. X        if (arts[i].part != (char *) 0) {
  1360. X            free ((char *) arts[i].part);
  1361. X            arts[i].part = (char *) 0;
  1362. X        }
  1363. X        if (arts[i].patch != (char *) 0) {
  1364. X            free ((char *) arts[i].patch);
  1365. X            arts[i].patch = (char *) 0;
  1366. X        }
  1367. X    }
  1368. X}
  1369. X
  1370. X
  1371. Xvoid free_active_arrays ()
  1372. X{
  1373. X    register int i;
  1374. X    
  1375. X    if (my_group != (int *) 0) {            /* my_group[] */
  1376. X        free ((char *) my_group);
  1377. X        my_group = (int *) 0;
  1378. X    }
  1379. X
  1380. X    if (unread != (int *) 0) {                /* unread[] */
  1381. X        free ((char *) unread);
  1382. X        unread = (int *) 0;
  1383. X    }
  1384. X
  1385. X    if (active != (struct group_t *) 0) {    /* active[] */
  1386. X        for (i=0 ; i < num_active ; i++) {
  1387. X            if (active[i].name != (char *) 0) {
  1388. X                free ((char *) active[i].name);
  1389. X                active[i].name = (char *) 0;
  1390. X            }
  1391. X            if (active[i].attribute.server != (char *) 0) {
  1392. X                free ((char *) active[i].attribute.server);
  1393. X                active[i].attribute.server = (char *) 0;
  1394. X            }
  1395. X            if (active[i].attribute.maildir != (char *) 0 ||
  1396. X                active[i].attribute.maildir != default_maildir) {
  1397. X                free ((char *) active[i].attribute.maildir);
  1398. X                active[i].attribute.maildir = (char *) 0;
  1399. X            }
  1400. X            if (active[i].attribute.savedir != (char *) 0 ||
  1401. X                active[i].attribute.savedir != default_savedir) {
  1402. X                free ((char *) active[i].attribute.savedir);
  1403. X                active[i].attribute.savedir = (char *) 0;
  1404. X            }
  1405. X            if (active[i].attribute.sigfile != (char *) 0 ||
  1406. X                active[i].attribute.sigfile != default_sigfile) {
  1407. X                free ((char *) active[i].attribute.sigfile);
  1408. X                active[i].attribute.sigfile = (char *) 0;
  1409. X            }
  1410. X        }
  1411. X        if (active != (struct group_t *) 0) {
  1412. X            free ((char *) active);
  1413. X            active = (struct group_t *) 0;
  1414. X        }
  1415. X    }
  1416. X}
  1417. X
  1418. X
  1419. Xvoid free_kill_array ()
  1420. X{
  1421. X    int i;
  1422. X    
  1423. X    for (i=0 ; i < kill_num ; i++) {
  1424. X        if (killf[i].kill_subj != (char *) 0) {
  1425. X            free ((char *) killf[i].kill_subj);
  1426. X            killf[i].kill_subj = (char *) 0;
  1427. X        }
  1428. X        if (killf[i].kill_from != (char *) 0) {
  1429. X            free ((char *) killf[i].kill_from);
  1430. X            killf[i].kill_from = (char *) 0;
  1431. X        }
  1432. X    }
  1433. X}
  1434. X
  1435. X
  1436. X/*
  1437. X *  reset save list array to 0 and free's all its allocated memory
  1438. X */
  1439. Xvoid free_save_array ()
  1440. X{
  1441. X    int i;
  1442. X    
  1443. X    for (i=0 ; i < save_num ; i++) {
  1444. X        if (save[i].subject != (char *) 0) {
  1445. X            free ((char *) save[i].subject);
  1446. X            save[i].subject = (char *) 0;
  1447. X        }
  1448. X        if (save[i].archive != (char *) 0) {
  1449. X            free ((char *) save[i].archive);
  1450. X            save[i].archive = (char *) 0;
  1451. X        }
  1452. X        if (save[i].dir != (char *) 0) {
  1453. X            free ((char *) save[i].dir);
  1454. X            save[i].dir = (char *) 0;
  1455. X        }
  1456. X        if (save[i].file != (char *) 0) {
  1457. X            free ((char *) save[i].file);
  1458. X            save[i].file = (char *) 0;
  1459. X        }
  1460. X        if (save[i].part != (char *) 0) {
  1461. X            free ((char *) save[i].part);
  1462. X            save[i].part = (char *) 0;
  1463. X        }
  1464. X        if (save[i].patch != (char *) 0) {
  1465. X            free ((char *) save[i].patch);
  1466. X            save[i].patch = (char *) 0;
  1467. X        }
  1468. X        save[i].index   = -1;
  1469. X        save[i].saved   = FALSE;
  1470. X        save[i].is_mailbox = FALSE;
  1471. X    }
  1472. X    
  1473. X    save_num = 0;
  1474. X}
  1475. X
  1476. X
  1477. Xchar *my_malloc (size)
  1478. X    unsigned size;
  1479. X{
  1480. X    char *p;
  1481. X
  1482. X    if ((p = (char *) calloc (1, (int) size)) == NULL) {
  1483. X        error_message (txt_out_of_memory, progname);
  1484. X        tin_done (1);
  1485. X    }
  1486. X    return p;
  1487. X}
  1488. X
  1489. X
  1490. Xchar *my_realloc (p, size)
  1491. X    char *p;
  1492. X    unsigned size;
  1493. X{
  1494. X    if (! p) {
  1495. X        p = (char *) calloc (1, (int) size);
  1496. X    } else {
  1497. X        p = (char *) realloc (p, (int) size);
  1498. X    }
  1499. X
  1500. X    if (! p) {
  1501. X        error_message (txt_out_of_memory, progname);
  1502. X        tin_done (1);
  1503. X    }
  1504. X    return p;
  1505. X}
  1506. END_OF_FILE
  1507.   if test 7630 -ne `wc -c <'memory.c'`; then
  1508.     echo shar: \"'memory.c'\" unpacked with wrong size!
  1509.   fi
  1510.   # end of 'memory.c'
  1511. fi
  1512. if test -f 'nntplib.h' -a "${1}" != "-c" ; then 
  1513.   echo shar: Will not clobber existing file \"'nntplib.h'\"
  1514. else
  1515.   echo shar: Extracting \"'nntplib.h'\" \(4658 characters\)
  1516.   sed "s/^X//" >'nntplib.h' <<'END_OF_FILE'
  1517. X/*
  1518. X *  Project   : tin - a threaded Netnews reader
  1519. X *  Module    : nntplib.h
  1520. X *  Author    : I.Lea
  1521. X *  Created   : 01-04-91
  1522. X *  Updated   : 10-05-92
  1523. X *  Notes     : nntp.h 1.5.11/1.6 with extensions for tin & CD-ROM
  1524. X *  Copyright : You may  freely  copy or  redistribute  this software,
  1525. X *              so  long as there is no profit made from its use, sale
  1526. X *              trade or  reproduction.  You may not change this copy-
  1527. X *              right notice, and it must be included in any copy made
  1528. X */
  1529. X
  1530. X#ifndef    NNTP_SERVER_FILE
  1531. X#    define    NNTP_SERVER_FILE    "/etc/nntpserver"
  1532. X#endif
  1533. X
  1534. X/*
  1535. X *  External routine declarations
  1536. X */
  1537. X
  1538. Xextern char *getserverbyfile();
  1539. Xextern int server_init();
  1540. Xextern int get_tcp_socket();
  1541. Xextern int handle_server_response();
  1542. Xextern void put_server();
  1543. Xextern int get_server();
  1544. Xextern void close_server();
  1545. X
  1546. X/*
  1547. X *  External file descriptors for the server connection
  1548. X */
  1549. X
  1550. Xextern FILE *ser_wr_fp;
  1551. X
  1552. X/*
  1553. X * Response codes for NNTP server
  1554. X *
  1555. X * @(#)Header: nntp.h,v 1.81 92/03/12 02:08:31 sob Exp $
  1556. X *
  1557. X * First digit:
  1558. X *
  1559. X *    1xx    Informative message
  1560. X *    2xx    Command ok
  1561. X *    3xx    Command ok so far, continue
  1562. X *    4xx    Command was correct, but couldn't be performed
  1563. X *        for some specified reason.
  1564. X *    5xx    Command unimplemented, incorrect, or a
  1565. X *        program error has occured.
  1566. X *
  1567. X * Second digit:
  1568. X *
  1569. X *    x0x    Connection, setup, miscellaneous
  1570. X *    x1x    Newsgroup selection
  1571. X *    x2x    Article selection
  1572. X *    x3x    Distribution
  1573. X *    x4x    Posting
  1574. X */
  1575. X
  1576. X#define    CHAR_INF    '1'
  1577. X#define    CHAR_OK        '2'
  1578. X#define    CHAR_CONT    '3'
  1579. X#define    CHAR_ERR    '4'
  1580. X#define    CHAR_FATAL    '5'
  1581. X
  1582. X#define    INF_HELP        100    /* Help text on way */
  1583. X#define    INF_AUTH        180    /* Authorization capabilities */
  1584. X#define    INF_DEBUG        199    /* Debug output */
  1585. X
  1586. X#define    OK_CANPOST        200    /* Hello; you can post */
  1587. X#define    OK_NOPOST        201    /* Hello; you can't post */
  1588. X#define    OK_SLAVE        202    /* Slave status noted */
  1589. X#define    OK_GOODBYE        205    /* Closing connection */
  1590. X#define    OK_GROUP        211    /* Group selected */
  1591. X#define    OK_GROUPS        215    /* Newsgroups follow */
  1592. X
  1593. X#define OK_XINDEX        218    /* Tin index follows */
  1594. X
  1595. X#define    OK_ARTICLE        220    /* Article (head & body) follows */
  1596. X#define    OK_HEAD            221    /* Head follows */
  1597. X#define    OK_BODY            222    /* Body follows */
  1598. X#define    OK_NOTEXT        223    /* No text sent -- stat, next, last */
  1599. X#define    OK_NEWNEWS        230    /* New articles by message-id follow */
  1600. X#define    OK_NEWGROUPS        231    /* New newsgroups follow */
  1601. X#define    OK_XFERED        235    /* Article transferred successfully */
  1602. X#define    OK_POSTED        240    /* Article posted successfully */
  1603. X#define    OK_AUTHSYS        280    /* Authorization system ok */
  1604. X#define    OK_AUTH            281    /* Authorization (user/pass) ok */
  1605. X#define OK_BIN            282    /* binary data follows */
  1606. X#define OK_SPLIST        283    /* spooldir list follows */
  1607. X#define OK_SPSWITCH        284    /* Switching to a different spooldir */
  1608. X#define OK_SPNOCHANGE        285    /* Still using same spooldir */
  1609. X#define OK_SPLDIRCUR        286    /* Current spooldir */
  1610. X#define OK_SPLDIRAVL        287    /* Available spooldir */
  1611. X#define OK_SPLDIRERR        288    /* Unavailable spooldir or invalid entry */
  1612. X
  1613. X#define CONT_XFER        335    /* Continue to send article */
  1614. X#define    CONT_POST        340    /* Continue to post article */
  1615. X#define    NEED_AUTHINFO        380    /* authorization is required */
  1616. X#define    NEED_AUTHDATA        381    /* <type> authorization data required */
  1617. X
  1618. X#define    ERR_GOODBYE        400    /* Have to hang up for some reason */
  1619. X#define    ERR_NOGROUP        411    /* No such newsgroup */
  1620. X#define    ERR_NCING        412    /* Not currently in newsgroup */
  1621. X
  1622. X#define ERR_XINDEX        418    /* No tin index for this group */
  1623. X
  1624. X#define    ERR_NOCRNT        420    /* No current article selected */
  1625. X#define    ERR_NONEXT        421    /* No next article in this group */
  1626. X#define    ERR_NOPREV        422    /* No previous article in this group */
  1627. X#define    ERR_NOARTIG        423    /* No such article in this group */
  1628. X#define ERR_NOART        430    /* No such article at all */
  1629. X#define ERR_GOTIT        435    /* Already got that article, don't send */
  1630. X#define ERR_XFERFAIL        436    /* Transfer failed */
  1631. X#define    ERR_XFERRJCT        437    /* Article rejected, don't resend */
  1632. X#define    ERR_NOPOST        440    /* Posting not allowed */
  1633. X#define    ERR_POSTFAIL        441    /* Posting failed */
  1634. X#define    ERR_NOAUTH        480    /* authorization required for command */
  1635. X#define    ERR_AUTHSYS        481    /* Authorization system invalid */
  1636. X#define    ERR_AUTHREJ        482    /* Authorization data rejected */
  1637. X#define ERR_INVALIAS        483    /* Invalid alias on spooldir cmd */
  1638. X#define ERR_INVNOSPDIR        484    /* No spooldir file found */
  1639. X
  1640. X#define    ERR_COMMAND        500    /* Command not recognized */
  1641. X#define    ERR_CMDSYN        501    /* Command syntax error */
  1642. X#define    ERR_ACCESS        502    /* Access to server denied */
  1643. X#define ERR_FAULT        503    /* Program fault, command not performed */
  1644. X#define    ERR_AUTHBAD        580    /* Authorization Failed */
  1645. X    
  1646. X/*
  1647. X * RFC 977 defines this; don't change it.
  1648. X */
  1649. X
  1650. X#define    NNTP_STRLEN        512
  1651. X
  1652. END_OF_FILE
  1653.   if test 4658 -ne `wc -c <'nntplib.h'`; then
  1654.     echo shar: \"'nntplib.h'\" unpacked with wrong size!
  1655.   fi
  1656.   # end of 'nntplib.h'
  1657. fi
  1658. if test -f 'signal.c' -a "${1}" != "-c" ; then 
  1659.   echo shar: Will not clobber existing file \"'signal.c'\"
  1660. else
  1661.   echo shar: Extracting \"'signal.c'\" \(8395 characters\)
  1662.   sed "s/^X//" >'signal.c' <<'END_OF_FILE'
  1663. X/*
  1664. X *  Project   : tin - a threaded Netnews reader
  1665. X *  Module    : signal.c
  1666. X *  Author    : I.Lea
  1667. X *  Created   : 01-04-91
  1668. X *  Updated   : 11-05-92
  1669. X *  Notes     : signal handlers for different modes and window resizing
  1670. X *  Copyright : (c) Copyright 1991-92 by Iain Lea
  1671. X *              You may  freely  copy or  redistribute  this software,
  1672. X *              so  long as there is no profit made from its use, sale
  1673. X *              trade or  reproduction.  You may not change this copy-
  1674. X *              right notice, and it must be included in any copy made
  1675. X */
  1676. X
  1677. X#include    "tin.h"
  1678. X
  1679. Xextern char *glob_art_group;
  1680. Xextern char *glob_group;
  1681. Xextern char *glob_page_group;
  1682. Xextern int glob_respnum;
  1683. Xextern int reread_active_file;
  1684. X
  1685. X#ifdef SIGTSTP
  1686. Xint do_sigtstp = 0;
  1687. X#endif
  1688. X
  1689. X
  1690. X#ifdef POSIX_JOB_CONTROL
  1691. X
  1692. X/*
  1693. X * for POSIX systems we know SIGTYPE  is void 
  1694. X */
  1695. Xvoid (*sigdisp(sig, func))()
  1696. X    int sig;
  1697. X    void (*func)();
  1698. X{
  1699. X    struct sigaction sa, osa;
  1700. X
  1701. X    sa.sa_handler = func;
  1702. X    sigemptyset (&sa.sa_mask);
  1703. X    sa.sa_flags = 0;
  1704. X#ifdef SA_RESTART
  1705. X    sa.sa_flags |= SA_RESTART;
  1706. X#endif
  1707. X    if (sigaction (sig, &sa, &osa) < 0) {
  1708. X        return ((void (*)(int))(-1));
  1709. X    }
  1710. X    return (osa.sa_handler);
  1711. X}
  1712. X
  1713. X#else
  1714. X
  1715. Xsigtype_t (*sigdisp(sig, func))()
  1716. X    int sig;
  1717. X    sigtype_t (*func)();
  1718. X{
  1719. X    return (signal (sig, func));
  1720. X}
  1721. X
  1722. X#endif
  1723. X
  1724. Xvoid set_signal_handlers ()
  1725. X{
  1726. X    signal (SIGINT, signal_handler);    /* ctrl-C */
  1727. X    signal (SIGQUIT, signal_handler);    /* ctrl-\ */
  1728. X    signal (SIGILL, signal_handler);
  1729. X    signal (SIGBUS, signal_handler);
  1730. X    signal (SIGSEGV, signal_handler);
  1731. X    signal (SIGPIPE, SIG_IGN);
  1732. X
  1733. X#ifdef SIGWINCH
  1734. X    if (debug == 2) {
  1735. X        wait_message ("SIGWINCH setting signal...");
  1736. X        sleep (2);
  1737. X    }
  1738. X    signal (SIGWINCH, main_resize);
  1739. X#endif
  1740. X
  1741. X#if defined(SIGTSTP) && ! defined(MINIX)
  1742. X    {
  1743. X        sigtype_t (*ptr)();
  1744. X        ptr = signal (SIGTSTP, SIG_DFL);
  1745. X        signal (SIGTSTP, ptr);
  1746. X        if (ptr != SIG_IGN) {
  1747. X            /*
  1748. X             *  SIGTSTP is ignored when starting from shells
  1749. X             *  without job-control
  1750. X             */
  1751. X            do_sigtstp = 1; 
  1752. X            signal (SIGTSTP, main_suspend);
  1753. X        }
  1754. X    }
  1755. X#endif
  1756. X}
  1757. X
  1758. X
  1759. Xvoid set_alarm_signal ()
  1760. X{
  1761. X#ifndef NO_RESYNC_ACTIVE_FILE
  1762. X    /*
  1763. X     * Only reread active file if news is not static (ie. CD-ROM)
  1764. X     */
  1765. X    if (strcmp (spooldir_alias, "news") == 0) {
  1766. X        signal (SIGALRM, signal_handler);
  1767. X        alarm (RESYNC_ACTIVE_SECS);
  1768. X    }    
  1769. X    reread_active_file = FALSE;
  1770. X#endif
  1771. X}
  1772. X
  1773. X
  1774. Xvoid signal_handler (sig)
  1775. X    int sig;
  1776. X{
  1777. X    char *sigtext;
  1778. X
  1779. X    switch (sig) {
  1780. X        case SIGINT:
  1781. X            if (update) {
  1782. X                sigtext = "SIGINT ";
  1783. X            } else {
  1784. X                signal (SIGINT, signal_handler);
  1785. X                return;
  1786. X            }
  1787. X            break;
  1788. X        case SIGQUIT:
  1789. X            sigtext = "SIGQUIT ";
  1790. X            break;
  1791. X        case SIGBUS:
  1792. X            sigtext = "SIGBUS ";
  1793. X            break;
  1794. X        case SIGSEGV:
  1795. X            sigtext = "SIGSEGV ";
  1796. X            break;
  1797. X#ifndef NO_RESYNC_ACTIVE_FILE
  1798. X        case SIGALRM:
  1799. X            set_alarm_signal ();
  1800. X            reread_active_file = TRUE;
  1801. X            return;
  1802. X#endif
  1803. X        default:
  1804. X            sigtext = "";
  1805. X            break;
  1806. X    }
  1807. X    Raw (FALSE);
  1808. X    EndWin ();
  1809. X    fprintf (stderr, "\n%s: signal handler caught signal %s(%d).\n",
  1810. X        progname, sigtext, sig);
  1811. X    if (sig != SIGINT && sig != SIGQUIT) {
  1812. X        fprintf (stderr, "%s: send a bug report to %s\n",
  1813. X            progname, BUG_REPORT_ADDRESS);
  1814. X    }
  1815. X    fflush (stderr);
  1816. X    exit (1);
  1817. X}
  1818. X
  1819. X
  1820. Xvoid set_win_size (num_lines, num_cols)
  1821. X    int *num_lines;
  1822. X    int *num_cols;
  1823. X{
  1824. X#ifdef TIOCGSIZE
  1825. X    struct ttysize win;
  1826. X#else
  1827. X#  ifdef TIOCGWINSZ
  1828. X    struct winsize win;
  1829. X#  endif
  1830. X#endif
  1831. X
  1832. X    init_screen_array (FALSE);        /* deallocate screen array */
  1833. X
  1834. X#ifdef TIOCGSIZE
  1835. X    if (ioctl (0, TIOCGSIZE, &win) == 0) {
  1836. X        if (win.ts_lines != 0) {
  1837. X            *num_lines = win.ts_lines - 1;
  1838. X        }
  1839. X        if (win.ts_cols != 0) {
  1840. X            *num_cols = win.ts_cols;
  1841. X        }
  1842. X    }
  1843. X#else
  1844. X#  ifdef TIOCGWINSZ
  1845. X    if (ioctl (0, TIOCGWINSZ, &win) == 0) {
  1846. X        if (win.ws_row != 0) {
  1847. X            *num_lines = win.ws_row - 1;
  1848. X        }
  1849. X        if (win.ws_col != 0) {
  1850. X            *num_cols = win.ws_col;
  1851. X        }
  1852. X    }
  1853. X#  endif
  1854. X#endif
  1855. X
  1856. X    init_screen_array (TRUE);        /* allocate screen array for resize */
  1857. X
  1858. X    set_subj_from_size (*num_cols);
  1859. X    
  1860. X    RIGHT_POS = *num_cols - 20;
  1861. X    MORE_POS  = *num_cols - 15;
  1862. X    NOTESLINES = *num_lines - INDEX_TOP - 1;
  1863. X    if (NOTESLINES <= 0) {
  1864. X        NOTESLINES = 1;
  1865. X    }
  1866. X}
  1867. X
  1868. X
  1869. Xvoid set_signals_art ()
  1870. X{
  1871. X#ifdef SIGTSTP
  1872. X    if (do_sigtstp) {
  1873. X        sigdisp (SIGTSTP, art_suspend);
  1874. X    }
  1875. X#endif
  1876. X
  1877. X#ifdef SIGWINCH
  1878. X    signal (SIGWINCH, art_resize);
  1879. X#endif
  1880. X}
  1881. X
  1882. X
  1883. Xvoid set_signals_group ()
  1884. X{
  1885. X#ifdef SIGTSTP
  1886. X    if (do_sigtstp) {
  1887. X        sigdisp (SIGTSTP, group_suspend);
  1888. X    }
  1889. X#endif
  1890. X
  1891. X#ifdef SIGWINCH
  1892. X    signal (SIGWINCH, group_resize);
  1893. X#endif
  1894. X}
  1895. X
  1896. X
  1897. Xvoid set_signals_page ()
  1898. X{
  1899. X#ifdef SIGTSTP
  1900. X    if (do_sigtstp) {
  1901. X        sigdisp (SIGTSTP, page_suspend);
  1902. X    }
  1903. X#endif
  1904. X
  1905. X#ifdef SIGWINCH
  1906. X    signal (SIGWINCH, page_resize);
  1907. X#endif
  1908. X}
  1909. X
  1910. X
  1911. Xvoid set_signals_select ()
  1912. X{
  1913. X#ifdef SIGTSTP
  1914. X    if (do_sigtstp) {
  1915. X        sigdisp (SIGTSTP, select_suspend);
  1916. X    }
  1917. X#endif
  1918. X
  1919. X#ifdef SIGWINCH
  1920. X    signal (SIGWINCH, select_resize);
  1921. X#endif
  1922. X}
  1923. X
  1924. X
  1925. Xvoid set_signals_spooldir ()
  1926. X{
  1927. X#ifdef SIGTSTP
  1928. X    if (do_sigtstp) {
  1929. X        sigdisp (SIGTSTP, spooldir_suspend);
  1930. X    }
  1931. X#endif
  1932. X
  1933. X#ifdef SIGWINCH
  1934. X    signal (SIGWINCH, spooldir_resize);
  1935. X#endif
  1936. X}
  1937. X
  1938. X
  1939. Xvoid set_signals_thread ()
  1940. X{
  1941. X#ifdef SIGTSTP
  1942. X    if (do_sigtstp) {
  1943. X        sigdisp (SIGTSTP, thread_suspend);
  1944. X    }
  1945. X#endif
  1946. X
  1947. X#ifdef SIGWINCH
  1948. X    signal (SIGWINCH, thread_resize);
  1949. X#endif
  1950. X}
  1951. X
  1952. X
  1953. X#ifdef SIGTSTP
  1954. X
  1955. X/* ARGSUSED0 */
  1956. Xvoid art_suspend (sig)
  1957. X    int sig;
  1958. X{
  1959. X    Raw (FALSE);
  1960. X    wait_message (txt_suspended_message);
  1961. X
  1962. X    kill (0, SIGSTOP);
  1963. X
  1964. X    sigdisp (SIGTSTP, art_suspend);
  1965. X
  1966. X    if (! update) {
  1967. X        Raw (TRUE);
  1968. X        art_resize (0);        
  1969. X    }
  1970. X}
  1971. X
  1972. X
  1973. X/* ARGSUSED0 */
  1974. Xvoid main_suspend (sig)
  1975. X    int sig;
  1976. X{
  1977. X    Raw (FALSE);
  1978. X    wait_message (txt_suspended_message);
  1979. X
  1980. X    kill (0, SIGSTOP);
  1981. X
  1982. X    sigdisp (SIGTSTP, main_suspend);
  1983. X
  1984. X    if (! update) {
  1985. X        Raw (TRUE);
  1986. X        main_resize (0);        
  1987. X    }
  1988. X}
  1989. X
  1990. X
  1991. X/* ARGSUSED0 */
  1992. Xvoid select_suspend (sig)
  1993. X    int sig;
  1994. X{
  1995. X    Raw (FALSE);
  1996. X    wait_message (txt_suspended_message);
  1997. X
  1998. X    kill (0, SIGSTOP);
  1999. X
  2000. X    sigdisp (SIGTSTP, select_suspend);
  2001. X
  2002. X    if (! update) {
  2003. X        Raw (TRUE);
  2004. X    }
  2005. X
  2006. X    select_resize (0);
  2007. X}
  2008. X
  2009. X
  2010. X/* ARGSUSED0 */
  2011. Xvoid spooldir_suspend (sig)
  2012. X    int sig;
  2013. X{
  2014. X    Raw (FALSE);
  2015. X    wait_message (txt_suspended_message);
  2016. X
  2017. X    kill (0, SIGSTOP);
  2018. X
  2019. X    sigdisp (SIGTSTP, spooldir_suspend);
  2020. X
  2021. X    if (! update) {
  2022. X        Raw (TRUE);
  2023. X    }
  2024. X
  2025. X    spooldir_resize (0);
  2026. X}
  2027. X
  2028. X
  2029. X/* ARGSUSED0 */
  2030. Xvoid group_suspend (sig)
  2031. X    int sig;
  2032. X{
  2033. X    Raw (FALSE);
  2034. X    wait_message (txt_suspended_message);
  2035. X
  2036. X    kill (0, SIGSTOP);
  2037. X
  2038. X    sigdisp (SIGTSTP, group_suspend);
  2039. X
  2040. X    if (! update) {
  2041. X        Raw (TRUE);
  2042. X    }
  2043. X
  2044. X    group_resize (0);        
  2045. X}
  2046. X
  2047. X
  2048. X/* ARGSUSED0 */
  2049. Xvoid page_suspend (sig)
  2050. X    int sig;
  2051. X{
  2052. X
  2053. X    Raw (FALSE);
  2054. X    wait_message (txt_suspended_message);
  2055. X
  2056. X    kill (0, SIGSTOP);
  2057. X
  2058. X    sigdisp (SIGTSTP, page_suspend);
  2059. X
  2060. X    mail_setup ();
  2061. X
  2062. X    if (! update) {
  2063. X        Raw (TRUE);
  2064. X    }
  2065. X
  2066. X    page_resize (0);        
  2067. X}
  2068. X
  2069. X
  2070. X/* ARGSUSED0 */
  2071. Xvoid thread_suspend (sig)
  2072. X    int sig;
  2073. X{
  2074. X    Raw (FALSE);
  2075. X    wait_message (txt_suspended_message);
  2076. X
  2077. X    kill (0, SIGSTOP);
  2078. X
  2079. X    sigdisp (SIGTSTP, thread_suspend);
  2080. X
  2081. X    if (! update) {
  2082. X        Raw (TRUE);
  2083. X    }
  2084. X    
  2085. X    thread_resize (0);        
  2086. X}
  2087. X
  2088. X
  2089. X/* ARGSUSED0 */
  2090. Xvoid rcfile_suspend (sig)
  2091. X    int sig;
  2092. X{
  2093. X    Raw (FALSE);
  2094. X    wait_message (txt_suspended_message);
  2095. X
  2096. X    kill (0, SIGSTOP);
  2097. X
  2098. X    sigdisp (SIGTSTP, rcfile_suspend);
  2099. X
  2100. X    Raw (TRUE);
  2101. X    show_rcfile_menu ();    
  2102. X}
  2103. X
  2104. X#endif /* SIGTSTP */    
  2105. X
  2106. X
  2107. X/* ARGSUSED0 */
  2108. Xvoid art_resize (sig)
  2109. X    int sig;
  2110. X{
  2111. X    char buf[LEN];
  2112. X
  2113. X#ifdef SIGWINCH
  2114. X    set_win_size (&LINES, &COLS);
  2115. X    signal (SIGWINCH, art_resize);
  2116. X#endif
  2117. X    mail_setup ();
  2118. X    ClearScreen ();
  2119. X    sprintf (buf, txt_group, glob_art_group);
  2120. X    wait_message (buf);
  2121. X}
  2122. X
  2123. X
  2124. X/* ARGSUSED0 */
  2125. Xvoid main_resize (sig)
  2126. X    int sig;
  2127. X{
  2128. X#ifdef SIGWINCH
  2129. X    set_win_size (&LINES, &COLS);
  2130. X    signal (SIGWINCH, main_resize);
  2131. X#endif
  2132. X    mail_setup ();
  2133. X}
  2134. X
  2135. X
  2136. X/* ARGSUSED0 */
  2137. Xvoid select_resize (sig)
  2138. X    int sig;
  2139. X{
  2140. X#ifdef SIGWINCH
  2141. X    set_win_size (&LINES, &COLS);
  2142. X    signal (SIGWINCH, select_resize);
  2143. X#endif
  2144. X    
  2145. X#ifndef USE_CLEARSCREEN
  2146. X    ClearScreen ();
  2147. X#endif
  2148. X    mail_setup ();
  2149. X    group_selection_page ();
  2150. X}
  2151. X
  2152. X
  2153. X/* ARGSUSED0 */
  2154. Xvoid spooldir_resize (sig)
  2155. X    int sig;
  2156. X{
  2157. X#ifdef SIGWINCH
  2158. X    set_win_size (&LINES, &COLS);
  2159. X    signal (SIGWINCH, spooldir_resize);
  2160. X#endif
  2161. X    
  2162. X#ifndef USE_CLEARSCREEN
  2163. X    ClearScreen ();
  2164. X#endif
  2165. X    mail_setup ();
  2166. X    show_spooldir_page ();
  2167. X}
  2168. X
  2169. X
  2170. X/* ARGSUSED0 */
  2171. Xvoid group_resize (sig)
  2172. X    int sig;
  2173. X{
  2174. X#ifdef SIGWINCH
  2175. X    set_win_size (&LINES, &COLS);
  2176. X    signal (SIGWINCH, group_resize);
  2177. X#endif
  2178. X    
  2179. X#ifndef USE_CLEARSCREEN
  2180. X    ClearScreen ();
  2181. X#endif
  2182. X    mail_setup ();
  2183. X    show_group_page (glob_group);
  2184. X}
  2185. X
  2186. X
  2187. X/* ARGSUSED0 */
  2188. Xvoid page_resize (sig)
  2189. X    int sig;
  2190. X{
  2191. X#ifdef SIGWINCH
  2192. X    set_win_size (&LINES, &COLS);
  2193. X    signal (SIGWINCH, page_resize);
  2194. X#endif
  2195. X    
  2196. X#ifndef USE_CLEARSCREEN
  2197. X    ClearScreen ();
  2198. X#endif
  2199. X    redraw_page (glob_respnum, glob_page_group);
  2200. X}
  2201. X
  2202. X
  2203. X/* ARGSUSED0 */
  2204. Xvoid thread_resize (sig)
  2205. X    int sig;
  2206. X{
  2207. X#ifdef SIGWINCH
  2208. X    set_win_size (&LINES, &COLS);
  2209. X    signal (SIGWINCH, thread_resize);
  2210. X#endif
  2211. X    
  2212. X#ifndef USE_CLEARSCREEN
  2213. X    ClearScreen ();
  2214. X#endif
  2215. X    mail_setup ();
  2216. X    show_thread_page ();
  2217. X}
  2218. END_OF_FILE
  2219.   if test 8395 -ne `wc -c <'signal.c'`; then
  2220.     echo shar: \"'signal.c'\" unpacked with wrong size!
  2221.   fi
  2222.   # end of 'signal.c'
  2223. fi
  2224. echo shar: End of archive 13 \(of 14\).
  2225. cp /dev/null ark13isdone
  2226. MISSING=""
  2227. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
  2228.     if test ! -f ark${I}isdone ; then
  2229.     MISSING="${MISSING} ${I}"
  2230.     fi
  2231. done
  2232. if test "${MISSING}" = "" ; then
  2233.     echo You have unpacked all 14 archives.
  2234.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2235. else
  2236.     echo You still must unpack the following archives:
  2237.     echo "        " ${MISSING}
  2238. fi
  2239. exit 0
  2240. exit 0 # Just in case...
  2241.