home *** CD-ROM | disk | FTP | other *** search
- /*
- * compress routines:
- * is_compress() returns 0 if uncompressed, number of bits if compressed.
- * uncompress(old, n, newch) - uncompress old into new, return sizeof new
- * $Id: compress.c,v 1.6 92/09/08 15:32:17 ian Exp $
- */
- #include <stdio.h>
- #include <stdlib.h>
- #ifndef MSC
- #include <unistd.h>
- #endif
- #include <string.h>
- #ifdef OS2
- #include <fcntl.h>
- #include <io.h>
- #include <process.h>
- #else
- #include <sys/wait.h>
- #endif
-
- #include "file.h"
-
- /* Check for compression, return nbits. Algorithm, in magic(4) format:
- * 0 string \037\235 compressed data
- * >2 byte&0x80 >0 block compressed
- * >2 byte&0x1f x %d bits
- */
- int
- is_compress(p, b)
- const unsigned char *p;
- int *b;
- {
-
- if (*p != '\037' || *(/*signed*/ char*)(p+1) != '\235')
- return 0; /* not compress()ed */
-
- *b = *(p+2) & 0x80;
- return *(p+2) & 0x1f;
- }
-
-
- int
- uncompress(old, newch, n)
- const unsigned char *old;
- unsigned char **newch;
- int n;
- {
- #ifdef NO_PIPE /* Use tempnam() */
-
- FILE *fp;
- char *tempname, filename[_MAX_PATH];
- int p;
-
- if ((tempname = tempnam("./", "tmp")) == NULL) {
- error("cannot create temporary file (%s).\n", strerror(errno));
- /*NOTREACHED*/
- }
- /* uncompress needs ".Z"; new filename must not exist */
- sprintf(filename, "%s.Z", tempname);
- if (access(filename, 0) == 0 || (fp = fopen(filename, "wb")) == NULL)
- error("cannot open tmp file %s (%s).\n", filename, strerror(errno));
-
- if (fwrite(old, 1, n, fp) != n) {
- error("write failed (%s).\n", strerror(errno));
- /*NOTREACHED*/
- }
- (void) fclose(fp);
-
- /* It appears that DOS wants "compress -d", not argv[0]=uncompress */
- if (p = spawnlp(P_WAIT, "compress", "compress", "-d", filename, NULL)) {
- unlink(filename);
- if (p == -1)
- error("could not execute `uncompress' (%s).\n", strerror(errno));
- else
- error("uncompress has failed on `%s'.\n", filename);
- }
- if ((*newch = (unsigned char *) malloc(n)) == NULL) {
- error("out of memory.\n");
- /*NOTREACHED*/
- }
- if ((fp = fopen(tempname, "rb")) == NULL) {
- error("cannot open tmp file %s (%s).\n", tempname, strerror(errno));
- /*NOTREACHED*/
- }
- if ((n = fread(*newch, 1, n, fp)) == 0) {
- free(*newch);
- error("read failed (%s).\n", strerror(errno));
- /*NOTREACHED*/
- }
- fclose(fp);
- unlink(tempname);
- free(tempname);
- return n;
-
- #else
-
- #ifdef USE_FORK
-
- int fdin[2], fdout[2];
-
- if (pipe(fdin) == -1 || pipe(fdout) == -1) {
- error("cannot create pipe (%s).\n", strerror(errno));
- /*NOTREACHED*/
- }
- switch (fork()) {
- case 0: /* child */
- (void) close(0);
- (void) dup(fdin[0]);
- (void) close(fdin[0]);
- (void) close(fdin[1]);
-
- (void) close(1);
- (void) dup(fdout[1]);
- (void) close(fdout[0]);
- (void) close(fdout[1]);
-
- execlp("uncompress", "uncompress", "-c", NULL);
- error("could not execute `uncompress' (%s).\n",
- strerror(errno));
- /*NOTREACHED*/
- case -1:
- error("could not fork (%s).\n", strerror(errno));
- /*NOTREACHED*/
-
- default: /* parent */
- (void) close(fdin[0]);
- (void) close(fdout[1]);
- if (write(fdin[1], old, n) != n) {
- error("write failed (%s).\n", strerror(errno));
- /*NOTREACHED*/
- }
- (void) close(fdin[1]);
- if ((*newch = (unsigned char *) malloc(n)) == NULL) {
- error("out of memory.\n");
- /*NOTREACHED*/
- }
- if ((n = read(fdout[0], *newch, n)) <= 0) {
- free(*newch);
- error("read failed (%s).\n", strerror(errno));
- /*NOTREACHED*/
- }
- (void) close(fdout[0]);
- (void) wait(NULL);
- return n;
- }
-
- #else
-
- int fdin[2], fdout[2];
- int handle[3], i, p;
-
- #ifdef MSC
- #define pipe(handles) _pipe(handles, 1024, O_BINARY)
- #endif
-
- if (pipe(fdin) == -1 || pipe(fdout) == -1) {
- error("cannot create pipe (%s).\n", strerror(errno));
- /*NOTREACHED*/
- }
- #ifdef OS2
- setmode(fdin[1], O_BINARY);
- setmode(fdout[0], O_BINARY);
- #endif
-
- if (write(fdin[1], old, n) != n) {
- error("write failed (%s).\n", strerror(errno));
- /*NOTREACHED*/
- }
- (void) close(fdin[1]);
-
- for (i = 0; i <= 2; i++)
- handle[i] = dup(i);
- dup2(fdin[0], 0);
- dup2(fdout[1], 1);
- dup2(fdout[1], 2);
- close(fdin[0]); close(fdout[1]);
-
- p = spawnlp(P_NOWAIT, "compress", "uncompress", "-c", NULL);
- for (i = 0; i <= 2; i++) {
- dup2(handle[i], i); close(handle[i]);
- }
- if (p == -1)
- error("could not execute `uncompress' (%s).\n", strerror(errno));
-
- if ((*newch = (unsigned char *) malloc(n)) == NULL) {
- error("out of memory.\n");
- /*NOTREACHED*/
- }
- if ((n = read(fdout[0], *newch, n)) <= 0) {
- free(*newch);
- error("read failed (%s).\n", strerror(errno));
- /*NOTREACHED*/
- }
- #ifdef MSC /* Clear the pipe. There must be a better way... */
- {
- char buf[256];
- while (read(fdout[0], buf, 256) > 0 )
- ;
- }
- #endif
- (void) close(fdout[0]);
- (void) wait(NULL);
- return n;
- #endif
- #endif
- }
-