home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume39 / slurp / part02 < prev    next >
Encoding:
Text File  |  1993-08-21  |  53.4 KB  |  1,977 lines

  1. Newsgroups: comp.sources.misc
  2. From: steveh@orbital.demon.co.uk (Stephen Hebditch)
  3. Subject: v39i038:  slurp - A passive NNTP transfer client, v1.08, Part02/03
  4. Message-ID: <1993Aug22.013227.28491@sparky.sterling.com>
  5. X-Md4-Signature: 5f17fc321783aa4745c83a557afbd1eb
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Sun, 22 Aug 1993 01:32:27 GMT
  9. Approved: kent@sparky.sterling.com
  10.  
  11. Submitted-by: steveh@orbital.demon.co.uk (Stephen Hebditch)
  12. Posting-number: Volume 39, Issue 38
  13. Archive-name: slurp/part02
  14. Environment: ANSI-C, UNIX
  15. Supersedes: slurp: Volume 36, Issue 13-14
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then feed it
  19. # into a shell via "sh file" or similar.  To overwrite existing files,
  20. # type "sh file -c".
  21. # Contents:  HISTORY conf.h fakesyslog.c history.c misc.c nntp.h
  22. #   slurp.1 slurp.h sockets.c space.c
  23. # Wrapped by kent@sparky on Sat Aug 21 20:28:15 1993
  24. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  25. echo If this archive is complete, you will see the following message:
  26. echo '          "shar: End of archive 2 (of 3)."'
  27. if test -f 'HISTORY' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'HISTORY'\"
  29. else
  30.   echo shar: Extracting \"'HISTORY'\" \(6069 characters\)
  31.   sed "s/^X//" >'HISTORY' <<'END_OF_FILE'
  32. XSLURP HISTORY
  33. X-------------
  34. X
  35. XV1.08
  36. X
  37. X    Unlink backup time file before renaming or an error occurs with the
  38. X    rename under SVR3.
  39. X
  40. X
  41. XV1.07 - 23 June 1993
  42. X
  43. X    Added support for a user-defined time file for use on machines with
  44. X    short filenames which were previously having the time backup
  45. X    trashed and couldn't support sub-lists.
  46. X
  47. X    If a history database type (DBZ, DBM, NDBM) is not defined then
  48. X    don't do any history lookups. This is useful for people using slurp
  49. X    on a machine where news is not running - perhaps piping batches to
  50. X    uux for sending on to another machine.
  51. X
  52. X    Fixed problem where if slurp was interrupted before the NEWNEWS
  53. X    section had completed, an invalid time would be written to the
  54. X    slurp.<hostname> file.
  55. X
  56. X    Duplicate socket file descriptor and then carry out a separate
  57. X    fdopen for read and write on each descriptor. This fixes some stdio
  58. X    memory problems that were caused by fdopening read and write
  59. X    streams on the same descriptor.
  60. X
  61. X    Rewrote get_ids function, removing some potential problems with its
  62. X    previous implementation.
  63. X
  64. X    Rewrote read_sys function (again!).
  65. X
  66. X    In process_id when in debug mode print after a message ID if ID
  67. X    discarded due to hitting maximum number of articles or was already
  68. X    present in the tree.
  69. X
  70. X    Removed inclusion of <unistd.h> in time.c and sockets.c - if it is
  71. X    needed then it will be included in slurp.h.
  72. X
  73. X    Replaced bzero and bcopy with ANSI memset and memcpy functions
  74. X    throughout, plus a few other bits of tidying up to make the Keep C
  75. X    Source Tidy Campaign happy.
  76. X
  77. X
  78. XV1.06 - 22 April 1993
  79. X
  80. X    Added signal handler to slurp.c to trap SIGHUP, SIGINT, SIGQUIT and
  81. X    SIGTERM. If they occur then the signal is reported to syslog, any
  82. X    currently open batch is submitted to the news system and the
  83. X    message IDs of any unretrieved articles are dumped to the
  84. X    slurp.<hostname> file.
  85. X
  86. X    Added NOBUFFOUT option. If defined, will turn off stdio buffering
  87. X    for the output stream to the server. This is necessary for ISC, SCO
  88. X    and some other SVR3 implementations which will otherwise give a
  89. X    memory fault when the socket is written to.
  90. X
  91. X    Added UNISTD option. If undefined then slurp won't include
  92. X    <unistd.h> which isn't present on some versions of UNIX.
  93. X
  94. X    If an ERR_ACCESS (code 502) result code is reported by the server
  95. X    when retrieving an article, then it will be treated as a missing
  96. X    article.
  97. X
  98. X    Correctly defined server_time in slurp.h - was long instead of
  99. X    time_t.
  100. X
  101. X
  102. XV1.05 - 1 March 1993
  103. X
  104. X    Completely cleaned up space.c. Added proper support for space
  105. X    checking in SVR4.
  106. X
  107. X    Modified read_sys so that it is possible to have lines in the
  108. X    slurp.sys file which are longer than BUFSIZ.
  109. X
  110. X    Check unretrieved message IDs in the slurp.<hostname> file start
  111. X    and end with chevrons.
  112. X
  113. X    Moved sublist in the command line arguments to being specified
  114. X    after the hostname with a slash separating them, to make things
  115. X    more consistent.
  116. X
  117. X    A few more minor tidy-ups, in particular portability has been
  118. X    improved in a few places.
  119. X
  120. X
  121. XV1.04 - 14 February 1993
  122. X
  123. X    Malloc message id separately from mnode structure as the previous
  124. X    method seemed to cause problems on some architectures.
  125. X
  126. X    Now handles article lines of >= 511 bytes without overwriting
  127. X    memory.
  128. X
  129. X    Support for simple authorisation protocol.
  130. X
  131. X    Support for INN 'MODE READER' command.
  132. X
  133. X    read_sys rewritten to allow command line flags to be specified for
  134. X    servers, support having more than one set of newsgroups to be
  135. X    retrieved from the same server, and provide the username and
  136. X    password for the simple authorisation protocol.
  137. X
  138. X    New choice of piping articles to rnews (possibly in one batch only)
  139. X    or writing article batches to the incoming news / rnews spool
  140. X    directory. This will provide a speed-up for users of INN.
  141. X
  142. X    Replaced slurp.tim file with slurp.<hostname> files, solving
  143. X    locking problems and providing support for the enhancement below.
  144. X
  145. X    If an error occurs during the article fetching stage, then dump the
  146. X    message ids of articles not yet retrieved to slurp.<hostname>.
  147. X    These can then be picked up in the next session, without having to
  148. X    restart the NEWNEWS back at the previous time.
  149. X
  150. X    No requirement for slurp.<hostname> to exist as slurp.tim used to
  151. X    have to be if you wanted a time written out.
  152. X
  153. X    Re-arranged the command line options.
  154. X
  155. X
  156. XV1.03 - 19 December 1992
  157. X
  158. X    Added extra compilation configuration option for machines that
  159. X    don't have strerror().
  160. X
  161. X    If a temporary file was opened for reading a long article into
  162. X    which wouldn't fit in memory, then it was flushed at the end of
  163. X    read_article. Unfortunately, the test wasn't done correctly so if a
  164. X    long article was once read in, it would keep flushing the now
  165. X    invalid file descriptor on future calls. Fixed by removing this
  166. X    altogether as the subsequent rewind would do the job anyway.
  167. X
  168. X    Open syslog *before* we start doing things that might want to write
  169. X    to it... Connected, articles retrieved and speed messages logged
  170. X    as LOG_INFO instead of the previously wrong LOG_NOTICE.
  171. X
  172. X    When mallocing space for the article id tree, only malloc enough
  173. X    room for the article id and left/right node pointers, not the whole
  174. X    structure, saving oodles of memory.
  175. X
  176. X    Corrected the test for the maximum size of a NEWNEWS request line.
  177. X
  178. X    Various minor tidy-ups.
  179. X
  180. X    Added manual page and made various improvements to the
  181. X    documentation.
  182. X
  183. X
  184. XV1.02 - 7 December 1992
  185. X
  186. X    Corrected openlog calls so correct 4.2/4.3 version of syslog is
  187. X    used.
  188. X
  189. X
  190. XV1.01 - 6 December 1992
  191. X
  192. X    Fixed some problems with null-dereferencing of nn_distributions.
  193. X    New slurp.tim not written if maximum number of messages that can
  194. X    be transferred is hit.
  195. X
  196. X    When debugging switched on, print line being sent to server before
  197. X    it is sent rather than after.
  198. X
  199. X    Added documentation on return codes.
  200. X
  201. X
  202. XV1.00 - 2 December 1992
  203. X
  204. X    Initial release.
  205. X
  206. X---- END OF DOCUMENTATION
  207. END_OF_FILE
  208.   if test 6069 -ne `wc -c <'HISTORY'`; then
  209.     echo shar: \"'HISTORY'\" unpacked with wrong size!
  210.   fi
  211.   # end of 'HISTORY'
  212. fi
  213. if test -f 'conf.h' -a "${1}" != "-c" ; then 
  214.   echo shar: Will not clobber existing file \"'conf.h'\"
  215. else
  216.   echo shar: Extracting \"'conf.h'\" \(6012 characters\)
  217.   sed "s/^X//" >'conf.h' <<'END_OF_FILE'
  218. X/*
  219. X * conf.h - compilation options for slurp
  220. X *
  221. X * Copyright (C) 1992/93 Stephen Hebditch. All rights reserved.
  222. X * TQM Communications, BCM Box 225, London, WC1N 3XX.
  223. X * steveh@orbital.demon.co.uk  +44 836 825962
  224. X *
  225. X * See README for more information and disclaimers
  226. X *
  227. X * $Id: conf.h,v 1.8 1993/08/20 10:36:02 root Exp root $
  228. X *
  229. X * $Log: conf.h,v $
  230. X * Revision 1.8  1993/08/20  10:36:02  root
  231. X * Removed SIGRET definition as unused.
  232. X *
  233. X * Revision 1.7  1993/06/23  10:22:38  root
  234. X * Removed NOBUFFOUT option.
  235. X * Amended description for DBM, NDBM and DBZ as can now have none
  236. X * defined if don't want to do history lookups.
  237. X * Amended RNEWS description to describe how to send batches via UUCP.
  238. X * Upped MAXCACHE value and improved description.
  239. X *
  240. X * Revision 1.6  1993/04/22  18:28:01  root
  241. X * Added new compilation options for NOBUFFOUT and UNISTD.
  242. X *
  243. X * Revision 1.5  1993/03/01  17:41:09  root
  244. X * Changed USG definition to SYSV, now used solely in slurp.h.
  245. X * Added explanation of defines for space.c.
  246. X *
  247. X * Revision 1.4  1993/02/14  14:36:16  root
  248. X * Removed BATCHARTSMAX, MSGIDMAX.
  249. X * Added INDIR, BATCHNAME.
  250. X * Modified TIMFILE, RNEWS.
  251. X *
  252. X * Revision 1.0  1992/10/29
  253. X * Initial coding.
  254. X *
  255. X */
  256. X
  257. X
  258. X/* SLURP CONFIGURATION
  259. X   =================== */
  260. X
  261. X/* Set these to the location of the slurp configuration files - NEWSLIB
  262. X   is usually a good place for them. The hostname will be added to the
  263. X   end of TIMFILE. */
  264. X
  265. X#define SYSFILE            "/usr/lib/news/slurp.sys"
  266. X#define TIMFILE            "/usr/lib/news/slurp."
  267. X
  268. X
  269. X/* If SPEEDUP is defined then there will always be one ARTICLE request
  270. X   stacked up at the NNTP server before the current article has
  271. X   finished being received. Although not strictly conforming to the
  272. X   standard this allows a much greater article throughput. */
  273. X
  274. X#define SPEEDUP
  275. X
  276. X
  277. X/* If defined then the number of characters per second transferred
  278. X   during the article request phase will be logged. */
  279. X
  280. X#define SPEEDSTATS
  281. X
  282. X
  283. X/* MAXCACHE sets the maximum number of articles that may be requested
  284. X   in any one session. If this is exceeded then it noted in the log and
  285. X   the new time for the next NEWNEWS will not be written. If you are
  286. X   transferring a large amount of news then you will probably need to
  287. X   increase this value. */
  288. X
  289. X#define MAXCACHE        8192
  290. X
  291. X
  292. X/* NEWS CONFIGURATION
  293. X   ================== */
  294. X
  295. X/* The location of the news history file. */
  296. X
  297. X#define HISTORY_FILE    "/usr/lib/news/history"
  298. X
  299. X
  300. X/* The database format used by the news history file. For modern C News
  301. X   and INN this will almost certainly be DBZ. If none of these are
  302. X   defined then history lookups will not take place. */
  303. X
  304. X#define DBZ
  305. X#undef    DBM
  306. X#undef    NDBM
  307. X
  308. X
  309. X/* The location of the rnews program - or any other program you wish to
  310. X   receive batches on stdin. If defined, slurp will pipe batches of
  311. X   articles to this program rather than creating batch files in INDIR */
  312. X
  313. X/* #define RNEWS        "/usr/bin/rnews" /* */
  314. X/* #define RNEWS        "compress | uux - -r -glow spooky!rnews" /* */
  315. X
  316. X
  317. X/* The place where incoming batches will be placed if RNEWS is not
  318. X   defined. This is usually /usr/spool/news/in.coming for C News and
  319. X   /var/spool/rnews for INN. */
  320. X
  321. X#define INDIR            "/var/spool/news/in.coming"
  322. X
  323. X
  324. X/* The optimum size of a news batch. Normally this can be left at
  325. X   300000L.  If you are using INN and have RNEWS defined, then set this
  326. X   to 0 so the pipe to rnews (and the socket to innd) is kept open
  327. X   throughout the session. */
  328. X
  329. X#define BATCHSIZEMAX    300000L
  330. X
  331. X
  332. X/* The location of the spool directory holding news articles. This is
  333. X   needed so we can check if there is enough space before starting to
  334. X   build up another batch of articles. */
  335. X
  336. X#define SPOOLDIR        "/var/spool/news"
  337. X
  338. X
  339. X/* If less then MINFREE blocks are available on the disk containing
  340. X   SPOOLDIR or less than MINFILES inodes are available then slurp will
  341. X   be aborted. If MINFREE is not defined then a space check is not
  342. X   carried out. */
  343. X
  344. X#define MINFREE 4000
  345. X/* #define MINFILES 1000 /* */
  346. X                        
  347. X
  348. X/* UNIX VERSION CONFIGURATION
  349. X   ========================== */
  350. X
  351. X/* Define SYSV if you are running a System V derivative and need
  352. X   <string.h>, <time.h> & <fcntl.h>. If it is undefined, then you're
  353. X   BSDish and need <strings.h> & <sys/time.h>. */
  354. X
  355. X#define SYSV
  356. X
  357. X
  358. X/* You may need additional defines to use the correct method of
  359. X   determining how much disk space there is on the file system
  360. X   containing your news spool. space.c understands defines for SVR4,
  361. X   SVR3, sun, hpux, pyr, hp300, __NeXT__, linux, apollo, ultrix,
  362. X   __bsdi__ and CMU_MACH. For other systems you may need to amend
  363. X   space.c. */
  364. X
  365. X#define SVR4
  366. X
  367. X
  368. X/* Define if your system has <unistd.h> */
  369. X
  370. X#define UNISTD
  371. X
  372. X
  373. X/* Define if your system has extern char sys_errlist[], but no strerror() */
  374. X
  375. X#undef SYS_ERRLIST
  376. X
  377. X
  378. X/* The facility name which syslog reports errors and stats under. If
  379. X   you don't want to use syslog for reporting then undefine and the
  380. X   information will be written to stderr instead. */
  381. X
  382. X#define SYSLOG            LOG_NEWS
  383. X
  384. X
  385. X/* If you don't have syslog then you can use the supplied fakesyslog
  386. X   instead. Define FAKESYSLOG to be the name of the file to contain the
  387. X   log. If your host supports the BSD fdopen() function and the
  388. X   O_APPEND flag to open(), you should define FAKEAPPEND with
  389. X   FAKESYSLOG so that multiple copies of nntpd don't trash the log with
  390. X   buffered fprintfs. */
  391. X   
  392. X/* #define FAKESYSLOG      "/usr/lib/news/nntplog" /* */
  393. X/* #define FAKEAPPEND /* */
  394. X
  395. X
  396. X/* STUFF BELOW PROBABLY DOESN'T NEED ALTERING
  397. X   ========================================== */
  398. X
  399. X#define COPYSIZE        16384    /* Articles bigger than this size will
  400. X                                   be written to a temporary file while
  401. X                                   they are being retrieved, rather than
  402. X                                   stored in memory */
  403. X
  404. X#define TIMEOUT            60 * 10    /* Max time to wait for a line from the
  405. X                                   server. */
  406. X
  407. X#define BATCHNAME        "nntp.XXXXXX"    /* Temporary filename for NNTP
  408. X                                           batch */
  409. X
  410. X/* END-OF-FILE */
  411. END_OF_FILE
  412.   if test 6012 -ne `wc -c <'conf.h'`; then
  413.     echo shar: \"'conf.h'\" unpacked with wrong size!
  414.   fi
  415.   # end of 'conf.h'
  416. fi
  417. if test -f 'fakesyslog.c' -a "${1}" != "-c" ; then 
  418.   echo shar: Will not clobber existing file \"'fakesyslog.c'\"
  419. else
  420.   echo shar: Extracting \"'fakesyslog.c'\" \(3189 characters\)
  421.   sed "s/^X//" >'fakesyslog.c' <<'END_OF_FILE'
  422. X/*
  423. X * $Id: fakesyslog.c,v 1.7 1993/06/07 11:05:52 root Exp $
  424. X *
  425. X * Fake syslog routines for systems that don't have syslog.
  426. X * Taken from an idea by Paul McKenny, <mckenny@sri-unix.arpa>.
  427. X * (Unfortunately, Paul, I can't distribute the real syslog code
  428. X * as you suggested ... sigh.)
  429. X *
  430. X * Warning: this file contains joe code that may offend you.
  431. X *
  432. X * $Log: fakesyslog.c,v $
  433. X * Revision 1.7  1993/06/07  11:05:52  root
  434. X * Include fcntl.h if SYSV is defined, rather than if FCNTL is.
  435. X *
  436. X * Revision 1.4  1993/02/14  14:51:30  root
  437. X * No changes.
  438. X *
  439. X */
  440. X
  441. X#include "slurp.h"
  442. X
  443. X#ifdef FAKESYSLOG
  444. X
  445. X#include "fakesyslog.h"
  446. X
  447. X#include <stdio.h>
  448. X#include <sys/signal.h>
  449. X#include <sys/types.h>
  450. X
  451. X#ifdef FAKEAPPEND
  452. X#include <sys/file.h>
  453. X#endif
  454. X
  455. X#ifdef SYSV
  456. X#include <fcntl.h>
  457. X#endif
  458. X
  459. Xextern    int    errno;
  460. Xextern    int    sys_nerr;
  461. Xextern    char    *sys_errlist[];
  462. X
  463. Xstatic FILE    *logfp;
  464. Xstatic int    failed = 0;
  465. Xstatic char    *ident = "syslog";
  466. Xstatic int     opt = 0;
  467. X#ifndef BSD_42
  468. Xstatic int    fac = 0;
  469. X#endif
  470. X
  471. Xextern char    *strcpy(), *strcat(), *ctime();
  472. Xextern time_t    time();
  473. X
  474. Xresetlog()
  475. X{
  476. X    closelog();
  477. X    failed = 0;
  478. X    if (logfp == NULL) {
  479. X#ifdef BSD_42
  480. X        openlog(ident, opt);
  481. X#else
  482. X        openlog(ident, opt, fac);
  483. X#endif
  484. X        if (logfp == NULL) {
  485. X            failed = 1;
  486. X            return;
  487. X        }
  488. X    }
  489. X}
  490. X
  491. X#ifdef BSD_42
  492. Xopenlog(newident,logopt)
  493. X    char *newident;
  494. X    int logopt;
  495. X#else
  496. Xopenlog(newident,logopt,facility)
  497. X    char *newident;
  498. X    int logopt, facility;
  499. X#endif
  500. X{
  501. X#ifdef FAKEAPPEND
  502. X/*
  503. X * why can't stdio give us the capability of O_APPEND?
  504. X */
  505. X    int fd;
  506. X
  507. X    fd = open(FAKESYSLOG, O_WRONLY|O_APPEND, 0664);
  508. X    if (fd < 0)
  509. X        logfp = NULL;
  510. X    else
  511. X        logfp = fdopen(fd, "a");
  512. X#else
  513. X    logfp = fopen(FAKESYSLOG, "a");
  514. X#endif
  515. X
  516. X    (void)signal(SIGHUP, resetlog);
  517. X
  518. X    if (newident && *newident)
  519. X        ident = newident;
  520. X    opt = logopt;
  521. X#ifndef BSD_42
  522. X    fac = facility;
  523. X#endif
  524. X}
  525. X
  526. Xcloselog()
  527. X{
  528. X    if (logfp) {
  529. X        (void)fclose(logfp);
  530. X        failed = 0;
  531. X        logfp = NULL;
  532. X    }
  533. X}
  534. X
  535. X/*ARGSUSED*/
  536. Xsetlogmask(maskpri)
  537. X    int maskpri;
  538. X{
  539. X}
  540. X
  541. Xsyslog(pri, msg, x1, x2, x3, x4, x5, x6)
  542. X    int    pri;
  543. X    char    *msg, *x1, *x2, *x3, *x4, *x5, *x6;
  544. X{
  545. X    char        buf[1024];
  546. X    char        *cp, *bp;
  547. X    time_t        clock;
  548. X
  549. X    if (failed)
  550. X        return;
  551. X
  552. X    if (logfp == NULL) {
  553. X#ifdef BSD_42
  554. X        openlog(ident, opt);
  555. X#else
  556. X        openlog(ident, opt, fac);
  557. X#endif
  558. X        if (logfp == NULL) {
  559. X            failed = 1;
  560. X            return;
  561. X        }
  562. X    }
  563. X
  564. X    (void) time(&clock);
  565. X    (void) strcpy(buf, ctime(&clock)+4);
  566. X    *(bp = buf + 16) = '\0';
  567. X
  568. X    (void) sprintf(bp, "localhost %s", ident ? ident : "");
  569. X    bp += strlen(bp);
  570. X
  571. X    if (opt&LOG_PID) {
  572. X        /* don't cache getpid() - who knows when we'll fork() */
  573. X        (void) sprintf(bp, "[%d]", getpid());
  574. X        bp += strlen(bp);
  575. X    }
  576. X
  577. X    if (ident) {
  578. X        (void) strcat(bp, ": ");
  579. X        bp += 2;
  580. X    } else {
  581. X        (void) strcat(bp, " ");
  582. X        bp ++;
  583. X    }
  584. X
  585. X    for (cp = msg; *cp; cp++) {
  586. X        if (*cp == '%' && cp[1] == 'm') {
  587. X            *bp = '\0';
  588. X            if (errno >= sys_nerr || errno < 0) {
  589. X                char    work[32];
  590. X                (void)sprintf(work, "unknown error #%d", errno);
  591. X                (void)strcat(bp, work);
  592. X            } else
  593. X                (void)strcat(bp, sys_errlist[errno]);
  594. X            bp = buf + strlen(buf);
  595. X            cp++;
  596. X        } else {
  597. X            *bp++ = *cp;
  598. X        }
  599. X    }
  600. X    *bp = '\0';
  601. X    /* Ah, the semantic security of C ... */
  602. X    if (bp[-1] != '\n')
  603. X        (void) strcat(bp, "\n");
  604. X
  605. X    fprintf(logfp, buf, x1, x2, x3, x4, x5, x6);
  606. X    (void) fflush(logfp);
  607. X}
  608. X
  609. X#endif
  610. END_OF_FILE
  611.   if test 3189 -ne `wc -c <'fakesyslog.c'`; then
  612.     echo shar: \"'fakesyslog.c'\" unpacked with wrong size!
  613.   fi
  614.   # end of 'fakesyslog.c'
  615. fi
  616. if test -f 'history.c' -a "${1}" != "-c" ; then 
  617.   echo shar: Will not clobber existing file \"'history.c'\"
  618. else
  619.   echo shar: Extracting \"'history.c'\" \(2024 characters\)
  620.   sed "s/^X//" >'history.c' <<'END_OF_FILE'
  621. X/*
  622. X * history - handle a news history file
  623. X *
  624. X * Copyright (C) 1992/93 Stephen Hebditch. All rights reserved.
  625. X * TQM Communications, BCM Box 225, London, WC1N 3XX.
  626. X * steveh@orbital.demon.co.uk  +44 836 825962
  627. X *
  628. X * See README for more information and disclaimers
  629. X *
  630. X * Routines to open and close a C-News style history file and determine
  631. X * whether or not a particular message id exists in the history file.
  632. X *
  633. X * $Id: history.c,v 1.7 1993/06/07 11:07:14 root Exp $
  634. X *
  635. X * $Log: history.c,v $
  636. X * Revision 1.7  1993/06/07  11:07:14  root
  637. X * If neither DBZ, DBM or NDBM are defined then don't carry out
  638. X * any history file lookups.
  639. X *
  640. X * Revision 1.6  1993/04/22  18:07:11  root
  641. X * No changes - put back in RCS after the RCS file went missing...
  642. X *
  643. X * Revision 1.4  1993/02/14  14:51:59  root
  644. X * No changes.
  645. X *
  646. X * Revision 1.0  1992/09/92
  647. X * Initial coding.
  648. X *
  649. X */
  650. X
  651. X#include "slurp.h"
  652. X
  653. X#ifdef DBM
  654. X  #undef NULL
  655. X  #include <dbm.h>
  656. X  #undef NULL
  657. X  #define NULL 0
  658. X#endif
  659. X
  660. X#ifdef DBZ
  661. X  #include <dbz.h>
  662. X#endif
  663. X
  664. X#ifdef NDBM
  665. X  #include <ndbm.h>
  666. X  #include <fcntl.h>
  667. X  static DBM *db = NULL;
  668. X#endif
  669. X
  670. X
  671. X/*
  672. X * open_history - Open history file
  673. X */
  674. X
  675. X    int
  676. Xopen_history ()
  677. X    {
  678. X#if defined (DBM) || defined (DBZ)
  679. X    if (dbminit (HISTORY_FILE) < 0)
  680. X        return (1);
  681. X#elif defined (NDBM)
  682. X     if ((db = dbm_open (HISTORY_FILE, O_RDONLY, 0)) == NULL)
  683. X        return (1);
  684. X#endif
  685. X
  686. X    return (0);
  687. X    }
  688. X
  689. X
  690. X/*
  691. X * close_history - Close history file
  692. X */
  693. X
  694. X    void
  695. Xclose_history ()
  696. X    {
  697. X#if defined (DBM) || defined (DBZ)
  698. X    (void) dbmclose ();
  699. X#elif defined (NDBM)
  700. X     dbm_close (db);
  701. X#endif
  702. X    }
  703. X
  704. X
  705. X/*
  706. X * Determine if message id already exists in the history file
  707. X */
  708. X
  709. X    int
  710. Xcheck_id (char *message_id)
  711. X    {
  712. X#if defined (DBM) || defined (NDBM) || defined (DBZ)
  713. X    datum k, d;
  714. X
  715. X/* Now check for presence with dbm/ndbm */
  716. X
  717. X    k.dptr = message_id;
  718. X    k.dsize = strlen (message_id) + 1;
  719. X#endif
  720. X
  721. X#if defined (DBM) || defined (DBZ)
  722. X    d = fetch (k);
  723. X    return (d.dptr == NULL);
  724. X#elif defined (NDBM)
  725. X     d = dbm_fetch (db, k);
  726. X    return (d.dptr == NULL);
  727. X#else
  728. X    return (TRUE);
  729. X#endif
  730. X    }
  731. X
  732. X/* END-OF-FILE */
  733. END_OF_FILE
  734.   if test 2024 -ne `wc -c <'history.c'`; then
  735.     echo shar: \"'history.c'\" unpacked with wrong size!
  736.   fi
  737.   # end of 'history.c'
  738. fi
  739. if test -f 'misc.c' -a "${1}" != "-c" ; then 
  740.   echo shar: Will not clobber existing file \"'misc.c'\"
  741. else
  742.   echo shar: Extracting \"'misc.c'\" \(3335 characters\)
  743.   sed "s/^X//" >'misc.c' <<'END_OF_FILE'
  744. X/*
  745. X * misc - general miscellaneous routines
  746. X *
  747. X * Copyright (C) 1992/93 Stephen Hebditch. All rights reserved.
  748. X * TQM Communications, BCM Box 225, London, WC1N 3XX.
  749. X * steveh@orbital.demon.co.uk  +44 836 825962
  750. X *
  751. X * See README for more information and disclaimers
  752. X *
  753. X * Assorted miscellaneous routines.
  754. X *
  755. X * $Id: misc.c,v 1.7 1993/06/07 11:08:12 root Exp $
  756. X *
  757. X * $Log: misc.c,v $
  758. X * Revision 1.7  1993/06/07  11:08:12  root
  759. X * Added stradd function.
  760. X *
  761. X * Revision 1.6  1993/04/22  18:31:11  root
  762. X * Hey, it's 1993!
  763. X *
  764. X * Revision 1.4  1993/02/14  14:53:27  root
  765. X * In log_sys if any message ids are present, then submit the
  766. X * currently open batch and write out the unretrieved message
  767. X * ids to slurp.<hostname> along with the new time.
  768. X *
  769. X * Revision 1.0  1992/11/27
  770. X * Initial coding.
  771. X *
  772. X */
  773. X
  774. X#include "slurp.h"
  775. X#include <stdarg.h>
  776. X
  777. Xstatic int in_log_sys = FALSE;
  778. X
  779. Xstatic void log_doit (int sysflag, const char *fmt, va_list ap);
  780. X
  781. X
  782. X/*
  783. X * stradd - If string1 is not NULL, then concatenate string1 and
  784. X * string2, remallocing the space the first occupies to provide
  785. X * enough room for them both. If string1 is null, then malloc space
  786. X * for string2 and copy string2 to it. Returns location of string.
  787. X */
  788. X
  789. X    char *
  790. Xstradd (const char *string1, const char *string2)
  791. X    {
  792. X    size_t len;
  793. X    char *new;
  794. X
  795. X    if (string1 == NULL)
  796. X        {
  797. X        len = strlen (string2) + sizeof (char);
  798. X        if ((new = (char *) malloc (len)) == NULL)
  799. X            log_sys ("stradd: malloc %d bytes", len);
  800. X        (void) strcpy (new, string2);
  801. X        }
  802. X    else
  803. X        {
  804. X        len = strlen (string1) + strlen (string2) + sizeof (char);
  805. X        if ((new = (char *) realloc ((void *) string1, len)) == NULL)
  806. X            log_sys ("stradd: realloc %d bytes", len);
  807. X        (void) strcat (new, string2);
  808. X        }
  809. X    return (new);
  810. X    }
  811. X
  812. X
  813. X/*
  814. X * log_ret - Log a message to stderr or syslog related to a system call
  815. X * containing the appropriate system error message and return.
  816. X */
  817. X
  818. X    void
  819. Xlog_ret (const char *fmt, ...)
  820. X    {
  821. X    va_list ap;
  822. X
  823. X    va_start (ap, fmt);
  824. X    log_doit (TRUE, fmt, ap);
  825. X    va_end (ap);
  826. X    return;
  827. X    }
  828. X
  829. X
  830. X/*
  831. X * log_sys - Log a message to stderr or syslog related to a system call.
  832. X * containing the appropriate system error message and exit program.
  833. X * If any message ids in the tree then write out slurp.<hostname> file
  834. X * and close the batch if open.
  835. X */
  836. X
  837. X    void
  838. Xlog_sys (const char *fmt, ...)
  839. X    {
  840. X    va_list ap;
  841. X
  842. X    va_start (ap, fmt);
  843. X    log_doit (TRUE, fmt, ap);
  844. X    va_end (ap);
  845. X    if ((!in_log_sys) && (root != NULL))
  846. X        {
  847. X        in_log_sys = TRUE;
  848. X        enqueue_batch ();
  849. X        if ((!no_time_flag) && (!no_id_load_flag))
  850. X            set_ntime ();
  851. X        }
  852. X    exit (1);
  853. X    }
  854. X
  855. X
  856. X/*
  857. X * log_msg - Log a message to stderr or syslog unrelated to a system call.
  858. X */
  859. X
  860. X    void
  861. Xlog_msg (const char *fmt, ...)
  862. X    {
  863. X    va_list ap;
  864. X
  865. X    va_start (ap, fmt);
  866. X    log_doit (FALSE, fmt, ap);
  867. X    va_end (ap);
  868. X    return;
  869. X    }
  870. X
  871. X
  872. X/*
  873. X * log_doit - Write an error message to stderr if debug_flag is set or
  874. X * syslog if not set. If sysflag is true then the last system error
  875. X * message is appended.
  876. X */
  877. X
  878. X    static void
  879. Xlog_doit (int sysflag, const char *fmt, va_list ap)
  880. X    {
  881. X    int errnosave;
  882. X    char buf [BUFSIZ];
  883. X
  884. X    errnosave = errno;
  885. X    (void) vsprintf (buf, fmt, ap);
  886. X    if (sysflag)
  887. X        (void) sprintf (buf + strlen (buf), ": %s", strerror (errnosave));
  888. X    (void) strcat (buf, "\n");
  889. X#ifdef SYSLOG
  890. X        if (!debug_flag)
  891. X            syslog (LOG_ERR, buf);
  892. X        else
  893. X#endif
  894. X            (void) fprintf (stderr, "%s: %s", pname, buf);
  895. X    }
  896. X
  897. X
  898. X/* END-OF-FILE */
  899. END_OF_FILE
  900.   if test 3335 -ne `wc -c <'misc.c'`; then
  901.     echo shar: \"'misc.c'\" unpacked with wrong size!
  902.   fi
  903.   # end of 'misc.c'
  904. fi
  905. if test -f 'nntp.h' -a "${1}" != "-c" ; then 
  906.   echo shar: Will not clobber existing file \"'nntp.h'\"
  907. else
  908.   echo shar: Extracting \"'nntp.h'\" \(3070 characters\)
  909.   sed "s/^X//" >'nntp.h' <<'END_OF_FILE'
  910. X/*
  911. X * Response codes for NNTP server
  912. X *
  913. X * @(#)Header: nntp.h,v 1.8 90/07/05 02:08:31 sob Exp $
  914. X *
  915. X * First digit:
  916. X *
  917. X *    1xx    Informative message
  918. X *    2xx    Command ok
  919. X *    3xx    Command ok so far, continue
  920. X *    4xx    Command was correct, but couldn't be performed
  921. X *        for some specified reason.
  922. X *    5xx    Command unimplemented, incorrect, or a
  923. X *        program error has occurred.
  924. X *
  925. X * Second digit:
  926. X *
  927. X *    x0x    Connection, setup, miscellaneous
  928. X *    x1x    Newsgroup selection
  929. X *    x2x    Article selection
  930. X *    x3x    Distribution
  931. X *    x4x    Posting
  932. X */
  933. X
  934. X#define    CHAR_INF    '1'
  935. X#define    CHAR_OK        '2'
  936. X#define    CHAR_CONT    '3'
  937. X#define    CHAR_ERR    '4'
  938. X#define    CHAR_FATAL    '5'
  939. X
  940. X#define    INF_HELP    100    /* Help text on way */
  941. X#define    INF_AUTH    180    /* Authorization capabilities */
  942. X#define    INF_DEBUG    199    /* Debug output */
  943. X
  944. X#define    OK_CANPOST    200    /* Hello; you can post */
  945. X#define    OK_NOPOST    201    /* Hello; you can't post */
  946. X#define    OK_SLAVE    202    /* Slave status noted */
  947. X#define    OK_GOODBYE    205    /* Closing connection */
  948. X#define    OK_GROUP    211    /* Group selected */
  949. X#define    OK_GROUPS    215    /* Newsgroups follow */
  950. X#define    OK_ARTICLE    220    /* Article (head & body) follows */
  951. X#define    OK_HEAD        221    /* Head follows */
  952. X#define    OK_BODY        222    /* Body follows */
  953. X#define    OK_NOTEXT    223    /* No text sent -- stat, next, last */
  954. X#define    OK_NEWNEWS    230    /* New articles by message-id follow */
  955. X#define    OK_NEWGROUPS    231    /* New newsgroups follow */
  956. X#define    OK_XFERED    235    /* Article transferred successfully */
  957. X#define    OK_POSTED    240    /* Article posted successfully */
  958. X#define    OK_AUTHSYS    280    /* Authorization system ok */
  959. X#define    OK_AUTH        281    /* Authorization (user/pass) ok */
  960. X
  961. X#define    CONT_XFER    335    /* Continue to send article */
  962. X#define    CONT_POST    340    /* Continue to post article */
  963. X#define    NEED_AUTHINFO    380    /* authorization is required */
  964. X#define    NEED_AUTHDATA    381    /* <type> authorization data required */
  965. X
  966. X#define    ERR_GOODBYE    400    /* Have to hang up for some reason */
  967. X#define    ERR_NOGROUP    411    /* No such newsgroup */
  968. X#define    ERR_NCING    412    /* Not currently in newsgroup */
  969. X#define    ERR_NOCRNT    420    /* No current article selected */
  970. X#define    ERR_NONEXT    421    /* No next article in this group */
  971. X#define    ERR_NOPREV    422    /* No previous article in this group */
  972. X#define    ERR_NOARTIG    423    /* No such article in this group */
  973. X#define    ERR_NOART    430    /* No such article at all */
  974. X#define    ERR_GOTIT    435    /* Already got that article, don't send */
  975. X#define    ERR_XFERFAIL    436    /* Transfer failed */
  976. X#define    ERR_XFERRJCT    437    /* Article rejected, don't resend */
  977. X#define    ERR_NOPOST    440    /* Posting not allowed */
  978. X#define    ERR_POSTFAIL    441    /* Posting failed */
  979. X#define    ERR_NOAUTH    480    /* authorization required for command */
  980. X#define    ERR_AUTHSYS    481    /* Authorization system invalid */
  981. X#define    ERR_AUTHREJ    482    /* Authorization data rejected */
  982. X
  983. X#define    ERR_COMMAND    500    /* Command not recognized */
  984. X#define    ERR_CMDSYN    501    /* Command syntax error */
  985. X#define    ERR_ACCESS    502    /* Access to server denied */
  986. X#define    ERR_FAULT    503    /* Program fault, command not performed */
  987. X#define    ERR_AUTHBAD    580    /* Authorization Failed */
  988. X
  989. X/* RFC 977 defines this; don't change it. */
  990. X
  991. X#define    NNTP_STRLEN    512
  992. END_OF_FILE
  993.   if test 3070 -ne `wc -c <'nntp.h'`; then
  994.     echo shar: \"'nntp.h'\" unpacked with wrong size!
  995.   fi
  996.   # end of 'nntp.h'
  997. fi
  998. if test -f 'slurp.1' -a "${1}" != "-c" ; then 
  999.   echo shar: Will not clobber existing file \"'slurp.1'\"
  1000. else
  1001.   echo shar: Extracting \"'slurp.1'\" \(8561 characters\)
  1002.   sed "s/^X//" >'slurp.1' <<'END_OF_FILE'
  1003. X.TH SLURP 1 "20 August 1993" "V1.08"
  1004. X
  1005. X.SH NAME
  1006. X.I slurp
  1007. X\- retrieve netnews articles from a remote NNTP server
  1008. X
  1009. X.SH SYNOPSIS
  1010. X.I slurp
  1011. X[
  1012. X.B \-g
  1013. X.I newsgroups/distributions
  1014. X]
  1015. X[
  1016. X.B \-t
  1017. X.I time
  1018. X]
  1019. X[
  1020. X.B \-a
  1021. X.I username/password
  1022. X]
  1023. X[
  1024. X.B \-d
  1025. X]
  1026. X[
  1027. X.B \-i
  1028. X]
  1029. X[
  1030. X.B \-l
  1031. X]
  1032. X[
  1033. X.B \-r
  1034. X]
  1035. X[
  1036. X.B \-w
  1037. X]
  1038. X.I hostname[ /sublist ][ :timefile ]
  1039. X
  1040. X.SH DESCRIPTION
  1041. X.PP
  1042. X.I Slurp
  1043. Xis an advanced passive NNTP client for UNIX. It will connect to a
  1044. Xremote NNTP server and retrieve articles in a specified set of Usenet
  1045. Xnewsgroups that have arrived after a particular time (typically the
  1046. Xlast time it was invoked) for processing by your local news system.
  1047. X
  1048. X.SH OPTIONS
  1049. X.TP
  1050. X.BI -g " newsgroups/distributions"
  1051. XIf specified then overrides any newsgroups and distributions specification
  1052. Xfor
  1053. X.I hostname
  1054. Xin the 
  1055. X.B slurp.sys
  1056. Xfile.
  1057. X.TP
  1058. X.BI -t " time"
  1059. XRetrieve articles that have arrived at the server after
  1060. X.I time
  1061. Xrather than using the time taken from
  1062. X.BR slurp.<hostname> .
  1063. XThis is in the standard NNTP time format of 'YYMMDD HHMMSS' GMT. For
  1064. Xexample, midnight GMT on the 1st of December 1992 will be '921201
  1065. X000000'. Note that you will need to use quotes around the time and
  1066. Xremember that the time is in GMT, not the local or server time.
  1067. X.TP
  1068. X.BI -a " username/password"
  1069. XIf specified then the username and password combination will be sent to
  1070. Xthe server as part of the simple authorisation protocol when the
  1071. Xconnection is first made.
  1072. X.TP
  1073. X.B -d
  1074. XEnable debugging. This diverts reporting to stderr instead of syslog
  1075. Xand turns on extra debugging output.
  1076. X.TP
  1077. X.B -i
  1078. XNormally if an error occurs while fetching articles from the server,
  1079. Xthe remaining message IDs to be fetched are written to
  1080. X.B slurp.<hostname>
  1081. Xso that they may be retrieved in the next session without having to
  1082. Xrestart the NEWNEWS at the same point. With this option selected, no
  1083. Xmessage IDs will be read from
  1084. X.B slurp.<hostname>
  1085. Xand in the event of an error occurring,
  1086. X.B slurp.<hostname>
  1087. Xwill not be updated.
  1088. X.TP
  1089. X.B -l
  1090. XLocal time is used to set the start time in
  1091. X.B slurp.<hostname>
  1092. Xfor the next news retrieval, rather than setting the start time through
  1093. Xa call to the tcp time service at the remote server.
  1094. X.TP
  1095. X.B -r
  1096. XA 'MODE READER' command is sent to the remote server. This is used when
  1097. Xconnecting with an INN site which needs to be switched from innd to
  1098. Xnnrpd so the NEWNEWS command can be issued.
  1099. X.TP
  1100. X.B -w
  1101. XThe time for the next news retrieval is not written to
  1102. X.BR slurp.<hostname> \.
  1103. X.TP
  1104. X.I hostname
  1105. XThe hostname of the remote NNTP server to connect to. This must be
  1106. Xspecified.
  1107. X.TP
  1108. X.I [/sublist]
  1109. XIf this is specified, then the entry in
  1110. X.B slurp.sys
  1111. Xwhich contains
  1112. X.I /sublist
  1113. Xafter the hostname will be used. This lets you take different groups
  1114. Xfrom the same server at different times.
  1115. X.TP
  1116. X.I [:timefile]
  1117. XUse this to specify an alternate filename to use for the file
  1118. Xcontaining the time for the next NEWNEWS at a particular host. Normally
  1119. Xslurp will use the hostname, but this can cause problems on file
  1120. Xsystems with short filenames.
  1121. X
  1122. X.SH "CONFIGURATION FILES"
  1123. X.PP
  1124. XThere are two configuration files used by
  1125. X.IR slurp .
  1126. X.SS slurp.sys
  1127. X.PP
  1128. XEntries in
  1129. X.B slurp.sys
  1130. Xtake the form
  1131. X.IP
  1132. Xhostname/sublist:groups/distributions:flags:username/password
  1133. X.PP
  1134. XThis format should be familar to people who have used the C News
  1135. X.B sys
  1136. Xfile. Entries for a particular host can be continued on more than one
  1137. Xline by using a '\\' at the end of the line. e.g.
  1138. X.IP
  1139. Xhostname:group1,group2,\\
  1140. X.br
  1141. Xgroup3,group4,group5
  1142. X.PP
  1143. X.I Slurp
  1144. Xis even more picky about the presence of whitespace than C News. It can
  1145. Xonly appear in comments. Comments begin with a '#' and continue to the
  1146. Xend of the line.
  1147. X.PP
  1148. XUsing distributions is
  1149. X.B not
  1150. Xrecommended - they're only really included for completeness. Under
  1151. Xcurrent NNTP implementations, setting distributions requires the server
  1152. Xto open each article, search through for the distributions line and
  1153. Xcheck it against the supplied list. This will not only increase the
  1154. Xload on the server substantially, but increase the amount of time for
  1155. Xthe connection.
  1156. X.PP
  1157. XThere are 3 possible flags: i, l and r which have the same meaning as
  1158. Xthe command line options. If present, username and password will be
  1159. Xsent to the server as part of the simple authorisation protocol when
  1160. Xthe connection is first made.
  1161. X.SS slurp.<hostname>[.<sublist>]
  1162. X.PP
  1163. XThe file
  1164. X.B slurp.<hostname>
  1165. Xcontains the time when
  1166. X.I slurp
  1167. Xlast connected to the NNTP server at <hostname>. If a sublist has been
  1168. Xspecified with the
  1169. X.B -s
  1170. Xoption then this will be appended with a period to the name.
  1171. X.I slurp
  1172. Xcan then use this time to pick up all the articles that have arrived at
  1173. Xthe server since the last session. It may be followed on subsequent
  1174. Xlines by a list of message IDs of articles that are to be retrieved
  1175. Xfrom the server in the next session.
  1176. X.PP
  1177. XEach time
  1178. X.I slurp
  1179. Xis run and
  1180. X.B slurp.<hostname>
  1181. Xupdated, the current
  1182. X.B slurp.<hostname>
  1183. Xwill be backed up in the file
  1184. X.BR slurp.<hostname>.o \.
  1185. X
  1186. X.SH OPERATION
  1187. X.PP
  1188. XWhen run,
  1189. X.I slurp
  1190. Xwill first retrieve the appropriate newsgroup list, distribution list
  1191. Xand start time for the specified server, either from the configuration
  1192. Xfiles or overriding those settings with the command line options.
  1193. X.PP
  1194. XIf the
  1195. X.B -w
  1196. Xoption is not set, then the current time will be obtained to use as the
  1197. Xstart time for the next session. If the
  1198. X.B -l
  1199. Xoption is specified, this will be taken from the local machine,
  1200. Xotherwise it will be retrieved from the remote server through a call to
  1201. Xthe tcp time service there. If
  1202. X.B -i
  1203. Xis not specified, then the message IDs of any articles which were not
  1204. Xretrieved in the last session will be loaded from
  1205. X.BR slurp.<hostname> \.
  1206. X.PP
  1207. X.I Slurp
  1208. Xwill now connect to the NNTP server at the remote host. If a username
  1209. Xand password for use with the simple authorisation protocol have been
  1210. Xsupplied then they will be sent to the server. If the
  1211. X.B -r
  1212. Xoption is specified, then a 'MODE READER' command will be sent, to
  1213. Xensure at INN sites that
  1214. X.I slurp
  1215. Xis talking to nnrpd.
  1216. X.PP
  1217. XA NEWNEWS request will now be issued, asking for all the articles that
  1218. Xhave arrived in the specified list of newsgroups since the specified
  1219. Xtime. The server will respond with a list of message IDs. If a message
  1220. XID is not already present in the local history file, then it will be
  1221. Xstored in memory. If the list of newsgroups is too large to fit on
  1222. Xone line (NNTP has a maximum line length of 512 characters) then a
  1223. Xseries of NEWNEWS requests will be carried out, adding further message
  1224. XIDs to the memory list if they are not already present.
  1225. X.PP
  1226. XOnce this has been completed,
  1227. X.I slurp
  1228. Xmoves into an article retrieval stage. It will go through the list of
  1229. Xmessage IDs in memory and request them in turn from the server, adding
  1230. Xeach article to the batch of articles being either stored in the
  1231. Xincoming news directory or piped to
  1232. X.I rnews.
  1233. XWhen a batch is found to be larger than the maximum size, it will be
  1234. Xsubmitted to the news system.
  1235. X.PP
  1236. XOnce all the articles have been retrieved, the final batch of articles
  1237. Xwill be submitted. If the
  1238. X.B -w
  1239. Xoption has not been set, then the previously obtained time to use for
  1240. Xthe next NEWNEWS will be written to
  1241. X.BR slurp.<hostname> .
  1242. XIf an error has occurred, then the message IDs of any unretrieved
  1243. Xarticles are also written to this file, for retrieval in the next
  1244. Xsession.
  1245. X.PP
  1246. XStatistics on the connection will be logged to syslog (or stderr if
  1247. Xsyslog is not available). The new article count is the total number of
  1248. Xarticles that have been submitted to the new system. The duplicate
  1249. Xcount is how many message IDs were found to already exist on the local
  1250. Xsystem. If two NEWNEWS requests are necessary and a message ID was
  1251. Xreturned by both requests, then it will be included twice in the
  1252. Xduplicate count. The missing count is those articles which were in the
  1253. Xserver's history file but didn't exist as actual article files, usually
  1254. Xbecause they have been cancelled. If configured, the speed of transfer
  1255. Xof the article retrieval stage will also be logged.
  1256. X
  1257. X.SH "RETURN CODES"
  1258. X.PP
  1259. XSlurp returns a series of return codes which may be useful to
  1260. Xcontrolling programs:-
  1261. X.RS
  1262. X0 - Successful completion
  1263. X.br
  1264. X1 - General system error
  1265. X.br
  1266. X2 - Incorrect arguments supplied or incorrect configuration files.
  1267. X.br
  1268. X3 - Error occurred during attempt to connect to remote host
  1269. X.br
  1270. X4 - NNTP Protocol error
  1271. X.br
  1272. X5 - Insufficient disk space available for news batch.
  1273. X.RE
  1274. X
  1275. X.SH FILES
  1276. X/usr/lib/news/slurp.sys
  1277. X.br
  1278. X/usr/lib/news/slurp.<hostname>
  1279. X.SH AUTHOR
  1280. XStephen Hebditch <steveh@orbital.demon.co.uk>
  1281. X.SH "SEE ALSO"
  1282. Xrnews(8)
  1283. X.br
  1284. XRFC977 \- Network News Transfer Protocol (NNTP),
  1285. X.br
  1286. XRFC1036 \- Usenet Article Format standard.
  1287. END_OF_FILE
  1288.   if test 8561 -ne `wc -c <'slurp.1'`; then
  1289.     echo shar: \"'slurp.1'\" unpacked with wrong size!
  1290.   fi
  1291.   # end of 'slurp.1'
  1292. fi
  1293. if test -f 'slurp.h' -a "${1}" != "-c" ; then 
  1294.   echo shar: Will not clobber existing file \"'slurp.h'\"
  1295. else
  1296.   echo shar: Extracting \"'slurp.h'\" \(3738 characters\)
  1297.   sed "s/^X//" >'slurp.h' <<'END_OF_FILE'
  1298. X/*
  1299. X * slurp.h - common definitions for slurp
  1300. X *
  1301. X * Copyright (C) 1992/93 Stephen Hebditch. All rights reserved.
  1302. X * TQM Communications, BCM Box 225, London, WC1N 3XX.
  1303. X * steveh@orbital.demon.co.uk  +44 836 825962
  1304. X *
  1305. X * See README for more information and disclaimers
  1306. X *
  1307. X * $Id: slurp.h,v 1.7 1993/06/07 11:17:47 root Exp $
  1308. X *
  1309. X * $Log: slurp.h,v $
  1310. X * Revision 1.7  1993/06/07  11:17:47  root
  1311. X * Removed bcopy/bzero definitions and used ANSI memcpy and memset
  1312. X * functions throughout the code instead.
  1313. X *
  1314. X * Revision 1.6  1993/04/22  18:10:09  root
  1315. X * Corrected function prototype of server_time - should have been
  1316. X * time_t instead of long.
  1317. X * Made <unistd.h> a compilation option.
  1318. X *
  1319. X * Revision 1.5  1993/03/01  17:57:44  root
  1320. X * Minor reshuffle, plus USG definition now SYSV.
  1321. X *
  1322. X * Revision 1.4  1993/02/14  14:40:55  root
  1323. X * Added no_id_load_flag.
  1324. X * Modified struct mnode to include used flag and remove msgid.
  1325. X * New process_id and set_ntime definitions.
  1326. X *
  1327. X * Revision 1.3  1992/12/15
  1328. X * Added SYS_ERRLIST definitions.
  1329. X *
  1330. X * Revision 1.1  1992/12/06
  1331. X * Added no_time flag.
  1332. X *
  1333. X * Revision 1.0  1992/10/29
  1334. X * Initial coding.
  1335. X *
  1336. X */
  1337. X
  1338. X/* Local header files */
  1339. X
  1340. X#include "conf.h"
  1341. X#include "nntp.h"
  1342. X
  1343. X
  1344. X/* Standard header files */
  1345. X
  1346. X#include <sys/types.h>
  1347. X#include <stdio.h>
  1348. X#include <stdlib.h>
  1349. X#include <limits.h>
  1350. X#include <ctype.h>
  1351. X#include <errno.h>
  1352. X
  1353. X#ifdef SYSLOG
  1354. X  #ifdef FAKESYSLOG
  1355. X    #include "fakesyslog.h"
  1356. X  #else
  1357. X    #include <syslog.h>
  1358. X  #endif
  1359. X#endif
  1360. X
  1361. X#ifdef UNISTD
  1362. X  #include <unistd.h>
  1363. X#endif
  1364. X
  1365. X#ifdef SYSV
  1366. X  #include <string.h>
  1367. X  #include <time.h>
  1368. X#else
  1369. X  #include <strings.h>
  1370. X  #include <sys/time.h>
  1371. X#endif
  1372. X
  1373. X#ifdef SYS_ERRLIST
  1374. X  extern const char *sys_errlist[];
  1375. X  #define strerror(x) (sys_errlist[x])
  1376. X#endif
  1377. X
  1378. X
  1379. X/* Important variables */
  1380. X
  1381. Xextern char *hostname;        /* Name of current NNTP server host */
  1382. Xextern char *pname;            /* Name of this program */
  1383. Xextern int  debug_flag;        /* Write extra debugging output to screen */
  1384. Xextern int  no_time_flag;    /* Don't update slurp.<hostname> */
  1385. Xextern int  no_id_load_flag;/* Don't dump / load message ids */
  1386. X
  1387. X/* Article counters */
  1388. X
  1389. Xextern int  dupart;            /* Number of duplicate articles */
  1390. Xextern int  misart;            /* Number of missing articles */
  1391. Xextern int  newart;            /* Number of new articles */
  1392. X
  1393. Xextern long totalsize;        /* Total size of articles tranferred */
  1394. X
  1395. X/* Details for NEWNEWS */
  1396. X
  1397. Xextern char *nn_newsgroups;
  1398. Xextern char *nn_time;
  1399. Xextern char *nn_distributions;
  1400. X
  1401. X/* Binary tree holding message ids */
  1402. X
  1403. Xstruct mnode
  1404. X    {
  1405. X    struct mnode *left;
  1406. X    struct mnode *right;
  1407. X    char *msgid;
  1408. X    int used;
  1409. X    };
  1410. X                          
  1411. Xextern struct mnode *root;
  1412. Xextern int entries;
  1413. X
  1414. X
  1415. X/* Slurp function prototypes */
  1416. X
  1417. Xextern void get_articles ();                        /* articles.c */
  1418. Xextern void enqueue_batch ();
  1419. X
  1420. Xextern int  open_history ();                        /* history.c */
  1421. Xextern void close_history ();
  1422. Xextern int  check_id (char *message_id);
  1423. X
  1424. Xextern void log_ret (const char *fmt, ...);            /* misc.c */
  1425. Xextern void log_sys (const char *fmt, ...);
  1426. Xextern void log_msg (const char *fmt, ...);
  1427. Xextern char *stradd (const char *, const char *);
  1428. X
  1429. Xextern void get_ids ();                                /* newnews.c */
  1430. Xextern void process_id (char *msgid);
  1431. X
  1432. Xextern void set_ntime ();                            /* slurp.c */
  1433. X
  1434. Xextern int  tcp_open (char *host, char *service);    /* sockets.c */
  1435. Xextern int  server_init (char *hostname);
  1436. Xextern void close_server ();
  1437. Xextern void get_server (char *buf, int size);
  1438. Xextern void put_server (char *buf);
  1439. X
  1440. Xextern int  space (int min_free);                    /* space.c */
  1441. X
  1442. Xextern time_t server_time ();                        /* time.c */
  1443. X
  1444. X
  1445. X/* The inevitable... */
  1446. X
  1447. X#if !defined (TRUE) || ((TRUE) != 1)
  1448. X  #define TRUE (1)
  1449. X#endif
  1450. X
  1451. X#if !defined (FALSE) || ((FALSE) != 0)
  1452. X  #define FALSE (0)
  1453. X#endif
  1454. X
  1455. X#ifndef PATH_MAX
  1456. X  #define PATH_MAX 1024
  1457. X#endif
  1458. X
  1459. X/* END-OF-FILE */
  1460. END_OF_FILE
  1461.   if test 3738 -ne `wc -c <'slurp.h'`; then
  1462.     echo shar: \"'slurp.h'\" unpacked with wrong size!
  1463.   fi
  1464.   # end of 'slurp.h'
  1465. fi
  1466. if test -f 'sockets.c' -a "${1}" != "-c" ; then 
  1467.   echo shar: Will not clobber existing file \"'sockets.c'\"
  1468. else
  1469.   echo shar: Extracting \"'sockets.c'\" \(6353 characters\)
  1470.   sed "s/^X//" >'sockets.c' <<'END_OF_FILE'
  1471. X/*
  1472. X * sockets - open a socket connection and read/write to nntp server
  1473. X *
  1474. X * Copyright (C) 1992/93 Stephen Hebditch. All rights reserved.
  1475. X * TQM Communications, BCM Box 225, London, WC1N 3XX.
  1476. X * steveh@orbital.demon.co.uk  +44 836 825962
  1477. X *
  1478. X * See README for more information and disclaimers
  1479. X *
  1480. X * Obtain the current time from the remote server in standard unix time
  1481. X * format for use with the next NEWNEWS. If the client is unable to
  1482. X * connect to the time server, then local time is used instead.
  1483. X *
  1484. X * $Id: sockets.c,v 1.7 1993/06/23 10:15:37 root Exp $
  1485. X *
  1486. X * $Log: sockets.c,v $
  1487. X * Revision 1.7  1993/06/23  10:15:37  root
  1488. X * Replaced bzero/bcopy definitions with ANSI memcpy and memset.
  1489. X * Duplicate fd before using fdopen separately on each fd for read
  1490. X * and write, fixing long-standing stdio memory problems.
  1491. X *
  1492. X * Revision 1.6  1993/04/22  18:25:16  root
  1493. X * If NOBUFFOUT defined then turn off stdio buffering for the
  1494. X * output stream to the server to get round problem with SVR3s.
  1495. X *
  1496. X * Revision 1.5  1993/03/01  18:00:18  root
  1497. X * Use ferror to detect erros, not return code.
  1498. X *
  1499. X * Revision 1.4  1993/02/14  16:22:42  root
  1500. X * No longer have get_server return a return code. Makes this module
  1501. X * no longer compatible with nntp 1.6 client library, but there ya go...
  1502. X * Changed error detection in put_server for no other reason than to
  1503. X * be consistent with elsewhere.
  1504. X *
  1505. X * Revision 1.3  1992/12/15
  1506. X * Removed unnecessary close() in close_server.
  1507. X * Syslog log level for connected message changed to LOG_INFO.
  1508. X *
  1509. X * Revision 1.1  1992/12/04
  1510. X * Print line before it is sent to server when debugging is on.
  1511. X *
  1512. X * Revision 1.0  1992/11/29
  1513. X * Adapted from nntpxfer-e code.
  1514. X * Incorporate code to set up a tcp connection, plus cleaned up the
  1515. X * existing code.
  1516. X *
  1517. X */
  1518. X
  1519. X#include "slurp.h"
  1520. X
  1521. X#include <signal.h>
  1522. X#include <setjmp.h>
  1523. X#include <netdb.h>
  1524. X#include <sys/socket.h>
  1525. X#include <netinet/in.h>
  1526. X#include <arpa/inet.h>
  1527. X
  1528. X#ifndef INADDR_NONE
  1529. X  #define INADDR_NONE 0xffffffff
  1530. X#endif
  1531. X
  1532. Xstruct sockaddr_in serv_addr;
  1533. Xstruct servent serv_info;
  1534. Xstruct hostent host_info;
  1535. X
  1536. Xstatic FILE *server_rd_fp;
  1537. Xstatic FILE *server_wr_fp;
  1538. X
  1539. X
  1540. X/*
  1541. X * tcp_open - Open a tcp connection to 'host' for service 'service',
  1542. X * returning a file descriptor for the socket.
  1543. X */
  1544. X
  1545. X    int
  1546. Xtcp_open (char *host, char *service)
  1547. X    {
  1548. X    int sockfd;
  1549. X    int on = 1;
  1550. X    unsigned long inaddr;
  1551. X    struct servent *sp;
  1552. X    struct hostent *hp;
  1553. X
  1554. X    (void) memset (&serv_addr, 0, sizeof (serv_addr));
  1555. X    serv_addr.sin_family = AF_INET;
  1556. X
  1557. X    /* Get service information */
  1558. X    if ((sp = getservbyname (service, "tcp")) == NULL)
  1559. X        {
  1560. X        log_ret ("tcp_open: Unknown service %s/tcp", service);
  1561. X        return (-1);
  1562. X        }
  1563. X    serv_info = *sp;
  1564. X    serv_addr.sin_port = sp->s_port;
  1565. X
  1566. X    /* Try to convert host name as dotted decimal */
  1567. X    if ((inaddr = inet_addr (host)) != INADDR_NONE)
  1568. X        {
  1569. X        (void) memcpy (&serv_addr.sin_addr, &inaddr, sizeof (inaddr));
  1570. X        host_info.h_name = NULL;
  1571. X        }
  1572. X    /* If that failed, then look up the host name */
  1573. X    else
  1574. X        {
  1575. X        if ((hp = gethostbyname (host)) == NULL)
  1576. X            {
  1577. X            log_ret ("tcp_open: Host name error: %s", host);
  1578. X            return (-1);
  1579. X            }
  1580. X        host_info = *hp;
  1581. X        (void) memcpy (&serv_addr.sin_addr, hp->h_addr, hp->h_length);
  1582. X        }
  1583. X
  1584. X    if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
  1585. X        {
  1586. X        log_ret ("tcp_open: Can't create TCP socket");
  1587. X        return (-1);
  1588. X        }
  1589. X
  1590. X    if (connect (sockfd, (struct sockaddr *) &serv_addr,
  1591. X        sizeof (serv_addr)) < 0)
  1592. X        {
  1593. X        log_ret ("tcp_open: Can't connect to server %s", host);
  1594. X        (void) close (sockfd);
  1595. X        return (-1);
  1596. X        }
  1597. X
  1598. X    if (setsockopt (sockfd, SOL_SOCKET, SO_KEEPALIVE, 
  1599. X                    (char *) &on, sizeof (on)) < 0)
  1600. X        log_ret ("tcp_open: Can't set KEEPALIVE on socket");
  1601. X
  1602. X    return (sockfd);
  1603. X    }
  1604. X
  1605. X/*
  1606. X * server_init - Open a connection to the NNTP server. Returns -1 if an
  1607. X * error occurs, otherwise the server's initial response code.
  1608. X */
  1609. X
  1610. X    int
  1611. Xserver_init (char *hostname)
  1612. X    {
  1613. X    char line [NNTP_STRLEN];
  1614. X    int server_rd_fd;
  1615. X    int server_wr_fd;
  1616. X
  1617. X    /* First try and make the connection */
  1618. X    if ((server_rd_fd = tcp_open (hostname, "nntp")) < 0)
  1619. X        return (-1);
  1620. X    server_wr_fd = dup (server_rd_fd);
  1621. X
  1622. X    /* Now fdopen to enable buffering of data */
  1623. X    if ((server_rd_fp = fdopen (server_rd_fd, "r")) == NULL)
  1624. X        {
  1625. X        log_ret ("server_init: Can't fdopen socket for reading");
  1626. X        return (-1);
  1627. X        }
  1628. X    if ((server_wr_fp = fdopen (server_wr_fd, "w")) == NULL)
  1629. X        {
  1630. X        log_ret ("server_init: Can't fdopen socket for writing");
  1631. X        return (-1);
  1632. X        }
  1633. X        
  1634. X    /* Inform everyone that we're there */
  1635. X#ifdef SYSLOG
  1636. X    if (!debug_flag)
  1637. X        syslog(LOG_INFO, "Connected to nntp server at %s", hostname);
  1638. X    else
  1639. X#endif
  1640. X        (void) fprintf (stderr, "Connected to nntp server at %s\n", hostname);
  1641. X
  1642. X    /* Get the greeting herald */
  1643. X    get_server (line, sizeof (line));
  1644. X    if (debug_flag)
  1645. X        (void) fprintf (stderr, "-> %s\n", line);
  1646. X
  1647. X    /* Return the banner code */
  1648. X    return (atoi (line));
  1649. X    }
  1650. X
  1651. X
  1652. X/*
  1653. X * close_server - Close down the NNTP server connection
  1654. X */
  1655. X
  1656. X    void
  1657. Xclose_server ()
  1658. X    {
  1659. X    char line [NNTP_STRLEN];
  1660. X
  1661. X    if (debug_flag)
  1662. X        (void) fprintf (stderr, "<- QUIT\n");
  1663. X    put_server ("QUIT");
  1664. X    get_server (line, sizeof (line));
  1665. X    if (debug_flag)
  1666. X        (void) fprintf (stderr, "-> %s\n", line);
  1667. X
  1668. X    (void) fclose (server_rd_fp);
  1669. X    (void) fclose (server_wr_fp);
  1670. X    }
  1671. X
  1672. X
  1673. Xstatic jmp_buf env_alrm;
  1674. X
  1675. X    static void
  1676. Xsig_alrm (int signo)
  1677. X    {
  1678. X    longjmp (env_alrm, 1);
  1679. X    }
  1680. X
  1681. X/*
  1682. X * get_server - Read a line up to CRLF from the socket into a buffer.
  1683. X */
  1684. X
  1685. X    void
  1686. Xget_server (char *line, int size)
  1687. X    {
  1688. X    int esave;
  1689. X    char *pos;
  1690. X
  1691. X    /* Set up an alarm to handle socket timeout */
  1692. X    if (setjmp (env_alrm))
  1693. X        {
  1694. X        (void) alarm (0);                    /* Reset alarm clock */
  1695. X        (void) signal (SIGALRM, SIG_DFL);
  1696. X        errno = EPIPE;
  1697. X        log_sys ("get_server: Read error on server socket");
  1698. X        }
  1699. X
  1700. X    (void) signal (SIGALRM, sig_alrm);
  1701. X    (void) alarm (TIMEOUT);
  1702. X
  1703. X    /* Read line */
  1704. X    (void) fgets (line, size, server_rd_fp);
  1705. X
  1706. X    /* Reset the alarm */
  1707. X    esave = errno;
  1708. X    (void) alarm (0);
  1709. X    (void) signal (SIGALRM, SIG_DFL);
  1710. X    errno = esave;
  1711. X
  1712. X    /* Report any error */
  1713. X    if (ferror (server_rd_fp))
  1714. X        log_sys ("get_server: Read error on server socket");
  1715. X
  1716. X    /* Kill the CRLF */
  1717. X    if (pos = strchr (line, '\r'))
  1718. X        *pos = '\0';
  1719. X    if (pos = strchr (line, '\n'))
  1720. X        *pos = '\0';
  1721. X    }
  1722. X
  1723. X/*
  1724. X * put_server - write a line from a linefer to a socket
  1725. X */
  1726. X
  1727. X    void
  1728. Xput_server (char *line)
  1729. X    {
  1730. X
  1731. X    (void) fprintf (server_wr_fp, "%s\r\n", line);
  1732. X    if (ferror (server_wr_fp))
  1733. X        log_sys ("put_server: Write error on server socket");
  1734. X    (void) fflush (server_wr_fp);
  1735. X    }
  1736. X
  1737. X/* END-OF-FILE */
  1738. END_OF_FILE
  1739.   if test 6353 -ne `wc -c <'sockets.c'`; then
  1740.     echo shar: \"'sockets.c'\" unpacked with wrong size!
  1741.   fi
  1742.   # end of 'sockets.c'
  1743. fi
  1744. if test -f 'space.c' -a "${1}" != "-c" ; then 
  1745.   echo shar: Will not clobber existing file \"'space.c'\"
  1746. else
  1747.   echo shar: Extracting \"'space.c'\" \(5486 characters\)
  1748.   sed "s/^X//" >'space.c' <<'END_OF_FILE'
  1749. X/*
  1750. X * space - determine free space on a filesystem
  1751. X *
  1752. X * Copyright (C) 1992/93 Stephen Hebditch and others.
  1753. X * TQM Communications, BCM Box 225, London, WC1N 3XX.
  1754. X * steveh@orbital.demon.co.uk  +44 836 825962
  1755. X *
  1756. X * See README for more information and disclaimers
  1757. X *
  1758. X * This routine determines if there is enough space on the filesystem
  1759. X * holding the news spool for a new batch of incoming articles.
  1760. X * It is based on space.c in the NNTP reference implementation which
  1761. X * credits Stan Barber <sob@bcm.tmc.edu>, Tad Guy <tadguy@cs.odu.edu>,
  1762. X * Chris Jepeway <jepeway@utkcs2.cs.utk.edu> and Tom Lane <tgl@cs.cmu.edu>
  1763. X * but has been heavily cleaned up and support for SVR4, Linux and
  1764. X * BSDI added.
  1765. X *
  1766. X * $Id: space.c,v 1.7 1993/06/14 15:25:42 root Exp $
  1767. X *
  1768. X * $Log: space.c,v $
  1769. X * Revision 1.7  1993/06/14  15:25:42  root
  1770. X * Added routine name to error messages.
  1771. X * Made close() consistent with usage elsewhere.
  1772. X *
  1773. X * Revision 1.6  1993/04/22  18:27:21  root
  1774. X * Changed NeXT define to __NeXT__.
  1775. X *
  1776. X * Revision 1.5  1993/03/01  18:08:20  root
  1777. X * Completely reworked from the original and heavily tidied up.
  1778. X * Support added for SVR4 and Linux.
  1779. X *
  1780. X * Revision 1.4  1993/02/14  16:12:20  root
  1781. X * Added support for BSDI.
  1782. X *
  1783. X */
  1784. X
  1785. X#include "slurp.h"
  1786. X
  1787. X#ifdef MINFREE
  1788. X
  1789. X#include <sys/types.h>
  1790. X#include <sys/stat.h>
  1791. X
  1792. X#define DFREE_OK        0
  1793. X#define DFREE_INODES    1
  1794. X#define DFREE_BLOCKS    2
  1795. X#define DFREE_ERR        3
  1796. X
  1797. X/*
  1798. X * Definitions for use with dfree() for various UNIX families.
  1799. X *
  1800. X * statfilesys        Routine to call when trying to stat a file system
  1801. X *                    to get the number of free blocks available.
  1802. X * statfs_type        The data type into which statfs() wants to return
  1803. X *                    useful information.
  1804. X * bombed            Boolean expression returning 1 if a call to statfs()
  1805. X *                    fails.
  1806. X * blkavail            Given a statfs_type called fs, return number of free
  1807. X *                    blocks available to a non-superuser.
  1808. X * filavail            Given a statfs_type called fs, return number of free
  1809. X *                    inodes available to a non-superuser.
  1810. X */
  1811. X
  1812. X  #if defined(SVR4)
  1813. X    #include <sys/statvfs.h>
  1814. X    #define statfilesys        statvfs
  1815. X    typedef struct statvfs     statfs_type;
  1816. X    #define bombed(call)    ((call) == -1)
  1817. X    #define blkavail(fs)    ((fs).f_bavail)
  1818. X    #define filavail(fs)    ((fs).f_favail)
  1819. X
  1820. X  #elif defined(sun) || defined(hpux) || defined(pyr) || defined(hp300) || defined(__NeXT__) || defined(linux)
  1821. X    #include <sys/vfs.h>
  1822. X    #define statfilesys        statfs
  1823. X    typedef struct statfs     statfs_type;
  1824. X    #define bombed(call)    ((call) == -1)
  1825. X    #define blkavail(fs)    ((fs).f_bavail)
  1826. X    #define filavail(fs)    ((fs).f_ffree)
  1827. X
  1828. X  #elif defined(apollo)
  1829. X    #include <sys/types.h>
  1830. X    #include <sys/statfs.h>
  1831. X    #define statfilesys(a,b) statfs (a, b, sizeof (struct statfs), 0)
  1832. X    typedef struct statfs     statfs_type;
  1833. X    #define bombed(call)    ((call) == -1)
  1834. X    #define blkavail(fs)    ((fs).f_bfree)
  1835. X    #define filavail(fs)    ((fs).f_ffree)
  1836. X
  1837. X  #elif defined(ultrix)
  1838. X    #include <sys/mount.h>
  1839. X    typedef struct fs_data    statfs_type;
  1840. X    #define statfilesys        statfs
  1841. X    #define bombed(call)    ((call) <= 0)
  1842. X    #define blkavail(fs)    ((int)((fs).fd_req.bfreen))
  1843. X    #define filavail(fs)    ((int)((fs).fd_req.gfree))
  1844. X
  1845. X  #elif defined(__bsdi__)
  1846. X    #include <sys/mount.h>
  1847. X    typedef struct statfs    statfs_type;
  1848. X    #define statfilesys        statfs
  1849. X    #define bombed(call)    ((call) < 0)
  1850. X    #define blkavail(fs)    ((int)((fs).f_bfree))
  1851. X    #define filavail(fs)    ((int)((fs).f_ffree))
  1852. X
  1853. X  #elif defined(SVR3)
  1854. X    #include <ustat.h>
  1855. X    typedef struct ustat statfs_type;
  1856. X        int
  1857. X    statfilesys (char *dir, statfs_type *fs)
  1858. X        {
  1859. X        struct stat file;
  1860. X        if (stat (dir, &file))
  1861. X            return (-1);
  1862. X        if (ustat (file.st_dev, fs))
  1863. X            return (-2);
  1864. X        return (0);
  1865. X        }
  1866. X    #define bombed(call)    (call != 0)
  1867. X    #define blkavail(fs)    ((fs).f_tfree)
  1868. X    #define filavail(fs)    ((fs).f_tinode)    
  1869. X
  1870. X  #elif defined(CMU_MACH)
  1871. X    #include <sys/ioctl.h>
  1872. X    typedef struct fsparam statfs_type;
  1873. X        int
  1874. X    statfilesys (char *dir, statfs_type *fs)
  1875. X        {
  1876. X        int fd;
  1877. X        fd = open (dir, O_RDONLY);
  1878. X        if (fd < 0)
  1879. X            return (-1);
  1880. X        if (ioctl (fd, FIOCFSPARAM, fs) < 0)
  1881. X            {
  1882. X            (void) close (fd);
  1883. X            return(-2);
  1884. X            }
  1885. X        (void) close (fd);
  1886. X        return (0);
  1887. X        }
  1888. X    #define bombed (call)    ((call) < 0)
  1889. X    #define blkavail (fs)    ((fs).fsp_free-((fs).fsp_size*(fs).fsp_minfree+99)/100)
  1890. X
  1891. X  #else
  1892. X    SPACE DEFINITIONS NOT AVAILABLE FOR THIS MACHINE OR NOT SET CORRECTLY
  1893. X  #endif
  1894. X
  1895. X
  1896. X/*
  1897. X * dfree - Return the free space available on the file system containing
  1898. X * the specified directory. Space is measured in kilobytes. A negative
  1899. X * value is returned if there is an error.
  1900. X */
  1901. X
  1902. X    static int
  1903. Xdfree (char *location, int free_space)
  1904. X    {
  1905. X    statfs_type fsys;
  1906. X
  1907. X    /* Return error if can't get file system info */
  1908. X    if (bombed (statfilesys (location, &fsys)))
  1909. X        return (DFREE_ERR);
  1910. X
  1911. X    /* If able to test if free inodes then do so */
  1912. X#if defined(filfree) && defined(MINFILES)
  1913. X    if (filfree (fsys) < MINFILES )
  1914. X         return (DFREE_INODES);
  1915. X#endif
  1916. X
  1917. X    /* Test if blocks are available */
  1918. X    if (blkavail (fsys) < free_space)
  1919. X        return (DFREE_BLOCKS);
  1920. X
  1921. X    return (DFREE_OK);
  1922. X    }
  1923. X
  1924. X
  1925. X/*
  1926. X * space - Returns 1 if there are a sufficient number of free blocks
  1927. X * and inodes on the filesystem containing the news spool, or 0 if
  1928. X * there are only a small number of blocks / inodes remaining.
  1929. X */
  1930. X
  1931. X    int
  1932. Xspace (int min_free)
  1933. X    {
  1934. X    switch (dfree (SPOOLDIR, min_free))
  1935. X        {
  1936. X        case DFREE_OK:
  1937. X            return (1);
  1938. X        case DFREE_ERR:
  1939. X            log_ret ("space: dfree failed due to system call error");
  1940. X            break;
  1941. X        case DFREE_INODES:
  1942. X            log_msg ("space: no inodes on %s", SPOOLDIR);
  1943. X            break;
  1944. X        case DFREE_BLOCKS:
  1945. X            log_msg ("space: no space on %s", SPOOLDIR);
  1946. X            break;
  1947. X        }
  1948. X    return (0);
  1949. X    }
  1950. X
  1951. X#endif /* MINFREE */
  1952. X
  1953. X/* END-OF-FILE */
  1954. END_OF_FILE
  1955.   if test 5486 -ne `wc -c <'space.c'`; then
  1956.     echo shar: \"'space.c'\" unpacked with wrong size!
  1957.   fi
  1958.   # end of 'space.c'
  1959. fi
  1960. echo shar: End of archive 2 \(of 3\).
  1961. cp /dev/null ark2isdone
  1962. MISSING=""
  1963. for I in 1 2 3 ; do
  1964.     if test ! -f ark${I}isdone ; then
  1965.     MISSING="${MISSING} ${I}"
  1966.     fi
  1967. done
  1968. if test "${MISSING}" = "" ; then
  1969.     echo You have unpacked all 3 archives.
  1970.     rm -f ark[1-9]isdone
  1971. else
  1972.     echo You still must unpack the following archives:
  1973.     echo "        " ${MISSING}
  1974. fi
  1975. exit 0
  1976. exit 0 # Just in case...
  1977.