OLD | NEW |
1 /*- | 1 /*- |
2 * Copyright 2003-2005 Colin Percival | 2 * Copyright 2003-2005 Colin Percival |
3 * All rights reserved | 3 * All rights reserved |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted providing that the following conditions | 6 * modification, are permitted providing that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 int i; | 62 int i; |
63 for (i = 0; i < SHA_DIGEST_LENGTH; ++i) | 63 for (i = 0; i < SHA_DIGEST_LENGTH; ++i) |
64 sprintf(&sha1str[i * 2], "%02x", sha1[i]); | 64 sprintf(&sha1str[i * 2], "%02x", sha1[i]); |
65 } | 65 } |
66 | 66 |
67 /* xzfile is a provisional stdio-like interface to xz/lzma2-compressed data. | 67 /* xzfile is a provisional stdio-like interface to xz/lzma2-compressed data. |
68 * liblzma does not currently include this functionality. The interface is | 68 * liblzma does not currently include this functionality. The interface is |
69 * read-only and only supports sequential access. */ | 69 * read-only and only supports sequential access. */ |
70 | 70 |
71 typedef struct { | 71 typedef struct { |
| 72 /* in and out are the underlying buffers to be used with lzma_stream. */ |
| 73 u_char in[BUFSIZ]; |
| 74 u_char out[BUFSIZ]; |
| 75 |
72 lzma_stream ls; | 76 lzma_stream ls; |
73 FILE *f; | 77 FILE *f; |
74 | 78 |
75 /* in and out are the underlying buffers to be used with lzma_stream. */ | |
76 u_char *in; | |
77 u_char *out; | |
78 | |
79 /* read_out points to the first byte in out not yet consumed by an | 79 /* read_out points to the first byte in out not yet consumed by an |
80 * xzread call. read_out_len tracks the amount of data available in | 80 * xzread call. read_out_len tracks the amount of data available in |
81 * out beginning at read_out. */ | 81 * out beginning at read_out. */ |
82 u_char *read_out; | 82 u_char *read_out; |
83 size_t read_out_len; | 83 size_t read_out_len; |
84 | 84 |
85 /* Error and end-of-file indicators. */ | 85 /* Error and end-of-file indicators. */ |
86 lzma_ret err; | 86 lzma_ret err; |
87 int eof; | 87 int eof; |
88 } xzfile; | 88 } xzfile; |
89 | 89 |
90 /* Initializes and returns a new xzfile pointer that will read from f. On | 90 /* Initializes and returns a new xzfile pointer that will read from f. On |
91 * failure, returns NULL. If err is non-NULL, it will be set to indicate any | 91 * failure, returns NULL. If err is non-NULL, it will be set to indicate any |
92 * error that may have occurred. */ | 92 * error that may have occurred. */ |
93 static xzfile *xzdopen(FILE *f, lzma_ret *err) | 93 static xzfile *xzdopen(FILE *f, lzma_ret *err) |
94 { | 94 { |
95 xzfile *xzf; | 95 xzfile *xzf; |
96 lzma_stream ls = LZMA_STREAM_INIT; | 96 lzma_stream ls = LZMA_STREAM_INIT; |
97 uint64_t physmem, memlimit; | 97 uint64_t physmem, memlimit; |
98 | 98 |
99 if (!(xzf = malloc(sizeof(xzfile)))) { | 99 if (!(xzf = malloc(sizeof(xzfile)))) { |
100 if (err) *err = LZMA_MEM_ERROR; | 100 if (err) *err = LZMA_MEM_ERROR; |
101 return NULL; | 101 return NULL; |
102 } | 102 } |
103 | 103 |
104 xzf->ls = ls; | 104 xzf->ls = ls; |
105 xzf->f = f; | 105 xzf->f = f; |
106 | 106 |
107 xzf->in = NULL; | |
108 xzf->out = NULL; | |
109 if (!(xzf->in = malloc(BUFSIZ)) || !(xzf->out = malloc(BUFSIZ))) { | |
110 if (err) *err = LZMA_MEM_ERROR; | |
111 free(xzf->out); | |
112 free(xzf->in); | |
113 free(xzf); | |
114 return NULL; | |
115 } | |
116 | |
117 xzf->read_out = xzf->out; | 107 xzf->read_out = xzf->out; |
118 xzf->read_out_len = 0; | 108 xzf->read_out_len = 0; |
119 | 109 |
120 xzf->err = LZMA_OK; | 110 xzf->err = LZMA_OK; |
121 xzf->eof = 0; | 111 xzf->eof = 0; |
122 | 112 |
123 /* Use the same memory limits used by xzdec and xz. Use 40% of | 113 /* Use the same memory limits used by xzdec and xz. Use 40% of |
124 * physical memory if 80MB or more, otherwise use 80% of physical | 114 * physical memory if 80MB or more, otherwise use 80% of physical |
125 * memory if 80MB or less, otherwise use 80MB. If physical memory | 115 * memory if 80MB or less, otherwise use 80MB. If physical memory |
126 * can't be determined, use 128MB. These limits should be sufficient | 116 * can't be determined, use 128MB. These limits should be sufficient |
127 * for any decompression on any general-purpose system. */ | 117 * for any decompression on any general-purpose system. */ |
128 physmem = lzma_physmem(); | 118 physmem = lzma_physmem(); |
129 if (physmem == 0) | 119 if (physmem == 0) |
130 physmem = 128 * 1024 * 1024; | 120 physmem = 128 * 1024 * 1024; |
131 memlimit = 40 * physmem / 100; | 121 memlimit = 40 * physmem / 100; |
132 if (memlimit < 80 * 1024 * 1024) { | 122 if (memlimit < 80 * 1024 * 1024) { |
133 memlimit = 80 * physmem / 100; | 123 memlimit = 80 * physmem / 100; |
134 if (memlimit > 80 * 1024 * 1024) | 124 if (memlimit > 80 * 1024 * 1024) |
135 memlimit = 80 * 1024 * 1024; | 125 memlimit = 80 * 1024 * 1024; |
136 } | 126 } |
137 | 127 |
138 xzf->err = lzma_stream_decoder(&xzf->ls, memlimit, | 128 xzf->err = lzma_stream_decoder(&xzf->ls, memlimit, |
139 LZMA_TELL_NO_CHECK | | 129 LZMA_TELL_NO_CHECK | |
140 LZMA_TELL_UNSUPPORTED_CHECK); | 130 LZMA_TELL_UNSUPPORTED_CHECK); |
141 if (xzf->err != LZMA_OK) { | 131 if (xzf->err != LZMA_OK) { |
142 if (err) *err = xzf->err; | 132 if (err) *err = xzf->err; |
143 free(xzf->out); | |
144 free(xzf->in); | |
145 free(xzf); | 133 free(xzf); |
146 return NULL; | 134 return NULL; |
147 } | 135 } |
148 | 136 |
149 if (err) *err = xzf->err; | 137 if (err) *err = xzf->err; |
150 return xzf; | 138 return xzf; |
151 } | 139 } |
152 | 140 |
153 /* Closes an xzfile opened by xzopen, freeing all memory and closing all | 141 /* Closes an xzfile opened by xzopen, freeing all memory and closing all |
154 * files. Returns LZMA_OK normally, or LZMA_STREAM_END if fclose fails. */ | 142 * files. Returns LZMA_OK normally, or LZMA_STREAM_END if fclose fails. */ |
155 static lzma_ret xzclose(xzfile *xzf) | 143 static lzma_ret xzclose(xzfile *xzf) |
156 { | 144 { |
157 lzma_ret lzma_err = LZMA_OK; | 145 lzma_ret lzma_err = LZMA_OK; |
158 | 146 |
159 lzma_end(&xzf->ls); | 147 lzma_end(&xzf->ls); |
160 if (fclose(xzf->f) != 0) | 148 if (fclose(xzf->f) != 0) |
161 lzma_err = LZMA_STREAM_END; | 149 lzma_err = LZMA_STREAM_END; |
162 free(xzf->out); | |
163 free(xzf->in); | |
164 free(xzf); | 150 free(xzf); |
165 | 151 |
166 return lzma_err; | 152 return lzma_err; |
167 } | 153 } |
168 | 154 |
169 /* Reads len uncompressed bytes from xzf into buf. Returns the number of bytes | 155 /* Reads len uncompressed bytes from xzf into buf. Returns the number of bytes |
170 * read, which may be less than len at the end of the file. Upon error, if | 156 * read, which may be less than len at the end of the file. Upon error, if |
171 * err is non-NULL, it will be set to an appropriate value, which will either | 157 * err is non-NULL, it will be set to an appropriate value, which will either |
172 * be a return value from lzma_code (with the exception of LZMA_STREAM_END, | 158 * be a return value from lzma_code (with the exception of LZMA_STREAM_END, |
173 * which is remapped to LZMA_OK), or LZMA_STREAM_END to indicate an I/O error. | 159 * which is remapped to LZMA_OK), or LZMA_STREAM_END to indicate an I/O error. |
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 /* Write the new file */ | 512 /* Write the new file */ |
527 if(((fd=open(argv[2],O_CREAT|O_TRUNC|O_WRONLY,0644))<0) || | 513 if(((fd=open(argv[2],O_CREAT|O_TRUNC|O_WRONLY,0644))<0) || |
528 (write(fd,new,newsize)!=newsize) || (close(fd)==-1)) | 514 (write(fd,new,newsize)!=newsize) || (close(fd)==-1)) |
529 err(1,"open/write/close(%s)",argv[2]); | 515 err(1,"open/write/close(%s)",argv[2]); |
530 | 516 |
531 free(new); | 517 free(new); |
532 free(old); | 518 free(old); |
533 | 519 |
534 return 0; | 520 return 0; |
535 } | 521 } |
OLD | NEW |