Patches to TRN 1.0.2 for remote threads via NNTP
Tim Iverson
iverson at xstor.com
Wed Jun 26 10:23:11 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. You will also need a virgin copy of trn 1.0.2.
What it does: Adds support for the nntp XTHREAD command when compiled for
use with an nntp server that supports XTHREAD. This causes
trn to get active2, db.init, and the thread files from the
server, so you no longer need to run mthreads on the client
machines.
To apply: Build nntp with the XTHREAD command. This patch uses some
new functions in clientlib.c. Then do
patch -p < this_file
To compile: sh ./Configure
make depend
make trn
The configure step is not optional. It is needed to build the new server.h
You might also want to edit your client makefile/installation so that
mthreads and friends are neither compiled nor installed.
- Tim Iverson
iverson at xstor.com -/- uunet!xstor!iverson
#
################ patch starts here
##
Prereq: v1.0.2
Index: patchlevel
@@ -1 +1 @@
-Trn v1.0.2
+Trn v1.0.2nntp
Index: Configure
@@ -2055,4 +2055,14 @@
=
=#include "$NNTPSRC/common/nntp.h"
+
+# if defined(OK_BIN) && defined(USETHREADS)
+# define XTHREAD
+EXT char *nntp_thread_name;
+EXT FILE *nntp_active2(void);
+EXT int nntp_dbinit(void *buf, int size);
+EXT void nntp_thread(void);
+EXT void nntp_unlink(void);
+# endif
+
=#endif
=EOF_SERVE
Index: common.h
@@ -798,9 +798,17 @@
=/* how to cancel an article, continued */
=#ifndef CANCELHEADER
-#ifdef INTERNET
+# ifndef CMSG_HACK
+# ifdef INTERNET
+# define CANCELHEADER "From: %L@%H (%N)\nNewsgroups: %n\nSubject: cancel %i\nControl: cancel %i\nReferences: %R\nDistribution: %D\nOrganization: %o\n\nThis message was cancelled from within trn.\n"
+# else
+# define CANCELHEADER "From:%L@%H.UUCP (%N)\nNewsgroups: %n\nSubject: cancel %i\nControl: cancel %i\nReferences: %R\nDistribution: %D\nOrganization: %o\n"
+# endif
+# else
+# ifdef INTERNET
=# define CANCELHEADER "From: %L@%H (%N)\nNewsgroups: %n\nSubject: cmsg cancel %i\nReferences: %R\nDistribution: %D\nOrganization: %o\n\nThis message was cancelled from within trn.\n"
-#else
+# else
=# define CANCELHEADER "From:%L@%H.UUCP (%N)\nNewsgroups: %n\nSubject: cmsg cancel %i\nReferences: %R\nDistribution: %D\nOrganization: %o\n"
-#endif
+# endif
+# endif
=#endif
=
Index: final.c
@@ -56,4 +56,8 @@
=#include "final.h"
=
+#ifdef SERVER
+# include "server.h"
+#endif
+
=void
=final_init()
@@ -112,4 +116,7 @@
= UNLINK(lockname);
=#ifdef SERVER
+# ifdef XTHREAD
+ nntp_unlink();
+# endif
= if (*active_name)
= UNLINK(active_name);
Index: ng.c
@@ -250,4 +250,9 @@
= }
=
+#ifdef XTHREAD /* use remote thread file? */
+# define thread_name(g) nntp_thread_name
+ nntp_thread();
+#endif
+
= /* FROM HERE ON, RETURN THRU CLEANUP OR WE ARE SCREWED */
=
@@ -651,4 +656,8 @@
= mode = oldmode;
= return exit_code;
+
+#ifdef thread_name /* undo the thread name patch (if active) */
+# undef thread_name
+#endif
=} /* Whew! */
=
Index: ngdata.c
@@ -90,6 +90,11 @@
=#ifdef USETHREADS
= if (use_threads) {
+# ifdef XTHREAD
+ cp = "server's active2";
+ actfp = nntp_active2();
+# else /* !XTHREADS */
= cp = filexp(ACTIVE2);
= actfp = fopen(cp,"r");
+# endif /* XTHREAD */
= if (actfp == Nullfp) {
= printf(cantopen,cp) FLUSH;
Index: nntp.c
@@ -0,0 +1,192 @@
+/* This file (and only this file - not the entire trn 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/29/91
+ */
+
+#include "EXTERN.h"
+#include "common.h"
+#include "server.h"
+
+#ifdef XTHREAD
+
+# ifdef __GNUC__
+# define alloca __builtin_alloca
+# endif
+
+static char /* tmp file names */
+ tmp_active2[] = "/tmp/12345678901234",
+ tmp_thread[] = "/tmp/12345678901234";
+
+static int /* !0 indicates tmp file has been created */
+ got_active2 = 0,
+ got_thread = 0;
+
+char *nntp_thread_name = NULL;
+
+
+/* This function returns a pointer to an open file containing a copy of the
+ * current active2 file on the server.
+ *
+ * entry: it is assumed the server is already open and accessible via
+ * the put_server() and get_server() functions.
+ *
+ * exit: on success, tmp file to hold server's active2 has been created
+ *
+ * return: file pointer opened for reading on success, NULL on failure.
+ */
+FILE *
+nntp_active2()
+{
+ char ser_line[512];
+ FILE *fp;
+
+ /* check to see if the server will even give us the active2 file */
+ put_server("LIST ACTIVE2");
+ if (get_server(ser_line, sizeof(ser_line)) || (*ser_line != CHAR_OK))
+ return NULL; /* server won't/can't give it to us */
+
+ /* first try to create the tmp file */
+ if (!got_active2)
+ {
+ sprintf(tmp_active2, "/tmp/rrnact2.%u", getpid());
+ if (!(fp = fopen(tmp_active2, "w")))
+ return NULL;
+ got_active2 = 1;
+ }
+
+ /* data is now waiting to be picked up - try to create the tmp file */
+ while (!get_server(ser_line, sizeof(ser_line)))
+ {
+ if (ser_line[0] == '.' && !ser_line[1])
+ break;
+ fprintf(fp, "%s\n", ser_line);
+ }
+
+ /* reopen the file for reading */
+ return fp = freopen(tmp_active2, "r", fp);
+}
+
+
+
+/* Load buf with the ouput of XTHREAD DBINIT. Don't exceed size bytes and
+ * return the actual number of bytes sent.
+ */
+int
+nntp_dbinit(buf, size)
+void *buf;
+int size;
+{
+ int rsize;
+ char *rbuf;
+
+ /* first try to do the command */
+ if (!(rsize = xthread("DBINIT")))
+ return rsize;
+
+ /* get space for the all of the bytes */
+ if (!(rbuf = alloca(rsize)))
+ return 0;
+
+ xthread_read(rbuf, rsize);
+ memcpy(buf, rbuf, rsize > size ? size : rsize);
+ return rsize;
+}
+
+
+
+/* Get the thread for the current GROUP and put it in a tmp file. The
+ * tmp file name is then placed in nntp_thread_name.
+ *
+ * entry: the nntp GROUP command has been used to select the
+ * desired newsgroup. ser_rd_fp and ser_wr_fp (the server
+ * read and write file pointers) are open; i.e. server_init()
+ * has been performed successfully.
+ *
+ * exit: a tmp file to hold the thread file from the server is
+ * created and nntp_thread_name is set to point at the
+ * name of that file. On failure, nntp_thread_name is
+ * set to point at the name of an empty file (/dev/null).
+ */
+void
+nntp_thread()
+{
+ int size;
+ char *buf;
+ FILE *fp;
+
+ /* start out as a pessimist */
+ nntp_thread_name = "/dev/null";
+
+ /* first try to do the command */
+ if (!(size = xthread(NULL)))
+ return;
+
+ /* get space for the all of the bytes */
+ if (!(buf = alloca(size)))
+ return;
+
+ /* read it in in one big gulp */
+ xthread_read(buf, size);
+
+ /* make sure we've got a place for the thread file */
+ if (!got_thread)
+ {
+ sprintf(tmp_thread, "/tmp/rrnthd.%u", getpid());
+ got_thread = 1;
+ }
+
+ /* try to create/open the tmp file */
+ if (!(fp = fopen(tmp_thread, "w")))
+ return;
+
+ /* write it out unbuffered */
+ write(fileno(fp), buf, size);
+ fclose(fp);
+ nntp_thread_name = tmp_thread;
+}
+
+
+
+/* Remove all temporary files used so far by the nntp support module.
+ * This routine could be much more general (and should if tmp files start
+ * proliferating).
+ */
+void
+nntp_unlink()
+{
+ if (got_active2)
+ UNLINK(tmp_active2);
+ if (got_thread)
+ UNLINK(tmp_thread);
+ got_active2 = got_thread = 0;
+}
+
+
+# if defined(M_XENIX) && !defined(M_UNIX) /* sco xenix lacks memmove */
+
+/* ansi memmove function for non-ansi compilers
+ */
+void *
+memmove(d, s, n)
+char *d,
+ *s;
+size_t n;
+{
+ void *r = d;
+
+ if (d < s) while (n--)
+ *d++ = *s++;
+ else for (d += n, s += n; n; --n)
+ *--d = *--s;
+
+ return r;
+}
+
+# endif /* M_XENIX */
+
+#endif /* not XTHREAD */
Index: rn.c
@@ -11,5 +11,5 @@
=
=static char rnid[] = "@(#)$Header: rn.c,v 4.3.3.3 91/01/16 03:28:42 davison Trn $";
-static char patchlevel[] = "Trn v1.0.2 based on Rn patchlevel 54";
+static char patchlevel[] = "Trn v1.0.2 (with nntp threads) based on Rn patchlevel 54";
=
=/* $Log: rn.c,v $
Index: rthreads.c
@@ -21,4 +21,8 @@
=#include "rthreads.h"
=
+#ifdef SERVER
+# include "server.h"
+#endif
+
=static FILE *fp_in;
=
@@ -40,7 +44,11 @@
=
= word_same = long_same = TRUE;
+#ifdef XTHREAD
+ if (nntp_dbinit(&mt_bmap, sizeof mt_bmap) >= sizeof mt_bmap - 1) {
+#else /* !XTHREAD */
= filename = filexp( "%X/db.init" );
= if( (fp_in = fopen( filename, FOPEN_RB )) != Nullfp ) {
= if( fread( &mt_bmap, 1, sizeof (BMAP), fp_in ) >= sizeof (BMAP)-1 ) {
+#endif /* XTHREAD */
= if( mt_bmap.version != DB_VERSION ) {
= printf( "\nThread database is the wrong version -- ignoring it.\n" ) FLUSH;
@@ -58,4 +66,5 @@
= }
= }
+#ifndef XTHREAD
= } else {
= goto no_db_init;
@@ -62,4 +71,5 @@
= }
= fclose( fp_in );
+#endif /* XTHREAD */
= } else {
= no_db_init:
##
################ patch ends here
#
More information about the Alt.sources
mailing list