=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/file/Attic/compress.c,v retrieving revision 1.5 retrieving revision 1.5.4.1 diff -u -r1.5 -r1.5.4.1 --- src/usr.bin/file/Attic/compress.c 2002/02/16 21:27:46 1.5 +++ src/usr.bin/file/Attic/compress.c 2003/03/12 02:14:16 1.5.4.1 @@ -1,4 +1,4 @@ -/* $OpenBSD: compress.c,v 1.5 2002/02/16 21:27:46 millert Exp $ */ +/* $OpenBSD: compress.c,v 1.5.4.1 2003/03/12 02:14:16 margarida Exp $ */ /* * compress routines: @@ -7,19 +7,26 @@ * uncompress(method, old, n, newch) - uncompress old into new, * using method, return sizeof new */ -#include -#include +#include "file.h" #include +#ifdef HAVE_UNISTD_H #include +#endif #include +#ifdef HAVE_SYS_WAIT_H +#include +#endif +#include +#include #include +#ifdef HAVE_LIBZ +#include +#endif -#include "file.h" - static struct { - char *magic; + const char *magic; int maglen; - char *argv[3]; + const char *const argv[3]; int silent; } compr[] = { { "\037\235", 2, { "uncompress", "-c", NULL }, 0 }, /* compressed */ @@ -33,6 +40,8 @@ static int ncompr = sizeof(compr) / sizeof(compr[0]); +static int swrite(int, const void *, size_t); +static int sread(int, void *, size_t); static int uncompress(int, const unsigned char *, unsigned char **, int); int @@ -64,8 +73,123 @@ return 1; } +/* + * `safe' write for sockets and pipes. + */ +static int +swrite(int fd, const void *buf, size_t n) +{ + int rv; + size_t rn = n; + do + switch (rv = write(fd, buf, n)) { + case -1: + if (errno == EINTR) + continue; + return -1; + default: + n -= rv; + buf = ((const char *)buf) + rv; + break; + } + while (n > 0); + return rn; +} + +/* + * `safe' read for sockets and pipes. + */ static int +sread(int fd, void *buf, size_t n) +{ + int rv; + size_t rn = n; + + do + switch (rv = read(fd, buf, n)) { + case -1: + if (errno == EINTR) + continue; + return -1; + case 0: + return rn - n; + default: + n -= rv; + buf = ((char *)buf) + rv; + break; + } + while (n > 0); + return rn; +} + +int +pipe2file(int fd, void *startbuf, size_t nbytes) +{ + char buf[4096]; + int r, tfd; + + (void)strcpy(buf, "/tmp/file.XXXXXX"); +#ifndef HAVE_MKSTEMP + { + char *ptr = mktemp(buf); + tfd = open(ptr, O_RDWR|O_TRUNC|O_EXCL|O_CREAT, 0600); + r = errno; + (void)unlink(ptr); + errno = r; + } +#else + tfd = mkstemp(buf); + r = errno; + (void)unlink(buf); + errno = r; +#endif + if (tfd == -1) { + error("Can't create temporary file for pipe copy (%s)\n", + strerror(errno)); + /*NOTREACHED*/ + } + + if (swrite(tfd, startbuf, nbytes) != nbytes) + r = 1; + else { + while ((r = sread(fd, buf, sizeof(buf))) > 0) + if (swrite(tfd, buf, r) != r) + break; + } + + switch (r) { + case -1: + error("Error copying from pipe to temp file (%s)\n", + strerror(errno)); + /*NOTREACHED*/ + case 0: + break; + default: + error("Error while writing to temp file (%s)\n", + strerror(errno)); + /*NOTREACHED*/ + } + + /* + * We duplicate the file descriptor, because fclose on a + * tmpfile will delete the file, but any open descriptors + * can still access the phantom inode. + */ + if ((fd = dup2(tfd, fd)) == -1) { + error("Couldn't dup destcriptor for temp file(%s)\n", + strerror(errno)); + /*NOTREACHED*/ + } + (void)close(tfd); + if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) { + error("Couldn't seek on temp file (%s)\n", strerror(errno)); + /*NOTREACHED*/ + } + return fd; +} + +static int uncompress(method, old, newch, n) int method; const unsigned char *old; @@ -92,7 +216,7 @@ if (compr[method].silent) (void) close(2); - execvp(compr[method].argv[0], compr[method].argv); + execvp(compr[method].argv[0], (char *const *)compr[method].argv); err(1, "could not execute `%s'", compr[method].argv[0]); /*NOTREACHED*/ case -1: