=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/file/Attic/compress.c,v retrieving revision 1.5 retrieving revision 1.6 diff -c -r1.5 -r1.6 *** src/usr.bin/file/Attic/compress.c 2002/02/16 21:27:46 1.5 --- src/usr.bin/file/Attic/compress.c 2003/03/03 22:24:08 1.6 *************** *** 1,4 **** ! /* $OpenBSD: compress.c,v 1.5 2002/02/16 21:27:46 millert Exp $ */ /* * compress routines: --- 1,4 ---- ! /* $OpenBSD: compress.c,v 1.6 2003/03/03 22:24:08 ian Exp $ */ /* * compress routines: *************** *** 7,25 **** * uncompress(method, old, n, newch) - uncompress old into new, * using method, return sizeof new */ ! #include ! #include #include #include #include #include - #include "file.h" - static struct { ! char *magic; int maglen; ! char *argv[3]; int silent; } compr[] = { { "\037\235", 2, { "uncompress", "-c", NULL }, 0 }, /* compressed */ --- 7,32 ---- * uncompress(method, old, n, newch) - uncompress old into new, * using method, return sizeof new */ ! #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 static struct { ! const char *magic; int maglen; ! const char *const argv[3]; int silent; } compr[] = { { "\037\235", 2, { "uncompress", "-c", NULL }, 0 }, /* compressed */ *************** *** 33,38 **** --- 40,47 ---- 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,71 **** --- 73,195 ---- 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,98 **** if (compr[method].silent) (void) close(2); ! execvp(compr[method].argv[0], compr[method].argv); err(1, "could not execute `%s'", compr[method].argv[0]); /*NOTREACHED*/ case -1: --- 216,222 ---- if (compr[method].silent) (void) close(2); ! execvp(compr[method].argv[0], (char *const *)compr[method].argv); err(1, "could not execute `%s'", compr[method].argv[0]); /*NOTREACHED*/ case -1: