Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!uunet!seismo!rutgers!mit-eddie!bloom-beacon!ucbvax!ucbarpa.Berkeley.EDU!fair
From: fair@ucbarpa.Berkeley.EDU (Erik E. Fair)
Newsgroups: news.config
Subject: Re: (*Hiccup*) pyramid overflows /usr/spool
Message-ID: <19884@ucbvax.BERKELEY.EDU>
Date: Tue, 28-Jul-87 02:23:57 EDT
Article-I.D.: ucbvax.19884
Posted: Tue Jul 28 02:23:57 1987
Date-Received: Wed, 29-Jul-87 04:00:19 EDT
References: <3834@pyramid.pyramid.com> <2523@hoptoad.uucp>
Sender: usenet@ucbvax.BERKELEY.EDU
Organization: USENET Protocol Police, Western Gateway Division
Lines: 248
Summary: Ask And Ye Shall Receive (diffs to UUCP enclosed)

"Those who do not know history are condemned to repeat it."

		- George Santayana

In the referenced article, gnu@hoptoad.uucp (John Gilmore) writes:
	[deleted]
		Best of all would be for uucp to just read the
	batch out of a pipe from the batcher -- why bother to copy
	it around on the disk? -- but that's a job for next year.
	(I understand that for a site like Pyramid that feeds the
	same batches to 18 sites, making a copy might be best.) A
	major problem with uucp is that it runs asynchronously to
	everything, but letting it "call out" to its client
	applications (mail, news) would fix a lot of this.

Mark Horton did this to the UUCP on cbosgd YEARS ago, and posted
the diffs to the network. This diff was even included in the news
distribution for a while, along with some other fixes and improvements
to UUCP that are now basically standard equipment with your garden
variety UUCP. I bet if someone asked (or looked in an old copy of
the news distribution) that it could be found.

In fact... [rummage... rummage... huge cloud of dust results from
blowing dust off old files] I have a copy of this thing right here
on my disk in my copy of the 2.10.1 news distribution.  I therefore
enclose it in this very posting. I knew that someone would ask for
it again...

	self-appointed network historian,

	Erik E. Fair	ucbvax!fair	fair@ucbarpa.berkeley.edu

N.B.	as with all context diffs, your line numbers may vary. In
	particular, note that the last mod date on most of the
	original files is in 1979...

-------------------------------------------------------------------------------
Excerpt from the README file:

=batch 
	Code to allow commands such as
	uux -c yoursys!rnews '<' =/usr/lib/news/batch_/usr/spool/batch/yoursys
	so that, once the connection is fired up and ready to transfer the
	file, the command "/usr/lib/news/batch /usr/spool/batch/yoursys"
	will be started up, and its output copied to the other system.
	The advantage here is that batching is possible without keeping
	a full copy of the news on spool waiting for a connection to
	be established.  This can be a big win if the other system is
	down for any length of time.  It does not good without the
	uux.minus.c mod below.  Beware of security issues - they have
	not been carefully addressed here, and this mod opens up some
	potential security holes.  It only allows one command to
	be fired up, and batch should check that the file of names
	is in a safe directory (not /usr/lib/uucp/L.sys or /etc/passwd).
	Ideally batch should be suid, since the command will run as uucp.
-------------------------------------------------------------------------------

*** chkpth.c	Sun May 27 20:55:39 1979
--- chkpth.c.new	Sat Apr  2 21:34:39 1983
***************
*** 40,45
  	char c;
  	int ret, i;
  
  	if (Uptfirst) {
  		ret = rdpth(Upt);
  		ASSERT(ret == 0, "INIT USERFILE %d", Nbrusers);

--- 40,48 -----
  	char c;
  	int ret, i;
  
+ 	if (prefix("=/usr/lib/news/batch", path))
+ 		return(0);
+ 
  	if (Uptfirst) {
  		ret = rdpth(Upt);
  		ASSERT(ret == 0, "INIT USERFILE %d", Nbrusers);
*** cntrl.c	Sun May 27 20:56:46 1979
--- cntrl.c.new	Sat Apr  2 21:37:03 1983
***************
*** 82,87
  char Wfile[MAXFULLNAME] = {'\0'};
  char Dfile[MAXFULLNAME];
  
  /*******
   *	cntrl(role, wkpre)
   *	int role;

--- 82,89 -----
  char Wfile[MAXFULLNAME] = {'\0'};
  char Dfile[MAXFULLNAME];
  
+ FILE *pfopen();
+ 
  /*******
   *	cntrl(role, wkpre)
   *	int role;
***************
*** 164,170
  			if (index(W_OPTNS, 'c') == NULL)
  				fp = fopen(Dfile, "r");
  			if (fp == NULL &&
! 			   (fp = fopen(filename, "r")) == NULL) {
  				/*  can not read data file  */
  				logent("CAN'T READ DATA", "FAILED");
  				unlinkdf(Dfile);

--- 166,172 -----
  			if (index(W_OPTNS, 'c') == NULL)
  				fp = fopen(Dfile, "r");
  			if (fp == NULL &&
! 			   (fp = pfopen(filename, "r")) == NULL) {
  				/*  can not read data file  */
  				logent("CAN'T READ DATA", "FAILED");
  				unlinkdf(Dfile);
***************
*** 282,288
  			notify(mailopt, W_USER, W_FILE1, Rmtname, &msg[1]);
  			ASSERT(role == MASTER,
  				"role - %d", role);
! 			fclose(fp);
  			unlinkdf(W_DFILE);
  			goto top;
  		}

--- 284,290 -----
  			notify(mailopt, W_USER, W_FILE1, Rmtname, &msg[1]);
  			ASSERT(role == MASTER,
  				"role - %d", role);
! 			pfclose(fp);
  			unlinkdf(W_DFILE);
  			goto top;
  		}
***************
*** 292,298
  			ASSERT(role == MASTER,
  				"role - %d", role);
  			ret = (*Wrdata)(fp, Ofn);
! 			fclose(fp);
  			if (ret != 0) {
  				(*Turnoff)();
  				return(FAIL);

--- 294,300 -----
  			ASSERT(role == MASTER,
  				"role - %d", role);
  			ret = (*Wrdata)(fp, Ofn);
! 			pfclose(fp);
  			if (ret != 0) {
  				(*Turnoff)();
  				return(FAIL);
*** expfile.c	Sun May 27 20:57:47 1979
--- expfile.c.new	Sat Apr  2 21:39:05 1983
***************
*** 19,24
  	int uid;
  
  	switch(file[0]) {
  	case '/':
  		return;
  	case '~':

--- 19,25 -----
  	int uid;
  
  	switch(file[0]) {
+ 	case '=':
  	case '/':
  		return;
  	case '~':
*** uux.c	Wed Aug 19 16:56:29 1981
--- uux.c.new	Sat Apr  2 21:40:01 1983
***************
*** 231,240
  			expfile(rest);
  			gename(DATAPRE, xsys, 'A', dfile);
  			DEBUG(4, "rest %s\n", rest);
! 			if ((chkpth(User, "", rest) || anyread(rest)) != 0) {
! 				fprintf(stderr, "permission denied %s\n", rest);
! 				cleanup(1);
! 			}
  			if (xcp(rest, dfile) != 0) {
  				fprintf(stderr, "can't copy %s to %s\n", rest, dfile);
  				cleanup(1);

--- 231,241 -----
  			expfile(rest);
  			gename(DATAPRE, xsys, 'A', dfile);
  			DEBUG(4, "rest %s\n", rest);
! 			if (rest[0] == '/')
! 				if ((chkpth(User, "", rest) || anyread(rest)) != 0) {
! 					fprintf(stderr, "permission denied %s\n", rest);
! 					cleanup(1);
! 				}
  			if (xcp(rest, dfile) != 0) {
  				fprintf(stderr, "can't copy %s to %s\n", rest, dfile);
  				cleanup(1);
******************
pfopen.c:
------------------
/*
 * Routine like fopen, but checks for processes to open.
 * The process name begins with =, and any underscores
 * are translated into blanks.  We don't do things in the
 * obvious way (start with | or !, use blanks as themselves)
 * because getargs can't parse strings containing blanks in
 * all versions of uucp.
 */

#include 

static FILE *prevval = NULL;

FILE *popen();

FILE *
pfopen(name, mode)
char *name, *mode;
{
	char cmdbuf[256];
	register char *p;

	if (*name != '=') {
		prevval = NULL;
		return fopen(name, mode);
	}

	strcpy(cmdbuf, name);
	for (p=cmdbuf; *p; p++)
		if (*p == '_')
			*p = ' ';
	p = cmdbuf+1;
	prevval = popen(p, mode);
	return prevval;
}

pfclose(fd)
FILE *fd;
{
	if (fd == prevval) {
		pclose(fd);
		prevval = NULL;
	} else
		fclose(fd);
}
****************
Also be sure to add pfopen.o to the list of .o files in the makefile.