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
| 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.19 2001/03/20 04:22:02 christos Exp $")
| 19FILE_RCSID("@(#)$Id: compress.c,v 1.20 2001/07/22 21:04:15 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, { "gzip", "-cdq", NULL }, 1 }, /* compressed */ 30 /* Uncompress can get stuck; so use gzip first if we have it 31 * Idea from Damien Clark, thanks! */ 32 { "\037\235", 2, { "uncompress", "-c", NULL }, 1 }, /* compressed */ 33 { "\037\213", 2, { "gzip", "-cdq", NULL }, 1 }, /* gzipped */ 34 { "\037\236", 2, { "gzip", "-cdq", NULL }, 1 }, /* frozen */ 35 { "\037\240", 2, { "gzip", "-cdq", NULL }, 1 }, /* SCO LZH */ 36 /* the standard pack utilities do not accept standard input */ 37 { "\037\036", 2, { "gzip", "-cdq", NULL }, 0 }, /* packed */
| 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, { "gzip", "-cdq", NULL }, 1 }, /* compressed */ 30 /* Uncompress can get stuck; so use gzip first if we have it 31 * Idea from Damien Clark, thanks! */ 32 { "\037\235", 2, { "uncompress", "-c", NULL }, 1 }, /* compressed */ 33 { "\037\213", 2, { "gzip", "-cdq", NULL }, 1 }, /* gzipped */ 34 { "\037\236", 2, { "gzip", "-cdq", NULL }, 1 }, /* frozen */ 35 { "\037\240", 2, { "gzip", "-cdq", NULL }, 1 }, /* SCO LZH */ 36 /* the standard pack utilities do not accept standard input */ 37 { "\037\036", 2, { "gzip", "-cdq", NULL }, 0 }, /* packed */
|
38 { "BZh", 3, { "bzip2", "-d", NULL }, 1 }, /* bzip2-ed */
| 38 { "BZh", 3, { "bzip2", "-cd", NULL }, 1 }, /* bzip2-ed */
|
39}; 40 41static int ncompr = sizeof(compr) / sizeof(compr[0]); 42 43 44static int uncompress __P((int, const unsigned char *, unsigned char **, int)); 45static int swrite __P((int, const void *, size_t)); 46static int sread __P((int, void *, size_t)); 47 48int 49zmagic(buf, nbytes) 50 unsigned char *buf; 51 int nbytes; 52{ 53 unsigned char *newbuf; 54 int newsize; 55 int i; 56 57 for (i = 0; i < ncompr; i++) { 58 if (nbytes < compr[i].maglen) 59 continue; 60 if (memcmp(buf, compr[i].magic, compr[i].maglen) == 0 && 61 (newsize = uncompress(i, buf, &newbuf, nbytes)) != 0) { 62 tryit(newbuf, newsize, 1); 63 free(newbuf); 64 printf(" ("); 65 tryit(buf, nbytes, 0); 66 printf(")"); 67 return 1; 68 } 69 } 70 71 if (i == ncompr) 72 return 0; 73 74 return 1; 75} 76 77/* 78 * `safe' write for sockets and pipes. 79 */ 80static int 81swrite(fd, buf, n) 82 int fd; 83 const void *buf; 84 size_t n; 85{ 86 int rv; 87 size_t rn = n; 88 89 do 90 switch (rv = write(fd, buf, n)) { 91 case -1: 92 if (errno == EINTR) 93 continue; 94 return -1; 95 default: 96 n -= rv; 97 buf = ((char *)buf) + rv; 98 break; 99 } 100 while (n > 0); 101 return rn; 102} 103 104 105/* 106 * `safe' read for sockets and pipes. 107 */ 108static int 109sread(fd, buf, n) 110 int fd; 111 void *buf; 112 size_t n; 113{ 114 int rv; 115 size_t rn = n; 116 117 do 118 switch (rv = read(fd, buf, n)) { 119 case -1: 120 if (errno == EINTR) 121 continue; 122 return -1; 123 default: 124 n -= rv; 125 buf = ((char *)buf) + rv; 126 break; 127 } 128 while (n > 0); 129 return rn; 130} 131 132static int 133uncompress(method, old, newch, n) 134 int method; 135 const unsigned char *old; 136 unsigned char **newch; 137 int n; 138{ 139 int fdin[2], fdout[2]; 140 141 if (pipe(fdin) == -1 || pipe(fdout) == -1) { 142 error("cannot create pipe (%s).\n", strerror(errno)); 143 /*NOTREACHED*/ 144 } 145 switch (fork()) { 146 case 0: /* child */ 147 (void) close(0); 148 (void) dup(fdin[0]); 149 (void) close(fdin[0]); 150 (void) close(fdin[1]); 151 152 (void) close(1); 153 (void) dup(fdout[1]); 154 (void) close(fdout[0]); 155 (void) close(fdout[1]); 156 if (compr[method].silent) 157 (void) close(2); 158 159 execvp(compr[method].argv[0], 160 (char *const *)compr[method].argv); 161 exit(1); 162 /*NOTREACHED*/ 163 case -1: 164 error("could not fork (%s).\n", strerror(errno)); 165 /*NOTREACHED*/ 166 167 default: /* parent */ 168 (void) close(fdin[0]); 169 (void) close(fdout[1]); 170 if (swrite(fdin[1], old, n) != n) { 171 n = 0; 172 goto err; 173 } 174 (void) close(fdin[1]); 175 fdin[1] = -1; 176 if ((*newch = (unsigned char *) malloc(n)) == NULL) { 177 n = 0; 178 goto err; 179 } 180 if ((n = sread(fdout[0], *newch, n)) <= 0) { 181 free(*newch); 182 n = 0; 183 goto err; 184 } 185err: 186 if (fdin[1] != -1) 187 (void) close(fdin[1]); 188 (void) close(fdout[0]); 189 (void) wait(NULL); 190 return n; 191 } 192}
| 39}; 40 41static int ncompr = sizeof(compr) / sizeof(compr[0]); 42 43 44static int uncompress __P((int, const unsigned char *, unsigned char **, int)); 45static int swrite __P((int, const void *, size_t)); 46static int sread __P((int, void *, size_t)); 47 48int 49zmagic(buf, nbytes) 50 unsigned char *buf; 51 int nbytes; 52{ 53 unsigned char *newbuf; 54 int newsize; 55 int i; 56 57 for (i = 0; i < ncompr; i++) { 58 if (nbytes < compr[i].maglen) 59 continue; 60 if (memcmp(buf, compr[i].magic, compr[i].maglen) == 0 && 61 (newsize = uncompress(i, buf, &newbuf, nbytes)) != 0) { 62 tryit(newbuf, newsize, 1); 63 free(newbuf); 64 printf(" ("); 65 tryit(buf, nbytes, 0); 66 printf(")"); 67 return 1; 68 } 69 } 70 71 if (i == ncompr) 72 return 0; 73 74 return 1; 75} 76 77/* 78 * `safe' write for sockets and pipes. 79 */ 80static int 81swrite(fd, buf, n) 82 int fd; 83 const void *buf; 84 size_t n; 85{ 86 int rv; 87 size_t rn = n; 88 89 do 90 switch (rv = write(fd, buf, n)) { 91 case -1: 92 if (errno == EINTR) 93 continue; 94 return -1; 95 default: 96 n -= rv; 97 buf = ((char *)buf) + rv; 98 break; 99 } 100 while (n > 0); 101 return rn; 102} 103 104 105/* 106 * `safe' read for sockets and pipes. 107 */ 108static int 109sread(fd, buf, n) 110 int fd; 111 void *buf; 112 size_t n; 113{ 114 int rv; 115 size_t rn = n; 116 117 do 118 switch (rv = read(fd, buf, n)) { 119 case -1: 120 if (errno == EINTR) 121 continue; 122 return -1; 123 default: 124 n -= rv; 125 buf = ((char *)buf) + rv; 126 break; 127 } 128 while (n > 0); 129 return rn; 130} 131 132static int 133uncompress(method, old, newch, n) 134 int method; 135 const unsigned char *old; 136 unsigned char **newch; 137 int n; 138{ 139 int fdin[2], fdout[2]; 140 141 if (pipe(fdin) == -1 || pipe(fdout) == -1) { 142 error("cannot create pipe (%s).\n", strerror(errno)); 143 /*NOTREACHED*/ 144 } 145 switch (fork()) { 146 case 0: /* child */ 147 (void) close(0); 148 (void) dup(fdin[0]); 149 (void) close(fdin[0]); 150 (void) close(fdin[1]); 151 152 (void) close(1); 153 (void) dup(fdout[1]); 154 (void) close(fdout[0]); 155 (void) close(fdout[1]); 156 if (compr[method].silent) 157 (void) close(2); 158 159 execvp(compr[method].argv[0], 160 (char *const *)compr[method].argv); 161 exit(1); 162 /*NOTREACHED*/ 163 case -1: 164 error("could not fork (%s).\n", strerror(errno)); 165 /*NOTREACHED*/ 166 167 default: /* parent */ 168 (void) close(fdin[0]); 169 (void) close(fdout[1]); 170 if (swrite(fdin[1], old, n) != n) { 171 n = 0; 172 goto err; 173 } 174 (void) close(fdin[1]); 175 fdin[1] = -1; 176 if ((*newch = (unsigned char *) malloc(n)) == NULL) { 177 n = 0; 178 goto err; 179 } 180 if ((n = sread(fdout[0], *newch, n)) <= 0) { 181 free(*newch); 182 n = 0; 183 goto err; 184 } 185err: 186 if (fdin[1] != -1) 187 (void) close(fdin[1]); 188 (void) close(fdout[0]); 189 (void) wait(NULL); 190 return n; 191 } 192}
|