home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!rs
- From: rs@uunet.UU.NET (Rich Salz)
- Newsgroups: comp.sources.unix
- Subject: v11i009: Buffered copy to/from physical devices
- Message-ID: <899@uunet.UU.NET>
- Date: 13 Aug 87 22:51:33 GMT
- Organization: UUNET Communications Services, Arlington, VA
- Lines: 330
- Approved: rs@uunet.UU.NET
-
- Submitted-by: <steinmetz!crdos1!davidsen>
- Posting-number: Volume 11, Issue 9
- Archive-name: bundle
-
- These programs allow a physical device to be the head or end of a pipe,
- allowing software which does not know about volumes to operate on
- multi-volume sets, and improving the performance of programs such as
- tar and cpio. It works on systems with 16 bit ints such as PC/IX, Xenix,
- and Microport.
-
- bill davidsen (davidsen@ge-crd.ARPA)
- ihnp4!seismo!rochester!steinmetz! \
- chinet! ->--- crdos1!davidsen
-
- [ Another spliced-in Makefile. --r$ ]
- #!/bin/sh
- # shar+ created from directory /usr2/davidsen
- echo 'x - bundle.1 (text)'
- sed << 'E!O!F' 's/^X//' > bundle.1
- X'\" Copyright 1986,87 by Bill Davidsen. This code may be used for
- X'\" personal or commercial purposes. It may be freely distributed
- X'\" in source form providing this notice is kept intact.
- X.TH bundle 1 Local
- X'\" Heading: name(sect) center (paren) name(sect)
- X.SH NAME
- Xbundle \- buffer and copy \fIstdin\fR to a physicaql device
- Xunbundle \- buffer and copy a physical device to \fIstdout\fR
- X.SH SYNOPSIS
- X\fBbundle\fR special dev_size buf_size
- X.br
- X\fBunbundle\fR special buf_size
- X.SH DESCRIPTION
- XThese programs allow a physical device to be the head or end of a pipe,
- Xallows software which does not know about volumes to operate on
- Xmulti-volume sets, and improves the performance of programs such as
- X\fItar\fR and \fIcpio\fR.
- X.P
- X\fBSpecial\fR is the name of a raw device, such as /dev/rmt0.
- X\fBdev_size\fR is the size of the device, given in bytes or kilobytes.
- XWhen \fBdev_size\fR bytes have been written to the output device, the
- Xoperator will be prompted for a media change. \fBBuf_size\fR is the size
- Xof the buffer for the write or read. For tape this should be the desired
- Xtape block size. For disk this should be a multiple of the size of a
- Xtrack. For disk output writing a track at a time rather than sectors
- Xcan reduce real time by a factor of three.
- X.SH EXAMPLES
- X ls *.c | cpio -o | bundle /dev/rfp021 395k 5k
- X unbundle /dev/rfp021 5k | cpio -idm
- X tar cf - /usr/local | bundle /dev/rmt0 4000k 8k
- X unbundle /dev/rmt0 8k | tar cf -
- X.SH WARNINGS
- X\fIunbundle\fR reads to EOF on the input device. There is no way to read
- Xonly part of a volume. If the \fBdev_size\fR is not a multiple of the
- X\fBbuf_size\fR, bizarre errors may occur.
- X.SH FILES
- X/dev/\fBspecial\fR
- X.SH SEE ALSO
- Xtar, cpio.
- X.SH AUTHOR
- XBill Davidsen (ihnp4!chinet!crdos1!davidsen)
- X'\" For more details, see man(7), as well as man(1), manroff(1), and mmt(1)
- E!O!F
- newsize=`wc -c < bundle.1`
- if [ $newsize -ne 1832 ]
- then echo "File bundle.1 was $newsize bytes, 1832 expected"
- fi
- echo 'x - bundle.c (text)'
- sed << 'E!O!F' 's/^X//' > bundle.c
- X/*****************************************************************
- X | Program name: bundle.c
- X |----------------------------------------------------------------
- X | accept standard input and write to a device named on the command
- X | line. The total bytes on the device and the buffer size are
- X | given on the command line. When the device is full, prompt
- X | for a new medium in the device and continue.
- X |
- X | Command form:
- X | bundle device Dsize Bsize
- X |----------------------------------------------------------------
- X | Author: Bill Davidsen, 8/16/86
- X | Version 1.6
- X | Last modified: 3/6/87
- X |----------------------------------------------------------------
- X | Copyright 1986,87 by Bill Davidsen. This code may be used for
- X | personal or commercial purposes. It may be freely distributed
- X | in source form providing this notice is kept intact.
- X *****************************************************************/
- X
- X#include <stdio.h>
- X
- X#ifdef DEBUG
- X#define debug(f,v) fprintf(stderr, f, v)
- X#else
- X#define debug(f,v)
- X#endif
- X
- Xstatic char *SCCS = "@(#) bundle 1.6";
- X
- Xmain (argc, argv)
- X int argc;
- X char *argv[];
- X{
- X char *buffer, /* i/o buffer */
- X *malloc ();
- X register long left; /* room left in the buffer */
- X long bufsize, devsize; /* buffer and device size */
- X long devleft = 0; /* room left on device */
- X int istat, /* stdin read status */
- X ostat, /* device write status */
- X dev, /* device name from open */
- X MediaNum = 1; /* sequential media # */
- X FILE *tty, *fopen ();
- X long getsize (); /* get size from argument */
- X
- X /* validate arguments */
- X if (argc != 4)
- X { /* invalid */
- X printf ("Format:\n bundle device DevSize BufSize\n");
- X printf ("Where size may be bytes (as 5120) or k (as 5k)\n");
- X exit (1);
- X }
- X
- X devsize = getsize (argv[2]);
- X debug ("Device size %ld", devsize);
- X bufsize = getsize (argv[3]);
- X debug (", buffer size %ld\n", bufsize);
- X if (devsize < 1 || devsize < bufsize)
- X { /* invalid specification of size */
- X printf ("Invalid buffer and/or device size\n");
- X exit (1);
- X }
- X
- X /* open the terminal for prompt */
- X tty = fopen ("/dev/tty", "r");
- X if (tty == NULL)
- X { /* mystery failure */
- X printf ("Unable to open /dev/tty for prompt\n");
- X exit (1);
- X }
- X
- X /* open the buffer */
- X buffer = malloc (bufsize);
- X debug ("Buffer allocated\n", 0);
- X if (buffer == NULL)
- X { /* can't mallocate */
- X printf ("Can't allocate space for the buffer\n");
- X exit (1);
- X }
- X
- X /* see if you can open the device */
- X printf ("Mount media #1 on %s and press RETURN", argv[1]);
- X while (getc (tty) != '\n');
- X dev = open (argv[1], 1);
- X if (dev < 0)
- X { /* invalid name */
- X printf ("Can't access device %s\n", argv[1]);
- X exit (1);
- X }
- X devleft = devsize; /* set media ready */
- X debug ("Enter copy loop\n\n", 0);
- X
- X /* main copy loop */
- X while (istat = fread (buffer, 1, (int) bufsize, stdin))
- X { /* until EOF */
- X debug ("Input read size %d\n", istat);
- X
- X if (devleft < istat)
- X { /* change media */
- X close (dev);
- X printf ("\007Mount media #%d on %s and press RETURN: ",
- X ++MediaNum, argv[1]);
- X while (getc (tty) != '\n');
- X dev = open (argv[1], 1);
- X devleft = devsize;
- X }
- X
- X /* write the buffer */
- X ostat = write (dev, buffer, bufsize);
- X debug ("Output write size %d\n", ostat);
- X
- X if (bufsize != ostat)
- X { /* error on write */
- X printf ("Error on device write!\n");
- X exit (1);
- X }
- X devleft -= ostat;
- X }
- X}
- X
- X/*
- X | Procedure: getsize
- X |-
- X | Convert the size string to bytes. If the last character is
- X | 'k', multiply by 1024
- X */
- X
- Xlong
- Xgetsize (string)
- X char *string;
- X{
- X register long len = strlen (string),
- X val = atol (string);
- X
- X if (string[len - 1] == 'k')
- X val *= 1024;
- X
- X return val;
- X}
- E!O!F
- newsize=`wc -c < bundle.c`
- if [ $newsize -ne 3803 ]
- then echo "File bundle.c was $newsize bytes, 3803 expected"
- fi
- echo 'x - unbundle.c (text)'
- sed << 'E!O!F' 's/^X//' > unbundle.c
- X/*****************************************************************
- X | Program: unbundle
- X | accept input from a device and write to stdout
- X |----------------------------------------------------------------
- X | Arguments:
- X | 1) device name
- X | 2) block size in bytes or k
- X | Version: 1.6
- X | Last modified: 3/6/87
- X |----------------------------------------------------------------
- X | Copyright 1986,87 by Bill Davidsen. This code may be used for
- X | personal or commercial purposes. It may be freely distributed
- X | in source form providing this notice is kept intact.
- X ****************************************************************/
- X
- X#include <stdio.h>
- X
- X#ifdef DEBUG
- X#define debug(f,v) fprintf(stderr, f, v)
- X#else
- X#define debug(f,v)
- X#endif
- Xmain (argc, argv)
- X int argc;
- X char *argv[];
- X{
- X char *buf, *malloc ();
- X int bufsize, dn, mnum = 1, ch, readsize;
- X static char *SCCSid = "@(#)unbundle 1.6";
- X long getsize (); /* size of buffer */
- X
- X if (argc != 3)
- X { /* bad calling sequence */
- X fprintf (stderr, "%s: wrong # of arguments\n", argv[0]);
- X fprintf (stderr, "Calling seq:\n %s device bufsize\n",
- X argv[0]);
- X exit (1);
- X }
- X
- X /* try to open the device */
- X dn = open (argv[1], 0);
- X if (dn < 0)
- X { /* open failed */
- X fprintf (stderr, "%s: can't open device %s\n", argv[0], argv[1]);
- X exit (1);
- X }
- X close (dn); /* so I can reopen */
- X
- X /* allocate the buffer */
- X bufsize = getsize (argv[2]);
- X debug ("Bufsize: %d\n", bufsize);
- X
- X buf = malloc (bufsize);
- X if (buf == NULL)
- X { /* can't allocate the buffer */
- X fprintf (stderr, "Can't allocate %d byte buffer\n", bufsize);
- X exit (1);
- X }
- X
- X for (;;)
- X { /* get a fresh mount and read it */
- X fprintf (stderr, "Mount input medium #%d on %s and press return: ",
- X mnum++, argv[1]);
- X read (0, &ch, 1);
- X open (argv[1], 0);
- X
- X while (readsize = read (dn, buf, bufsize))
- X write (1, buf, readsize);
- X close (dn);
- X }
- X}
- X
- X/*
- X | Procedure: getsize
- X |-
- X | Convert the size string to bytes. If the last character is
- X | 'k', multiply by 1024
- X */
- X
- Xlong
- Xgetsize (string)
- X char *string;
- X{
- X register long len = strlen (string),
- X val = atol (string);
- X
- X if (string[len - 1] == 'k')
- X val *= 1024;
- X
- X return val;
- X}
- X
- E!O!F
- newsize=`wc -c < unbundle.c`
- if [ $newsize -ne 2271 ]
- then echo "File unbundle.c was $newsize bytes, 2271 expected"
- fi
-
- echo x - Makefile
- sed -e 's/^X// >Makefile <\SHAR_EOF
- #all: bundle unbundle
- #bundle: bundle.c
- # $(CC) -o bundle $(CFLAGS) bundle.c
- #unbundle: unbundle.c
- # $(CC) -o unbundle $(CFLAGS) unbundle.c
- #install: all bundle.c
- # @echo Copy programs and manpage to appropriate directories
- SHAR_EOF
- echo No error check, lazy moderator...
-
- --
-
- Rich $alz
- Cronus Project, BBN Labs rsalz@bbn.com
- Moderator, comp.sources.unix sources@uunet.uu.net
-