compress.c revision 68349
1/* 2 * compress routines: 3 * zmagic() - returns 0 if not recognized, uncompresses and prints 4 * information if recognized 5 * uncompress(method, old, n, newch) - uncompress old into new, 6 * using method, return sizeof new 7 */ 8#include "file.h" 9#include <stdio.h> 10#include <stdlib.h> 11#ifdef HAVE_UNISTD_H 12#include <unistd.h> 13#endif 14#include <string.h> 15#ifdef HAVE_SYS_WAIT_H 16#include <sys/wait.h> 17#endif 18#ifndef lint 19FILE_RCSID("@(#)$Id: compress.c,v 1.17 2000/08/05 17:36:47 christos Exp $") 20#endif 21 22 23static struct { 24 const char *magic; 25 int maglen; 26 const char *const argv[3]; 27 int silent; 28} compr[] = { 29 { "\037\235", 2, { "uncompress", "-c", NULL }, 0 }, /* compressed */ 30 { "\037\235", 2, { "gzip", "-cdq", NULL }, 1 }, /* compressed */ 31 { "\037\213", 2, { "gzip", "-cdq", NULL }, 1 }, /* gzipped */ 32 { "\037\236", 2, { "gzip", "-cdq", NULL }, 1 }, /* frozen */ 33 { "\037\240", 2, { "gzip", "-cdq", NULL }, 1 }, /* SCO LZH */ 34 /* the standard pack utilities do not accept standard input */ 35 { "\037\036", 2, { "gzip", "-cdq", NULL }, 0 }, /* packed */ 36 { "BZh", 3, { "bzip2", "-d", NULL }, 1 }, /* bzip2-ed */ 37}; 38 39static int ncompr = sizeof(compr) / sizeof(compr[0]); 40 41 42static int uncompress __P((int, const unsigned char *, unsigned char **, int)); 43 44int 45zmagic(buf, nbytes) 46 unsigned char *buf; 47 int nbytes; 48{ 49 unsigned char *newbuf; 50 int newsize; 51 int i; 52 53 for (i = 0; i < ncompr; i++) { 54 if (nbytes < compr[i].maglen) 55 continue; 56 if (memcmp(buf, compr[i].magic, compr[i].maglen) == 0 && 57 (newsize = uncompress(i, buf, &newbuf, nbytes)) != 0) { 58 tryit(newbuf, newsize, 1); 59 free(newbuf); 60 printf(" ("); 61 tryit(buf, nbytes, 0); 62 printf(")"); 63 return 1; 64 } 65 } 66 67 if (i == ncompr) 68 return 0; 69 70 return 1; 71} 72 73 74static int 75uncompress(method, old, newch, n) 76 int method; 77 const unsigned char *old; 78 unsigned char **newch; 79 int n; 80{ 81 int fdin[2], fdout[2]; 82 83 if (pipe(fdin) == -1 || pipe(fdout) == -1) { 84 error("cannot create pipe (%s).\n", strerror(errno)); 85 /*NOTREACHED*/ 86 } 87 switch (fork()) { 88 case 0: /* child */ 89 (void) close(0); 90 (void) dup(fdin[0]); 91 (void) close(fdin[0]); 92 (void) close(fdin[1]); 93 94 (void) close(1); 95 (void) dup(fdout[1]); 96 (void) close(fdout[0]); 97 (void) close(fdout[1]); 98 if (compr[method].silent) 99 (void) close(2); 100 101 execvp(compr[method].argv[0], 102 (char *const *)compr[method].argv); 103 exit(1); 104 /*NOTREACHED*/ 105 case -1: 106 error("could not fork (%s).\n", strerror(errno)); 107 /*NOTREACHED*/ 108 109 default: /* parent */ 110 (void) close(fdin[0]); 111 (void) close(fdout[1]); 112 if (write(fdin[1], old, n) != n) 113 return 0; 114 (void) close(fdin[1]); 115 if ((*newch = (unsigned char *) malloc(n)) == NULL) 116 return 0; 117 if ((n = read(fdout[0], *newch, n)) <= 0) { 118 free(*newch); 119 return 0; 120 } 121 (void) close(fdout[0]); 122 (void) wait(NULL); 123 return n; 124 } 125} 126