[comp.sources.bugs] copytape fix allowing network operation

mouse@mcgill-vision.UUCP (der Mouse) (11/21/87)

The copytape program posted to comp.sources.unix is a very nice and
extremely useful program.  However, when it was updated recently to fix
some bugs, some other bugs were introduced.  While it may be true that

% copytape /dev/rmt8 /dev/rmt9

or

% copytape /dev/rmt8 tempfile
(switch tapes)
% copytape tempfile /dev/rmt8

will work, it is not true that

% copytape < /dev/rmt8 | rsh othermachine copytape \> /dev/rmt8

works.  This is because an assumption about the nature of data files is
made that is valid for real files but not for network connections or
pipes....  When read(...,n,...) is done on a file, the system
guarantees that if (at least) n bytes remain before end-of-file, the
read will read all n.  With a pipe or a network connection, this is not
the case.  Here is a fix to copytape to make it work across network
connections or pipes:

*** copytape.c.original	Fri Nov 20 22:42:38 1987
--- copytape.c	Fri Nov 20 22:30:01 1987
***************
*** 193,199 ****
--- 193,234 ----
      exit(0);
  }
  
+ /* When reading from a file, read(...,n,...) is guaranteed to return
+    n bytes if they are present.  When reading from a pipe or a network
+    connection, this is not the case.  Hence.... */
+ int Read(fd,buf,n)
+ int fd;
+ char *buf;
+ int n;
+ {
+  int left;
+  char *bp;
+  int did;
+  int nr;
  
+  bp = buf;
+  left = n;
+  did = 0;
+  while (left > 0)
+   { nr = read(fd,bp,left);
+     if (nr < 0)
+      { if (did == 0)
+ 	{ did = -1;
+ 	}
+        break;
+      }
+     else if (nr == 0)
+      { break;
+      }
+     else
+      { did += nr;
+        bp += nr;
+        left -= nr;
+      }
+   }
+  return(did);
+ }
+ 
  /*
   * Input up to 256K from a file or tape. If input file is a tape, then
   * do markcount stuff.  Input record length will be supplied by the
***************
*** 229,249 ****
  	};
      }
      /* Input is really a data file. */
!     l2 = read(fd, header, 5);
      if (l2 != 5 || strncmp(header, "CPTP:", 5) != 0)
  	return FORMAT_ERROR;
  
!     l2 = read(fd, header, 4);
      if (strncmp(header, "BLK ", 4) == 0) {
! 	l2 = read(fd, header, 7);
  	if (l2 != 7)
  	    return FORMAT_ERROR;
  	header[6] = '\0';
  	len = atoi(header);
! 	l2 = read(fd, tapebuf, len);
  	if (l2 != len)
  	    return FORMAT_ERROR;
! 	read(fd, header, 1);	/* skip trailing newline */
      } else if (strncmp(header, "MRK\n", 4) == 0)
  	return TAPE_MARK;
      else if (strncmp(header, "EOT\n", 4) == 0)
--- 264,284 ----
  	};
      }
      /* Input is really a data file. */
!     l2 = Read(fd, header, 5);
      if (l2 != 5 || strncmp(header, "CPTP:", 5) != 0)
  	return FORMAT_ERROR;
  
!     l2 = Read(fd, header, 4);
      if (strncmp(header, "BLK ", 4) == 0) {
! 	l2 = Read(fd, header, 7);
  	if (l2 != 7)
  	    return FORMAT_ERROR;
  	header[6] = '\0';
  	len = atoi(header);
! 	l2 = Read(fd, tapebuf, len);
  	if (l2 != len)
  	    return FORMAT_ERROR;
! 	Read(fd, header, 1);	/* skip trailing newline */
      } else if (strncmp(header, "MRK\n", 4) == 0)
  	return TAPE_MARK;
      else if (strncmp(header, "EOT\n", 4) == 0)

					der Mouse

				(mouse@mcgill-vision.uucp)

mkhaw@teknowledge-vaxc.ARPA (Mike Khaw) (11/24/87)

Has anyone been able to make copytape use the freeware remote magtape
routines from vol.2 issue 21 of the old mod.sources?  I followed the
directions from that package, but they appear not to have made any
difference; i.e., you're supposed to be able to do things like

	copytape /dev/rmt8 remote_host:/dev/rmt8

(instead of having to use a pipe to rsh), but copytape never seems to
get access to the remote tape drive.

Mike Khaw
-- 
internet:  mkhaw@teknowledge-vaxc.arpa
usenet:	   {uunet|sun|ucbvax|decwrl|uw-beaver}!mkhaw%teknowledge-vaxc.arpa
USnail:	   Teknowledge Inc, 1850 Embarcadero Rd, POB 10119, Palo Alto, CA 94303

david@elroy.Jpl.Nasa.Gov (David Robinson) (11/25/87)

In article <19109@teknowledge-vaxc.ARPA>, mkhaw@teknowledge-vaxc.ARPA (Mike Khaw) writes:
> Has anyone been able to make copytape use the freeware remote magtape
> routines from vol.2 issue 21 of the old mod.sources?  I followed the
> directions from that package, but they appear not to have made any
> difference; i.e., you're supposed to be able to do things like
  
> 	copytape /dev/rmt8 remote_host:/dev/rmt8
  
> (instead of having to use a pipe to rsh), but copytape never seems to
> get access to the remote tape drive.
  
> Mike Khaw



I have a version of copytape that runs with the rmtlib library
that was posted quite a while ago.  The version of copytape
is not the latest but I have had no troubles.  If there
is enough interest I will post a copy.







-- 
	David Robinson		elroy!david@csvax.caltech.edu     ARPA
				david@elroy.jpl.nasa.gov
				ames!elroy!david UUCP
Disclaimer: No one listens to me anyway!