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

  1. /*
  2.  * compress routines:
  3.  *    is_compress() returns 0 if uncompressed, number of bits if compressed.
  4.  *    uncompress(old, n, newch) - uncompress old into new, return sizeof new
  5.  * $Id: compress.c,v 1.6 92/09/08 15:32:17 ian Exp $
  6.  */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #ifndef MSC
  10. #include <unistd.h>
  11. #endif
  12. #include <string.h>
  13. #ifdef OS2
  14. #include <fcntl.h>
  15. #include <io.h>
  16. #include <process.h>
  17. #else
  18. #include <sys/wait.h>
  19. #endif
  20.  
  21. #include "file.h"
  22.  
  23. /* Check for compression, return nbits. Algorithm, in magic(4) format:
  24.  * 0       string          \037\235        compressed data
  25.  * >2      byte&0x80       >0              block compressed
  26.  * >2      byte&0x1f       x               %d bits
  27.  */
  28. int
  29. is_compress(p, b)
  30. const unsigned char *p;
  31. int *b;
  32. {
  33.  
  34.     if (*p != '\037' || *(/*signed*/ char*)(p+1) != '\235')
  35.         return 0;    /* not compress()ed */
  36.  
  37.     *b = *(p+2) & 0x80;
  38.     return *(p+2) & 0x1f;
  39. }
  40.  
  41.  
  42. int
  43. uncompress(old, newch, n)
  44. const unsigned char *old;
  45. unsigned char **newch;
  46. int n;
  47. {
  48. #ifdef NO_PIPE      /* Use tempnam() */
  49.  
  50.     FILE    *fp;
  51.     char    *tempname, filename[_MAX_PATH];
  52.     int    p;
  53.  
  54.     if ((tempname = tempnam("./", "tmp")) == NULL) {
  55.         error("cannot create temporary file (%s).\n", strerror(errno));    
  56.         /*NOTREACHED*/
  57.     }
  58.     /* uncompress needs ".Z"; new filename must not exist */
  59.     sprintf(filename, "%s.Z", tempname);
  60.     if (access(filename, 0) == 0 || (fp = fopen(filename, "wb")) == NULL)
  61.         error("cannot open tmp file %s (%s).\n", filename, strerror(errno));
  62.  
  63.     if (fwrite(old, 1, n, fp) != n) {
  64.         error("write failed (%s).\n", strerror(errno));
  65.         /*NOTREACHED*/
  66.         }
  67.     (void) fclose(fp);
  68.     
  69.     /* It appears that DOS wants "compress -d", not argv[0]=uncompress */
  70.     if (p = spawnlp(P_WAIT, "compress", "compress", "-d", filename, NULL)) {
  71.         unlink(filename);
  72.         if (p == -1)
  73.             error("could not execute `uncompress' (%s).\n",  strerror(errno));
  74.         else
  75.             error("uncompress has failed on `%s'.\n", filename);
  76.     }
  77.     if ((*newch = (unsigned char *) malloc(n)) == NULL) {
  78.         error("out of memory.\n");
  79.         /*NOTREACHED*/
  80.     }
  81.     if ((fp = fopen(tempname, "rb")) == NULL) {
  82.         error("cannot open tmp file %s (%s).\n", tempname, strerror(errno));
  83.         /*NOTREACHED*/
  84.     }
  85.     if ((n = fread(*newch, 1, n, fp)) == 0) {
  86.         free(*newch);
  87.         error("read failed (%s).\n", strerror(errno));
  88.         /*NOTREACHED*/
  89.     }
  90.     fclose(fp);
  91.     unlink(tempname);
  92.     free(tempname);
  93.     return n;
  94.  
  95. #else
  96.  
  97. #ifdef USE_FORK
  98.  
  99.     int fdin[2], fdout[2];
  100.  
  101.     if (pipe(fdin) == -1 || pipe(fdout) == -1) {
  102.         error("cannot create pipe (%s).\n", strerror(errno));    
  103.         /*NOTREACHED*/
  104.     }
  105.     switch (fork()) {
  106.     case 0:    /* child */
  107.         (void) close(0);
  108.         (void) dup(fdin[0]);
  109.         (void) close(fdin[0]);
  110.         (void) close(fdin[1]);
  111.  
  112.         (void) close(1);
  113.         (void) dup(fdout[1]);
  114.         (void) close(fdout[0]);
  115.         (void) close(fdout[1]);
  116.  
  117.         execlp("uncompress", "uncompress", "-c", NULL);
  118.         error("could not execute `uncompress' (%s).\n", 
  119.               strerror(errno));
  120.         /*NOTREACHED*/
  121.     case -1:
  122.         error("could not fork (%s).\n", strerror(errno));
  123.         /*NOTREACHED*/
  124.  
  125.     default: /* parent */
  126.         (void) close(fdin[0]);
  127.         (void) close(fdout[1]);
  128.         if (write(fdin[1], old, n) != n) {
  129.             error("write failed (%s).\n", strerror(errno));
  130.             /*NOTREACHED*/
  131.         }
  132.         (void) close(fdin[1]);
  133.         if ((*newch = (unsigned char *) malloc(n)) == NULL) {
  134.             error("out of memory.\n");
  135.             /*NOTREACHED*/
  136.         }
  137.         if ((n = read(fdout[0], *newch, n)) <= 0) {
  138.             free(*newch);
  139.             error("read failed (%s).\n", strerror(errno));
  140.             /*NOTREACHED*/
  141.         }
  142.         (void) close(fdout[0]);
  143.         (void) wait(NULL);
  144.         return n;
  145.     }
  146.  
  147. #else
  148.  
  149.     int fdin[2], fdout[2];
  150.     int handle[3], i, p;
  151.  
  152. #ifdef MSC
  153. #define pipe(handles) _pipe(handles, 1024, O_BINARY)
  154. #endif
  155.  
  156.     if (pipe(fdin) == -1 || pipe(fdout) == -1) {
  157.         error("cannot create pipe (%s).\n", strerror(errno));    
  158.         /*NOTREACHED*/
  159.     }
  160. #ifdef OS2
  161.     setmode(fdin[1], O_BINARY);
  162.     setmode(fdout[0], O_BINARY);
  163. #endif
  164.  
  165.     if (write(fdin[1], old, n) != n) {
  166.         error("write failed (%s).\n", strerror(errno));
  167.         /*NOTREACHED*/
  168.         }
  169.     (void) close(fdin[1]);
  170.  
  171.     for (i = 0; i <= 2; i++) 
  172.         handle[i] = dup(i);
  173.     dup2(fdin[0], 0);
  174.     dup2(fdout[1], 1);
  175.     dup2(fdout[1], 2);
  176.     close(fdin[0]); close(fdout[1]);
  177.  
  178.     p = spawnlp(P_NOWAIT, "compress", "uncompress", "-c", NULL);
  179.     for (i = 0; i <= 2; i++) {
  180.         dup2(handle[i], i); close(handle[i]);
  181.     }
  182.     if (p == -1)
  183.         error("could not execute `uncompress' (%s).\n",  strerror(errno));
  184.  
  185.     if ((*newch = (unsigned char *) malloc(n)) == NULL) {
  186.         error("out of memory.\n");
  187.         /*NOTREACHED*/
  188.     }
  189.     if ((n = read(fdout[0], *newch, n)) <= 0) {
  190.         free(*newch);
  191.         error("read failed (%s).\n", strerror(errno));
  192.         /*NOTREACHED*/
  193.     }
  194. #ifdef MSC                /* Clear the pipe. There must be a better way... */
  195.     { 
  196.     char buf[256];
  197.     while (read(fdout[0], buf, 256) > 0 )
  198.         ;
  199.     }
  200. #endif
  201.     (void) close(fdout[0]);
  202.     (void) wait(NULL);
  203.     return n; 
  204. #endif
  205. #endif
  206. }
  207.