tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

magic unmbers in rmt protocol



It came up in chat today that dump/rmt uses hardcoded integer values
that are then passed as the flags argument of open. This is wrong for
several reasons.

The following patch corrects it. The rmt part is untested (don't have
a suitable setup to test it with) -- if someone who uses rmt could
check it out that would be helpful.

Based on discussion with mrg, the rmt patch accepts a bunch of open
flags that dump doesn't send, because it's apparently useful to be
able to use rmt to dump to remote regular files with a suitably
patched dump. Getting the latter written and committed is for some
future time :-)

Question: should the defines go in a new <protocols/rmt.h> or is that
overkill? Right now they're pasted in both programs, which is not
ideal but not a huge issue either.

Index: usr.sbin/rmt/rmt.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/rmt/rmt.c,v
retrieving revision 1.17
diff -u -p -r1.17 rmt.c
--- usr.sbin/rmt/rmt.c	23 Jan 2018 21:06:25 -0000	1.17
+++ usr.sbin/rmt/rmt.c	17 Mar 2021 19:18:13 -0000
@@ -59,6 +59,25 @@ __RCSID("$NetBSD: rmt.c,v 1.17 2018/01/2
 #include <string.h>
 #include <unistd.h>
 
+/*
+ * The wire protocol uses integer literals for the open mode,
+ * corresponding to the traditional O_RDONLY and O_RDWR values.
+ * Traditional dump sends only either O_RDONLY or O_RDWR, but
+ * since it's useful to use rmt to dump to remote regular files
+ * we also allow some other flags, using the NetBSD values
+ * (which are likely the historical ones, but I'm not sure).
+ */
+#define RMT_O_RDONLY	0
+#define RMT_O_RDWR	2
+#define RMT_O_ACCMODE	3
+#define RMT_O_APPEND	8
+#define RMT_O_NOFOLLOW	0x100
+#define RMT_O_CREAT	0x200
+#define RMT_O_TRUNC	0x400
+#define RMT_O_EXCL	0x800
+#define RMT_O_REGULAR	0x02000000
+#define RMT_O_FLAGS	0x02000f08
+
 int	tape = -1;
 
 int	maxrecsize = -1;
@@ -77,6 +96,7 @@ FILE	*debug;
 char	*checkbuf(char *, int);
 void	 error(int);
 void	 getstring(char *, size_t);
+static int decode_mode(const char *);
 
 int
 main(int argc, char *argv[])
@@ -85,6 +105,7 @@ main(int argc, char *argv[])
 	int rval;
 	char c;
 	int n, i, cc;
+	int openflags;
 
 	argc--, argv++;
 	if (argc > 0) {
@@ -106,7 +127,12 @@ top:
 		getstring(device, sizeof(device));
 		getstring(mode, sizeof(mode));
 		DEBUG2("rmtd: O %s %s\n", device, mode);
-		tape = open(device, atoi(mode),
+		openflags = decode_mode(mode);
+		if (openflags == -1) {
+			error(EINVAL);
+			goto top;
+		}
+		tape = open(device, openflags,
 		    S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
 		if (tape < 0)
 			goto ioerror;
@@ -246,3 +272,49 @@ error(int num)
 	(void)snprintf(resp, sizeof(resp), "E%d\n%s\n", num, strerror(num));
 	(void)write(STDOUT_FILENO, resp, strlen(resp));
 }
+
+static int
+decode_mode(const char *buf)
+{
+	unsigned val;
+	int ret;
+	char *more;
+
+	errno = 0;
+	val = strtol(buf, &more, 0);
+	if (errno != 0 || *more != '\0') {
+		return -1;
+	}
+	switch (val & RMT_O_ACCMODE) {
+	    case RMT_O_RDONLY:
+		ret = O_RDONLY;
+		break;
+	    case RMT_O_RDWR:
+		ret = O_RDWR;
+		break;
+	    default:
+		return -1;
+	}
+	if ((val & RMT_O_FLAGS) != val) {
+		return -1;
+	}
+	if (val & RMT_O_APPEND) {
+		ret |= O_APPEND;
+	}
+	if (val & RMT_O_NOFOLLOW) {
+		ret |= O_NOFOLLOW;
+	}
+	if (val & RMT_O_CREAT) {
+		ret |= O_CREAT;
+	}
+	if (val & RMT_O_TRUNC) {
+		ret |= O_TRUNC;
+	}
+	if (val & RMT_O_EXCL) {
+		ret |= O_EXCL;
+	}
+	if (val & RMT_O_REGULAR) {
+		ret |= O_REGULAR;
+	}
+	return ret;
+}
Index: sbin/dump/dump.h
===================================================================
RCS file: /cvsroot/src/sbin/dump/dump.h,v
retrieving revision 1.59
diff -u -p -r1.59 dump.h
--- sbin/dump/dump.h	3 Dec 2020 08:25:57 -0000	1.59
+++ sbin/dump/dump.h	17 Mar 2021 19:18:14 -0000
@@ -244,6 +244,8 @@ void	lfs_wrap_go(void);
 #endif
 
 /* rdump routines */
+#define RMT_O_RDONLY 	0
+#define RMT_O_RDWR 	2
 #if defined(RDUMP) || defined(RRESTORE)
 void	rmtclose(void);
 int	rmthost(const char *);
Index: sbin/dump/tape.c
===================================================================
RCS file: /cvsroot/src/sbin/dump/tape.c,v
retrieving revision 1.55
diff -u -p -r1.55 tape.c
--- sbin/dump/tape.c	1 Mar 2019 16:42:11 -0000	1.55
+++ sbin/dump/tape.c	17 Mar 2021 19:18:14 -0000
@@ -391,7 +391,7 @@ trewind(int eject)
 #ifdef RDUMP
 	if (host) {
 		rmtclose();
-		while (rmtopen(tape, 0, 0) < 0)
+		while (rmtopen(tape, RMT_O_RDONLY, 0) < 0)
 			sleep(10);
 		if (eflag && eject) {
 			msg("Ejecting %s\n", tape);
@@ -431,7 +431,7 @@ close_rewind(void)
 	if (lflag) {
 		for (i = 0; i < lflag / 10; i++) { /* wait lflag seconds */
 			if (host) {
-				if (rmtopen(tape, 0, 0) >= 0) {
+				if (rmtopen(tape, RMT_O_RDONLY, 0) >= 0) {
 					rmtclose();
 					return;
 				}
@@ -667,7 +667,7 @@ restore_check_point:
 			msg("Dumping volume %d on %s\n", tapeno, tape);
 		}
 #ifdef RDUMP
-		while ((tapefd = (host ? rmtopen(tape, 2, 1) :
+		while ((tapefd = (host ? rmtopen(tape, RMT_O_RDWR, 1) :
 			pipeout ? 1 : open(tape, O_WRONLY|O_CREAT, 0666))) < 0)
 #else
 		while ((tapefd = (pipeout ? 1 :


-- 
David A. Holland
dholland%netbsd.org@localhost


Home | Main Index | Thread Index | Old Index