Patches to NNTP 1.5.11 to support remote threads for TRN

Tim Iverson iverson at xstor.com
Wed Jun 26 10:17:35 AEST 1991


This patch file requires patch-2.0.2.0 patchlevel 12u4.  You might have some
success with unipatch or earlier 12u* versions of patch, but you're on your
own there.  Basically, it extends the nntp command set to allow trn to
retrieve thread information via nntp - the need for a local threads database
is eliminated.


What it does:	modifies the LIST command to also list trn's active2 file.
		adds an XTHREAD command so trn can access threads remotely.

To apply:	cd nntp-1.5.11
		patch -p < this_file

To compile:	None of the installation files or Makefiles are modified,
		so you will have to follow the directions included with
		nntp.  For SCO Unix, you should apply the sco unix patch.

- Tim Iverson
  iverson at xstor.com -/- uunet!xstor!iverson

#
################ patch starts here
##
Prereq: "1.5.11
Index: common/version.c
@@ -3,3 +3,3 @@
= */
=
-char	nntp_version[] = "1.5.11 (10 February 1991)";
+char	nntp_version[] = "1.5.11a (1 April 1991)";
Index: common/clientlib.c
@@ -634,2 +634,72 @@
=}
=
+
+
+static	int	bytes = 0;	/* bytes remaining to be transfered */
+
+/* This function issues an XTHREAD command and prepares xthread_read() for
+ * the data transfer by reading the status line returned by the server.
+ *
+ * entry:	server must be open and ready to accept commands.
+ *
+ * exit:	server will be transfering XTHREAD data.
+ *
+ * return:	bytes to be transfered on success, 0 for error.
+ */
+int
+xthread(cmd)
+char	*cmd;
+{
+	char	buf[512];
+
+	/* send the given xthread command */
+	sprintf(buf, cmd && *cmd ? "XTHREAD %s\r\n" : "XTHREAD\r\n", cmd);
+	put_server(buf);
+
+	/* try to get the status line and the status code */
+	if (get_server(buf, sizeof buf) || *buf != CHAR_OK)
+		return bytes = 0;
+
+	/* try to get the number of bytes being transfered */
+	if (sscanf(buf, "%*d%d", &bytes) != 1)
+		return bytes = 0;
+	return bytes;
+}
+
+
+/* This function is used to read the data sent as a result of the
+ * XTHREAD command.
+ *
+ * entry:	There must have been a successful call to xthread() or
+ *		xthread_read() preceding the current call.
+ *
+ *		No other communication to or from the server after XTHREAD is
+ *		issued and before this function returns EOF or error is
+ *		allowed - otherwise we'll block for data that'll never come.
+ *
+ * exit:	The buffer is filled with data from the XTHREAD command.
+ *
+ * return:	bytes read into the buffer, 0 for eof or error.
+ */
+int
+xthread_read(buf, n)
+void	*buf;
+int	n;
+{
+	/* if no bytes to read, then just return EOF */
+	if (!bytes)
+		return bytes;
+
+	/* try to read some data from the server */
+	bytes -= (n = fread(buf, 1, n > bytes ? bytes : n, ser_rd_fp));
+
+	/* if no more left, then fetch the end-of-command signature */
+	if (!bytes)
+	{
+		char buf[5];	/* "\r\n.\r\n" */
+
+		fread(buf, sizeof buf, 1, ser_rd_fp);
+	}
+
+	return n;
+}
Index: common/clientlib.h
@@ -10,2 +10,4 @@
=extern	int	get_server();
=extern	void	close_server();
+extern	int	xthread();
+extern	int	xthread_read();
Index: common/conf.h.dist
@@ -95,4 +95,13 @@
=			/* loaded already, defining this may be a bad idea */
=
+#define XTHREAD		/* Optional XTHREAD command.  This allows trn to
+			 * keep all data on the server.
+			 */
+
+#ifdef	XTHREAD		/* locations for trn data files (on server) */
+# define ACTIVE2_FILE	"/usr/local/lib/trn/active2"
+# define DBINIT_FILE	"/usr/local/lib/trn/db.init"
+#endif
+
=/* Things that vary in network implementations */
=#define	SUBNET		/* If you have 4.3 subnetting */
Index: common/nntp.h
@@ -49,4 +49,5 @@
=#define	OK_AUTHSYS	280	/* Authorization system ok */
=#define	OK_AUTH		281	/* Authorization (user/pass) ok */
+#define	OK_BIN		282	/* binary data follows */
=
=#define	CONT_XFER	335	/* Continue to send article */
Index: server/Makefile
@@ -7,5 +7,5 @@
=	newgroups.o newnews.o nextlast.o ngmatch.o post.o parsit.o scandir.o \
=	slave.o spawn.o strcasecmp.o subnet.o time.o xhdr.o fakesyslog.o \
-	batch.o auth.o timer.o ../common/version.o
+	batch.o auth.o timer.o xthread.o ../common/version.o
=
=SRVRSRC = main.c serve.c access.c access_inet.c access_dnet.c active.c \
@@ -13,5 +13,5 @@
=	newgroups.c newnews.c nextlast.c ngmatch.c post.c parsit.c scandir.c \
=	slave.c spawn.c strcasecmp.c subnet.c time.c xhdr.c fakesyslog.c \
-	batch.c auth.c timer.c ../common/version.c
+	batch.c auth.c timer.c xthread.c ../common/version.c
=
=SRVRINC = common.h ../common/conf.h ../common/nntp.h timer.h
@@ -19,4 +19,6 @@
=SRCS	= ${SRVRSRC}
=
+THREADS	= ../../trn/threads.o
+
=# -ldbm here if you've #define'ed DBM in ../common/conf.h
=LIBS	= -ldbm
@@ -30,8 +32,12 @@
=all:	nntpd
=
-nntpd: ${SRVROBJ} ${SRVRINC}
-	${CC} ${CFLAGS} -o nntpd ${SRVROBJ} ${LIBS}
+nntpd: ${SRVROBJ} ${SRVRINC} ${THREADS}
+	${CC} ${CFLAGS} -o nntpd ${SRVROBJ} ${THREADS} ${LIBS}
=
=${SRVROBJ}: ${SRVRINC}
+
+$(THREADS) :
+	@echo You must first build threads.o as used in trn.
+	@false
=
=install: nntpd
Index: server/common.h
@@ -165,4 +165,10 @@
=extern	char	rnews[];
=
+#ifdef	XTHREAD
+extern	char	active2file[];
+extern	char	dbinitfile[];
+extern	char	*threadfile;
+#endif
+
=extern	char	**group_array;
=extern	char	*actbuf;
Index: server/globals.c
@@ -27,4 +27,10 @@
=char	rnews[] = RNEWS;
=
+#ifdef	XTHREAD
+char	active2file[] = ACTIVE2_FILE;
+char	dbinitfile[] = DBINIT_FILE;
+char	*threadfile = NULL;
+#endif
+
=/*
= * Other random externals.
Index: server/group.c
@@ -101,4 +101,12 @@
=		*cp = '.';
=
+#ifdef	XTHREAD
+	{
+		extern char *thread_name(const char *newsgroup);
+
+		threadfile = thread_name(argv[1]);
+	}
+#endif
+
=	printf("%d %d %d %d %s\r\n",
=		OK_GROUP,
Index: server/help.c
@@ -22,6 +22,13 @@
=	printf("STAT        NEWGROUPS    HELP\r\n");
=	printf("IHAVE       NEWNEWS      SLAVE\r\n");
-	printf("\r\nAdditionally, the following extention is supported:\r\n\r\n");
+#if defined(XHDR) || defined(XTHREAD)
+	printf("\r\nAdditionally, the following extentions are supported:\r\n\r\n");
+# ifdef	XHDR
=	printf("XHDR        Retrieve a single header line from a range of articles.\r\n");
+# endif	XHDR
+# ifdef	XTHREAD
+	printf("XTHREAD     Retrieve trn thread file for the current group.\r\n");
+# endif
+#endif
=	printf("\r\n");
=	printf("Bugs to Stan Barber (Internet: nntp at tmc.edu; UUCP: ...!bcm!nntp)\r\n");
Index: server/list.c
@@ -46,6 +46,27 @@
=		items = "newsgroup descriptions";
=		format = "Descriptions in form \"group description\".";
+#ifdef	XTHREAD
+	} else if (argc == 2 && !strcasecmp(argv[1],"active2")){
+                num_groups = read_groups();
+                if (num_groups == 0){ /* can't get a group list */
+                  printf("%d Group update failed. Try later.\r\n",
+                         ERR_FAULT);
+                  (void) fflush(stdout);
+# ifdef LOG
+                  syslog(LOG_INFO, "%s group update failed in LIST", hostname);
+# endif
+                  exit(1);
+                }
+		filename = active2file;
+		items = "threaded newsgroups";
+		format = "Threaded groups in form \"group high low y/n/m\".";
+#endif	/* XTHREAD */
=	} else {
-		printf("%d Usage: LIST [ACTIVE|NEWSGROUPS|DISTRIBUTIONS]\r\n",
+		printf(
+#ifdef	XTHREAD
+		"%d Usage: LIST [ACTIVE|ACTIVE2|DISTRIBUTIONS|NEWSGROUPS]\r\n",
+#else
+		"%d Usage: LIST [ACTIVE|NEWSGROUPS|DISTRIBUTIONS]\r\n",
+#endif	/* XTHREAD */
=			ERR_CMDSYN);
=		(void) fflush(stdout);
Index: server/serve.c
@@ -27,5 +27,5 @@
=extern	int	ahbs(), group(), help(), ihave();
=extern	int	list(), newgroups(), newnews(), nextlast(), post();
-extern	int	slave(), stat(), xhdr();
+extern	int	slave(), stat(), xhdr(), xthread();
=
=extern int errno;
@@ -62,4 +62,7 @@
=	"xhdr",		0,	xhdr,
=#endif XHDR
+#ifdef XTHREAD
+	"xthread",	0,	xthread,
+#endif
=};
=#define NUMCMDS (sizeof(cmdtbl) / sizeof(struct cmdent))
Index: server/xthread.c
@@ -0,0 +1,115 @@
+/* This file (and only this file - not the entire nntp distribution) is
+ * hereby placed in the public domain.  Use it as you see fit, but if you
+ * manage to find some wonderful use for this code elsewhere, it would be
+ * nice to receive mention for it.
+ *
+ * - Tim Iverson
+ *   iverson at xstor.com -/- uunet!xstor!iverson
+ *   3/28/91
+ */
+
+#include "common.h"
+
+#ifdef XTHREAD
+
+# ifdef __GNUC__
+#  define alloca __builtin_alloca
+# else
+extern	void *alloca(unsigned int bytes);
+# endif
+
+
+/* Usage: XTHREAD [DBINIT|THREAD]
+ *
+ * DBINIT	dump the contents of the db.init file to stdout
+ * THREAD	dump the contents of the thread file for the current
+ *		newsgroup to stdout (default if no argument).
+ *
+ * N.B. These two files are not ascii and no attempt is made at converting
+ *	native byte size to any type of standard whatsoever.  This'll have
+ *	to be fixed if this command is to be integrated into the protocol.
+ *
+ * This command is not documented in rfc977.
+ */
+
+void
+xthread(argc, argv)
+int	argc;
+char	*argv[];
+{
+	register FILE	*fp;
+	struct stat	s;
+	char		*buf, *file, *what;
+
+	/* can't transfer threads, only read 'em */
+	if (!canread)
+	{
+		printf("%d You only have permission to transfer, sorry.\r\n",
+			ERR_ACCESS);
+		(void) fflush(stdout);
+		return;
+	}
+
+	/* "parse" the argument */
+	if (argc == 2 && !strcasecmp(argv[1], "dbinit"))
+	{
+		file = dbinitfile;
+		what = "db.init";
+	}
+	else if (argc == 1 || argc == 2 && !strcasecmp(argv[1], "thread"))
+	{
+		if (!threadfile)
+		{
+			printf("%d You are not currently in a newsgroup.\r\n",
+				ERR_NCING);
+			(void) fflush(stdout);
+			return;
+		}
+		file = threadfile;
+		what = "thread";
+	}
+	else
+	{
+		printf("%d Usage: XTHREAD [DBINIT|THREAD]\r\n", ERR_CMDSYN);
+		(void) fflush(stdout);
+		return;
+	}
+
+	/* try to open the file to be transfered */
+	if (!(fp = fopen(file, "r")))
+	{
+		printf("%d %s file is not available.\r\n", ERR_FAULT, what);
+		(void) fflush(stdout);
+#ifdef SYSLOG
+		syslog(LOG_ERR, "xthread: fopen %s: %m", file);
+#endif
+		return;
+	}
+
+	/* tell 'em how much binary data is coming down the pike */
+	fstat(fileno(fp), &s);
+	printf("%d %u bytes of %s file follows verbatim "
+		"(binary!)\r\n", OK_BIN, s.st_size, what);
+
+	/* copy the file verbatim to stdout */
+	if (buf = alloca(s.st_size))
+	{
+		/* ah-so! got lotsa memoree */
+		read(fileno(fp), buf, s.st_size);
+		fwrite(buf, s.st_size, 1, stdout);
+	}
+	else
+	{
+		int		bytes;
+		char		buf[BUFSIZ];
+
+		while (bytes = fread(buf, 1, sizeof buf, fp))
+			fwrite(buf, bytes, 1, stdout);
+	}
+
+	fputs("\r\n.\r\n", stdout);
+	fflush(stdout);
+	fclose(fp);
+}
+
+#endif /* not XTHREAD */
##
################ patch ends here
#



More information about the Alt.sources mailing list