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

  1. Newsgroups: comp.sources.misc
  2. From: iain%anl433.uucp@germany.eu.net (Iain J. Lea)
  3. Subject:  v30i011:  tin - threaded full screen newsreader, Part11/14
  4. Message-ID: <1992May20.172831.29872@sparky.imd.sterling.com>
  5. X-Md4-Signature: 1b59fca5dabf547e426085c05a927621
  6. Date: Wed, 20 May 1992 17:28:31 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 11
  11. Archive-name: tin/part11
  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:  FAQ curses.c init.c open.c
  22. # Wrapped by kent@sparky on Tue May 19 13:38:05 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 11 (of 14)."'
  26. if test -f 'FAQ' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'FAQ'\"
  28. else
  29.   echo shar: Extracting \"'FAQ'\" \(14588 characters\)
  30.   sed "s/^X//" >'FAQ' <<'END_OF_FILE'
  31. X[ NOTE: IGNORE THIS DOCUMENT UNTIL A LATER DATE - IT IS NOT COMPLETE - Iain ]
  32. X[ THIS DOCUMENT USES THE NN FAQ AS ITS BASE WITH PERMISSION FROM BILL WOHLER]
  33. X
  34. XSubject: TIN Frequently Asked Questions (FAQ) with Answers
  35. XSummary: This document answers Frequently Asked Questions about TIN,
  36. X     a menu-based, point and shoot, USENET news reader.
  37. XKeywords: FAQ tin news question answer newsrc digest article nntp
  38. X          newsgroup cancel mail signature header netnews usenet kill
  39. XFollowup-To: poster
  40. X
  41. XArchive-name: tin-faq/part01
  42. XLast-modified: 01/05/92
  43. X  
  44. X  This is a living list of frequently asked questions on the Usenet
  45. X  news reader TIN (Tass & Iain's Newsreader). The point of this is to
  46. X  circulate existing information, and avoid rehashing old answers.
  47. X  Better to build on top than start again.  Please read this document
  48. X  before posting to a newsgroup concerning tin.
  49. X  
  50. X  This article is posted monthly.  If it has already expired and
  51. X  you're not reading this, you can hope that you saved the last bit of
  52. X  question 3 so that you can get a copy yourself.
  53. X  
  54. X  When someone posts a frequently-asked question, I will point out to
  55. X  them that the answer is here to ensure that everybody gets their
  56. X  question answered fully and to eliminate unnecessary traffic in this
  57. X  newsgroup.  Posted answers that are in the FAQ are just as annoying as
  58. X  posted questions that are in the FAQ!
  59. X  
  60. X  Your comments, additions and fixes to this list are welcome: please
  61. X  send them to Iain Lea (iain%anl433.uucp@Germany.EU.net).  Complete, 
  62. X  accurate and grammatically correct answers are appreciated to reduce 
  63. X  the time I have to take to test or edit your answers.
  64. X  
  65. X
  66. XFrom: Preface
  67. XSubject: Table of Contents
  68. X
  69. XLegend: + new, - deleted, ! changed
  70. X
  71. XIntroductory
  72. X
  73. X 1.  Why should I use tin?
  74. X 2.  Where can I get tin?
  75. X 3.  What references exist for tin?
  76. X 4.  How should I report bugs?
  77. X 5.  How can I convert from rn to nn?
  78. X 6.  How can I make life simpler when starting nn for the first time?
  79. X 7.  Is there an X interface to tin?
  80. X
  81. XBuilding tin
  82. X
  83. X 10. What machines does tin run on?
  84. X
  85. XUsing tin
  86. X
  87. X 20. How do I save files that I can read later with MH, elm, Mail, ...?
  88. X 21. How come nn doesn't show the Lines count?
  89. X 22. How can I find all articles having to do with a certain topic?
  90. X 23. How can I set a different Organization name?
  91. X 24. Can all non-selected subjects be automatically placed in my kill file?
  92. X 25. Can I automatically kill articles based on the Newsgroups header?
  93. X 26. How can I select one article in a thread with auto-select-subject set?
  94. X 27. Is there a library of macros and other nn features?
  95. X 28. Can one search for patterns in the entire article from the menu?
  96. X 29. How can I remove old articles from folders?
  97. X 30. What's the best way to save multi-part articles?
  98. X 31. When saving in +a/b/c keeps you from saving in +a/b.
  99. X 32. Can I use my mailer to send mail?
  100. X 33. How can I see the original article with the current subject?
  101. X 34. Can I choose newsgroups as I do articles, ie. with a menu?
  102. X 35. How can I post prewritten articles with nn?
  103. X 36. How do I eliminate double signatures?
  104. X 37. How can I make mail replies go to a different machine?
  105. X 38. How come more articles get selected than I expect?  
  106. X 39. Any plans for trn-ish thread following?  
  107. X 40. Setting new-group-action to "ask before adding" doesn't work.
  108. X 41. Why does nn crash when a letter one past the highest letter is selected?
  109. X 42. Why do articles without a Lines header appear empty?
  110. X
  111. XFrom: Preface
  112. XSubject: Viewing This Article
  113. X  
  114. X  To skip to a particular question numbered xx, use "/^F.*xx" with most
  115. X  pagers.  In GNU Emacs type "M-C-s ^F.*xx", (or C-r to search backwards),
  116. X  followed by ESC to end the search.
  117. X  
  118. X  To skip to new or changed questions, use "/^F.*[!+]" with most pagers and
  119. X  "M-C-s ^F.*[!+]" in GNU Emacs.
  120. X  
  121. X  This article is in digest format.  Nn may have already broken this
  122. X  message into separate articles; if not, then type "G %".  In rn, use
  123. X  ^G to skip sections.
  124. X  
  125. X  To get an overview of just the questions in GNU Emacs, type "M-2 C-x $".
  126. X  Use "C-x $" to display the text again ("M-0 C-l C-x $" ensures that
  127. X  the current cursor location remains on the screen).
  128. X  
  129. X  Contributer's E-Mail addresses can be found at the bottom of this article.
  130. X  
  131. X  
  132. XFrom: Intro-1
  133. XSubject: Why should I use tin?
  134. X  
  135. X  tin is a menu based (point and shoot) netnews reader with a complete
  136. X  set of features especially suited to the novice user.  Since its first
  137. X  release in Aug 1991 it has started to replace rn and other well-known
  138. X  news readers at many sites.
  139. X  
  140. X  Some of the key features of tin are:
  141. X  
  142. X  * Automatic kill & selection of articles based on subject or author.
  143. X  
  144. X  *  Based more on Notes and tass than rn type newreaders.
  145. X  *  Full screen, easy to use with on-line help at all levels.
  146. X  *  Reads news locally (ie. /usr/spool/news) and/or via NNTP/INN.
  147. X  *  Threads on Subject: and/or Archive-name: mail headers.
  148. X  *  Four different operating levels:
  149. X     -  Group selection level
  150. X     -  Thread selection level
  151. X     -  Article selection level
  152. X     -  Article viewer
  153. X  *  Same interface to mail, pipe, print & save articles.
  154. X  *  Auto unpacking of multi-part shar & uuencoded articles.
  155. X  *  Auto kill & selection of articles based on subject or author.
  156. X  *  Batch mode to mail/save new news when user is on holiday.
  157. X  *  Builtin NNTP mini-inews & clientlib.c
  158. X  *  NNTP extensions XUSER & XINDEX allow central index files. 
  159. X  
  160. X  
  161. XFrom: Intro-2
  162. XSubject: Where can I get tin?
  163. X  
  164. X  The current version of tin is 1.1 PL3.
  165. X  
  166. X  via anonymous ftp:
  167. X    ftp.Germany.EU.net []
  168. X      pub/news/tin/tin.tar.Z            ~250k
  169. X  
  170. X  via mail:
  171. X    Send a note to ftpmail@decwrl.dec.com whose body contains "help"
  172. X    on a line by itself get information on getting ftp sources by
  173. X    mail.
  174. X  
  175. X  
  176. XFrom: Intro-3 !
  177. XSubject: What references exist for tin?
  178. X  
  179. X  Usenet:
  180. X    news.software.readers
  181. X    news.software.notes
  182. X  
  183. X  Mailing list:
  184. X    none
  185. X  
  186. X  
  187. XFrom: Intro-4
  188. XSubject: How should I report bugs?
  189. X  
  190. X  Either mail them to  iain%anl433.uucp@Germany.EU.net  and be sure
  191. X  to include the version number as well as what hardware and operating
  192. X  system you are using, or better yet, use the 'B' bug command within tin.
  193. X  
  194. X  
  195. XFrom: Intro-6
  196. XSubject: How can I make life simpler when starting tin for the first time?
  197. X  
  198. X  tin -c
  199. X  sysadmin can set interesting groups in LIBDIR/subscriptions
  200. X  Subscribe/unsubscribe from uninteresting groups with sSuU commands at
  201. X  group selection level.  
  202. X
  203. X
  204. XFrom: Intro-7 
  205. XSubject: Is there an X interface to tin?
  206. X  
  207. X  No.
  208. X  
  209. X  
  210. XFrom: Building nn-10
  211. XSubject: What machines does tin run on?
  212. X
  213. X  * 386/486 PC & Xenix 2.3.2/SCO SysVR3.2/ISC SysVR3.2/ATT SysVr4.0
  214. X    386 PC & Minix 386 
  215. X    Amdahl & SysVR3
  216. X  * Apollo DN4500 & DomainOS 10.3
  217. X    Apricot VX/FT & SCO 3.2.2
  218. X    Atari STe & Minix 1.5.10.3b
  219. X    Convex C220 & Convex Un*x
  220. X  * Dec 5000/Vax & Ultrix 4.1/4.2
  221. X    DIAB DS90 & D-NIX 5.3
  222. X  * DG Aviion 300 & DG-UX 4.30
  223. X    Harris HCX & CX/UX
  224. X    HP 720/845 & HP-UX 7.0
  225. X    IBM RS/6000 & AIX 3.1.5
  226. X    ICL DRS6000 & SysVR4.0 
  227. X    NCR Tower & SysV
  228. X    Powerbook 140 & MacMinix
  229. X    Sequent S81 & PTX 1.3 / Dynix
  230. X    SGI 4D/35 & IRIX 4.0.1
  231. X  * SNI MX300/MX500 & Sinix 5.22/5.23/5.24/5.4
  232. X  * Sony News & NewsOS 4.1
  233. X  * Sun 3/4/IPC/SS1/SS2 & SunOS 4.0.3/4.1/4.1.1 
  234. X  * Vax 11/785 & BSD 4.3
  235. X
  236. X  * donates that the author has compiled & used tin on that machine.
  237. X
  238. X  
  239. XFrom: Using nn-22
  240. XSubject: How can I find all articles having to do with a certain topic?
  241. X  
  242. X  nngrab invokes nn on all articles whose subject or keyword fields
  243. X  contain a desired keyword.  This shows one how important it is to
  244. X  use descriptive subjects and keywords when posting articles.  For
  245. X  more information, read the manual page.
  246. X  
  247. X  
  248. XFrom: Using nn-23 
  249. XSubject: How can I set a different Organization name?
  250. X  
  251. X  This header (along with the Reply-To:) are user-specified in the
  252. X  init file.  An init file may include the lines:
  253. X  
  254. X  set mail-header Reply-To: steven@Transact.COM;Organization: Transact Software
  255. X  set news-header Reply-To: steven@Transact.COM;Organization: Transact Software
  256. X  
  257. X  You can include any headers that you want in the headers, either in
  258. X  mail or news postings, and they may be different.  --Steven M. List
  259. X  
  260. X  A Reply-To header is useful when your system generates either an
  261. X  unwanted or blatantly wrong return address for you.  If this header
  262. X  is present, then mailers use it instead of the system generated From
  263. X  header.  --Bill Wohler
  264. X  
  265. X  
  266. XFrom: Using nn-28
  267. XSubject: Is the Xref: header used to mark crosposted articles read?
  268. X  
  269. X  No. On the TODO list.
  270. X  
  271. X  
  272. XFrom: Using nn-28
  273. XSubject: Can one search for patterns in the entire article from the menu?
  274. X  
  275. X  No.
  276. X  
  277. X  
  278. XFrom: Using nn-29
  279. XSubject: How can I remove old articles from folders?
  280. X  
  281. X  Just open the folder in the usual way and C(ancel) the articles you
  282. X  want to remove from the folder.  When you leave the folder, nn will
  283. X  rewrite the folder with the "cancel"ed articles removed.  --Kim Storm
  284. X  
  285. X  
  286. XFrom: Using nn-30
  287. XSubject: What's the best way to save multi-part articles?
  288. X  
  289. X  This is VERY easy - all you have to do is to save the articles from
  290. X  the menu, e.g.
  291. X  
  292. X    W(rite) +file.* a b c d... <space>
  293. X  
  294. X  where a b c d... are the articles on the menu you want to save.  You
  295. X  can also save the selected articles on the menu with * (only on
  296. X  current page) or + (on all menu pages).  --Kim Storm
  297. X  
  298. X  
  299. XFrom: Using nn-31 
  300. XSubject: When saving in +a/b/c keeps you from saving in +a/b.
  301. X  
  302. X  This happens when default-save-file is $F.  Try changing
  303. X  default-save-file to $F/$N (my favorite) to get, for example,
  304. X  +news/software/nn/1022, or $G to put everything in
  305. X  +news.software.nn.  Finally, if you really did want the behavior of
  306. X  +$F, a compromise would be to use +$F. (Andrew's favorite) instead
  307. X  (one can use anything other than '.'). --Bill Wohler & Andrew Swann
  308. X  
  309. X  Alternatively, use +$F/$L, to place articles for news.software.nn in
  310. X  the file +/news/software/nn/nn.  This has two advantages:
  311. X  1) You can later read through the folder "nn" and save some of the
  312. X    articles under new folder names having to do with the topic.  For
  313. X    example, you might save auto-select topics under +$F/auto-sel,
  314. X    that is, +/news/software/nn/auto-sel.
  315. X  2) If at a later date, a new newsgroup is added below nn, articles
  316. X    can still be saved under that subgroup since +/news/software/nn is
  317. X    already a directory, not a folder.  --Harry Herman
  318. X  
  319. X  
  320. XFrom: Using nn-33 
  321. XSubject: How can I see the original article with the current subject?
  322. X  
  323. X  While reading an article, use "G RET RET RET".  --Bill Wohler
  324. X  
  325. X  
  326. XFrom: Using nn-35
  327. XSubject: How can I post prewritten articles with nn?
  328. X  
  329. X  nnpost will construct the header for the posted article, so it
  330. X  requires several arguments to be specified before the article is
  331. X  posted, e.g. a newsgroup name and a subject.  If some arguments are
  332. X  missing, nnpost will prompt for the missing arguments.
  333. X  
  334. X  If your pre-written article includes a full header, then you should
  335. X  not use nnpost; instead you should feed the article to "inews -h"
  336. X  directly (which is what nnpost does after building the header from
  337. X  the arguments).  --Kim Storm
  338. X  
  339. X  
  340. XFrom: Using nn-36
  341. XSubject: How do I eliminate double signatures?
  342. X  
  343. X  Double signatures occur when both nn and inews append your .signature
  344. X  file. 
  345. X  
  346. X  If you want inews to append your .signature file, use:
  347. X  
  348. X    unset append-signature-post
  349. X  
  350. X  If you want nn to append your .signature file, you can copy nn's aux
  351. X  file (ie. /usr/local/lib/nn/aux) to your .nn directory and set the
  352. X  mail-script and news-script variables to ~/.nn/aux.  In your copy of
  353. X  the aux script, you can either specify a different place for your
  354. X  .signature file (like $HOME/.nn/signature) or you can get fancy: you
  355. X  can use specific .signatures for certain groups, or use the output of
  356. X  a program.
  357. X  
  358. X  
  359. XFrom: Using nn-37 
  360. XSubject: How can I make mail replies go to a different machine?
  361. X  
  362. X  See "How can I set a different Organization name?"
  363. X  
  364. X  
  365. XFrom: Using nn-39 
  366. XSubject: Any plans for trn-ish thread following?  
  367. X  
  368. X  At the moment, no.
  369. X  
  370. X  
  371. XFrom: Using nn-42 +  
  372. XSubject: Why do articles without a Lines header appear empty?
  373. X  
  374. X  I discovered that this problem only shows up if you have
  375. X  header-lines set to a string that includes "L".  I suspect having
  376. X  the line count patch sets something that makes nn think there is a
  377. X  Lines header and then the header-string is telling it to display the
  378. X  Lines header but there isn't one and things get messed up.  --Gary
  379. X  Morris
  380. X  
  381. X  
  382. XFrom: Appendix
  383. XSubject: Glossary
  384. X  
  385. X  NNTP        Network News Transport Protocol (see RFC 977)
  386. X  
  387. X  
  388. XFrom: Appendix
  389. XSubject: Acknowledgements
  390. X
  391. XI'd like to thank the following people for providing ideas on the
  392. Xlayout of this article:
  393. X
  394. XJoe Wells <jbw@bigbird.bu.edu>          Richard M. Stallman <rms@gnu.ai.mit.edu>
  395. XDavid Elliott <dce@smsc.sony.com>     Tom Christiansen <tchrist@convex.com>
  396. XEugene N. Miya <eugene@nas.nasa.gov>
  397. X
  398. X
  399. XWe are also grateful to the following individuals that have provided
  400. Xanswers or other information to make this a better document.  The
  401. Xactual list is undoubtedly larger.
  402. X
  403. XF.F. Jacot Guillarmod <ccfj@hippo.ru.ac.za>  Mr. Kim F. Storm <storm@texas.dk>
  404. XSteven M. List <itkin@mrspoc.transact.com>   Steven Grady <grady@fx.com>
  405. XRichard M. Mathews <richard@locus.com>         Ian Taylor <ian@airs.com>
  406. XDave Shaver <shaver@convex.com>             Paul Eggert <eggert@twinsun.com>
  407. XMichael Rawdon <rawdon@rex.cs.tulane.edu>    Joerg Napp <napp@uni-paderborn.de>
  408. XDave Hayes <dave@elxr.jpl.nasa.gov>         Gary Morris <garym@telesoft.com>
  409. XAndrew Swann <swann@imada.ou.dk>         Alexis Rosen <alexis@panix.com>
  410. XDavid B. Thomas <dt@yenta.alb.nm.us>         Jeffery Small <jeff@cjsa.wa.com>
  411. XRichard Reiner <rreiner@nexus.yorku.ca>         Max Heffler <max@compaq.com>
  412. XHarry Herman <herman@corpane.uucp>         Luc Rooijakkers <lwj@cs.kun.nl>
  413. XPaul Bickerstaff <pbickers@tamaluit.phys.uidaho.edu>
  414. X
  415. X
  416. XFrom: Appendix
  417. XSubject: Warranty
  418. X
  419. X[The following statement epitomizes the ridiculous state of 
  420. Xaffairs in America and can be ignored outside of America...]
  421. X
  422. XNo Warranty: Because this article is provided free of charge as a
  423. Xservice to news.software.readers readers, we provide absolutely no
  424. Xwarranty, to the extent permitted by applicable state law.  This
  425. Xarticle is provided "as is" without warranty of any kind, either
  426. Xexpressed or implied, including, but not limited to, the implied
  427. Xwarranties of merchantability and fitness for a particular purpose.
  428. XShould the information prove defective, you assume the cost of all
  429. Xnecessary servicing, repair or correction.
  430. END_OF_FILE
  431.   if test 14588 -ne `wc -c <'FAQ'`; then
  432.     echo shar: \"'FAQ'\" unpacked with wrong size!
  433.   fi
  434.   # end of 'FAQ'
  435. fi
  436. if test -f 'curses.c' -a "${1}" != "-c" ; then 
  437.   echo shar: Will not clobber existing file \"'curses.c'\"
  438. else
  439.   echo shar: Extracting \"'curses.c'\" \(7985 characters\)
  440.   sed "s/^X//" >'curses.c' <<'END_OF_FILE'
  441. X/*
  442. X *  Project   : tin - a threaded Netnews reader
  443. X *  Module    : curses.c
  444. X *  Author    : D.Taylor & I.Lea
  445. X *  Created   : ??-??-86
  446. X *  Updated   : 03-04-92
  447. X *  Notes     : This is a screen management library borrowed with permission
  448. X *              from the Elm mail system (a great mailer--I highly recommend
  449. X *              it!).This library was hacked to provide what tin needs.
  450. X *  Copyright : Copyright (c) 1986-92 Dave Taylor & Iain Lea
  451. X *              The Elm Mail System  -  $Revision: 2.1 $   $State: Exp $
  452. X */
  453. X
  454. X#include <stdio.h>
  455. X#include <curses.h>
  456. X#include <sys/errno.h>
  457. X
  458. X#define DEFAULT_LINES_ON_TERMINAL    24
  459. X#define DEFAULT_COLUMNS_ON_TERMINAL    80
  460. X
  461. Xint LINES = 23;
  462. Xint COLS  = 80;
  463. Xint inverse_okay = TRUE;
  464. Xstatic int _inraw = FALSE;                  /* are we IN rawmode?    */
  465. X
  466. X
  467. X#ifndef INDEX_DAEMON
  468. X
  469. X#define        BACKSPACE    '\b'
  470. X#define        VERY_LONG_STRING    2500
  471. X
  472. X#ifdef BSD 
  473. X#    ifndef BSD4_1
  474. X#        include <sgtty.h>
  475. X#    else
  476. X#        include <termio.h>
  477. X#    endif
  478. X#else
  479. X#    ifndef SYSV
  480. X#        ifndef MINIX
  481. X#            ifdef sinix
  482. X#                include <termios.h>
  483. X#            else
  484. X#                include <termio.h>
  485. X#            endif
  486. X#        else
  487. X#            include <sgtty.h>
  488. X#        endif
  489. X#    endif
  490. X#endif
  491. X
  492. X#define TTYIN    0
  493. X
  494. X#ifdef SHORTNAMES
  495. X# define _clearinverse    _clrinv
  496. X# define _cleartoeoln    _clrtoeoln
  497. X# define _cleartoeos    _clr2eos
  498. X#endif
  499. X
  500. X#if defined(BSD) || defined(MINIX)
  501. X#    define TCGETA    TIOCGETP
  502. X#    define TCSETAW    TIOCSETP
  503. X
  504. Xstruct sgttyb _raw_tty,
  505. X          _original_tty;
  506. X#else
  507. X#    ifdef sinix
  508. X#        ifndef TCGETA
  509. X#            define TCGETA    STCGETA
  510. X#        endif
  511. X#        ifndef TCSETA
  512. X#            define TCSETAW    STCSETAW
  513. X#        endif
  514. Xstruct termios _raw_tty, 
  515. X              _original_tty;
  516. X#    else
  517. Xstruct termio _raw_tty, 
  518. X              _original_tty;
  519. X#    endif
  520. X#endif
  521. X
  522. Xstatic char *_clearscreen, *_moveto, *_cleartoeoln, *_cleartoeos,
  523. X            *_setinverse, *_clearinverse, *_setunderline, *_clearunderline,
  524. X            *_terminalinit, *_terminalend;
  525. X
  526. Xstatic int _lines,_columns;
  527. X
  528. Xstatic char _terminal[1024];              /* Storage for terminal entry */
  529. Xstatic char _capabilities[1024];           /* String for cursor motion */
  530. X
  531. Xstatic char *ptr = _capabilities;    /* for buffering         */
  532. X
  533. Xint    outchar ();            /* char output for tputs */
  534. Xextern char    *tgetstr ();        /* Get termcap capability */
  535. Xextern char    *tgoto ();        /* and the goto stuff    */
  536. X
  537. X#endif /* INDEX_DAEMON */
  538. X
  539. X#include "tin.h"
  540. X
  541. X
  542. Xint InitScreen ()
  543. X{
  544. X#ifndef INDEX_DAEMON
  545. X
  546. X    extern int tgetent();      /* get termcap entry */
  547. X    char termname[40], *p;
  548. X    
  549. X    if ((p = (char *) getenv ("TERM")) == NULL) {
  550. X        fprintf (stderr, "%s: TERM variable must be set to use screen capabilities\n", progname);
  551. X        return (FALSE);
  552. X    }
  553. X    if (strcpy (termname, p) == NULL) {
  554. X        fprintf (stderr,"%s: Can't get TERM variable\n", progname);
  555. X        return (FALSE);
  556. X    }
  557. X    if (tgetent (_terminal, termname) != 1) {
  558. X        fprintf (stderr,"%s: Can't get entry for TERM\n", progname);
  559. X        return (FALSE);
  560. X    }
  561. X
  562. X    /* load in all those pesky values */
  563. X    _clearscreen    = tgetstr ("cl", &ptr);
  564. X    _moveto         = tgetstr ("cm", &ptr);
  565. X    _cleartoeoln    = tgetstr ("ce", &ptr);
  566. X    _cleartoeos     = tgetstr ("cd", &ptr);
  567. X    _lines          = tgetnum ("li");
  568. X    _columns        = tgetnum ("co");
  569. X    _setinverse     = tgetstr ("so", &ptr);
  570. X    _clearinverse   = tgetstr ("se", &ptr);
  571. X    _setunderline   = tgetstr ("us", &ptr);
  572. X    _clearunderline = tgetstr ("ue", &ptr);
  573. X    _terminalinit   = tgetstr ("ti", &ptr);
  574. X    _terminalend    = tgetstr ("te", &ptr);
  575. X
  576. X    InitWin ();
  577. X
  578. X    if (!_clearscreen) {
  579. X        fprintf (stderr,
  580. X            "%s: Terminal must have clearscreen (cl) capability\n",progname);
  581. X        return (FALSE);
  582. X    }
  583. X    if (!_moveto) {
  584. X        fprintf (stderr,
  585. X            "%s: Terminal must have cursor motion (cm)\n", progname);
  586. X        return (FALSE);
  587. X    }
  588. X    if (!_cleartoeoln) {
  589. X        fprintf (stderr,
  590. X            "%s: Terminal must have clear to end-of-line (ce)\n", progname);
  591. X        return (FALSE);
  592. X    }
  593. X    if (!_cleartoeos) {
  594. X        fprintf (stderr,
  595. X            "%s: Terminal must have clear to end-of-screen (cd)\n", progname);
  596. X        return (FALSE);
  597. X    }
  598. X
  599. X
  600. X
  601. X
  602. X
  603. X
  604. X
  605. X
  606. X
  607. X
  608. X    if (_lines == -1)
  609. X        _lines = DEFAULT_LINES_ON_TERMINAL;
  610. X    if (_columns == -1)
  611. X        _columns = DEFAULT_COLUMNS_ON_TERMINAL;
  612. X    /* kludge to workaround no inverse */
  613. X    if (_setinverse == 0) {
  614. X        _setinverse = _setunderline;
  615. X        _clearinverse = _clearunderline;
  616. X        if (_setinverse == 0)
  617. X            draw_arrow_mark = 1;
  618. X    }
  619. X    return (TRUE);
  620. X
  621. X#else
  622. X
  623. X    return (FALSE);
  624. X
  625. X#endif /* INDEX_DAEMON */
  626. X}
  627. X
  628. X/*
  629. X *  returns the number of lines and columns on the display.
  630. X */
  631. Xvoid ScreenSize (num_lines, num_columns)
  632. X    int *num_lines, *num_columns;
  633. X{
  634. X#ifndef INDEX_DAEMON
  635. X
  636. X    if (_lines == 0) _lines = DEFAULT_LINES_ON_TERMINAL;
  637. X    if (_columns == 0) _columns = DEFAULT_COLUMNS_ON_TERMINAL;
  638. X
  639. X    *num_lines = _lines - 1;        /* assume index from zero*/
  640. X    *num_columns = _columns;        /* assume index from one */
  641. X
  642. X#endif /* INDEX_DAEMON */
  643. X}
  644. X
  645. Xvoid InitWin ()
  646. X{
  647. X#ifndef INDEX_DAEMON
  648. X
  649. X    if (_terminalinit) {
  650. X        tputs (_terminalinit, 1, outchar);
  651. X        fflush (stdout);
  652. X    }
  653. X
  654. X#endif /* INDEX_DAEMON */
  655. X}
  656. X
  657. Xvoid EndWin ()
  658. X{
  659. X#ifndef INDEX_DAEMON
  660. X
  661. X    if (_terminalend) {
  662. X        tputs (_terminalend, 1, outchar);
  663. X        fflush (stdout);
  664. X    }
  665. X    
  666. X#endif /* INDEX_DAEMON */
  667. X}
  668. X
  669. X/*
  670. X *  clear the screen: returns -1 if not capable
  671. X */
  672. X
  673. Xvoid ClearScreen ()
  674. X{
  675. X#ifndef INDEX_DAEMON
  676. X
  677. X    tputs (_clearscreen, 1, outchar);
  678. X    fflush (stdout);      /* clear the output buffer */
  679. X
  680. X#endif /* INDEX_DAEMON */
  681. X}
  682. X
  683. X/*
  684. X *  move cursor to the specified row column on the screen.
  685. X *  0,0 is the top left!
  686. X */
  687. X
  688. Xvoid MoveCursor (row, col)
  689. X    int row, col;
  690. X{
  691. X#ifndef INDEX_DAEMON
  692. X
  693. X    char *stuff, *tgoto();
  694. X
  695. X    stuff = tgoto (_moveto, col, row);
  696. X    tputs (stuff, 1, outchar);
  697. X    fflush (stdout);
  698. X
  699. X#endif /* INDEX_DAEMON */
  700. X}
  701. X
  702. X/*
  703. X *  clear to end of line
  704. X */
  705. X
  706. Xvoid CleartoEOLN ()
  707. X{
  708. X#ifndef INDEX_DAEMON
  709. X
  710. X    tputs (_cleartoeoln, 1, outchar);
  711. X    fflush (stdout);  /* clear the output buffer */
  712. X
  713. X#endif /* INDEX_DAEMON */
  714. X}
  715. X
  716. X/*
  717. X *  clear to end of screen
  718. X */
  719. X
  720. Xvoid CleartoEOS ()
  721. X{
  722. X#ifndef INDEX_DAEMON
  723. X
  724. X    int i;
  725. X    
  726. X    if (_cleartoeos) {
  727. X        tputs (_cleartoeos, 1, outchar);
  728. X    } else {
  729. X        for (i=_lines ; i < _lines ; i++) {
  730. X            MoveCursor (i, 0);
  731. X            CleartoEOLN ();
  732. X        }
  733. X    }
  734. X    fflush (stdout);  /* clear the output buffer */
  735. X
  736. X#endif /* INDEX_DAEMON */
  737. X}
  738. X
  739. X/*
  740. X *  set inverse video mode
  741. X */
  742. X
  743. Xvoid StartInverse ()
  744. X{
  745. X#ifndef INDEX_DAEMON
  746. X
  747. X    if (_setinverse && inverse_okay)
  748. X        tputs (_setinverse, 1, outchar);
  749. X    fflush (stdout);
  750. X
  751. X#endif /* INDEX_DAEMON */
  752. X}
  753. X
  754. X/*
  755. X *  compliment of startinverse
  756. X */
  757. X
  758. Xvoid EndInverse ()
  759. X{
  760. X#ifndef INDEX_DAEMON
  761. X
  762. X    if (_clearinverse && inverse_okay)
  763. X        tputs (_clearinverse, 1, outchar);
  764. X    fflush (stdout);
  765. X
  766. X#endif /* INDEX_DAEMON */
  767. X}
  768. X
  769. X/*
  770. X *  returns either 1 or 0, for ON or OFF
  771. X */
  772. X
  773. Xint RawState()
  774. X{
  775. X    return (_inraw);
  776. X}
  777. X
  778. X/*
  779. X *  state is either TRUE or FALSE, as indicated by call
  780. X */
  781. X
  782. Xvoid Raw(state)
  783. X    int state;
  784. X{
  785. X#ifndef INDEX_DAEMON
  786. X
  787. X    if (state == FALSE && _inraw) {
  788. X      (void) ioctl(TTYIN, TCSETAW, &_original_tty);
  789. X      _inraw = 0;
  790. X    }
  791. X    else if (state == TRUE && ! _inraw) {
  792. X
  793. X      (void) ioctl(TTYIN, TCGETA, &_original_tty);    /** current setting **/
  794. X
  795. X      (void) ioctl(TTYIN, TCGETA, &_raw_tty);    /** again! **/
  796. X#if defined(BSD) || defined(MINIX)
  797. X      _raw_tty.sg_flags &= ~(ECHO | CRMOD);    /* echo off */
  798. X      _raw_tty.sg_flags |= CBREAK;    /* raw on    */
  799. X#else
  800. X      _raw_tty.c_lflag &= ~(ICANON | ECHO);    /* noecho raw mode        */
  801. X
  802. X      _raw_tty.c_cc[VMIN] = '\01';    /* minimum # of chars to queue    */
  803. X      _raw_tty.c_cc[VTIME] = '\0';    /* minimum time to wait for input */
  804. X#endif
  805. X
  806. X      (void) ioctl(TTYIN, TCSETAW, &_raw_tty);
  807. X
  808. X      _inraw = 1;
  809. X    }
  810. X    
  811. X#endif /* INDEX_DAEMON */
  812. X}
  813. X
  814. X/*
  815. X *  read a character with Raw mode set!
  816. X */
  817. X
  818. Xint ReadCh()
  819. X{
  820. X#ifndef INDEX_DAEMON
  821. X    extern int errno;
  822. X    char ch;
  823. X    register int result = 0;
  824. X    
  825. X#ifdef READ_CHAR_HACK
  826. X#undef getc
  827. X    while ((result = getc(stdin)) == EOF) {
  828. X        if (feof(stdin))
  829. X            break;
  830. X
  831. X        if (ferror(stdin) && errno != EINTR)
  832. X            break;
  833. X
  834. X        clearerr(stdin);
  835. X    }
  836. X
  837. X    return ((result == EOF) ? EOF : result & 0xFF);
  838. X#else
  839. X
  840. X    while ((result = read(0, &ch, 1)) < 0 && errno == EINTR)
  841. X        ;    /* spin on signal interrupts */
  842. X
  843. X        return((result <= 0 ) ? EOF : ch & 0xFF);
  844. X#endif        
  845. X
  846. X#endif /* INDEX_DAEMON */
  847. X}
  848. X
  849. X/*
  850. X *  output a character. From tputs... (Note: this CANNOT be a macro!)
  851. X */
  852. X
  853. Xint outchar(c)
  854. X    char c;
  855. X{
  856. X    fputc (c, stdout);
  857. X}
  858. END_OF_FILE
  859.   if test 7985 -ne `wc -c <'curses.c'`; then
  860.     echo shar: \"'curses.c'\" unpacked with wrong size!
  861.   fi
  862.   # end of 'curses.c'
  863. fi
  864. if test -f 'init.c' -a "${1}" != "-c" ; then 
  865.   echo shar: Will not clobber existing file \"'init.c'\"
  866. else
  867.   echo shar: Extracting \"'init.c'\" \(14261 characters\)
  868.   sed "s/^X//" >'init.c' <<'END_OF_FILE'
  869. X/*
  870. X *  Project   : tin - a threaded Netnews reader
  871. X *  Module    : init.c
  872. X *  Author    : I.Lea
  873. X *  Created   : 01-04-91
  874. X *  Updated   : 09-05-92
  875. X *  Notes     :
  876. X *  Copyright : (c) Copyright 1991-92 by Iain Lea
  877. X *              You may  freely  copy or  redistribute  this software,
  878. X *              so  long as there is no profit made from its use, sale
  879. X *              trade or  reproduction.  You may not change this copy-
  880. X *              right notice, and it must be included in any copy made
  881. X */
  882. X
  883. X#include    "tin.h"
  884. X
  885. Xchar rcdir[PATH_LEN];
  886. Xchar rcfile[PATH_LEN];
  887. Xchar indexdir[PATH_LEN];
  888. Xchar killfile[PATH_LEN];
  889. Xchar postfile[PATH_LEN];
  890. Xchar unthreadfile[PATH_LEN];
  891. Xchar cvers[LEN];
  892. Xchar nntp_server[LEN];
  893. Xchar active_file[PATH_LEN];
  894. Xchar subscriptions_file[PATH_LEN];
  895. Xchar homedir[PATH_LEN];
  896. Xchar userid[LEN];
  897. Xchar delgroups[LEN];
  898. Xchar default_maildir[PATH_LEN];            /* mailbox dir where = saves are stored */
  899. Xchar newsrc[PATH_LEN];
  900. Xchar newnewsrc[PATH_LEN];
  901. Xchar add_addr[LEN];            /* address to add to rR reply to author with mail */
  902. Xchar bug_addr[LEN];            /* address to add send bug reports to */
  903. Xchar txt_help_bug_report[LEN];    /* address to add send bug reports to */
  904. Xchar reply_to[LEN];            /* Reply-To: address */
  905. Xchar my_org[LEN];            /* Organization: */
  906. Xchar my_distribution[LEN];        /* Distribution: */
  907. Xchar default_sigfile[PATH_LEN];
  908. Xchar default_signature[PATH_LEN];
  909. Xchar default_shell_command[LEN];    /* offers user default choice */
  910. Xchar killsubj[LEN];            /* contains Subject:'s not to be shown */
  911. Xchar killfrom[LEN];            /* conatins From:'s not to be shown */
  912. Xchar page_header[LEN];        /* page header of pgm name and version */
  913. Xchar default_savedir[PATH_LEN];            /* directory to save articles to */
  914. Xchar spooldir[PATH_LEN];        /* directory where news is */
  915. Xchar spooldir_alias[PATH_LEN];        /* alias of spooldir being used */
  916. Xchar mail_news_user[LEN];    /* mail new news to this user address */
  917. Xchar mailer[PATH_LEN];            /* mail program */
  918. Xchar mailbox[PATH_LEN];            /* system mailbox for each user */
  919. Xchar printer[LEN];            /* printer program specified from tinrc */
  920. Xchar cmd_line_printer[LEN];    /* printer program specified on cmd line */
  921. Xchar article[PATH_LEN];            /* ~/.article file */
  922. Xchar dead_article[PATH_LEN];    /* ~/dead.article file */
  923. Xchar progname[PATH_LEN];        /* program name */
  924. Xchar redirect_output[LEN];    /* /dev/null or nothing if -D option */
  925. X
  926. Xint xindex_supported = FALSE;
  927. Xint xuser_supported = FALSE;
  928. Xint xspooldir_supported = FALSE;
  929. Xint NOTESLINES;                        /* set in set_win_size () */
  930. Xint RIGHT_POS;                        /* set in set_win_size () */
  931. Xint MORE_POS;                        /* set in set_win_size () */
  932. Xint confirm_action;
  933. Xint max_subj = 0;
  934. Xint max_from = 0;
  935. Xint max_active;
  936. Xint num_active;                        /* one past top of active */
  937. Xint group_top;                        /* one past top of my_group */
  938. Xint groupname_len = 0;                    /* one past top of my_group */
  939. Xint catchup = FALSE;                /* mark all arts read in all subscribed groups */
  940. Xint update_fork = FALSE;            /* update index files by forked tin -u */
  941. Xint verbose = FALSE;                /* update index files only mode */
  942. Xint start_line_offset;                /* used by invoke_editor for line no. */
  943. Xint inn_nntp_server = FALSE;            /* read news via INN NNTP */
  944. Xint read_news_via_nntp = FALSE;        /* read news locally or via NNTP */
  945. Xint local_index;                    /* do private indexing? */
  946. Xint max_art;
  947. Xint real_gid;
  948. Xint real_uid;
  949. Xint real_umask;
  950. Xint start_editor_offset;
  951. Xint tin_uid;
  952. Xint tin_gid;
  953. Xint top = 0;
  954. Xint top_base;
  955. Xint check_any_unread = FALSE;
  956. Xint notify_new_groups = FALSE;
  957. Xint start_any_unread = FALSE;
  958. X
  959. Xint catchup_read_groups;    /* ask if read groups are to be marked read */
  960. Xint cmd_line;                /* batch / interactive mode */
  961. Xint created_rcdir;            /* checks if first time tin is started */
  962. Xint default_printer;        /* set to false if user give a printer with -p switch */
  963. Xint default_show_author;    /* show_author value from 'M' menu in tinrc */
  964. Xint draw_arrow_mark;        /* draw -> or highlighted bar */
  965. Xint full_page_scroll;        /* page half/full screen of articles/groups */
  966. Xint killed_articles;        /* killed / auto-selected hot articles */
  967. Xint mark_saved_read;        /* mark saved article/thread as read */
  968. Xint num_of_hot_arts;
  969. Xint num_of_killed_arts;
  970. Xint num_of_tagged_arts;
  971. Xint process_id;
  972. Xint pos_first_unread;        /* position cursor at first/last unread article */
  973. Xint post_proc_type;            /* type of post processing to be performed */
  974. Xint print_header;            /* print all of mail header or just Subject: & From lines */
  975. Xint save_archive_name;        /* save thread with name from Archive-name: field */
  976. Xint mail_news;                /* mail all arts to specified user */
  977. Xint save_news;                /* save all arts to savedir structure */
  978. Xint show_author;            /* show Subject & From or only Subject in group menu */
  979. Xint show_only_unread;        /* show only new/unread arts or all arts */
  980. Xint spooldir_is_active;            /* set TRUE if current spooldir is active news feed */
  981. Xint sort_art_type;            /* sort arts[] array by subject,from or date field */
  982. Xint thread_arts;            /* thread/unthread articles for viewing */
  983. X
  984. X#ifdef INDEX_DAEMON
  985. Xint update = TRUE;                    /* update index files only mode */
  986. X#else
  987. Xint update = FALSE;                    /* update index files only mode */
  988. X#endif
  989. X
  990. Xstruct passwd *myentry;
  991. X
  992. X
  993. X/*
  994. X * Get users home directory, userid, and a bunch of other stuff!
  995. X */
  996. X
  997. Xvoid init_selfinfo ()
  998. X{
  999. X    extern char *getlogin ();
  1000. X    extern struct passwd *getpwnam ();
  1001. X    char nam[LEN];
  1002. X    char *p;
  1003. X    FILE *fp;
  1004. X    struct stat sb;
  1005. X
  1006. X    process_id = getpid ();
  1007. X    
  1008. X    tin_uid = geteuid ();
  1009. X    tin_gid = getegid ();
  1010. X    real_uid = getuid ();
  1011. X    real_gid = getgid ();
  1012. X
  1013. X    real_umask = umask (0);
  1014. X    umask (real_umask);
  1015. X    
  1016. X#ifdef SVR4
  1017. X    setlocale (LC_ALL, "");
  1018. X#endif
  1019. X        
  1020. X    /*
  1021. X     * we're setuid, so index in /usr/spool/news even if user root
  1022. X     * This is quite essential if non local index files are 
  1023. X     * to be updated during the night from crontab by root.
  1024. X     */
  1025. X    if (tin_uid != real_uid) {
  1026. X        local_index = FALSE;
  1027. X        set_real_uid_gid ();
  1028. X
  1029. X    } else {    /* index in users home directory ~/.tin/.index */
  1030. X        local_index = TRUE;
  1031. X    }
  1032. X
  1033. X    myentry = (struct passwd *) 0;
  1034. X    if ((p = getlogin ()) != (char *) 0) {
  1035. X        myentry = getpwnam (p);
  1036. X    } else {
  1037. X        myentry = getpwuid (getuid ());
  1038. X    }
  1039. X
  1040. X    strcpy (userid, myentry->pw_name);
  1041. X
  1042. X    if ((p = (char *) getenv ("HOME")) != NULL) {
  1043. X        strcpy (homedir, p);
  1044. X    } else {
  1045. X        strcpy (homedir, myentry->pw_dir);
  1046. X    }
  1047. X
  1048. X    catchup_read_groups = FALSE;
  1049. X    confirm_action = TRUE;
  1050. X    created_rcdir = FALSE;
  1051. X#ifdef USE_INVERSE_HACK
  1052. X    inverse_okay = FALSE;
  1053. X    draw_arrow_mark = TRUE;
  1054. X#else
  1055. X    draw_arrow_mark = FALSE;
  1056. X#endif
  1057. X    default_move_group = 0;
  1058. X#ifdef BSD
  1059. X    default_printer = TRUE;
  1060. X#else    
  1061. X    default_printer = FALSE;
  1062. X#endif
  1063. X    default_show_author = SHOW_FROM_NAME;
  1064. X    full_page_scroll = TRUE;
  1065. X    killed_articles = FALSE;
  1066. X    mark_saved_read = TRUE;
  1067. X    num_of_hot_arts = 0;
  1068. X    num_of_killed_arts = 0;
  1069. X    num_of_tagged_arts = 0;
  1070. X    post_proc_type = POST_PROC_NONE;
  1071. X    pos_first_unread = TRUE;
  1072. X    print_header = FALSE;
  1073. X    save_archive_name = TRUE;
  1074. X    save_news = FALSE;
  1075. X    show_only_unread = FALSE;
  1076. X    sort_art_type = SORT_BY_DATE_ASCEND;
  1077. X    start_editor_offset = TRUE;
  1078. X    thread_arts = TRUE;
  1079. X    
  1080. X    killsubj[0] = '\0';
  1081. X    killfrom[0] = '\0';
  1082. X    
  1083. X    cmd_line_printer[0] = '\0';
  1084. X    default_author_search[0] = '\0';
  1085. X    default_goto_group[0] = '\0';
  1086. X    default_group_search[0] = '\0';
  1087. X    default_subject_search[0] = '\0';
  1088. X    default_art_search[0] = '\0';
  1089. X    default_crosspost_group[0] = '\0';
  1090. X    default_mail_address[0] = '\0';
  1091. X    default_pipe_command[0] = '\0';
  1092. X    default_post_subject[0] = '\0';
  1093. X    default_regex_pattern[0] = '\0';
  1094. X    default_save_file[0] = '\0';
  1095. X    default_shell_command[0] = '\0';
  1096. X    nntp_server[0] = '\0';
  1097. X    proc_ch_default = 'n';
  1098. X
  1099. X    /*
  1100. X     * set start spooldir to active newsfeed
  1101. X     */
  1102. X    strcpy (spooldir_alias, "news");
  1103. X    strcpy (spooldir, SPOOLDIR);
  1104. X
  1105. X    set_tindir ();    
  1106. X
  1107. X    sprintf (active_file, "%s/active", LIBDIR);
  1108. X    sprintf (article, "%s/.article", homedir);
  1109. X    sprintf (dead_article, "%s/dead.article", homedir);
  1110. X    sprintf (delgroups, "%s/.delgroups", homedir);
  1111. X    sprintf (mailbox, "%s/%s", DEFAULT_MAILBOX, userid);
  1112. X    sprintf (default_maildir, "%s/%s", homedir, DEFAULT_MAILDIR);
  1113. X    sprintf (default_savedir, "%s/News", homedir);
  1114. X    sprintf (default_sigfile, "%s/.Sig", homedir);
  1115. X    sprintf (default_signature, "%s/.signature", homedir);
  1116. X    sprintf (subscriptions_file, "%s/subscriptions", LIBDIR);
  1117. X
  1118. X    strcpy (mailer, get_val ("MAILER", DEFAULT_MAILER));
  1119. X    strcpy (printer, DEFAULT_PRINTER);
  1120. X    strcpy (spooldir, SPOOLDIR);
  1121. X    strcpy (bug_addr, BUG_REPORT_ADDRESS);
  1122. X    strcpy (redirect_output, "> /dev/null 2>&1");
  1123. X
  1124. X#ifdef INDEX_DAEMON
  1125. X    strcpy (newsrc, active_file);    /* so that all groups are indexed */
  1126. X    sprintf (indexdir, "%s/.index", spooldir);
  1127. X
  1128. X    if (stat (indexdir, &sb) == -1) {
  1129. X        mkdir (indexdir, 0777);
  1130. X    }
  1131. X#else
  1132. X    if (stat (rcdir, &sb) == -1) {
  1133. X        created_rcdir = TRUE;
  1134. X        mkdir (rcdir, 0755);
  1135. X    }
  1136. X    if (tin_uid != real_uid) {
  1137. X        sprintf (indexdir, "%s/.index", spooldir);
  1138. X
  1139. X        set_tin_uid_gid ();
  1140. X        if (stat (indexdir, &sb) == -1) {
  1141. X            mkdir (indexdir, 0777);
  1142. X        }
  1143. X        set_real_uid_gid ();
  1144. X    } else if (stat (indexdir, &sb) == -1) {
  1145. X        mkdir (indexdir, 0755);
  1146. X    }
  1147. X    if (stat (postfile, &sb) == -1) {
  1148. X        if ((fp = fopen (postfile, "w")) != NULL) {
  1149. X            fclose (fp);
  1150. X        }
  1151. X    }
  1152. X    if (stat (unthreadfile, &sb) == -1) {
  1153. X        if ((fp = fopen (unthreadfile, "w")) != NULL) {
  1154. X            fclose (fp);
  1155. X        }
  1156. X    }
  1157. X
  1158. X    read_rcfile ();
  1159. X
  1160. X    show_author = default_show_author;
  1161. X
  1162. X#endif /* INDEX_DAEMON */    
  1163. X
  1164. X    if (stat (active_file, &sb) >= 0)
  1165. X        goto got_active;
  1166. X
  1167. X    /*
  1168. X     *  I hate forgetting to define LIBDIR correctly.  Guess a couple
  1169. X     *  of the likely places if it's not where LIBDIR says it is.
  1170. X     */
  1171. X
  1172. X    strcpy (active_file, "/usr/lib/news/active");
  1173. X    if (stat (active_file, &sb) >= 0)
  1174. X        goto got_active;
  1175. X
  1176. X    strcpy (active_file, "/usr/local/lib/news/active");
  1177. X    if (stat (active_file, &sb) >= 0)
  1178. X        goto got_active;
  1179. X
  1180. X    strcpy (active_file, "/usr/public/lib/news/active");
  1181. X    if (stat (active_file, &sb) >= 0)
  1182. X        goto got_active;
  1183. X
  1184. X    /*
  1185. X     *  Oh well. Revert to what LIBDIR says it is to produce a useful
  1186. X     *  error message when read_active_file () fails later.
  1187. X     */
  1188. X
  1189. X    sprintf (active_file, "%s/active", LIBDIR);
  1190. X
  1191. Xgot_active:
  1192. X
  1193. X    /*
  1194. X     *  check enviroment for ORGANIZATION / NEWSORG
  1195. X     */
  1196. X    my_org[0] = '\0';
  1197. X#ifdef apollo
  1198. X    if ((p = (char *) getenv ("NEWSORG")) != NULL) {
  1199. X#else    
  1200. X    if ((p = (char *) getenv ("ORGANIZATION")) != NULL) {
  1201. X#endif
  1202. X        my_strncpy (my_org, p, sizeof (my_org));
  1203. X        goto got_org;
  1204. X    }
  1205. X
  1206. X    /*
  1207. X     *  check ~/.tin/organization for organization
  1208. X     */
  1209. X    sprintf (nam, "%s/organization", rcdir);
  1210. X    fp = fopen (nam, "r");
  1211. X
  1212. X    /*
  1213. X     *  check LIBDIR/organization for system wide organization
  1214. X     */
  1215. X    if (fp == NULL) {
  1216. X        sprintf (nam, "%s/organization", LIBDIR);
  1217. X        fp = fopen (nam, "r");
  1218. X    }
  1219. X
  1220. X    if (fp == NULL) {
  1221. X        sprintf (nam, "/usr/lib/news/organization");
  1222. X        fp = fopen (nam, "r");
  1223. X    }
  1224. X
  1225. X    if (fp == NULL) {
  1226. X        sprintf (nam, "/usr/local/lib/news/organization");
  1227. X        fp = fopen (nam, "r");
  1228. X    }
  1229. X
  1230. X    if (fp == NULL) {
  1231. X        sprintf (nam, "/usr/public/lib/news/organization");
  1232. X        fp = fopen (nam, "r");
  1233. X    }
  1234. X
  1235. X    if (fp == NULL) {
  1236. X        sprintf (nam, "/etc/organization");
  1237. X        fp = fopen (nam, "r");
  1238. X    }
  1239. X
  1240. X    if (fp != NULL) {
  1241. X        if (fgets (my_org, sizeof (my_org), fp) != NULL) {
  1242. X            for (p = my_org; *p && *p != '\n'; p++)
  1243. X                continue;
  1244. X            *p = '\0';
  1245. X        }
  1246. X        fclose (fp);
  1247. X    }
  1248. X
  1249. Xgot_org:;
  1250. X
  1251. X    /*
  1252. X     *  check enviroment for REPLYTO
  1253. X     */
  1254. X    reply_to[0] = '\0';
  1255. X    if ((p = (char *) getenv ("REPLYTO")) != NULL) {
  1256. X        my_strncpy (reply_to, p, sizeof (reply_to));
  1257. X        goto got_reply;
  1258. X    }
  1259. X
  1260. X    sprintf (nam, "%s/replyto", rcdir);
  1261. X    if ((fp = fopen (nam, "r")) != NULL) {
  1262. X        if (fgets (reply_to, sizeof (reply_to), fp) != NULL) {
  1263. X            reply_to[strlen (reply_to)-1] = '\0';
  1264. X        }
  1265. X        fclose (fp);
  1266. X    }
  1267. X
  1268. Xgot_reply:;
  1269. X
  1270. X    /*
  1271. X     *  check enviroment for DISTRIBUTION
  1272. X     */
  1273. X    my_distribution[0] = '\0';
  1274. X    if ((p = (char *) getenv ("DISTRIBUTION")) != NULL) {
  1275. X        my_strncpy (my_distribution, p, sizeof (my_distribution));
  1276. X    }
  1277. X
  1278. X    /*
  1279. X     *  check enviroment for ADD_ADDRESS
  1280. X      */
  1281. X    add_addr[0] = '\0';
  1282. X    if ((p = (char *) getenv ("ADD_ADDRESS")) != NULL) {
  1283. X        my_strncpy (add_addr, p, sizeof (add_addr));
  1284. X        goto got_add_addr;
  1285. X    }
  1286. X
  1287. X    sprintf (nam, "%s/add_address", rcdir);
  1288. X    if ((fp = fopen (nam, "r")) != NULL) {
  1289. X        if (fgets (add_addr, sizeof (add_addr), fp) != NULL) {
  1290. X            add_addr[strlen (add_addr)-1] = '\0';
  1291. X        }
  1292. X        fclose (fp);
  1293. X    }
  1294. X
  1295. Xgot_add_addr:;
  1296. X
  1297. X    /*
  1298. X     *  check enviroment for BUG_ADDRESS
  1299. X     */
  1300. X    if ((p = (char *) getenv ("BUG_ADDRESS")) != NULL) {
  1301. X        my_strncpy (bug_addr, p, sizeof (bug_addr));
  1302. X        goto got_bug_addr;
  1303. X    }
  1304. X
  1305. X    sprintf (nam, "%s/bug_address", rcdir);
  1306. X    if ((fp = fopen (nam, "r")) != NULL) {
  1307. X        if (fgets (bug_addr, sizeof (bug_addr), fp) != NULL) {
  1308. X            bug_addr[strlen (bug_addr)-1] = '\0';
  1309. X        }
  1310. X        fclose (fp);
  1311. X    }
  1312. X
  1313. Xgot_bug_addr:;
  1314. X    sprintf (txt_help_bug_report, txt_help_bug, bug_addr);
  1315. X}
  1316. X
  1317. X/*
  1318. X * Set up ~/.tin directory & support files depending on where the news
  1319. X * is being read from (ie. active news / CD-ROM spooldir).  Note that
  1320. X * any control files which may be specific to a given spooldir (various
  1321. X * CD issues versus live news) should be under the spooldir_alias 
  1322. X * subdirectory also.
  1323. X */
  1324. Xvoid set_tindir ()
  1325. X{
  1326. X    extern int reread_active_file;
  1327. X    struct stat sb;
  1328. X    
  1329. X    if (strcmp (spooldir_alias, "news") != 0) {
  1330. X        sprintf (rcdir,  "%s/%s", get_val ("TINDIR", homedir), RCDIR);
  1331. X        /*
  1332. X         * Create directories
  1333. X         */
  1334. X        if (stat (rcdir, &sb) == -1) {
  1335. X            mkdir (rcdir, 0755);
  1336. X        }
  1337. X        sprintf (rcdir, "%s/%s", rcdir, spooldir_alias); 
  1338. X        if (stat (rcdir, &sb) == -1) {
  1339. X            created_rcdir = TRUE;
  1340. X            mkdir (rcdir, 0755);
  1341. X        }
  1342. X        /*
  1343. X         * Use a separate .newsrc file for every spooldir 
  1344. X         */
  1345. X        sprintf (newsrc, "%s/.newsrc", rcdir);
  1346. X        sprintf (newnewsrc, "%s/.newnewsrc", rcdir);
  1347. X
  1348. X        spooldir_is_active = FALSE;
  1349. X        reread_active_file = FALSE;
  1350. X        alarm (0);
  1351. X    } else {
  1352. X        if (stat (rcdir, &sb) == -1) {
  1353. X            mkdir (rcdir, 0755);
  1354. X        }
  1355. X        sprintf (rcdir,  "%s/%s", get_val ("TINDIR", homedir), RCDIR);
  1356. X        sprintf (rcfile,   "%s/%s", rcdir, RCFILE);
  1357. X        sprintf (killfile, "%s/%s", rcdir, KILLFILE);
  1358. X        sprintf (postfile, "%s/%s", rcdir, POSTFILE);
  1359. X        sprintf (unthreadfile, "%s/%s", rcdir, UNTHREADFILE);
  1360. X        sprintf (newsrc, "%s/.newsrc", homedir);
  1361. X        sprintf (newnewsrc, "%s/.newnewsrc", homedir);
  1362. X
  1363. X        spooldir_is_active = TRUE;
  1364. X        reread_active_file = TRUE;
  1365. X    }
  1366. X    sprintf (indexdir, "%s/%s", rcdir, INDEXDIR);
  1367. X    if (stat (indexdir, &sb) == -1) {
  1368. X        mkdir (indexdir, 0755);
  1369. X    }
  1370. X}
  1371. X
  1372. X
  1373. Xint create_mail_save_dirs ()
  1374. X{
  1375. X    int created = FALSE;
  1376. X    struct stat sb;
  1377. X    
  1378. X    if (stat (default_maildir, &sb) == -1) {
  1379. X        mkdir (default_maildir, 0755);
  1380. X        created = TRUE;
  1381. X    }
  1382. X    if (stat (default_savedir, &sb) == -1) {
  1383. X        mkdir (default_savedir, 0755);
  1384. X        created = TRUE;
  1385. X    }
  1386. X    
  1387. X    return (created);
  1388. X}
  1389. END_OF_FILE
  1390.   if test 14261 -ne `wc -c <'init.c'`; then
  1391.     echo shar: \"'init.c'\" unpacked with wrong size!
  1392.   fi
  1393.   # end of 'init.c'
  1394. fi
  1395. if test -f 'open.c' -a "${1}" != "-c" ; then 
  1396.   echo shar: Will not clobber existing file \"'open.c'\"
  1397. else
  1398.   echo shar: Extracting \"'open.c'\" \(13908 characters\)
  1399.   sed "s/^X//" >'open.c' <<'END_OF_FILE'
  1400. X/*
  1401. X *  Project   : tin - a threaded Netnews reader
  1402. X *  Module    : open.c
  1403. X *  Author    : I.Lea & R.Skrenta
  1404. X *  Created   : 01-04-91
  1405. X *  Updated   : 12-05-92
  1406. X *  Notes     : reads news locally (ie. /usr/spool/news) or via NNTP
  1407. X *  Copyright : (c) Copyright 1991-92 by Iain Lea & Rich Skrenta
  1408. X *              You may  freely  copy or  redistribute  this software,
  1409. X *              so  long as there is no profit made from its use, sale
  1410. X *              trade or  reproduction.  You may not change this copy-
  1411. X *              right notice, and it must be included in any copy made
  1412. X */
  1413. X
  1414. X#include    "tin.h"
  1415. X#include    "nntplib.h"
  1416. X
  1417. X/*
  1418. X * Directory handling code - Hopefully one of these is right for you. 
  1419. X */
  1420. X#ifdef BSD
  1421. X#    ifdef sinix
  1422. X#        include <dir.h>
  1423. X#    else
  1424. X#        include <sys/dir.h>
  1425. X#    endif
  1426. X#    define        DIR_BUF        struct direct
  1427. X#    define        D_LENGTH    d_namlen
  1428. X#endif
  1429. X#ifdef M_XENIX
  1430. X#    include <sys/ndir.h>
  1431. X#    define        DIR_BUF        struct direct
  1432. X#    define        D_LENGTH    d_namlen
  1433. X#endif
  1434. X#ifndef DIR_BUF
  1435. X#    include    <dirent.h>
  1436. X#    define        DIR_BUF        struct dirent
  1437. X#    define        D_LENGTH    d_reclen
  1438. X#endif
  1439. X
  1440. Xint nntp_codeno = 0;
  1441. X
  1442. X#ifdef NNTP_ABLE
  1443. Xint compiled_with_nntp = TRUE;        /* used in mail_bug_report() info */
  1444. X#else
  1445. Xint compiled_with_nntp = FALSE;
  1446. X#endif
  1447. X
  1448. X#ifdef NO_POSTING
  1449. Xint    can_post = FALSE;
  1450. X#else
  1451. Xint    can_post = TRUE;
  1452. X#endif
  1453. X
  1454. Xchar server_name[LEN];
  1455. X
  1456. X
  1457. Xvoid nntp_open ()
  1458. X{
  1459. X#ifdef NNTP_ABLE    
  1460. X    char *server;
  1461. X    int ret;
  1462. X
  1463. X    if (read_news_via_nntp) {
  1464. X        debug_nntp ("nntp_open", "BEGIN");
  1465. X
  1466. X        if (nntp_server[0]) {
  1467. X            server = nntp_server;
  1468. X        } else {
  1469. X            server = getserverbyfile (NNTP_SERVER_FILE);
  1470. X        }
  1471. X
  1472. X        if (server == (char *) 0) {
  1473. X            error_message (txt_cannot_get_nntp_server_name, "");
  1474. X            error_message (txt_server_name_in_file_env_var, NNTP_SERVER_FILE);
  1475. X            exit(1);
  1476. X        }
  1477. X
  1478. X        if (update == FALSE) {
  1479. X            sprintf (msg, txt_connecting, server);
  1480. X            wait_message (msg);
  1481. X        }
  1482. X        
  1483. X        debug_nntp ("nntp_open", server);
  1484. X
  1485. X        ret = server_init (server);
  1486. X        if (update == FALSE) {
  1487. X            fputc ('\n', stdout);
  1488. X        }
  1489. X
  1490. X        debug_nntp_respcode (ret);
  1491. X
  1492. X        switch (ret) {
  1493. X        case OK_CANPOST:
  1494. X#ifndef NO_POSTING        
  1495. X            can_post = TRUE;
  1496. X#endif            
  1497. X            break;
  1498. X
  1499. X        case OK_NOPOST:
  1500. X            can_post = FALSE;
  1501. X            break;    
  1502. X
  1503. X        case -1:
  1504. X            error_message (txt_failed_to_connect_to_server, server);
  1505. X            exit (1);
  1506. X
  1507. X        default:
  1508. X            sprintf (msg, "%s: %s", progname, nntp_respcode (ret));
  1509. X            error_message (msg, "");
  1510. X            exit (1);
  1511. X        }
  1512. X
  1513. X        /*
  1514. X         * Find out if NNTP supports my XINDEX & XUSER commands
  1515. X         */
  1516. X        debug_nntp ("nntp_open", "xindex");
  1517. X        put_server ("xindex");    
  1518. X        if (get_respcode () != ERR_COMMAND) {
  1519. X            xindex_supported = TRUE;
  1520. X        }
  1521. X        debug_nntp ("nntp_open", "xuser");
  1522. X        put_server ("xuser");    
  1523. X        if (get_respcode () != ERR_COMMAND) {
  1524. X            xuser_supported = TRUE;
  1525. X        }
  1526. X        
  1527. X        /*
  1528. X         * If INN NNTP & XINDEX not supported switch to mode reader
  1529. X         */
  1530. X        if (! xindex_supported) {
  1531. X            debug_nntp ("nntp_open", "mode reader");
  1532. X            put_server ("mode reader");    
  1533. X            if (get_respcode () != ERR_COMMAND) {
  1534. X                inn_nntp_server = TRUE;
  1535. X            }
  1536. X        }
  1537. X    }
  1538. X    /*
  1539. X     * Find out if NNTP supports SPOOLDIR command
  1540. X     */
  1541. X    get_spooldir ();
  1542. X#endif    
  1543. X}
  1544. X
  1545. X
  1546. Xvoid nntp_close ()
  1547. X{
  1548. X#ifdef NNTP_ABLE
  1549. X    if (read_news_via_nntp) {
  1550. X        debug_nntp ("nntp_close", "END");
  1551. X        close_server ();
  1552. X    }
  1553. X#endif    
  1554. X}
  1555. X
  1556. X
  1557. XFILE *open_active_fp ()
  1558. X{
  1559. X    if (read_news_via_nntp) {
  1560. X#ifdef NNTP_ABLE
  1561. X        put_server ("list");
  1562. X        if (get_respcode () != OK_GROUPS) {
  1563. X            debug_nntp ("open_active_fp", "NOT_OK");
  1564. X            return (FILE *) 0;
  1565. X        }
  1566. X        debug_nntp ("open_active_fp", "OK");
  1567. X        return nntp_to_fp ();
  1568. X#else
  1569. X        return (FILE *) 0;
  1570. X#endif        
  1571. X    } else {
  1572. X        return fopen (active_file, "r");
  1573. X    }
  1574. X}
  1575. X
  1576. X
  1577. XFILE *open_subscription_fp ()
  1578. X{
  1579. X    if (read_news_via_nntp) {
  1580. X#ifdef NNTP_ABLE
  1581. X        put_server ("list subscriptions");
  1582. X        if (get_respcode () != OK_GROUPS) {
  1583. X            debug_nntp ("open_subscription_fp", "NOT_OK");
  1584. X            return (FILE *) 0;
  1585. X        }
  1586. X        debug_nntp ("open_subscription_fp", "OK");
  1587. X        return nntp_to_fp ();
  1588. X#else
  1589. X        return (FILE *) 0;
  1590. X#endif        
  1591. X    } else {
  1592. X        return fopen (subscriptions_file, "r");
  1593. X    }
  1594. X}
  1595. X
  1596. X
  1597. XFILE *open_index_fp (group_name)
  1598. X    char *group_name;
  1599. X{
  1600. X    char line[NNTP_STRLEN];
  1601. X    extern char index_file[PATH_LEN];
  1602. X
  1603. X    find_index_file (group_name);
  1604. X    
  1605. X    if (read_news_via_nntp && xindex_supported) {
  1606. X        sprintf (line, "xindex %s", group_name);
  1607. X        debug_nntp ("open_index_fp", line);
  1608. X        put_server (line);
  1609. X        if (get_respcode () != OK_XINDEX) {
  1610. X            debug_nntp ("open_index_fp", "NOT_OK");
  1611. X            return (FILE *) 0;
  1612. X        }
  1613. X        debug_nntp ("open_index_fp", "OK");
  1614. X        return nntp_to_fp ();
  1615. X    } else {
  1616. X        return fopen (index_file, "r");
  1617. X    }
  1618. X}
  1619. X
  1620. X
  1621. XFILE *open_art_fp (group_path, art)
  1622. X    char *group_path;
  1623. X    long art;
  1624. X{
  1625. X    char buf[LEN];
  1626. X    int respcode;
  1627. X    struct stat sb;
  1628. X    extern long note_size;
  1629. X
  1630. X    if (read_news_via_nntp) {
  1631. X#ifdef NNTP_ABLE
  1632. X        sprintf (buf, "article %ld", art);
  1633. X        debug_nntp ("open_art_fp", buf);
  1634. X        put_server (buf);
  1635. X        if ((respcode = get_respcode ()) != OK_ARTICLE) {
  1636. X            error_message ("%s", nntp_respcode (respcode));
  1637. X            debug_nntp ("open_art_fp", buf);
  1638. X            return (FILE *) 0;
  1639. X        }
  1640. X
  1641. X        debug_nntp ("open_art_fp", "OK");
  1642. X
  1643. X        return nntp_to_fp ();
  1644. X#else
  1645. X        return (FILE *) 0;
  1646. X#endif
  1647. X    } else {
  1648. X        sprintf (buf, "%s/%s/%ld", spooldir, group_path, art);
  1649. X
  1650. X        if (stat (buf, &sb) < 0) {
  1651. X            note_size = 0;
  1652. X        } else {
  1653. X            note_size = sb.st_size;
  1654. X        }
  1655. X        return fopen (buf, "r");
  1656. X    }
  1657. X}
  1658. X
  1659. X
  1660. XFILE *open_header_fp (group_path, art)
  1661. X    char *group_path;
  1662. X    long art;
  1663. X{
  1664. X    char buf[LEN];
  1665. X    
  1666. X    if (read_news_via_nntp) {
  1667. X#ifdef NNTP_ABLE    
  1668. X        sprintf(buf, "head %ld", art);
  1669. X        
  1670. X        debug_nntp ("open_header_fp", buf);
  1671. X
  1672. X        put_server (buf);
  1673. X        if (get_respcode () != OK_HEAD) {
  1674. X            debug_nntp ("open_header_fp", "NOT_OK_HEAD");
  1675. X            return (FILE *) 0;
  1676. X        }
  1677. X
  1678. X        debug_nntp ("open_header_fp", "OK_HEAD");
  1679. X
  1680. X        return nntp_to_fp ();
  1681. X#else
  1682. X        return (FILE *) 0;
  1683. X#endif        
  1684. X    } else {
  1685. X        sprintf (buf, "%s/%s/%ld", spooldir, group_path, art);
  1686. X        return fopen (buf, "r");
  1687. X    }
  1688. X}
  1689. X
  1690. X/*
  1691. X *  Longword comparison routine for the qsort()
  1692. X */
  1693. X
  1694. Xint base_comp (p1, p2)
  1695. X    char *p1;
  1696. X    char *p2;
  1697. X{
  1698. X    long *a = (long *) p1;
  1699. X    long *b = (long *) p2;
  1700. X
  1701. X    if (*a < *b)
  1702. X        return -1;
  1703. X    if (*a > *b)
  1704. X        return 1;
  1705. X    return 0;
  1706. X}
  1707. X
  1708. X
  1709. X/*
  1710. X *  Read the article numbers existing in a group's spool directory
  1711. X *  into base[] and sort them.  top_base is one past top.
  1712. X */
  1713. X
  1714. Xvoid setup_base (group, group_path)
  1715. X    char *group;
  1716. X    char *group_path;
  1717. X{
  1718. X    char buf[LEN];
  1719. X#ifdef NNTP_ABLE
  1720. X    char line[NNTP_STRLEN];
  1721. X#endif
  1722. X    DIR *d;
  1723. X    DIR_BUF *e;
  1724. X    long art, start, last, dummy, count;
  1725. X
  1726. X    top_base = 0;
  1727. X
  1728. X    if (read_news_via_nntp) {
  1729. X
  1730. X#ifdef NNTP_ABLE
  1731. X        sprintf (buf, "group %s", group);
  1732. X
  1733. X        debug_nntp ("setup_base", buf);
  1734. X        
  1735. X        put_server (buf);
  1736. X
  1737. X        if (get_server (line, NNTP_STRLEN) == -1) {
  1738. X            error_message (txt_connection_to_server_broken, "");
  1739. X            tin_done (1);
  1740. X        }
  1741. X
  1742. X        if (atoi(line) != OK_GROUP) {
  1743. X            debug_nntp ("setup_base", "NOT_OK");
  1744. X            return;
  1745. X        }
  1746. X
  1747. X        debug_nntp ("setup_base", line);
  1748. X
  1749. X        sscanf (line,"%ld %ld %ld %ld", &dummy, &count, &start, &last);
  1750. X        if (last - count > start) {
  1751. X            start = last - count;
  1752. X        }
  1753. X
  1754. X        while (start <= last) {
  1755. X            if (top_base >= max_art) {
  1756. X                expand_art();
  1757. X            }
  1758. X            base[top_base++] = start++;
  1759. X        }
  1760. X#else
  1761. X        return; 
  1762. X#endif
  1763. X    } else {
  1764. X        sprintf (buf, "%s/%s", spooldir, group_path);
  1765. X
  1766. X        if (access (buf, 4) != 0) {
  1767. X            return;
  1768. X        }
  1769. X
  1770. X        d = opendir (buf);
  1771. X        if (d != NULL) {
  1772. X            while ((e = readdir (d)) != NULL) {
  1773. X                art = my_atol (e->d_name, (int) e->D_LENGTH);
  1774. X                if (art >= 0) {
  1775. X                    if (top_base >= max_art)
  1776. X                        expand_art ();
  1777. X                    base[top_base++] = art;
  1778. X                }
  1779. X            }
  1780. X            closedir (d);
  1781. X            qsort ((char *) base, top_base, sizeof (long), base_comp);
  1782. X        }
  1783. X    }
  1784. X}
  1785. X
  1786. X/*
  1787. X *  get a response code from the server and return it to the caller
  1788. X */
  1789. X
  1790. Xint get_respcode ()
  1791. X{
  1792. X#ifdef NNTP_ABLE
  1793. X    char line[NNTP_STRLEN];
  1794. X
  1795. X    if (get_server (line, NNTP_STRLEN) == -1) {
  1796. X        error_message (txt_connection_to_server_broken, "");
  1797. X        tin_done (1);
  1798. X    }
  1799. X
  1800. X    debug_nntp ("get_respcode", line);
  1801. X    
  1802. X    return atoi (line);
  1803. X#else
  1804. X    return (0);
  1805. X#endif
  1806. X}
  1807. X
  1808. X
  1809. Xint stuff_nntp (fnam)
  1810. X    char *fnam;
  1811. X{
  1812. X#ifdef NNTP_ABLE
  1813. X    FILE *fp;
  1814. X    char line[NNTP_STRLEN];
  1815. X    extern char *mktemp ();
  1816. X    struct stat sb;
  1817. X    extern long note_size;
  1818. X
  1819. X    strcpy (fnam, "/tmp/tin_nntpXXXXXX");
  1820. X    mktemp (fnam);
  1821. X
  1822. X    if ((fp = fopen (fnam, "w")) == (FILE *) 0) {
  1823. X        perror_message (txt_stuff_nntp_cannot_open, fnam);
  1824. X        return FALSE;
  1825. X    }
  1826. X
  1827. X    while (1) {
  1828. X        if (get_server (line, NNTP_STRLEN) == -1) {
  1829. X            error_message (txt_connection_to_server_broken, "");
  1830. X            tin_done (1);
  1831. X        }
  1832. X
  1833. X        debug_nntp ("stuff_nntp", line);
  1834. X        
  1835. X        if (strcmp (line, ".") == 0)
  1836. X            break;            /* end of text */
  1837. X        strcat (line, "\n");
  1838. X        if (line[0] == '.')        /* reduce leading .'s */
  1839. X            fputs (&line[1], fp);
  1840. X        else
  1841. X            fputs (line, fp);
  1842. X    }
  1843. X    fclose (fp);
  1844. X
  1845. X    if (stat (fnam, &sb) < 0)
  1846. X        note_size = 0;
  1847. X    else
  1848. X        note_size = sb.st_size;
  1849. X
  1850. X    return TRUE;
  1851. X#else
  1852. X    return TRUE;
  1853. X#endif
  1854. X}
  1855. X
  1856. X
  1857. XFILE *nntp_to_fp ()
  1858. X{
  1859. X#ifdef NNTP_ABLE
  1860. X    char fnam[LEN];
  1861. X    FILE *fp = (FILE *) 0;
  1862. X    
  1863. X    if (! stuff_nntp (fnam)) {
  1864. X        debug_nntp ("nntp_to_fp", "! stuff_nntp()");
  1865. X        return (FILE *) 0;
  1866. X    }
  1867. X
  1868. X    if ((fp = fopen (fnam, "r")) == (FILE *) 0) {
  1869. X        perror_message (txt_nntp_to_fp_cannot_reopen, fnam);
  1870. X        return (FILE *) 0;
  1871. X    }
  1872. X    
  1873. X    unlink (fnam);
  1874. X    return fp;
  1875. X#else
  1876. X    return (FILE *) 0;
  1877. X#endif
  1878. X}
  1879. X
  1880. X/*
  1881. X * Log user info to local file or NNTP logfile
  1882. X */
  1883. X
  1884. Xvoid log_user ()
  1885. X{
  1886. X    char buf[32], *ptr;
  1887. X    char line[NNTP_STRLEN];
  1888. X#ifdef LOG_USER
  1889. X    FILE *fp;
  1890. X    long epoch;
  1891. X#endif
  1892. X    extern struct passwd *myentry;
  1893. X
  1894. X    my_strncpy (buf, myentry->pw_gecos, sizeof (buf)-1);
  1895. X
  1896. X    if (read_news_via_nntp && xuser_supported) {
  1897. X        if ((ptr = (char *) strchr(buf, ','))) {
  1898. X            *ptr = '\0';
  1899. X        }
  1900. X        sprintf (line, "xuser %s (%s)", myentry->pw_name, buf);
  1901. X
  1902. X        debug_nntp ("log_user", line);
  1903. X        put_server (line);
  1904. X    } else {
  1905. X#ifdef LOG_USER
  1906. X        if ((fp = fopen (LOG_USER_FILE, "a+")) != (FILE *) 0) {
  1907. X            time (&epoch);
  1908. X            fprintf (fp, "%s%d: %-32s (%-8s) %s", VERSION, PATCHLEVEL,
  1909. X                    buf, myentry->pw_name, ctime (&epoch));
  1910. X            fclose (fp);
  1911. X            chmod (LOG_USER_FILE, 0666);
  1912. X        }    
  1913. X#endif
  1914. X    }
  1915. X}
  1916. X
  1917. X/*
  1918. X * NNTP strings for get_respcode()
  1919. X */
  1920. X
  1921. Xchar *nntp_respcode (respcode)
  1922. X    int respcode;
  1923. X{
  1924. X#ifdef NNTP_ABLE
  1925. X
  1926. X    static char *text;
  1927. X    
  1928. X    switch (respcode) {
  1929. X        case 0:
  1930. X            text = "";
  1931. X            break;
  1932. X        case INF_HELP:
  1933. X            text = "100  Help text on way";
  1934. X            break;
  1935. X        case INF_AUTH:
  1936. X            text = "180  Authorization capabilities";
  1937. X            break;
  1938. X        case INF_DEBUG:
  1939. X            text = "199  Debug output";
  1940. X            break;
  1941. X        case OK_CANPOST:
  1942. X            text = "200  Hello; you can post";
  1943. X            break;
  1944. X        case OK_NOPOST:
  1945. X            text = "201  Hello; you can't post";
  1946. X            break;
  1947. X        case OK_SLAVE:
  1948. X            text = "202  Slave status noted";
  1949. X            break;
  1950. X        case OK_GOODBYE:
  1951. X            text = "205  Closing connection";
  1952. X            break;
  1953. X        case OK_GROUP:
  1954. X            text = "211  Group selected";
  1955. X            break;
  1956. X        case OK_GROUPS:
  1957. X            text = "215  Newsgroups follow";
  1958. X            break;
  1959. X        case OK_XINDEX:
  1960. X            text = "218  Group index file follows";
  1961. X            break;
  1962. X        case OK_ARTICLE:
  1963. X            text = "220  Article (head & body) follows";
  1964. X            break;
  1965. X        case OK_HEAD:
  1966. X            text = "221  Head follows";
  1967. X            break;
  1968. X        case OK_BODY:
  1969. X            text = "222  Body follows";
  1970. X            break;
  1971. X        case OK_NOTEXT:
  1972. X            text = "223  No text sent -- stat, next, last";
  1973. X            break;
  1974. X        case OK_NEWNEWS:
  1975. X            text = "230  New articles by message-id follow";
  1976. X            break;
  1977. X        case OK_NEWGROUPS:
  1978. X            text = "231  New newsgroups follow";
  1979. X            break;
  1980. X        case OK_XFERED:
  1981. X            text = "235  Article transferred successfully";
  1982. X            break;
  1983. X        case OK_POSTED:
  1984. X            text = "240  Article posted successfully";
  1985. X            break;
  1986. X        case OK_AUTHSYS:
  1987. X            text = "280  Authorization system ok";
  1988. X            break;
  1989. X        case OK_AUTH:
  1990. X            text = "281  Authorization (user/pass) ok";
  1991. X            break;
  1992. X        case OK_BIN:
  1993. X            text = "282  binary data follows";
  1994. X            break;
  1995. X        case OK_SPLIST:
  1996. X            text = "283  spooldir list follows";
  1997. X            break;
  1998. X        case OK_SPSWITCH:
  1999. X            text = "284  Switching to a different spooldir";
  2000. X            break;
  2001. X        case OK_SPNOCHANGE:
  2002. X            text = "285  Still using same spooldir";
  2003. X            break;
  2004. X        case OK_SPLDIRCUR:
  2005. X            text = "286  Current spooldir";
  2006. X            break;
  2007. X        case OK_SPLDIRAVL:
  2008. X            text = "287  Available spooldir";
  2009. X            break;
  2010. X        case OK_SPLDIRERR:
  2011. X            text = "288  Unavailable spooldir or invalid entry";
  2012. X            break;
  2013. X        case CONT_XFER:
  2014. X            text = "335  Continue to send article";
  2015. X            break;
  2016. X        case CONT_POST:
  2017. X            text = "340  Continue to post article";
  2018. X            break;
  2019. X        case NEED_AUTHINFO:
  2020. X            text = "380  authorization is required";
  2021. X            break;
  2022. X        case NEED_AUTHDATA:
  2023. X            text = "381  <type> authorization data required";
  2024. X            break;
  2025. X        case ERR_GOODBYE:
  2026. X            text = "400  Have to hang up for some reason";
  2027. X            break;
  2028. X        case ERR_NOGROUP:
  2029. X            text = "411  No such newsgroup";
  2030. X            break;
  2031. X        case ERR_NCING:
  2032. X            text = "412  Not currently in newsgroup";
  2033. X            break;
  2034. X        case ERR_XINDEX:
  2035. X            text = "418  No index file for this group";
  2036. X            break;
  2037. X        case ERR_NOCRNT:
  2038. X            text = "420  No current article selected";
  2039. X            break;
  2040. X        case ERR_NONEXT:
  2041. X            text = "421  No next article in this group";
  2042. X            break;
  2043. X        case ERR_NOPREV:
  2044. X            text = "422  No previous article in this group";
  2045. X            break;
  2046. X        case ERR_NOARTIG:
  2047. X            text = "423  No such article in this group";
  2048. X            break;
  2049. X        case ERR_NOART:
  2050. X            text = "430  No such article at all";
  2051. X            break;
  2052. X        case ERR_GOTIT:
  2053. X            text = "435  Already got that article, don't send";
  2054. X            break;
  2055. X        case ERR_XFERFAIL:
  2056. X            text = "436  Transfer failed";
  2057. X            break;
  2058. X        case ERR_XFERRJCT:
  2059. X            text = "437  Article rejected, don't resend";
  2060. X            break;
  2061. X        case ERR_NOPOST:
  2062. X            text = "440  Posting not allowed";
  2063. X            break;
  2064. X        case ERR_POSTFAIL:
  2065. X            text = "441  Posting failed";
  2066. X            break;
  2067. X        case ERR_NOAUTH:
  2068. X            text = "480  authorization required for command";
  2069. X            break;
  2070. X        case ERR_AUTHSYS:
  2071. X            text = "481  Authorization system invalid";
  2072. X            break;
  2073. X        case ERR_AUTHREJ:
  2074. X            text = "482  Authorization data rejected";
  2075. X            break;
  2076. X        case ERR_INVALIAS:
  2077. X            text = "483  Invalid alias on spooldir cmd";
  2078. X            break;
  2079. X        case ERR_INVNOSPDIR:
  2080. X            text = "484  No spooldir file found";
  2081. X            break;
  2082. X        case ERR_COMMAND:
  2083. X            text = "500  Command not recognized";
  2084. X            break;
  2085. X        case ERR_CMDSYN:
  2086. X            text = "501  Command syntax error";
  2087. X            break;
  2088. X        case ERR_ACCESS:
  2089. X            text = "502  Access to server denied";
  2090. X            break;
  2091. X        case ERR_FAULT:
  2092. X            text = "503  Program fault, command not performed";
  2093. X            break;
  2094. X        case ERR_AUTHBAD:
  2095. X            text = "580  Authorization Failed";
  2096. X            break;
  2097. X        default:
  2098. X            text = "Unknown NNTP response code";
  2099. X            break;
  2100. X    }
  2101. X    return (text);
  2102. X#else
  2103. X    return ("");
  2104. X#endif
  2105. X}
  2106. END_OF_FILE
  2107.   if test 13908 -ne `wc -c <'open.c'`; then
  2108.     echo shar: \"'open.c'\" unpacked with wrong size!
  2109.   fi
  2110.   # end of 'open.c'
  2111. fi
  2112. echo shar: End of archive 11 \(of 14\).
  2113. cp /dev/null ark11isdone
  2114. MISSING=""
  2115. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
  2116.     if test ! -f ark${I}isdone ; then
  2117.     MISSING="${MISSING} ${I}"
  2118.     fi
  2119. done
  2120. if test "${MISSING}" = "" ; then
  2121.     echo You have unpacked all 14 archives.
  2122.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2123. else
  2124.     echo You still must unpack the following archives:
  2125.     echo "        " ${MISSING}
  2126. fi
  2127. exit 0
  2128. exit 0 # Just in case...
  2129.