Subject: 'rdump' ported to 2.11BSD (#122)
Index:	etc/dump/ 2.11BSD

Description:
	"rdump" was missing from 2.11BSD even though the man page was
	present in chapter 8.

Repeat-By:
	Attempt to run 'rdump'.  Note the "command not found" error.

Fix:
	Unshar the file below (you will need write permission on the
	/usr/src/etc/dump directory).  Then:

		cd /usr/src/etc/dump
		patch < /tmp/c
		make all
		make install

	There was one missing module (dumprmt.c) which has been imported
	from a 4.3Reno system.

	The number of blocks of inodes to read at a time had to be
	reduced (this has a negligible effect on the speed of dump) 
	in order to acccomodate the network routines (gethostbyname, etc).

	'rrestor' does not exist either at this time but that program is
	so large (it almost does not fit as it exists) that it will need
	much work to be able to have the networking code added to it.
==========================================================================
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	/tmp/c
#	/usr/src/etc/dump/dumprmt.c
# This archive created: Sat Mar  6 16:29:29 1993
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f '/tmp/c'
then
	echo shar: "will not over-write existing file '/tmp/c'"
else
sed 's/^X//' << \SHAR_EOF > '/tmp/c'
Xdiff -c -r /usr/src/etc/dump.old/Makefile /usr/src/etc/dump/Makefile
X*** /usr/src/etc/dump.old/Makefile	Mon Jan 18 08:46:36 1993
X--- /usr/src/etc/dump/Makefile	Sun Feb 28 18:22:26 1993
X***************
X*** 17,41 ****
X  SEPFLAG=-i
X  
X  HDRS=	dump.h
X! SRCS=	dumpitime.c dumpmain.c dumpoptr.c dumptape.c dumptraverse.c unctime.c
X  OBJS=	dumpitime.o dumpmain.o dumpoptr.o dumptape.o dumptraverse.o unctime.o
X  
X! all: dump dumpdir
X  
X  dump: ${OBJS}
X  	cc ${CFLAGS} ${SEPFLAG} ${OBJS} -o dump
X  
X  dumpdir: dumpdir.c
X  	cc ${CFLAGS} ${SEPFLAG} dumpdir.c -o dumpdir
X  
X  install: all
X  	install -s dump ${DESTDIR}/etc/dump
X  	install -s dumpdir ${DESTDIR}/etc/dumpdir
X  
X  clean:
X! 	rm -f *.o dump dumpdir
X  
X  lint:
X! 	lint -chapbx ${CFLAGS} ${SRCS}
X  
X  ${OBJS}: dump.h
X--- 17,58 ----
X  SEPFLAG=-i
X  
X  HDRS=	dump.h
X! SRCS=	dumpitime.c dumpmain.c dumpoptr.c dumptape.c dumptraverse.c unctime.c \
X! 	dumprmt.c
X  OBJS=	dumpitime.o dumpmain.o dumpoptr.o dumptape.o dumptraverse.o unctime.o
X+ ROBJS=	dumpitime.o dumprmain.o dumpoptr.o dumprtape.o dumptraverse.o \
X+ 	unctime.o dumprmt.o
X  
X! all: dump rdump dumpdir
X  
X  dump: ${OBJS}
X  	cc ${CFLAGS} ${SEPFLAG} ${OBJS} -o dump
X  
X+ rdump: ${ROBJS}
X+ 	cc ${CFLAGS} ${SEPFLAG} ${ROBJS} -o rdump
X+ 
X  dumpdir: dumpdir.c
X  	cc ${CFLAGS} ${SEPFLAG} dumpdir.c -o dumpdir
X  
X  install: all
X  	install -s dump ${DESTDIR}/etc/dump
X+ 	install -s rdump ${DESTDIR}/etc/rdump
X  	install -s dumpdir ${DESTDIR}/etc/dumpdir
X  
X  clean:
X! 	rm -f *.o dump rdump dumpdir
X  
X  lint:
X! 	lint -chapbx ${CFLAGS} -DRDUMP ${SRCS}
X  
X  ${OBJS}: dump.h
X+ 
X+ ${ROBJS}: dump.h
X+ 
X+ dumprmain.o: dumpmain.c
X+ 	cc -c -DRDUMP ${CFLAGS} dumpmain.c
X+ 	mv dumpmain.o dumprmain.o
X+ 
X+ dumprtape.o: dumptape.c
X+ 	cc -c -DRDUMP ${CFLAGS} dumptape.c
X+ 	mv dumptape.o dumprtape.o
Xdiff -c -r /usr/src/etc/dump.old/dump.h /usr/src/etc/dump/dump.h
X*** /usr/src/etc/dump.old/dump.h	Mon Oct  1 06:20:54 1990
X--- /usr/src/etc/dump/dump.h	Sun Feb 28 22:27:40 1993
X***************
X*** 1,7 ****
X  /*
X   * "@(#)dump.h	1.1 (Berkeley) 10/13/80"
X   */
X! #define	NI	6	/* number of blocks of inodes per read */
X  
X  #include <stdio.h>
X  #include <ctype.h>
X--- 1,7 ----
X  /*
X   * "@(#)dump.h	1.1 (Berkeley) 10/13/80"
X   */
X! #define	NI	4	/* number of blocks of inodes per read */
X  
X  #include <stdio.h>
X  #include <ctype.h>
Xdiff -c -r /usr/src/etc/dump.old/dumpmain.c /usr/src/etc/dump/dumpmain.c
X*** /usr/src/etc/dump.old/dumpmain.c	Mon Oct  1 05:37:09 1990
X--- /usr/src/etc/dump/dumpmain.c	Sun Feb 28 17:38:02 1993
X***************
X*** 8,13 ****
X--- 8,17 ----
X  long	blockswritten = 0L;	/* number of blocks written on current tape */
X  int	tapeno = 0;	/* current tape number */
X  int	density = 160;	/* density in 0.1" units */
X+ #ifdef RDUMP
X+ char	*host;
X+ int	rmthost();
X+ #endif
X  
X  main(argc, argv)
X  	int	argc;
X***************
X*** 110,116 ****
X  		pipeout++;
X  		tape = "standard output";
X  	}
X! 
X  	if (signal(SIGHUP, sighup) == SIG_IGN)
X  		signal(SIGHUP, SIG_IGN);
X  	if (signal(SIGTRAP, sigtrap) == SIG_IGN)
X--- 114,133 ----
X  		pipeout++;
X  		tape = "standard output";
X  	}
X! #ifdef RDUMP
X! 	{ char *index();
X! 	  host = tape;
X! 	  tape = index(host, ':');
X! 	  if (tape == 0) {
X! 		msg("need keyletter ``f'' and device ``host:tape''\n");
X! 		exit(1);
X! 	  }
X! 	  *tape++ = 0;
X! 	  if (rmthost(host) == 0)
X! 		exit(X_ABORT);
X! 	}
X! 	setuid(getuid());	/* rmthost() is the only reason to be setuid */
X! #endif
X  	if (signal(SIGHUP, sighup) == SIG_IGN)
X  		signal(SIGHUP, SIG_IGN);
X  	if (signal(SIGTRAP, sigtrap) == SIG_IGN)
X***************
X*** 148,154 ****
X--- 165,175 ----
X  	msg("Dumping %s ", disk);
X  	if (dt != 0)
X  		msgtail("(%s) ", dt->fs_file);
X+ #ifdef RDUMP
X+ 	msgtail("to %s on host %s\n", tape, host);
X+ #else
X  	msgtail("to %s\n", tape);
X+ #endif
X  
X  	fi = open(disk, 0);
X  	if (fi < 0) {
X***************
X*** 203,218 ****
X--- 224,247 ----
X  	pass(dump, nodmap);
X  
X  	spcl.c_type = TS_END;
X+ #ifndef	RDUMP
X  	for(i=0; i<NTREC; i++)
X  		spclrec();
X+ #endif
X  	msg("DUMP: %ld tape blocks on %d tape(s)\n",spcl.c_tapea,spcl.c_volume);
X  	msg("DUMP IS DONE\n");
X  
X  	putitime();
X+ #ifndef RDUMP
X  	if (!pipeout) {
X  		close(to);
X  		rewind();
X  	}
X+ #else
X+ 	for (i = 0; i < NTREC; i++)
X+ 		spclrec();
X+ 	rewind();
X+ #endif
X  	broadcast("DUMP IS DONE!\7\7\n");
X  	Exit(X_FINOK);
X  }
Xdiff -c -r /usr/src/etc/dump.old/dumptape.c /usr/src/etc/dump/dumptape.c
X*** /usr/src/etc/dump.old/dumptape.c	Mon Oct  1 19:03:14 1990
X--- /usr/src/etc/dump/dumptape.c	Sun Feb 28 17:47:30 1993
X***************
X*** 14,19 ****
X--- 14,24 ----
X  char	(*tblock)[DEV_BSIZE];	/* Pointer to malloc()ed buffer for tape */
X  #define	writesize (NTREC * DEV_BSIZE) /* Size of malloc()ed buffer for tape */
X  int	trecno = 0;
X+ #ifdef RDUMP
X+ extern char *host;
X+ int	rmtopen(), rmtwrite();
X+ void	rmtclose();
X+ #endif RDUMP
X  extern int read(), write();
X  
X  /*
X***************
X*** 151,157 ****
X  	for (f = 0; f < SLAVES; f++)
X  		close(slavefd[f]);
X  	while (wait(NULL) >= 0)    ;	/* wait for any signals from slaves */
X! 	msg("Tape rewinding\n");
X  	close(to);
X  	while ((f = open(tape, 0)) < 0)
X  		sleep (10);
X--- 156,171 ----
X  	for (f = 0; f < SLAVES; f++)
X  		close(slavefd[f]);
X  	while (wait(NULL) >= 0)    ;	/* wait for any signals from slaves */
X! 	msg("Closing %s\n", tape);
X! #ifdef RDUMP
X! 	if (host) {
X! 		rmtclose();
X! 		while (rmtopen(tape, 0) < 0)
X! 			sleep(10);
X! 		rmtclose();
X! 		return;
X! 	}
X! #endif RDUMP
X  	close(to);
X  	while ((f = open(tape, 0)) < 0)
X  		sleep (10);
X***************
X*** 257,265 ****
X  		msg("Child on Tape %d has parent %d, my pid = %d\n",
X  			tapeno+1, parentpid, getpid());
X  #endif TDEBUG
X! 		while ((to = pipeout ? 1 : creat(tape, 0666)) < 0)
X! 			if (!query("Cannot open tape.  Do you want to retry the open?"))
X  				dumpabort();
X  
X  		enslave();  /* Share open tape file descriptor with slaves */
X  
X--- 271,288 ----
X  		msg("Child on Tape %d has parent %d, my pid = %d\n",
X  			tapeno+1, parentpid, getpid());
X  #endif TDEBUG
X! #ifdef RDUMP
X! 		while ((to = (host ? rmtopen(tape, 2) :
X! 			pipeout ? 1 : open(tape, O_WRONLY|O_CREAT, 0666))) < 0)
X! #else RDUMP
X! 		while ((to =
X! 			pipeout ? 1 : open(tape, O_WRONLY|O_CREAT, 0666)) < 0)
X! #endif RDUMP
X! 		    {
X! 			msg("Cannot open output \"%s\".\n", tape);
X! 			if (!query("Do you want to retry the open?"))
X  				dumpabort();
X+ 		}
X  
X  		enslave();  /* Share open tape file descriptor with slaves */
X  
X***************
X*** 386,391 ****
X--- 409,415 ----
X  	register int cmd, prev[2], next[2];
X  {
X  	register int nread, toggle = 0;
X+ 	int nwrite;
X  
X  	close(fi);
X  	if ((fi = open(disk, 0)) < 0) { 	/* Need our own seek pointer */
X***************
X*** 411,417 ****
X  		}
X  		flock(prev[toggle], LOCK_EX);	/* Wait our turn */
X  
X! 		if (write(to, tblock[0], writesize) != writesize) {
X  			kill(master, SIGUSR1);
X  			for (;;)
X  				sigpause(0L);
X--- 435,452 ----
X  		}
X  		flock(prev[toggle], LOCK_EX);	/* Wait our turn */
X  
X! #ifdef RDUMP
X! 		if ((nwrite = (host ? rmtwrite(tblock[0], writesize)
X! 			: write(to, tblock[0], writesize))) != writesize) {
X! #else RDUMP
X! 		if ((nwrite = write(to, tblock[0], writesize))
X! 		    != writesize) {
X! #endif RDUMP
X! 			if (nwrite == -1) 
X! 				perror("write");
X! 			else
X! 				msg("short write: got %d instead of %d\n",
X! 				    nwrite, writesize);
X  			kill(master, SIGUSR1);
X  			for (;;)
X  				sigpause(0L);
SHAR_EOF
fi
if test -f '/usr/src/etc/dump/dumprmt.c'
then
	echo shar: "will not over-write existing file '/usr/src/etc/dump/dumprmt.c'"
else
sed 's/^X//' << \SHAR_EOF > '/usr/src/etc/dump/dumprmt.c'
X/*-
X * Copyright (c) 1980 The Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X *    notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X *    notice, this list of conditions and the following disclaimer in the
X *    documentation and/or other materials provided with the distribution.
X * 3. All advertising materials mentioning features or use of this software
X *    must display the following acknowledgement:
X *	This product includes software developed by the University of
X *	California, Berkeley and its contributors.
X * 4. Neither the name of the University nor the names of its contributors
X *    may be used to endorse or promote products derived from this software
X *    without specific prior written permission.
X *
X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X * SUCH DAMAGE.
X */
X
X#if	!defined(lint) && defined(DOSCCS)
Xstatic char sccsid[] = "@(#)dumprmt.c	5.11 (Berkeley) 3/7/91";
X#endif
X
X#include <sys/param.h>
X#include <sys/mtio.h>
X#include <sys/ioctl.h>
X#include <sys/socket.h>
X#include <sys/inode.h>
X#include <signal.h>
X
X#include <netinet/in.h>
X
X#include <netdb.h>
X#include <protocols/dumprestor.h>
X#include <pwd.h>
X#include <stdio.h>
X#ifdef __STDC__
X#include <unistd.h>
X#include <stdlib.h>
X#include <string.h>
X#endif
X
X#define	TS_CLOSED	0
X#define	TS_OPEN		1
X
X#define	rmtstate	rstate
Xstatic	int rmtstate = TS_CLOSED;
Xint	rmtape;
Xvoid	rmtgetconn();
Xvoid	rmtconnaborted();
Xint	rmtreply();
Xint	rmtgetb();
Xvoid	rmtgets();
Xint	rmtcall();
Xchar	*rmtpeer;
X
Xextern void msg();
X
Xint
Xrmthost(host)
X	char *host;
X{
X
X	rmtpeer = host;
X	signal(SIGPIPE, rmtconnaborted);
X	rmtgetconn();
X	if (rmtape < 0)
X		return (0);
X	return (1);
X}
X
Xvoid
Xrmtconnaborted()
X{
X
X	fprintf(stderr, "rdump: Lost connection to remote host.\n");
X	exit(1);
X}
X
Xvoid
Xrmtgetconn()
X{
X	static struct servent *sp = 0;
X	struct passwd *pw;
X	char *name = "root";
X	int size;
X
X	if (sp == 0) {
X		sp = getservbyname("shell", "tcp");
X		if (sp == 0) {
X			fprintf(stderr, "rdump: shell/tcp: unknown service\n");
X			exit(1);
X		}
X	}
X	pw = getpwuid(getuid());
X	if (pw && pw->pw_name)
X		name = pw->pw_name;
X	rmtape = rcmd(&rmtpeer, sp->s_port, name, name, "rmt", 0);
X	size = NTREC * DEV_BSIZE;
X	while (size > DEV_BSIZE &&
X	    setsockopt(rmtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0)
X		size -= DEV_BSIZE;
X}
X
Xint
Xrmtopen(tape, mode)
X	char *tape;
X	int mode;
X{
X	char buf[256];
X
X	(void)sprintf(buf, "O%s\n%d\n", tape, mode);
X	rmtstate = TS_OPEN;
X	return (rmtcall(tape, buf));
X}
X
Xvoid
Xrmtclose()
X{
X
X	if (rmtstate != TS_OPEN)
X		return;
X	rmtcall("close", "C\n");
X	rmtstate = TS_CLOSED;
X}
X
Xint
Xrmtread(buf, count)
X	char *buf;
X	int count;
X{
X	char line[30];
X	int n, i, cc;
X	extern errno;
X
X	(void)sprintf(line, "R%d\n", count);
X	n = rmtcall("read", line);
X	if (n < 0) {
X		errno = n;
X		return (-1);
X	}
X	for (i = 0; i < n; i += cc) {
X		cc = read(rmtape, buf+i, n - i);
X		if (cc <= 0) {
X			rmtconnaborted();
X		}
X	}
X	return (n);
X}
X
Xint
Xrmtwrite(buf, count)
X	char *buf;
X	int count;
X{
X	char line[30];
X
X	(void)sprintf(line, "W%d\n", count);
X	write(rmtape, line, strlen(line));
X	write(rmtape, buf, count);
X	return (rmtreply("write"));
X}
X
Xvoid
Xrmtwrt0(count)
X	int count;
X{
X	char line[30];
X
X	(void)sprintf(line, "W%d\n", count);
X	write(rmtape, line, strlen(line));
X}
X
Xvoid
Xrmtwrt1(buf, count)
X	char *buf;
X	int count;
X{
X
X	write(rmtape, buf, count);
X}
X
Xint
Xrmtwrt2()
X{
X
X	return (rmtreply("write"));
X}
X
Xint
Xrmtseek(offset, pos)
X	off_t offset;
X	int pos;
X{
X	char line[80];
X
X	(void)sprintf(line, "L%ld\n%d\n", offset, pos);
X	return (rmtcall("seek", line));
X}
X
Xstruct	mtget mts;
X
Xstruct mtget *
Xrmtstatus()
X{
X	register int i;
X	register char *cp;
X
X	if (rmtstate != TS_OPEN)
X		return (0);
X	rmtcall("status", "S\n");
X	for (i = 0, cp = (char *)&mts; i < sizeof(mts); i++)
X		*cp++ = rmtgetb();
X	return (&mts);
X}
X
Xint
Xrmtioctl(cmd, count)
X	int cmd, count;
X{
X	char buf[256];
X
X	if (count < 0)
X		return (-1);
X	(void)sprintf(buf, "I%d\n%d\n", cmd, count);
X	return (rmtcall("ioctl", buf));
X}
X
Xint
Xrmtcall(cmd, buf)
X	char *cmd, *buf;
X{
X
X	if (write(rmtape, buf, strlen(buf)) != strlen(buf))
X		rmtconnaborted();
X	return (rmtreply(cmd));
X}
X
Xint
Xrmtreply(cmd)
X	char *cmd;
X{
X	char code[30], emsg[BUFSIZ];
X
X	rmtgets(code, sizeof (code));
X	if (*code == 'E' || *code == 'F') {
X		rmtgets(emsg, sizeof (emsg));
X		msg("%s: %s\n", cmd, emsg, code + 1);
X		if (*code == 'F') {
X			rmtstate = TS_CLOSED;
X			return (-1);
X		}
X		return (-1);
X	}
X	if (*code != 'A') {
X		msg("Protocol to remote tape server botched (code %s?).\n",
X		    code);
X		rmtconnaborted();
X	}
X	return (atoi(code + 1));
X}
X
Xint
Xrmtgetb()
X{
X	char c;
X
X	if (read(rmtape, &c, 1) != 1)
X		rmtconnaborted();
X	return (c);
X}
X
Xvoid
Xrmtgets(cp, len)
X	char *cp;
X	int len;
X{
X
X	while (len > 1) {
X		*cp = rmtgetb();
X		if (*cp == '\n') {
X			cp[1] = 0;
X			return;
X		}
X		cp++;
X		len--;
X	}
X	msg("Protocol to remote tape server botched (in rmtgets).\n");
X	rmtconnaborted();
X}
SHAR_EOF
fi
exit 0
#	End of shell archive
