rsalz@bbn.com (Rich Salz) (04/20/88)
Submitted-by: Phil Lapsley <phil@ucbvax.berkeley.edu> Posting-number: Volume 14, Issue 48 Archive-name: nntp1.5/part02 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 2 (of 9)." # Wrapped by rsalz@fig.bbn.com on Tue Apr 19 18:16:37 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f './common/nntp.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./common/nntp.h'\" else echo shar: Extracting \"'./common/nntp.h'\" \(2530 characters\) sed "s/^X//" >'./common/nntp.h' <<'END_OF_FILE' X/* X * Response codes for NNTP server X * X * @(#)nntp.h 1.7 (Berkeley) 1/11/88 X * X * First digit: X * X * 1xx Informative message X * 2xx Command ok X * 3xx Command ok so far, continue X * 4xx Command was correct, but couldn't be performed X * for some specified reason. X * 5xx Command unimplemented, incorrect, or a X * program error has occured. X * X * Second digit: X * X * x0x Connection, setup, miscellaneous X * x1x Newsgroup selection X * x2x Article selection X * x3x Distribution X * x4x Posting X */ X X#define CHAR_INF '1' X#define CHAR_OK '2' X#define CHAR_CONT '3' X#define CHAR_ERR '4' X#define CHAR_FATAL '5' X X#define INF_HELP 100 /* Help text on way */ X#define INF_DEBUG 199 /* Debug output */ X X#define OK_CANPOST 200 /* Hello; you can post */ X#define OK_NOPOST 201 /* Hello; you can't post */ X#define OK_SLAVE 202 /* Slave status noted */ X#define OK_GOODBYE 205 /* Closing connection */ X#define OK_GROUP 211 /* Group selected */ X#define OK_GROUPS 215 /* Newsgroups follow */ X#define OK_ARTICLE 220 /* Article (head & body) follows */ X#define OK_HEAD 221 /* Head follows */ X#define OK_BODY 222 /* Body follows */ X#define OK_NOTEXT 223 /* No text sent -- stat, next, last */ X#define OK_NEWNEWS 230 /* New articles by message-id follow */ X#define OK_NEWGROUPS 231 /* New newsgroups follow */ X#define OK_XFERED 235 /* Article transferred successfully */ X#define OK_POSTED 240 /* Article posted successfully */ X X#define CONT_XFER 335 /* Continue to send article */ X#define CONT_POST 340 /* Continue to post article */ X X#define ERR_GOODBYE 400 /* Have to hang up for some reason */ X#define ERR_NOGROUP 411 /* No such newsgroup */ X#define ERR_NCING 412 /* Not currently in newsgroup */ X#define ERR_NOCRNT 420 /* No current article selected */ X#define ERR_NONEXT 421 /* No next article in this group */ X#define ERR_NOPREV 422 /* No previous article in this group */ X#define ERR_NOARTIG 423 /* No such article in this group */ X#define ERR_NOART 430 /* No such article at all */ X#define ERR_GOTIT 435 /* Already got that article, don't send */ X#define ERR_XFERFAIL 436 /* Transfer failed */ X#define ERR_XFERRJCT 437 /* Article rejected, don't resend */ X#define ERR_NOPOST 440 /* Posting not allowed */ X#define ERR_POSTFAIL 441 /* Posting failed */ X X#define ERR_COMMAND 500 /* Command not recognized */ X#define ERR_CMDSYN 501 /* Command syntax error */ X#define ERR_ACCESS 502 /* Access to server denied */ X#define ERR_FAULT 503 /* Program fault, command not performed */ X X/* RFC 977 defines this; don't change it. */ X X#define NNTP_STRLEN 512 END_OF_FILE if test 2530 -ne `wc -c <'./common/nntp.h'`; then echo shar: \"'./common/nntp.h'\" unpacked with wrong size! fi # end of './common/nntp.h' fi if test -f './doc/config.sh' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./doc/config.sh'\" else echo shar: Extracting \"'./doc/config.sh'\" \(1847 characters\) sed "s/^X//" >'./doc/config.sh' <<'END_OF_FILE' X#!/bin/sh X# X# Shell script for making manual pages X# X# Created by Stan Barber; Mon Apr 6 13:25:27 CDT 1987 X# Modified by Phil Lapsley; Thu Oct 15 17:43:40 PDT 1987 X# X X# X# ------------- SITE DEPENDENT STUFF --------------------------- X# (modify these lines to suit your system) X# X# the location of inetd on your system (usually /etc/inetd) MINETD=/etc/inetd X# the location of the inetd configuration file (usually /etc/inetd.conf) MINETDCONFIG=/etc/inetd.conf X# the location of nntpd following installation (usually /etc/nntpd) MNNTPD=/etc/nntpd X# the location of the hosts file (usually /etc/hosts) MHOSTFILE=/etc/hosts X# the location of the services file (usually /etc/services) MSERVICES=/etc/services X# the location of the networks file (usually /etc/networks) MNETWORKFILE=/etc/networks X# The location of the news spool directory (usually /usr/spool/news) MNEWSSPOOL=/usr/spool/news X# The location of the news library directory (usually /usr/lib/news) MNEWSLIB=/usr/lib/news X# The location of the file containing the name of the nntp server machine X# (usually /usr/local/lib/rn/server) MSERVERFILE=/usr/local/lib/rn/server X# The location of rn's local library (usually /usr/local/lib/rn) MRNLIB=/usr/local/lib/rn X# X# ------------ END OF SITE DEPENDENT STUFF --------------------- X# (you should not have to touch anything below). X echo "Extracting $2 from $1 ..." X X( echo g%NEWSLIB%s%NEWSLIB%$MNEWSLIB% echo g%NEWSSPOOL%s%NEWSSPOOL%$MNEWSSPOOL% echo g%INETDCONFIG%s%INETDCONFIG%$MINETDCONFIG% echo g%LNNTPD%s%LNNTPD%$MNNTPD% echo g%INETD%s%INETD%$MINETD% echo g%HOSTFILE%s%HOSTFILE%$MHOSTFILE% echo g%SERVICES%s%SERVICES%$MSERVICES% echo g%NETWORKFILE%s%NETWORKFILE%$MNETWORKFILE% echo g%RNLIB%s%RNLIB%$MRNLIB% echo w echo q X) > /tmp/ed.$$ X rm -f $2 cp $1 $2 chmod 644 $2 X(ed $2 < /tmp/ed.$$) 2>&1 > /dev/null rm /tmp/ed.$$ X echo "Finished." END_OF_FILE if test 1847 -ne `wc -c <'./doc/config.sh'`; then echo shar: \"'./doc/config.sh'\" unpacked with wrong size! fi chmod +x './doc/config.sh' # end of './doc/config.sh' fi if test -f './doc/mkgrdates.dst' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./doc/mkgrdates.dst'\" else echo shar: Extracting \"'./doc/mkgrdates.dst'\" \(1911 characters\) sed "s/^X//" >'./doc/mkgrdates.dst' <<'END_OF_FILE' X.\" X.\" @(#)mkgrdates.dst 1.3 (Berkeley) 10/15/87 X.\" X.TH MKGRDATES 8C "26 October 1985" X.UC 4 X.SH NAME mkgrdates \- Make the newsgroup creation date file for the NNTP server X.SH SYNOPSIS X.B NEWSLIB/mkgrdates X.SH NOTICE X.I Mkgrdates is no longer used, and does not need to be run from crontab. It is included only for completeness and backward compatibility. For more information, see the manual page for X.I nntpd. X.SH DESCRIPTION X.I Mkgrdates maintains the newsgroup creation date file for the Network News Transfer Protocol server, which uses it for the NEWGROUPS command. When executed, X.I mkgrdates goes through the active file, X.IR NEWSLIB/active , and creates the file X.I NEWSLIB/groupdates containing the creation dates and times of the newsgroups in the active file. The X.I groupdates file has one line for each newsgroup, in the form X``date newsgroup'' where ``date'' is the newsgroup's creation time, in seconds since midnight, Jan. 1, X1970, GMT, and ``newsgroup'' is the name of the newsgroup in question. X.PP Since generating the X.I groupdates file is expensive, when X.I mkgrdates is run it creates the file X.I NEWSLIB/mkgdstats containing the length, in bytes, of the active file. The next time X.I mkgrdates is invoked, it compares the contents of the X.I mkgdstats file against the length of the active file, and exits if these lengths are the same. If the lengths are not the same, it rebuilds the X.I groupdates file, and sets the X.I mkgdstats file to the appropriate value. This scheme avoids a fair amount of what would be wasted computing. X.PP X.I Mkgrdates should be run once or twice a day by an entry in X.I /usr/lib/crontab X.SH BUGS It's a crock; X.I mkgrdates' function needs to be done by the news system. NNTP version 1.4 does not use this program at all, and decides whether a group is ``new'' or not by a (rather poor) heuristic. X.SH AUTHOR Phil Lapsley X.SH SEE ALSO cron(1), nntpd(8C) END_OF_FILE if test 1911 -ne `wc -c <'./doc/mkgrdates.dst'`; then echo shar: \"'./doc/mkgrdates.dst'\" unpacked with wrong size! fi # end of './doc/mkgrdates.dst' fi if test -f './inews/README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./inews/README'\" else echo shar: Extracting \"'./inews/README'\" \(2253 characters\) sed "s/^X//" >'./inews/README' <<'END_OF_FILE' X X This is a "pseudo" inews which allows remote posting using the NNTP server. Essentially it takes a bunch of arguments and ignores ones starting with "-", expecting to find at least one which is a file name. If no files are specified, it uses standard input as the input file. X X It then opens a connection to the NNTP server on the remote machine and blasts the article across. It then closes the connection. If it doesn't find a From: or Path: line, it inserts them, in the default format X X From: login@hostname.DOMAIN (Full_name) X Path: hostname!login X where DOMAIN is a #define in ../common/conf.h, and should be changed to reflect your system. A good choice is .UUCP if you are not a member of the Internet. "Full_name" understands the & hack in password files. X X "hostname" is figured out by what you've #defined in ../common/conf.h. If you have defined GHNAME, it uses the gethostname() call. If you've defined UUNAME, it figured it out from the file X/etc/uucpname. Finally, if neither is defined it gets it from X/usr/include/whoami.h. If you have GHNAME defined and your gethostname() returns your fully-qualified Internet name, undefine DOMAIN. X X The point here is that the thing looks like inews to any program which would care to post something (e.g., Pnews, postnews, what have you). The difference is that the article will look like it was posted on the remote end, not on the local end. Please note that "postnews" X(nor any of the other standard news programs) is not required for rrn/nntp on client machines. X X The "test*" files in this directory provide some good test material for inews; you can just redirect inews to take input from them or whatever. X X Thanks to Steven Grady <grady@postgres.berkeley.edu> for writing this, and for wasting a lot of his valuable time dealing with the can-o'-worms that is the real inews. X BUGS: X X This version of inews doesn't handle real inews options. As a result, some posting programs (notably the Gnumacs front end) will fail if they use this program. In the interests of simplicity, I have no plans for modifying mini-inews to handle real-inews options. However, if you'd like to send me diffs I'll be more than happy to install them for the next release. END_OF_FILE if test 2253 -ne `wc -c <'./inews/README'`; then echo shar: \"'./inews/README'\" unpacked with wrong size! fi # end of './inews/README' fi if test -f './inews/uname.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./inews/uname.c'\" else echo shar: Extracting \"'./inews/uname.c'\" \(2177 characters\) sed "s/^X//" >'./inews/uname.c' <<'END_OF_FILE' X/* X * This software is Copyright (c) 1986 by Rick Adams. X * X * Permission is hereby granted to copy, reproduce, redistribute or X * otherwise use this software as long as: there is no monetary X * profit gained specifically from the use or reproduction or this X * software, it is not sold, rented, traded or otherwise marketed, and X * this copyright notice is included prominently in any copy X * made. X * X * The author make no claims as to the fitness or correctness of X * this software for any use whatsoever, and it is provided as is. X * Any use of this software is at the user's own risk. X * X * This routine is compatible with the Unix T/S system call uname, X * which figures out the name of the local system. X * However, we do it by reading the file /usr/include/whoami.h. X * This avoids having to recompile uucp for each site and hence X * avoids having to distribute the source to uucp to people who X * have only binary licenses. X */ X X#ifdef SCCSID static char *SccsId = "@(#)uname.c 2.9 1/20/86"; X#endif /* SCCSID */ X X#include <stdio.h> X#include "../common/conf.h" X X#ifdef UNAME X# define DONE X#endif /* UNAME */ X X#ifdef GHNAME uname(uptr) char *uptr; X{ X gethostname(uptr, 256); X} X# define DONE X#endif X X#ifdef UUNAME uname(uptr) char *uptr; X{ X FILE *uucpf; X register char *p; X /* uucp name is stored in /etc/uucpname or /local/uucpname */ X X if (((uucpf = fopen("/etc/uucpname", "r")) == NULL && X (uucpf = fopen("/local/uucpname", "r")) == NULL) || X fgets(uptr, 256, uucpf) == NULL) { X fprintf(stderr, "no sysname in %s\n", "/etc/uucpname"); X return; X } X p = index(uptr, '\n'); X if (p) X *p = '\0'; X if (uucpf != NULL) X fclose(uucpf); X} X#define DONE X#endif /* UUNAME */ X X#ifndef DONE X#define HDRFILE "/usr/include/whoami.h" X uname(uptr) char *uptr; X{ X char buf[BUFSIZ]; X FILE *fd; X X fd = fopen(HDRFILE, "r"); X if (fd == NULL) { X fprintf(stderr, "Cannot open %s\n", HDRFILE); X exit(1); X } X X for (;;) { /* each line in the file */ X if (fgets(buf, sizeof buf, fd) == NULL) { X fprintf(stderr, "no sysname in %s\n", HDRFILE); X fclose(fd); X exit(2); X } X if (sscanf(buf, "#define sysname \"%[^\"]\"", uptr) == 1) { X fclose(fd); X return; X } X } X} X#endif END_OF_FILE if test 2177 -ne `wc -c <'./inews/uname.c'`; then echo shar: \"'./inews/uname.c'\" unpacked with wrong size! fi # end of './inews/uname.c' fi if test -f './rrnpatches/getactive.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./rrnpatches/getactive.c'\" else echo shar: Extracting \"'./rrnpatches/getactive.c'\" \(1518 characters\) sed "s/^X//" >'./rrnpatches/getactive.c' <<'END_OF_FILE' X#include <stdio.h> X#include "config.h" X#include "EXTERN.h" X#include "server.h" X main(argc, argv) X int argc; X char *argv[]; X{ X char ser_line[256]; X int response; X register char *server; X register FILE *actfp; X X if (argc != 2) { X fprintf(stderr, "Usage: getactive filename\n"); X exit(1); X } X X server = getserverbyfile(SERVER_FILE); X if (server == NULL) { X fprintf(stderr, "Couldn't get name of news server from %s\n", X SERVER_FILE); X fprintf(stderr, X "Either fix this file, or put NNTPSERVER in your environment.\n"); X exit(1); X } X X response = server_init(server); X if (response < 0) { X fprintf(stderr, X "getactive: Can't get active file from server %s.\n", X server); X exit(1); X } X X if (handle_server_response(response, server) < 0) X exit(1); X X put_server("LIST"); /* tell server we want the active file */ X (void) get_server(ser_line, sizeof(ser_line)); X if (*ser_line != CHAR_OK) { /* and then see if that's ok */ X fprintf(stderr, X "getactive: Can't get active file from server.\n"); X fprintf(stderr, "Server said: %s\n", ser_line); X exit(1); X } X X actfp = fopen(argv[1], "w"); /* and get ready */ X if (actfp == NULL) { X close_server(); X perror(argv[1]); X exit(1); X } X X while (get_server(ser_line, sizeof(ser_line)) >= 0) { /* while */ X if (ser_line[0] == '.') /* there's another line */ X break; /* get it and write it to */ X if (actfp != NULL) { /* the temporary active file */ X fputs(ser_line, actfp); X putc('\n', actfp); X } X } X X (void) fclose(actfp); X close_server(); X} END_OF_FILE if test 1518 -ne `wc -c <'./rrnpatches/getactive.c'`; then echo shar: \"'./rrnpatches/getactive.c'\" unpacked with wrong size! fi # end of './rrnpatches/getactive.c' fi if test -f './rrnpatches/init.c.pat' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./rrnpatches/init.c.pat'\" else echo shar: Extracting \"'./rrnpatches/init.c.pat'\" \(1708 characters\) sed "s/^X//" >'./rrnpatches/init.c.pat' <<'END_OF_FILE' X*** rn/init.c Sun Mar 15 19:54:18 1987 X--- rrn/init.c Mon May 25 23:31:56 1987 X*************** X*** 44,49 X #include "ngstuff.h" X #include "rcln.h" X #include "respond.h" X #include "ng.h" X #include "INTERN.h" X #include "init.h" X X--- 44,50 ----- X #include "ngstuff.h" X #include "rcln.h" X #include "respond.h" X+ #include "server.h" X #include "ng.h" X #include "INTERN.h" X #include "init.h" X*************** X*** 56,61 X char *tcbuf; X register bool foundany = FALSE; X long time(); X #ifdef NOLINEBUF X static char std_out_buf[BUFSIZ]; /* must be static or malloced */ X X X--- 57,66 ----- X char *tcbuf; X register bool foundany = FALSE; X long time(); X+ #ifdef SERVER X+ char *server; X+ int response; X+ #endif SERVER X #ifdef NOLINEBUF X static char std_out_buf[BUFSIZ]; /* must be static or malloced */ X X*************** X*** 123,128 X X if (!checkflag) X newsnews_check(); X X /* open active file, etc. */ X X X--- 128,159 ----- X X if (!checkflag) X newsnews_check(); X+ X+ #ifdef SERVER X+ X+ /* open connection to server if appropriate */ X+ X+ server = getserverbyfile(SERVER_FILE); X+ if (server == NULL) { X+ fprintf(stderr, "Can't get the name of the news server from %s\n", X+ SERVER_FILE); X+ fprintf(stderr, X+ "Either fix this file, or put NNTPSERVER in your environment.\n"); X+ finalize(1); X+ } X+ X+ response = server_init(server); X+ if (response < 0) { X+ fprintf(stderr, X+ "Couldn't connect to %s news server, try again later.\n", X+ server); X+ finalize(1); X+ } X+ X+ if (handle_server_response(response, server) < 0) X+ finalize(1); X+ X+ #endif SERVER X X /* open active file, etc. */ X END_OF_FILE if test 1708 -ne `wc -c <'./rrnpatches/init.c.pat'`; then echo shar: \"'./rrnpatches/init.c.pat'\" unpacked with wrong size! fi # end of './rrnpatches/init.c.pat' fi if test -f './rrnpatches/ngdata.c.pat' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./rrnpatches/ngdata.c.pat'\" else echo shar: Extracting \"'./rrnpatches/ngdata.c.pat'\" \(2563 characters\) sed "s/^X//" >'./rrnpatches/ngdata.c.pat' <<'END_OF_FILE' X*** rn/ngdata.c Sun Mar 15 19:54:39 1987 X--- rrn/ngdata.c Sun Mar 15 22:26:37 1987 X*************** X*** 14,19 X #include "intrp.h" X #include "final.h" X #include "rcln.h" X #include "INTERN.h" X #include "ngdata.h" X X X--- 14,20 ----- X #include "intrp.h" X #include "final.h" X #include "rcln.h" X+ #include "server.h" X #include "INTERN.h" X #include "ngdata.h" X X*************** X*** 17,22 X #include "INTERN.h" X #include "ngdata.h" X X void X ngdata_init() X { X X--- 18,27 ----- X #include "INTERN.h" X #include "ngdata.h" X X+ #ifdef SERVER X+ char active_name[256]; X+ #endif SERVER X+ X void X ngdata_init() X { X*************** X*** 20,25 X void X ngdata_init() X { X /* The following is only for systems that do not zero globals properly */ X #ifdef ZEROGLOB X # ifdef CACHEFIRST X X--- 25,34 ----- X void X ngdata_init() X { X+ #ifdef SERVER X+ char ser_line[256]; X+ char *cp; X+ #endif X /* The following is only for systems that do not zero globals properly */ X #ifdef ZEROGLOB X # ifdef CACHEFIRST X*************** X*** 30,35 X X /* open the active file */ X X actfp = fopen(filexp(ACTIVE),"r"); X if (actfp == Nullfp) { X printf(cantopen,filexp(ACTIVE)) FLUSH; X X--- 39,72 ----- X X /* open the active file */ X X+ #ifdef SERVER X+ X+ put_server("LIST"); /* tell server we want the active file */ X+ (void) get_server(ser_line, sizeof(ser_line)); X+ if (*ser_line != CHAR_OK) { /* and then see if that's ok */ X+ fprintf(stdout, "Can't get active file from server: \n%s\n", ser_line); X+ finalize(1); X+ } X+ X+ cp = filexp("/tmp/rrnact.%$"); /* make a temporary name */ X+ strcpy(active_name, cp); X+ actfp = fopen(active_name, "w+"); /* and get ready */ X+ if (actfp == Nullfp) { X+ printf(cantopen,filexp(ACTIVE)) FLUSH; X+ finalize(1); X+ } X+ X+ while (get_server(ser_line, sizeof(ser_line)) >= 0) { /* while */ X+ if (ser_line[0] == '.') /* there's another line */ X+ break; /* get it and write it to */ X+ fputs(ser_line, actfp); X+ putc('\n', actfp); X+ } X+ X+ fseek(actfp,0L,0); /* just get to the beginning */ X+ X+ #else not SERVER X+ X actfp = fopen(filexp(ACTIVE),"r"); X X #endif SERVER X*************** X*** 31,36 X /* open the active file */ X X actfp = fopen(filexp(ACTIVE),"r"); X if (actfp == Nullfp) { X printf(cantopen,filexp(ACTIVE)) FLUSH; X finalize(1); X X--- 68,76 ----- X #else not SERVER X X actfp = fopen(filexp(ACTIVE),"r"); X+ X+ #endif SERVER X+ X if (actfp == Nullfp) { X printf(cantopen,filexp(ACTIVE)) FLUSH; X finalize(1); END_OF_FILE if test 2563 -ne `wc -c <'./rrnpatches/ngdata.c.pat'`; then echo shar: \"'./rrnpatches/ngdata.c.pat'\" unpacked with wrong size! fi # end of './rrnpatches/ngdata.c.pat' fi if test -f './rrnpatches/respond.c.pat' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./rrnpatches/respond.c.pat'\" else echo shar: Extracting \"'./rrnpatches/respond.c.pat'\" \(1520 characters\) sed "s/^X//" >'./rrnpatches/respond.c.pat' <<'END_OF_FILE' X*** rn/respond.c Sun Mar 15 19:54:33 1987 X--- rrn/respond.c Sun Mar 15 20:48:49 1987 X*************** X*** 237,242 X crmode(); X } X s_bomb: X if (chdir(spool) || chdir(ngdir)) { X printf(nocd,ngdir) FLUSH; X sig_catcher(0); X X--- 237,245 ----- X crmode(); X } X s_bomb: X+ #ifdef SERVER X+ if (chdir(spool)) { X+ #else not SERVER X if (chdir(spool) || chdir(ngdir)) { X #endif SERVER X printf(nocd,ngdir) FLUSH; X*************** X*** 238,243 X } X s_bomb: X if (chdir(spool) || chdir(ngdir)) { X printf(nocd,ngdir) FLUSH; X sig_catcher(0); X } X X--- 241,247 ----- X if (chdir(spool)) { X #else not SERVER X if (chdir(spool) || chdir(ngdir)) { X+ #endif SERVER X printf(nocd,ngdir) FLUSH; X sig_catcher(0); X } X*************** X*** 417,422 X #ifdef TERSE X fputs("\n(+cbreak)\n",stdout) FLUSH; X #endif X if (chdir(spool) || chdir(ngdir)) { X printf(nocd,ngdir) FLUSH; X sig_catcher(0); X X--- 421,429 ----- X #ifdef TERSE X fputs("\n(+cbreak)\n",stdout) FLUSH; X #endif X+ #ifdef SERVER X+ if (chdir(spool)) { X+ #else not SERVER X if (chdir(spool) || chdir(ngdir)) { X #endif SERVER X printf(nocd,ngdir) FLUSH; X*************** X*** 418,423 X fputs("\n(+cbreak)\n",stdout) FLUSH; X #endif X if (chdir(spool) || chdir(ngdir)) { X printf(nocd,ngdir) FLUSH; X sig_catcher(0); X } X X--- 425,431 ----- X if (chdir(spool)) { X #else not SERVER X if (chdir(spool) || chdir(ngdir)) { X+ #endif SERVER X printf(nocd,ngdir) FLUSH; X sig_catcher(0); X } END_OF_FILE if test 1520 -ne `wc -c <'./rrnpatches/respond.c.pat'`; then echo shar: \"'./rrnpatches/respond.c.pat'\" unpacked with wrong size! fi # end of './rrnpatches/respond.c.pat' fi if test -f './server/SYSLOG' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./server/SYSLOG'\" else echo shar: Extracting \"'./server/SYSLOG'\" \(2107 characters\) sed "s/^X//" >'./server/SYSLOG' <<'END_OF_FILE' SYSLOG INFO X If LOG is defined, the following informational messages are logged at LOG_INFO. All messages are preceded by the host name executing the command. X host connect "host" connected to the server. host refused connection "host" tried to connect, but was denied. host unrecognized %s "host" gave an unknown command, %s. host group newsgroup "host" isssued GROUP to "newsgroup". host post rejected "host" tried to POST, but was denied. host post succeeded "host" tried to POST, inews worked. host post failed "host" tried to POST, inews failed. host timeout "host" didn't issue a command for TIMEOUT X seconds (#defined in common/conf.h), so X nntpd closed the connection. host transfer_timeout "host" hasn't sent any lines of data X during article transmission for XFER_TIMEOUT X seconds, so nntpd closed the connection. host ihave_stats accepted %d rejected %d failed %d X "host" quit, having offered news articles X to us for transfer. We accepted %d, X rejected %d (having already seem them), X and %d failed (inews exited non-zero). host newnews %s %s %s GMT|local %s X "host" issued NEWNEWS in group %s, X from date %s time %s. Timezone was X either GMT or local. <%s> distributions. host newnews_stats told %d took %d X "host" asked for new news (see above). X We told it about %d articles, and it X subsequently issued %d ARTICLE commands, X presumably to retrieve the asked about msgs. host exit %d aritcles %d groups "host" quit, having read a total of %d X articles and %d groups. host times user %f system %f elapsed %f X "host" quit, having used %f user seconds, X %f system seconds, and %f real-time elapsed X seconds. X The following messages are logged at priority LOG_DEBUG if IHAVE_DEBUG is #defined in common/conf.h: X host ihave artid rejected "host" offered "artid", we already had it. host ihave artid accepted failed "host" offered "artid", we didn't host ihave artid accepted succeeded have it, and the rnews worked or not. X The following error message is logged at LOG_ERR: X host spawn: EOF before period on a line by itself END_OF_FILE if test 2107 -ne `wc -c <'./server/SYSLOG'`; then echo shar: \"'./server/SYSLOG'\" unpacked with wrong size! fi # end of './server/SYSLOG' fi if test -f './server/ahbs.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./server/ahbs.c'\" else echo shar: Extracting \"'./server/ahbs.c'\" \(2721 characters\) sed "s/^X//" >'./server/ahbs.c' <<'END_OF_FILE' X#ifndef lint static char *sccsid = "@(#)ahbs.c 1.8 (Berkeley) 1/11/88"; X#endif X X#include "common.h" X static char *verbage[] = { X "head and body follow", X "head follows", X "body follows", X "request text separately" X}; X X/* X * {ARTICLE,HEAD,BODY,STAT} <messageid>|articlenum X * X * Retrieve article, head, body, or stat, depending on the X * command we were invoked with. X */ X ahbs(argc, argv) X int argc; X char *argv[]; X{ X char artbuf[MAXPATHLEN], art_id[MAXBUFLEN]; X register char c; X int method; X register FILE *fp; /* For Message-ID retrieval only */ X X if (argc > 2) { X printf("%d Usage: %s <message-id>|article_number.\r\n", argv[0], X ERR_CMDSYN); X (void) fflush(stdout); X return; X } X X if ((c = *argv[0]) == 'a' || c == 'A') X method = ARTICLE; X else if ((c == 's' || c == 'S')) X method = STAT; X else X method = ((c == 'h' || c == 'H') ? HEAD : BODY); X X if (argc == 2 && *argv[1] == '<') { /* Message ID */ X fp = openartbyid(argv[1]); X if (fp == NULL) { X printf("%d No article by message-id %s, sorry.\r\n", X ERR_NOART, argv[1]); X (void) fflush(stdout); X return; X } X if (check_ngperm(fp) == 0) { X printf("%d Can't give that to you, sorry.\r\n", X ERR_ACCESS); X (void) fflush(stdout); X (void) fclose(fp); X return; X } X printf("%d 0 %s Article retrieved, %s.\r\n", X OK_ARTICLE + method, argv[1], verbage[method]); X spew(fp, method); X (void) fclose(fp); X#ifdef LOG X if (nn_told) X nn_took++; X#endif X return; X } X X /* Else we're trying to read */ X X if (!canread) { X printf("%d You only have permission to transfer, sorry.\r\n", X ERR_ACCESS); X (void) fflush(stdout); X return; X } X X if (!ingroup) { X printf("%d You are not currently in a newsgroup.\r\n", X ERR_NCING); X (void) fflush(stdout); X return; X } X X if (argc == 1) { X if (art_ptr < 0 || art_ptr >= num_arts) { X printf("%d No article is currently selected.\r\n", X ERR_NOCRNT); X (void) fflush(stdout); X return; X } X (void) sprintf(artbuf, "%d", art_array[art_ptr]); X } else X (void) strcpy(artbuf, argv[1]); X X if (!valid_art(artbuf)) { X printf("%d Invalid article number: %s.\r\n", X ERR_NOARTIG, artbuf); X (void) fflush(stdout); X return; X } X X while (open_valid_art(artbuf, art_id) == NULL) { X if (argc > 1) { X printf("%d Invalid article number: %s.\r\n", X ERR_NOARTIG, artbuf); X (void) fflush(stdout); X return; X } else { X if (++art_ptr >= num_arts) { X printf("%d Invalid article number.\r\n", X ERR_NOARTIG); X (void) fflush(stdout); X return; X } X (void) sprintf(artbuf, "%d", art_array[art_ptr]); X } X } X X printf("%d %s %s Article retrieved; %s.\r\n", X OK_ARTICLE + method, artbuf, art_id, verbage[method]); X X spew(art_fp, method); X X if (argc > 1) X art_ptr = findart(artbuf); X} END_OF_FILE if test 2721 -ne `wc -c <'./server/ahbs.c'`; then echo shar: \"'./server/ahbs.c'\" unpacked with wrong size! fi # end of './server/ahbs.c' fi if test -f './server/common.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./server/common.h'\" else echo shar: Extracting \"'./server/common.h'\" \(2383 characters\) sed "s/^X//" >'./server/common.h' <<'END_OF_FILE' X/* X * Common declarations, includes, and other goodies. X * X * @(#)common.h 1.26 (Berkeley) 2/10/88 X */ X X X#include <stdio.h> X#include <sys/types.h> X#include <sys/stat.h> X#include <errno.h> X#include <ctype.h> X#include <pwd.h> X#include <sys/file.h> X#include <sys/param.h> X#ifdef BSD2_10 X#include <short_names.h> X#endif BSD2_10 X X#include "../common/nntp.h" X#include "../common/conf.h" X X#ifdef SYSLOG X# ifdef FAKESYSLOG X# include "fakesyslog.h" X# else X# include <syslog.h> X# endif X#endif X X#ifdef USG extern struct passwd *getpwent(), *getpwuid(), *getpwnam(); X# include <string.h> X#else not USG X# include <strings.h> X# include <sys/wait.h> X#endif not USG X X#ifdef NDIR X# include <ndir.h> X#else not NDIR X# include <sys/dir.h> X#endif not NDIR X X#ifdef FCNTL X# include <fcntl.h> X#endif FCNTL X X/* X * <dbm.h> stupidly defines NULL, which is why the following X * brain death is necessary. X */ X X#ifdef DBM X# undef NULL X# include <dbm.h> X# undef NULL X# define NULL 0 X#endif DBM X X#ifdef NDBM X# include <ndbm.h> X#endif X X/* X * Some generic maximums. X */ X X#ifndef MAXPATHLEN X#define MAXPATHLEN 1024 X#endif not MAXPATHLEN X X#ifndef MAXHOSTNAMELEN X#define MAXHOSTNAMELEN 256 X#endif not MAXHOSTNAMELEN X X#define MAXBUFLEN 1024 X X/* X * For "spew()" X */ X X#define ARTICLE 0 X#define HEAD 1 X#define BODY 2 X#define STAT 3 X X/* X * For "ngmatch()" X */ X X#define ALLBUT 1 X X#define valid_art(s) (atoi(s) != 0) X X#define putline(s) fputs((s), stdout); putchar('\r'); putchar('\n'); X extern int errno; X extern char *gets(), *fgets(); extern char *mktemp(); extern FILE *open_valid_art(); extern FILE *openartbyid(); extern char *gethistent(); extern int restreql(); extern int s1strneql(); /* for ngmatch */ X extern char spooldir[]; extern char activefile[]; extern char accessfile[]; extern char historyfile[]; extern char ngdatefile[]; extern char inews[]; extern char rnews[]; X extern char **group_array; extern int num_groups; extern char *homedir; extern int ingroup; extern int maxgroups; extern int art_array[]; extern int art_ptr; extern FILE *art_fp; extern int num_arts; extern int uid_poster, gid_poster; extern int canread, canpost, canxfer; extern char **ngpermlist; extern int ngpermcount; X extern char nntp_version[]; X X#ifdef LOG extern int grps_acsd, arts_acsd; extern char hostname[]; X extern int ih_accepted; extern int ih_rejected; extern int ih_failed; X extern int nn_told; extern int nn_took; X#endif END_OF_FILE if test 2383 -ne `wc -c <'./server/common.h'`; then echo shar: \"'./server/common.h'\" unpacked with wrong size! fi # end of './server/common.h' fi if test -f './server/group.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./server/group.c'\" else echo shar: Extracting \"'./server/group.c'\" \(2127 characters\) sed "s/^X//" >'./server/group.c' <<'END_OF_FILE' X#ifndef lint static char *sccsid = "@(#)group.c 1.11 (Berkeley) 2/6/88"; X#endif X X#include "common.h" X X/* X * GROUP newsgroup X * X * Change the current group to the specified newsgroup. X * We also change our current directory to that newsgroup if X * a spool directory for it exists. X * If the newsgroup specified is invalid, the old newsgroup X * remains selected. X */ X group(argc, argv) X int argc; X char *argv[]; X{ X char temp_dir[256]; X int high_msg, low_msg; X char *cp; X char *reqlist[2]; X X if (argc != 2) { X printf("%d Usage: GROUP newsgroup.\r\n", ERR_CMDSYN); X (void) fflush(stdout); X return; X } X X if (!canread) { X printf("%d You only have permission to transfer, sorry.\r\n", X ERR_ACCESS); X (void) fflush(stdout); X return; X } X X if (index(argv[1], '/') != (char *) NULL) { X printf("%d Invalid group name.\r\n", ERR_NOGROUP); X (void) fflush(stdout); X return; X } X X if (find_group(argv[1], num_groups, &low_msg, &high_msg) < 0) { X printf("%d Invalid group name.\r\n", ERR_NOGROUP); X (void) fflush(stdout); X return; X } X X reqlist[0] = argv[1]; X reqlist[1] = NULL; X X if (ngpermcount) { X if (ngmatch(s1strneql, ALLBUT, X ngpermlist, ngpermcount, reqlist, 1) == 0) { X printf("%d You're not allowed to read %s, sorry.\r\n", X ERR_ACCESS, argv[1]); X (void) fflush(stdout); X return; X } X } X X close_crnt(); X (void) chdir(spooldir); X X#ifdef LOG X syslog(LOG_INFO, "%s group %s", hostname, argv[1]); X#endif X X while ((cp = index(argv[1], '.')) != (char *) NULL) X *cp = '/'; X X (void) strcpy(temp_dir, spooldir); X (void) strcat(temp_dir, "/"); X (void) strcat(temp_dir, argv[1]); X X /* X * (void) because a group can be in the active file X * but not have a spool directory. Just leave us X * chdired to base spool directory if this fails. X */ X (void) chdir(temp_dir); X X#ifdef LOG X ++grps_acsd; X#endif X X num_arts = scan_dir(low_msg, high_msg); X art_ptr = 0; X X ingroup = 1; X X while ((cp = index(argv[1], '/')) != (char *) NULL) X *cp = '.'; X X printf("%d %d %d %d %s\r\n", X OK_GROUP, X num_arts, X (num_arts > 0 ? art_array[0] : 0), X (num_arts > 0 ? art_array[num_arts-1] : 0), X argv[1]); X (void) fflush(stdout); X} END_OF_FILE if test 2127 -ne `wc -c <'./server/group.c'`; then echo shar: \"'./server/group.c'\" unpacked with wrong size! fi # end of './server/group.c' fi if test -f './server/main.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./server/main.c'\" else echo shar: Extracting \"'./server/main.c'\" \(2151 characters\) sed "s/^X//" >'./server/main.c' <<'END_OF_FILE' X#ifdef EXCELAN struct sockaddr_in current_peer = { AF_INET, IPPORT_NNTP }; X#endif X#ifndef lint static char *sccsid = "@(#)main.c 1.10 (Berkeley) 2/6/88"; X#endif X X/* X * Network News Transfer Protocol server X * X * Phil Lapsley X * University of California, Berkeley X * (Internet: phil@berkeley.edu; UUCP: ...!ucbvax!phil) X */ X X#include "common.h" X#include <sys/socket.h> X#include <netinet/in.h> X#ifndef EXCELAN X#include <netdb.h> X#endif X#include <signal.h> X main() X{ X X#ifdef ALONE /* If no inetd */ X X int sockt, client, length; X struct sockaddr_in from; X extern int reaper(); X X disassoc(); X X /* fd 0-2 should be open and point to / now. */ X X#ifdef SYSLOG X#ifdef BSD_42 X openlog("nntpd", LOG_PID); /* fd 3 */ X#else X openlog("nntpd", LOG_PID, SYSLOG); /* fd 3 */ X#endif X#endif X X#ifdef FASTFORK X num_groups = read_groups(); /* Read active file now (fd 4) */ X /* and then do it every */ X set_timer(); /* so often later */ X#endif X X#ifndef EXCELAN X sockt = get_socket(); /* should be fd 4 or 5 */ X#endif X X#ifndef USG X (void) signal(SIGCHLD, reaper); X#endif X X#ifndef EXCELAN X if (listen(sockt, SOMAXCONN) < 0) { X#ifdef SYSLOG X syslog(LOG_ERR, "main: listen: %m"); X#endif X exit(1); X } X#endif X X for (;;) { X#ifdef EXCELAN X int status; X sockt = get_socket(); X if (sockt < 0) X continue; X client = accept(sockt, &from); X#else X length = sizeof (from); X client = accept(sockt, &from, &length); X#endif EXCELAN X if (client < 0) { X#ifdef SYSLOG X if (errno != EINTR) X syslog(LOG_ERR, "accept: %m\n"); X#endif X#ifdef EXCELAN X close(sockt); X sleep(1); X#endif X continue; X } X X switch (fork()) { X case -1: X#ifdef SYSLOG X syslog(LOG_ERR, "fork: %m\n"); X#endif X#ifdef EXCELAN X (void) close(sockt); X#endif X (void) close(client); X break; X X case 0: X#ifdef EXCELAN X if (fork()) X exit(0); X bcopy(&from,¤t_peer,sizeof(from)); X make_stdio(sockt); X#else X (void) close(sockt); X make_stdio(client); X#endif X serve(); X break; X X default: X#ifdef EXCELAN X (void) close(sockt); X (void) wait(&status); X#else X (void) close(client); X#endif X break; X } X } X X#else /* We have inetd */ X X serve(); X X#endif X} END_OF_FILE if test 2151 -ne `wc -c <'./server/main.c'`; then echo shar: \"'./server/main.c'\" unpacked with wrong size! fi # end of './server/main.c' fi if test -f './server/newgroups.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./server/newgroups.c'\" else echo shar: Extracting \"'./server/newgroups.c'\" \(2497 characters\) sed "s/^X//" >'./server/newgroups.c' <<'END_OF_FILE' X#ifndef lint static char *sccsid = "@(#)newgroups.c 1.13 (Berkeley) 2/6/88"; X#endif X X#include "common.h" X#include "time.h" X X/* X * NEWGROUPS date time ["GMT"] [<distributions>] X * X * Display new newsgroups since a given date and time, but only X * for those in <distributions>. X */ X newgroups(argc, argv) X int argc; X char *argv[]; X{ X char line[NNTP_STRLEN]; X register char *cp, *temp; X static char **dist_list = (char **) NULL; X int distcount = 0; X int i; X long date; X register FILE *date_fp; X X if (argc < 3) { printf("%d Usage: NEWGROUPS yymmdd hhmmss [\"GMT\"] [<distributions>].\r\n", X ERR_CMDSYN); X (void) fflush(stdout); X return; X } X X date_fp = fopen(ngdatefile, "r"); X if (date_fp == NULL) { X#ifdef SYSLOG X syslog(LOG_ERR, "newgroups: fopen %s: %m", ngdatefile); X#endif X printf("%d Cannot open newsgroup date file.\r\n", ERR_FAULT); X (void) fflush(stdout); X return; X } X X /* YYMMDD HHMMSS */ X if (strlen(argv[1]) != 6 || strlen(argv[2]) != 6) { X printf("%d Date/time must be in form YYMMDD HHMMSS.\r\n", X ERR_CMDSYN); X (void) fflush(stdout); X (void) fclose(date_fp); X return; X } X X (void) strcpy(line, argv[1]); /* yymmdd */ X (void) strcat(line, argv[2]); /* hhmmss */ X X date = dtol(line); X if (date < 0) { X printf("%d Invalid date specification.\r\n", ERR_CMDSYN); X (void) fflush(stdout); X (void) fclose(date_fp); X return; X } X X argc -= 3; X argv += 3; X X if (argc > 0 && !strcasecmp(*argv, "GMT")) { /* We store stuff in GMT */ X ++argv; /* anyway, so this is */ X --argc; /* a "noop" */ X } else /* But that means not GMT */ X date = local_to_gmt(date); /* is a definite "op" */ X X if (argc > 0) { X distcount = get_distlist(&dist_list, *argv); X if (distcount < 0) { X printf("%d Bad distribution list %s:\r\n", *argv); X (void) fflush(stdout); X (void) fclose(date_fp); X return; X } X } X X printf("%d New newsgroups since %s follow.\r\n", OK_NEWGROUPS, line); X X while (fgets(line, sizeof(line), date_fp) != NULL) { X if ((cp = index(line, '\n')) != NULL) X *cp = '\0'; X if ((cp = index(line, ' ')) != NULL) X *cp = '\0'; X if (atoi(line) < date) X break; X X if (distcount == 0) { X putline(cp + 1); X } else { X temp = cp + 1; X cp = index(temp, '.'); X if (cp == NULL) X continue; X *cp = '\0'; X for (i = 0; i < distcount; ++i) X if (strcmp(temp, dist_list[i]) == 0) { X *cp = '.'; X putline(temp); X break; X } X } X } X putchar('.'); X putchar('\r'); X putchar('\n'); X (void) fflush(stdout); X (void) fclose(date_fp); X} END_OF_FILE if test 2497 -ne `wc -c <'./server/newgroups.c'`; then echo shar: \"'./server/newgroups.c'\" unpacked with wrong size! fi # end of './server/newgroups.c' fi if test -f './server/nextlast.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./server/nextlast.c'\" else echo shar: Extracting \"'./server/nextlast.c'\" \(1876 characters\) sed "s/^X//" >'./server/nextlast.c' <<'END_OF_FILE' X#ifndef lint static char *sccsid = "@(#)nextlast.c 1.4 (Berkeley) 1/11/88"; X#endif X X#include "common.h" X X/* X * NEXT X * LAST X * X * Retrieve the message-id of the next or last article in the X * newsgroup. Position the current article pointer to this X * article. X */ X nextlast(argc, argv) X int argc; X char *argv[]; X{ X char artbuf[MAXPATHLEN], art_id[MAXBUFLEN]; X int oldptr; X int next; X X if (!canread) { X printf("%d You only have permission to transfer, sorry.\r\n", X ERR_ACCESS); X (void) fflush(stdout); X return; X } X X if (!ingroup) { X printf("%d You are not currently in a newsgroup.\r\n", X ERR_NCING); X (void) fflush(stdout); X return; X } X X if (argc != 1) { X printf("%d NEXT/LAST need no arguments.\r\n", ERR_CMDSYN); X (void) fflush(stdout); X return; X } X X next = (argv[0][0] == 'n' || argv[0][0] == 'N'); X X if (art_ptr < 0 || art_ptr >= num_arts) { X printf("%d No current article selected.\r\n", X ERR_NOCRNT); X (void) fflush(stdout); X return; X } X X if (next ? (art_ptr + 1 >= num_arts) : (art_ptr - 1 < 0)) { X printf("%d No %s article to retrieve.\r\n", X ERR_NONEXT, next ? "next" : "previous"); X (void) fflush(stdout); X return; X } X X oldptr = art_ptr; X (void) sprintf(artbuf, "%d", art_array[next ? ++art_ptr : --art_ptr]); X X if (!valid_art(artbuf)) { X printf("%d Invalid article number: %s.\r\n", ERR_NOARTIG, X artbuf); X (void) fflush(stdout); X return; X } X X while (open_valid_art(artbuf, art_id) == NULL) { X if (((next) ? (++art_ptr >= num_arts) : (--art_ptr < 0))) { X printf("%d No %s article to retrieve.\r\n", X ERR_NONEXT, next ? "next" : "previous"); X art_ptr = oldptr; X (void) fflush(stdout); X return; X } X (void) sprintf(artbuf, "%d", art_array[art_ptr]); X } X X printf("%d %s %s Article retrieved; request text separately.\r\n", X OK_NOTEXT, artbuf, art_id); X X if (argc > 1) X art_ptr = findart(artbuf); X (void) fflush(stdout); X} END_OF_FILE if test 1876 -ne `wc -c <'./server/nextlast.c'`; then echo shar: \"'./server/nextlast.c'\" unpacked with wrong size! fi # end of './server/nextlast.c' fi if test -f './server/ngmatch.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./server/ngmatch.c'\" else echo shar: Extracting \"'./server/ngmatch.c'\" \(2373 characters\) sed "s/^X//" >'./server/ngmatch.c' <<'END_OF_FILE' X#ifndef lint static char *sccsid = "@(#)ngmatch.c 1.3 (Berkeley) 2/6/88"; X#endif X X#include "common.h" X X/* X * nntpngmatch -- match a list of newsgroup specifiers with a list of X * given newsgroups. A pointer to the routine which determines a match is X * also given. This allows us to do regular expression handling for RFC X * 977's NEWNEWS, and more efficient "strncmps" for the access file, which X * must be checked often. X * X * This is NOT the same routine as ngmatch in the news software. Pity. X * X * Parameters: "nglist" is the list of group specifiers (limited X * regexp) to match against. X * "ngcount" is the number of groups in nglist. X * "matchlist" is the list of newsgroups to match against. X * "matchcount" is number of groups in matchlist. X * X * Returns: 1 if the named newsgroup is in the list. X * 0 otherwise. X */ X ngmatch(func, dflt, ngspec, ngspeccount, matchlist, matchcount) X int (*func)(); X int dflt; X char **ngspec; X int ngspeccount; X char **matchlist; X int matchcount; X{ X register int i, j; X register int match; X register char *cp; X X if (ngspeccount == 0) X return (1); X X match = dflt; X X for (i = 0; i < matchcount; ++i) { X if (cp = index(matchlist[i], '/')) X *cp = '\0'; X for (j = 0; j < ngspeccount; ++j) { X if (ngspec[j][0] == '!') { /* Handle negation */ X if ((*func)(ngspec[j]+1, matchlist[i])) { X match = 0; X } X } else { X if ((*func)(ngspec[j], matchlist[i])) { X match = 1; X } X } X } X } X X return (match); X} X X X/* X * restreql -- A small regular expression string equivalnce routine. X * Thanks and a tip of the hat to Nick Lai, <lai@shadow.berkeley.edu> X * for this time saving device. X * X * Parameters: "w" is an asterisk-broadened regexp, X * "s" is a non-regexp string. X * Returns: 1 if match, 0 otherwise. X * X * Side effects: None. X */ X restreql(w, s) X register char *w; X register char *s; X{ X X while (*s && *w) { X switch (*w) { X case '*': X for (w++; *s; s++) X if (restreql(w, s)) X return 1; X break; X default: X if (*w != *s) X return 0; X w++, s++; X break; X } X } X if (*s) X return 0; X while (*w) X if (*w++ != '*') X return 0; X X return 1; X} X X X/* X * s1strneql -- see if s1 is equivalent to s2 up to the length of s1. X * Return non-zero if so, 0 otherwise. X */ X s1strneql(s1, s2) X register char *s1; X register char *s2; X{ X return (!strncmp(s1, s2, strlen(s1))); X} END_OF_FILE if test 2373 -ne `wc -c <'./server/ngmatch.c'`; then echo shar: \"'./server/ngmatch.c'\" unpacked with wrong size! fi # end of './server/ngmatch.c' fi if test -f './server/parsit.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./server/parsit.c'\" else echo shar: Extracting \"'./server/parsit.c'\" \(2471 characters\) sed "s/^X//" >'./server/parsit.c' <<'END_OF_FILE' X#ifndef lint static char *osccsid = "@(#)parsit.c 1.1 (Berkeley) 12/5/84"; static char *sccsid = "@(#)parsit.c 1.2 (Berkeley) 10/15/87"; X#endif X X/* X * Parse a string of words separated by spaces into an X * array of pointers to characters, just like good ol' argv[] X * and argc. X * X * Usage: X * X * char line[132]; X * char **argv; X * int argc; X * X * argv = (char **) NULL; X * argc = parsit(line, &argv); X * X * returns the number of words parsed in argc. argv[argc] will X * be (char *) NULL to indicate end of list, if you're not X * happy with just knowing how many words you have. X * X * Note that setting argv = (char **) NULL is only done the first X * time the routine is called with a new "argv" -- it tells X * parsit that "argv" is a new array, and parsit shouldn't free X * up the elements (as it would do if it were an old array). X * X * Phil Lapsley X * College of Engineering X * University of California, Berkeley X * (ARPA: phil@Berkeley.ARPA; UUCP: ...!ucbvax!phil) X */ X X#include <stdio.h> X extern char *malloc(), *strcpy(); X parsit(line, array) char *line; char ***array; X{ X char **argv; X char word[132]; X char *linecp; X int i, j, num_words; X X argv = *array; X if (argv != (char **) NULL) { /* Check to see if we should */ X for (i = 0; argv[i] != (char *) NULL; i++) /* free */ X free(argv[i]); /* the old array */ X free((char *) argv); /* and then free the ptr itself */ X } X X linecp = line; X num_words = 0; X while (1) { /* count words in input */ X for (; *linecp == ' ' || *linecp == '\t'; ++linecp) X ; X if (*linecp == '\0') X break; X X for (; *linecp != ' ' && *linecp != '\t' && *linecp != '\0'; ++linecp) X ; X ++num_words; X if (*linecp == '\0') X break; X } X X /* Then malloc enough for that many words plus 1 (for null) */ X X if ((argv = (char **) malloc((num_words + 1) * sizeof(char *))) == X (char **) NULL) { X fprintf(stderr, "parsit: malloc out of space!\n"); X return(0); X } X X j = i = 0; X while (1) { /* Now build the list of words */ X for (; *line == ' ' || *line == '\t'; ++line) X ; X if (*line == '\0') X break; X X i = 0; X for (; *line != ' ' && *line != '\t' && *line != '\0'; ++line) X word[i++] = *line; X word[i] = '\0'; X argv[j] = malloc(strlen(word) + 1); X if (argv[j] == (char *) NULL) { X fprintf(stderr, "parsit: malloc out of space!\n"); X return(0); X } X X (void) strcpy(argv[j], word); X ++j; X if (*line == '\0') X break; X } X argv[j] = (char *) NULL; /* remember null at end of list */ X *array = argv; X return(j); X} END_OF_FILE if test 2471 -ne `wc -c <'./server/parsit.c'`; then echo shar: \"'./server/parsit.c'\" unpacked with wrong size! fi # end of './server/parsit.c' fi if test -f './support/README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./support/README'\" else echo shar: Extracting \"'./support/README'\" \(1902 characters\) sed "s/^X//" >'./support/README' <<'END_OF_FILE' X>>>>>>>>>>>>>>>>>>>>>>>>> No software in the NNTP 1.4 package X>> NOTE NOTE NOTE NOTE >> uses the NEWGROUPS command. As a result, X>> NOTE NOTE NOTE NOTE >> mkgrdates is no longer supported, but is X>>>>>>>>>>>>>>>>>>>>>>>>> included for completeness. X X Mkgrdates is run by cron periodically (say, every 6 or 12 hours -- it's up to you). All it does is produce a cronologically ordered list of newsgroups in the active file, along with their dates of creation. It tries to be intelligent, and if the active file hasn't changed since it was last run, it simply exits. X X So, you'll need to put "mkgrdates" in /usr/lib/crontab to be run periodically. Every day is probably good enough. X X Some things you might want to be aware of are that it creates and updates the files STAT_FILE and NGDATE_FILE, defined in X../common/conf.h. It's up to you to define these constants to suit your system. X X The file "access_file" is the file which tells the news server which hosts can read, which can post, and which can transfer. This file wants to be installed wherever ACCESS_FILE in ../common/conf.h says it should be (you can configure this to suit you). Remember that this should be readable by whatever uid the news server runs as. Further, remember that the entry "default" must be first in the table. X X >>> The access file will support subnets iff you have <<< X >>> defined SUBNET when you made the server. <<< X X Finally, edit Makefile to reflect DESTDIR -- where you want the binary to be installed for mkgrdates. X X If you're having the nntp server log copious info, you will probably want to run the stat package developed by Erik Fair. Once a week you should have crontab do X X awk -f nntp_awk nntplog.old >& nntp_report X where "nntplog.old" is the last week's nntp log file produced by syslog. Any errors which it cannot resolve are placed in the front of the report. END_OF_FILE if test 1902 -ne `wc -c <'./support/README'`; then echo shar: \"'./support/README'\" unpacked with wrong size! fi # end of './support/README' fi if test -f './xmit/Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./xmit/Makefile'\" else echo shar: Extracting \"'./xmit/Makefile'\" \(1833 characters\) sed "s/^X//" >'./xmit/Makefile' <<'END_OF_FILE' X# Compile time flags: X# BSD4_2 - We're a 4.2 BSD UNIX (or later, includes Ultrix) X# 4.2BSD accounting X# USG - We're a USG (System III/V) UNIX X# unreliable signals, strchr, missing bcopy, X# might have lockf(2) X# USELOG="file" - Log transmission stats to this file X# DECNET - We're an Ultrix system with DECNET X# (this implies BSD4_2) X# EXCELAN - We're a USG system with an EXCELAN ethernet board X# to fake real networking with. X# X# these two are implied by EXCELAN: X# NONETDB - We don't have gethostbyname(3) and getservbyname(3) X# and inet_ntoa(3) and inet_addr(3) X# OLDSOCKET - We use the old (pre 4.2 BSD) socket(2) args X# X# these are implied by BSD4_2: X# SYSLOG - We have syslog(3) X# FTRUNCATE - We have ftruncate(2) X# RELSIG - We have 4BSD's reliable signals X# (although I use the signal(2) interface) X DEFS= -DBSD4_2 X# -lresolv needed below for pyramids LIBS= CFLAGS= -O ${DEFS} DESTDIR=/usr/lib/news HFILES=nntpxmit.h get_tcp_conn.h llist.h sysexits.h nntp.h SRC=nntpxmit.c remote.c llist.c get_tcp_conn.c OBJ=nntpxmit.o remote.o llist.o get_tcp_conn.o FILES=Makefile nntpxmit.1 ${SRC} ${HFILES} shlock.c nntpsend.csh nntpsend.sh nntp_awk X all: nntpxmit shlock X nntpxmit: ${OBJ} X cc -o $@ ${OBJ} ${LIBS} X @ls -las $@ ; size $@ X nntpxmit.o: nntpxmit.c nntpxmit.h llist.h X get_tcp_conn.o: get_tcp_conn.c get_tcp_conn.h X remote.o: remote.c nntpxmit.h get_tcp_conn.h X llist.o: llist.c llist.h X shlock: shlock.c X cc ${CFLAGS} -o shlock shlock.c X install: nntpxmit shlock X cp nntpxmit shlock ${DESTDIR} X cd ${DESTDIR}; chmod 755 nntpxmit shlock X @echo "You'll have to edit nntpsend for local config." X lint: X lint -hbx ${DEFS} ${SRC} ${LIBS} X clean: X rm -f nntpxmit shlock ${OBJ} X dist: nntpxmit.tar X nntpxmit.tar: ${FILES} X tar cvhf nntpxmit.tar ${FILES} X X# two for Phil Lapsley distrib: clean X check:; X END_OF_FILE if test 1833 -ne `wc -c <'./xmit/Makefile'`; then echo shar: \"'./xmit/Makefile'\" unpacked with wrong size! fi # end of './xmit/Makefile' fi if test -f './xmit/nntp.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./xmit/nntp.h'\" else echo shar: Extracting \"'./xmit/nntp.h'\" \(2468 characters\) sed "s/^X//" >'./xmit/nntp.h' <<'END_OF_FILE' X/* X * Response codes for NNTP server X * X * @(#)response_codes.h 1.6 (Berkeley) 2/6/86 X * X * First digit: X * X * 1xx Informative message X * 2xx Command ok X * 3xx Command ok so far, continue X * 4xx Command was correct, but couldn't be performed X * for some specified reason. X * 5xx Command unimplemented, incorrect, or a X * program error has occured. X * X * Second digit: X * X * x0x Connection, setup, miscellaneous X * x1x Newsgroup selection X * x2x Article selection X * x3x Distribution X * x4x Posting X */ X X#define CHAR_INF '1' X#define CHAR_OK '2' X#define CHAR_CONT '3' X#define CHAR_ERR '4' X#define CHAR_FATAL '5' X X#define INF_HELP 100 /* Help text on way */ X#define INF_DEBUG 199 /* Debug output */ X X#define OK_CANPOST 200 /* Hello; you can post */ X#define OK_NOPOST 201 /* Hello; you can't post */ X#define OK_SLAVE 202 /* Slave status noted */ X#define OK_GOODBYE 205 /* Closing connection */ X#define OK_GROUP 211 /* Group selected */ X#define OK_GROUPS 215 /* Newsgroups follow */ X#define OK_ARTICLE 220 /* Article (head & body) follows */ X#define OK_HEAD 221 /* Head follows */ X#define OK_BODY 222 /* Body follows */ X#define OK_NOTEXT 223 /* No text sent -- stat, next, last */ X#define OK_NEWNEWS 230 /* New articles by message-id follow */ X#define OK_NEWGROUPS 231 /* New newsgroups follow */ X#define OK_XFERED 235 /* Article transferred successfully */ X#define OK_POSTED 240 /* Article posted successfully */ X X#define CONT_XFER 335 /* Continue to send article */ X#define CONT_POST 340 /* Continue to post article */ X X#define ERR_GOODBYE 400 /* Have to hang up for some reason */ X#define ERR_NOGROUP 411 /* No such newsgroup */ X#define ERR_NCING 412 /* Not currently in newsgroup */ X#define ERR_NOCRNT 420 /* No current article selected */ X#define ERR_NONEXT 421 /* No next article in this group */ X#define ERR_NOPREV 422 /* No previous article in this group */ X#define ERR_NOARTIG 423 /* No such article in this group */ X#define ERR_NOART 430 /* No such article at all */ X#define ERR_GOTIT 435 /* Already got that article, don't send */ X#define ERR_XFERFAIL 436 /* Transfer failed */ X#define ERR_XFERRJCT 437 /* Article rejected, don't resend */ X#define ERR_NOPOST 440 /* Posting not allowed */ X#define ERR_POSTFAIL 441 /* Posting failed */ X X#define ERR_COMMAND 500 /* Command not recognized */ X#define ERR_CMDSYN 501 /* Command syntax error */ X#define ERR_ACCESS 502 /* Access to server denied */ X#define ERR_FAULT 503 /* Program fault, command not performed */ END_OF_FILE if test 2468 -ne `wc -c <'./xmit/nntp.h'`; then echo shar: \"'./xmit/nntp.h'\" unpacked with wrong size! fi # end of './xmit/nntp.h' fi if test -f './xmit/nntpsend.csh' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./xmit/nntpsend.csh'\" else echo shar: Extracting \"'./xmit/nntpsend.csh'\" \(1550 characters\) sed "s/^X//" >'./xmit/nntpsend.csh' <<'END_OF_FILE' X#!/bin/csh -f X# X# What we have here is a csh script for sending netnews to NNTP sites. X# set batchdir=/usr/spool/news/batch libdir=/usr/spool/news/lib set path=( $libdir /usr/ucb /usr/bin /bin $path ) set pname=$0 set pname=$pname:t echo ${pname}: "[$$]" begin `date` X# X# Go to where the action is X# cd $batchdir umask 022 X# X# For NNTP X# X# Here "foo", "bar", and "zot" are the Internet names of X# the machines to which to send. We make the supposition X# that the batch files will be a host's internet name. X# So, for example "nike"'s internet name is "ames-titan.arpa". X# Because of this, your sys file must have "ames-titan.arpa" X# as the batch file output for the machine "nike". X# foreach host ( {cad,zen,jade,cartan}.berkeley.edu decvax.dec.com cgl.ucsf.edu ucdavis.edu 128.54.0.1 ) X set lock=NNTP_LOCK.${host} tmp=${host}.tmp send=${host}.nntp X shlock -p $$ -f ${lock} X if ($status == 0) then X if ( -e ${tmp} ) then X cat ${tmp} >> ${send} X rm ${tmp} X endif X if ( -e ${host} ) then X# if there's already other work to do, let the tmp file cool off. X# we'll pick it up again during the next iteration to make sure that X# we don't miss anything that inews is adding to it now. X if ( -e ${send} ) then X mv ${host} ${tmp} X else X mv ${host} ${send} X endif X endif X if ( -e ${send} ) then X echo ${pname}: "[$$]" begin ${host} X time nntpxmit ${host}:${send} X echo ${pname}: "[$$]" end ${host} X endif X rm -f ${lock} X else X echo ${pname}: "[$$]" ${host} locked by "[`cat ${lock}`]" X endif end echo ${pname}: "[$$]" end `date` END_OF_FILE if test 1550 -ne `wc -c <'./xmit/nntpsend.csh'`; then echo shar: \"'./xmit/nntpsend.csh'\" unpacked with wrong size! fi chmod +x './xmit/nntpsend.csh' # end of './xmit/nntpsend.csh' fi if test -f './xmit/nntpxmit.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./xmit/nntpxmit.h'\" else echo shar: Extracting \"'./xmit/nntpxmit.h'\" \(1545 characters\) sed "s/^X//" >'./xmit/nntpxmit.h' <<'END_OF_FILE' X/* X** Random stuff needed for nntpxmit X** X** This file also contains a lot of assumptions about what features X** are available on the local system - if something is not working X** to your liking, look them over carefully. X*/ X typedef int (*ifunp)(); /* pointer to function that returns int */ X X#define dprintf if (Debug) fprintf X X#define TIMEOUT 3600 /* seconds to read timeout in sfgets */ X X#ifndef TRUE X#define TRUE 1 X#define FALSE 0 X#endif X X/* in goodbye() wait (or not) for QUIT response */ X#define WAIT TRUE X#define DONT_WAIT FALSE X X/* in lockfd(), blocking, or non_blocking */ X#define BLOCK FALSE X#define DONT_BLOCK TRUE X X#ifndef FAIL X#define FAIL (-1) X#endif X X X/* DECNET support is only there if the DECNET compile-time option defined */ X#define T_IP_TCP 1 /* transport is IP/TCP */ X#define T_DECNET 2 /* transport is DECNET */ X#define T_FD 3 /* transport is a descriptor */ X X/* for syslog, if we compile it in */ X#define L_DEBUG 1 X#define L_INFO 2 X#define L_NOTICE 3 X#define L_WARNING 4 X X#if (DECNET && !BSD4_2) /* if we have DECNET, we're an Ultrix */ X#define BSD4_2 X#undef USG X#endif X X#if (EXCELAN && !USG) /* if we have EXCELAN, we're an Uglix */ X#define USG X#undef BSD4_2 X#endif X X#ifdef USG /* USG pinheadedness */ X#define index strchr X#define rindex strrchr X#define u_long unsigned long X#define u_short unsigned short X#endif X X#ifdef BSD4_2 /* look at all these goodies we get! */ X#define FTRUNCATE X#define SYSLOG X#define RELSIG X#endif BSD4_2 X X#ifdef apollo X#undef SYSLOG /* Apollos don't have this by default */ X#endif END_OF_FILE if test 1545 -ne `wc -c <'./xmit/nntpxmit.h'`; then echo shar: \"'./xmit/nntpxmit.h'\" unpacked with wrong size! fi # end of './xmit/nntpxmit.h' fi echo shar: End of archive 2 \(of 9\). cp /dev/null ark2isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 9 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.