home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 6 File
/
06-File.zip
/
FILE39.ZIP
/
compress.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-08
|
5KB
|
207 lines
/*
* 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
}