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