From: lm@slovax.Eng.Sun.COM (Larry McVoy)
Newsgroups: comp.os.linux
Subject: compress each file in tar - a partial fix
Date: 12 Sep 1992 05:41:27 GMT
Organization: Sun Microsystems, Mountain View
Distribution: world
Reply-To: lm@sun.com (Larry McVoy)
NNTP-Posting-Host: slovax


Recently, there was some discussion about compressing each file on
input and (optionally) decompressing each file on output.  I haven't
solved that problem but here is a tool that might.  The general idea is
that you can take an fd, call compress(fd, COMPRESS) or compress(fd,
UNCOMPRESS) and the fd turns into a compressed stream or an
uncompressed stream.  That should be sufficient to do the tar hacks
(which I might go do one of these days).

Anyway, can people take a look at this and tell me what they think?
I used named pipse, if Linux doesn't grok those but does grok pipe()
then I'll convert it over.  If people seem to like it, I'll polish it 
a bit, make a man page, and submit to the glibc folks.

--lm

#! /bin/sh
# Contents:  README compress.h compressfd.c zcat.c zcomp.c
# Wrapped by lm@slovax on Fri Sep 11 22:36:24 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(450 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XCompress the stream.  Take a file descriptor and turn the byte stream
Xinto a compressed byte stream, using named pipes.  You lose the ability
Xto seek but most people don't seek.
X
X
XUsage
X	#include	"compress.h"
X	#include	<fcntl.h>
X
X	compress(fd, flag);
X
XExample
X
X	fd = open("xxx.Z", O_WRONLY|O_CREAT, 0664);
X	compress(fd, COMPRESS);
X
X	normal writes of fd here...
X
X
X	fd = open("xxx.Z", O_RDONLY);
X	compress(fd, UNCOMPRESS);
X
X	normal reads of fd here...
END_OF_FILE
if test 450 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'compress.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'compress.h'\"
else
echo shar: Extracting \"'compress.h'\" \(167 characters\)
sed "s/^X//" >'compress.h' <<'END_OF_FILE'
X#ifndef	_COMPRESS_H
X#define	_COMPRESS_H	"@(#)compress.h	1.1"
X
X#define	COMPRESS	1
X#define	UNCOMPRESS	2
X
X/* could add others, such as pack et al */
X
X#endif	_COMPRESS_H
END_OF_FILE
if test 166 -ne `wc -c <'compress.h'`; then
    echo shar: \"'compress.h'\" unpacked with wrong size!
fi
# end of 'compress.h'
fi
if test -f 'compressfd.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'compressfd.c'\"
else
echo shar: Extracting \"'compressfd.c'\" \(1753 characters\)
sed "s/^X//" >'compressfd.c' <<'END_OF_FILE'
X/*
X * @(#)compressfd.c	1.2 (c) 1992 Larry McVoy, may be freely used.
X *
X * Turn a byte stream into a compressed/uncompressed byte stream.
X * You lose the ability to seek.
X *
X * In all cases,
X *	create a named pipe
X *	fork
X *	child:
X *		set up stdin / stdout
X *		exec [un]compress
X *	parent:
X *		unlinks pipe after opening it
X *		dups pipe to fd
X */
X#include "compress.h"
X#include <fcntl.h>
X#include <sys/param.h>
X
Xcompress(fd, flag)
X	int	fd;	/* byte stream to compress */
X	int	flag;	/* COMPRESS, UNCOMPRESS */
X{
X	char	fifo[MAXPATHLEN];
X	char	*av[5];
X	int	fd2;
X	int	mode;
X
X	mode = fcntl(fd, F_GETFL, 0);
X	mode &= O_RDONLY|O_WRONLY;
X	if (mode != O_RDONLY && mode != O_WRONLY) {
X		return (-1);
X	}
X	if (flag != COMPRESS && flag != UNCOMPRESS) {
X		return (-1);
X	}
X	sprintf(fifo, "/usr/tmp/comp%d", getpid());
X	if (mkfifo(fifo, 0644)) {
X		return (-1);
X	}
X	switch (fork()) {
X	    case -1:	/* no more processes, skip it */
X		(void) unlink(fifo);
X		return (-1);
X	    case 0:	/* child */
X		/*
X		 * RDONLY:
X		 *	parent reads from pipe
X		 *	child writes to pipe, reads from fd
X		 * WRONLY:
X		 *	parent writes to pipe
X		 *	child reads from pipe, writes to fd
X		 */
X		if (mode == O_RDONLY) {
X			close(0);
X			dup(fd);	/* puts it at 0 */
X			close(fd);
X			close(1);
X			if ((fd = open(fifo, O_WRONLY)) == -1)
X				exit(1);
X		} else {
X			close(1);
X			dup(fd);	/* puts it at 1 */
X			close(fd);
X			close(0);
X			if ((fd = open(fifo, O_RDONLY)) == -1)
X				exit(1);
X		}
X		if (flag == COMPRESS)
X			execlp("compress", "compress", "-f", 0);
X		else
X			execlp("uncompress", "uncompress", "-f", 0);
X		perror("compress");
X		exit(1);
X		/*NOTREACHED*/
X	    default:	/* parent */
X		fd2 = open(fifo, mode);
X		dup2(fd2, fd);
X		close(fd2);
X		unlink(fifo);
X		return (0);
X	}
X	/*NOTREACHED*/
X}
END_OF_FILE
if test 1753 -ne `wc -c <'compressfd.c'`; then
    echo shar: \"'compressfd.c'\" unpacked with wrong size!
fi
# end of 'compressfd.c'
fi
if test -f 'zcat.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'zcat.c'\"
else
echo shar: Extracting \"'zcat.c'\" \(344 characters\)
sed "s/^X//" >'zcat.c' <<'END_OF_FILE'
X#include "compress.h"
X#include <fcntl.h>
X#include <stdio.h>
X
Xmain(ac, av)
X	char	**av;
X{
X	while (++av, --ac)
X		zcat(av[0]);
X}
X
Xzcat(f)
X	char	*f;
X{
X	char	buf[10000];
X	int	fd, n;
X
X	fd = open(f, O_RDONLY);
X	compress(fd, UNCOMPRESS);
X	while ((n = read(fd, buf, sizeof(buf))) > 0) {
X		write(1, buf, n);
X	}
X	if (n < 0)
X		perror("read");
X	close(fd);
X}
END_OF_FILE
if test 344 -ne `wc -c <'zcat.c'`; then
    echo shar: \"'zcat.c'\" unpacked with wrong size!
fi
# end of 'zcat.c'
fi
if test -f 'zcomp.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'zcomp.c'\"
else
echo shar: Extracting \"'zcomp.c'\" \(359 characters\)
sed "s/^X//" >'zcomp.c' <<'END_OF_FILE'
X
X#include "compress.h"
X#include <fcntl.h>
X#include <stdio.h>
X
Xmain(ac, av)
X	char	**av;
X{
X	while (++av, --ac)
X		zcat(av[0]);
X}
X
Xzcat(f)
X	char	*f;
X{
X	char	buf[10000];
X	int	fd, n;
X
X	fd = open(f, O_WRONLY|O_CREAT, 0644);
X	compress(fd, UNCOMPRESS);
X	while ((n = read(0, buf, sizeof(buf))) > 0) {
X		write(fd, buf, n);
X	}
X	if (n < 0)
X		perror("read");
X	close(fd);
X}
END_OF_FILE
if test 359 -ne `wc -c <'zcomp.c'`; then
    echo shar: \"'zcomp.c'\" unpacked with wrong size!
fi
# end of 'zcomp.c'
fi
echo shar: End of shell archive.
exit 0
---
Larry McVoy			(415) 336-7627			 lm@sun.com
Newsgroups: comp.os.linux