JunkBox_Lib  1.10.2
gz_tool.c
Go to the documentation of this file.
1 
10 #ifdef CPLUSPLUS
11  #undef CPLUSPLUS
12 #endif
13 
14 #include "gz_tool.h"
15 #include "jbxl_state.h"
16 
17 
18 #ifndef DISABLE_ZLIB
19 
20 
22 //
23 
33 {
34  Buffer dec = init_Buffer();
35 
36  if (enc.buf==NULL) return dec;
37 
38  z_stream zstrm;
39  zstrm.zalloc = Z_NULL;
40  zstrm.zfree = Z_NULL;
41  zstrm.opaque = Z_NULL;
42  zstrm.next_in = Z_NULL;
43  zstrm.avail_in = 0;
44 
45  int ret = inflateInit2(&zstrm, 47);
46  if (ret!=Z_OK) return dec;
47 
48  //
49  dec = make_Buffer(enc.vldsz*5);
50  Buffer wrk = make_Buffer(BUFSZ);
51 
52  zstrm.next_in = enc.buf;
53  zstrm.avail_in = (size_t)enc.vldsz;
54 
55  do {
56  zstrm.next_out = wrk.buf;
57  zstrm.avail_out = (size_t)wrk.bufsz;
58 
59  ret = inflate(&zstrm, Z_NO_FLUSH);
60  if (ret!=Z_OK && ret!=Z_STREAM_END) {
61  wrk.vldsz = wrk.bufsz - zstrm.avail_out;
62  cat_Buffer(&wrk, &dec);
63  inflateEnd(&zstrm);
64  free_Buffer(&wrk);
65  //
66  DEBUG_MODE PRINT_MESG("ERROR: GZ_DECODE_DATA: inflate error = %d\n", ret);
67  dec.state = JBXL_ERROR;
68  return dec;
69  }
70 
71  wrk.vldsz = wrk.bufsz - zstrm.avail_out;
72  cat_Buffer(&wrk, &dec);
73 
74  if (ret==Z_STREAM_END && zstrm.avail_in!=0) {
75  ret = inflateReset(&zstrm);
76  }
77 
78  } while (ret!=Z_STREAM_END && zstrm.avail_in>0);
79  //
80 
81  inflateEnd(&zstrm);
82  free_Buffer(&wrk);
83 
84  return dec;
85 }
86 
87 
99 void deflate2gzip(Buffer* def)
100 {
101  unsigned char gzip_header[] = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};
102  unsigned char gzip_tailer[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // CRC32 4Byte, ISIZE 4Byte
103 
104  Buffer gzp = init_Buffer();
105 
106  if (def->buf[0]==GZIP_DEFLATE_ID1 && def->buf[1]==GZIP_DEFLATE_ID2) {
107  gzp = make_Buffer(def->vldsz+16);
108  cat_b2Buffer(gzip_header, &gzp, 10);
109  cat_b2Buffer(def->buf+2, &gzp, def->vldsz-2);
110  cat_b2Buffer(gzip_tailer, &gzp, 8);
111  free_Buffer(def);
112  *def = gzp;
113  }
114 
115  return;
116 }
117 
118 
119 
121 // FILE I/O
122 //
123 
133 int gz_decode_fp(FILE* infp, FILE* otfp)
134 {
135  if (infp==NULL || otfp==NULL) return 0;
136 
137  int sz = 0;
138  unsigned char inbuf[LBUF];
139  unsigned char otbuf[BUFSZ];
140 
141  //
142  z_stream zstrm;
143  zstrm.zalloc = Z_NULL;
144  zstrm.zfree = Z_NULL;
145  zstrm.opaque = Z_NULL;
146  zstrm.next_in = Z_NULL;
147  zstrm.avail_in = 0;
148 
149  int ret = inflateInit2(&zstrm, 47);
150  if (ret!=Z_OK) return JBXL_ERROR;
151 
152  do {
153  zstrm.next_in = inbuf;
154  zstrm.avail_in = (int)fread(inbuf, 1, LBUF, infp);
155 
156  do {
157  zstrm.next_out = otbuf;
158  zstrm.avail_out = BUFSZ;
159 
160  ret = inflate(&zstrm, Z_NO_FLUSH);
161  if (ret!=Z_OK && ret!=Z_STREAM_END) {
162  fwrite(otbuf, BUFSZ-zstrm.avail_out, 1, otfp);
163  //
164  inflateEnd(&zstrm);
165  DEBUG_MODE PRINT_MESG("ERROR: GZ_DECODE_FP: inflate error = %d\n", ret);
166  if (sz==0) sz = JBXL_ERROR;
167  return sz;
168  }
169 
170  int otsz = BUFSZ - zstrm.avail_out;
171  fwrite(otbuf, otsz, 1, otfp);
172  sz += otsz;
173 
174  if (ret==Z_STREAM_END && zstrm.avail_in!=0) {
175  ret = inflateReset(&zstrm);
176  }
177 
178  } while (ret!=Z_STREAM_END && zstrm.avail_in>0);
179  //
180  } while(!feof(infp));
181 
182  inflateEnd(&zstrm);
183 
184  return sz;
185 }
186 
187 
188 /*
189 int gz_encode_gzfp(FILE* fp, gzFile* gf)
190 
191 ファイル fpを圧縮して gzipファイル gfへ保存する.fread() で読んで,gzwrite() で書き込む.
192 
193 @param fp 読み込み用の通常ファイルへのポインタ.
194 @param gf 書き込み用のgzipファイルへのポインタ.
195 @return 読み込んだファイルのサイズ.
196 */
197 int gz_encode_gzfp(FILE* fp, gzFile* gf)
198 {
199  size_t cc, sz;
200  unsigned char buf[RECVBUFSZ];
201 
202  if (*gf==NULL) return JBXL_ARGS_ERROR;
203 
204  memset(buf, 0, RECVBUFSZ);
205  sz = cc = fread(buf, RECVBUFSZ, 1, fp);
206  while(cc>0) {
207  gzwrite(*gf, (voidp)buf, (unsigned int)cc);
208  memset(buf, 0, cc);
209  cc = fread(buf, RECVBUFSZ, 1, fp);
210  sz += cc;
211  }
212 
213  return (int)sz;
214 }
215 
216 
226 int gz_decode_gzfp(gzFile* gf, FILE* fp)
227 {
228  int cc, sz;
229  unsigned char buf[RECVBUFSZ];
230 
231  if (*gf==NULL) return JBXL_ARGS_ERROR;
232 
233  memset(buf, 0, RECVBUFSZ);
234  sz = cc = gzread(*gf, (voidp)buf, RECVBUFSZ);
235  while(cc>0) {
236  fwrite(buf, cc, 1, fp);
237  memset(buf, 0, cc);
238  cc = gzread(*gf, (voidp)buf, RECVBUFSZ);
239  sz += cc;
240  }
241 
242  return sz;
243 }
244 
245 
255 int gz_encode_file(const char* fmfn, const char* tofn)
256 {
257  size_t cc, sz;
258  unsigned char buf[RECVBUFSZ];
259  gzFile gf;
260  FILE* fp;
261 
262  fp = fopen(fmfn, "rb");
263  if (fp==NULL) return JBXL_FILE_OPEN_ERROR;
264 
265  gf = gzopen(tofn, "wb");
266  if (gf==NULL) {
267  fclose(fp);
269  }
270 
271  memset(buf, 0, RECVBUFSZ);
272  sz = cc = fread(buf, RECVBUFSZ, 1, fp);
273  while(cc>0) {
274  gzwrite(gf, (voidp)buf, (unsigned int)cc);
275  memset(buf, 0, cc);
276  cc = fread(buf, RECVBUFSZ, 1, fp);
277  sz += cc;
278  }
279 
280  gzclose(gf);
281  fclose(fp);
282 
283  return (int)sz;
284 }
285 
286 
296 int gz_decode_file(const char* fmfn, const char* tofn)
297 {
298  FILE* infp;
299  FILE* otfp;
300 
301  infp = fopen(fmfn, "rb");
302  if (infp==NULL) return JBXL_FILE_OPEN_ERROR;
303 
304  otfp = fopen(tofn, "wb");
305  if (otfp==NULL) {
306  fclose(infp);
308  }
309 
310  int sz = gz_decode_fp(infp, otfp);
311 
312  fclose(infp);
313  fclose(otfp);
314 
315  return sz;
316 
317 /*
318  int cc, sz;
319  unsigned char buf[RECVBUFSZ];
320  gzFile gf;
321  FILE* fp;
322 
323  gf = gzopen(fmfn, "rb");
324  if (gf==NULL) return JBXL_FILE_OPEN_ERROR;
325 
326  fp = fopen(tofn, "wb");
327  if (fp==NULL) {
328  gzclose(gf);
329  return JBXL_FILE_DESTOPEN_ERROR;
330  }
331 
332  memset(buf, 0, RECVBUFSZ);
333  sz = cc = gzread(gf, (voidp)buf, RECVBUFSZ);
334  while(cc>0) {
335  fwrite(buf, cc, 1, fp);
336  memset(buf, 0, cc);
337  cc = gzread(gf, (voidp)buf, RECVBUFSZ);
338  sz += cc;
339  }
340 
341  gzclose(gf);
342  fclose(fp);
343 
344  return sz;
345 */
346 }
347 
348 
358 int gz_decode_file_replace(const char* fn, const char* tempdir)
359 {
360  int cc;
361  char* tempfn;
362 
363  tempfn = temp_filename(tempdir, 16);
364  cc = gz_decode_file(fn, tempfn);
365  if (cc<=0) {
366  unlink(tempfn);
367  free(tempfn);
368  return cc;
369  }
370 
371  unlink(fn);
372  rename(tempfn, fn);
373  freeNull(tempfn);
374 
375  return cc;
376 }
377 
378 
380 {
381  if (enc.vldsz<2) return FALSE;
382 
383  if (enc.buf[0]==0x1f && enc.buf[1]==0x8b) return TRUE;
384  return FALSE;
385 }
386 
387 
388 
389 
391 // tiny Tar
392 
393 void extract_tTar(Buffer tardata, Buffer prefix, mode_t mode)
394 {
395  Tar_Header tar_header;
396 
397  long unsigned int size = 0;
398  long unsigned int datalen = (long unsigned int)(tardata.vldsz - 1024);
399 
400 #ifdef WIN32
401  if (prefix.buf[prefix.vldsz-1]!='\\') cat_s2Buffer("\\", &prefix);
402 #else
403  if (prefix.buf[prefix.vldsz-1]!='/') cat_s2Buffer("/", &prefix);
404 #endif
405  //
406  int long_link = FALSE;
407  Buffer long_link_name = init_Buffer();
408  //
409  while (size < datalen) {
410  memcpy(&tar_header, (char*)&tardata.buf[size], sizeof(Tar_Header));
411  Buffer fname = make_Buffer_bystr(tar_header.name);
412 
413  if (!long_link && (*tar_header.typeflag=='L' || *tar_header.typeflag=='K')) {
414  // GNU Long Link
415  long_link = TRUE;
416  }
417  else if (long_link) {
418  fname = dup_Buffer(long_link_name);
419  free_Buffer(&long_link_name);
420  long_link_name = init_Buffer();
421  long_link = FALSE;
422  }
423  else {
424  fname = make_Buffer_bystr(tar_header.name);
425  }
426 
427  if (*tar_header.typeflag=='x') {
428  PRINT_MESG("xLib/extract_tTar: ERROR: type flag \"x\" (POSIX pax extend header) is not supported\n");
429  }
430  //
432  size += sizeof(Tar_Header);
433  //
434  Buffer path = dup_Buffer(prefix);
435  if (!long_link) {
436  cat_Buffer(&fname, &path);
437  free_Buffer(&fname);
438  }
439  //
440  int ret = mkdirp((char*)path.buf, mode);
441  if (ret<0) PRINT_MESG("xLib/extract_tTar: WARNING: Failed to create directory.\n");
442  long unsigned int len = (long unsigned int)strtol(tar_header.size, NULL, 8);
443  if (long_link) {
444  long_link_name = make_Buffer_bystr(&tardata.buf[size]);
445  }
446  else {
447  write_file((char*)path.buf, &tardata.buf[size], len);
448  }
449  free_Buffer(&path);
450  //
451  if (len%512>0) len = (len/512 + 1)*512;
452  size += len;
453  }
454  free_Buffer(&long_link_name);
455  return;
456 }
457 
458 
459 void extract_tTar_file(const char* fn)
460 {
461  UNUSED(fn);
462 
463  return;
464 }
465 
466 
467 #endif
Buffer make_Buffer(int sz)
Buffer型変数のバッファ部をつくり出す.
Definition: buffer.c:71
int cat_b2Buffer(void *src, Buffer *dst, int len)
任意のバイナリデータsrcを Buffer型変数dstへ lenバイト catする.
Definition: buffer.c:585
void free_Buffer(Buffer *buf)
Buffer型変数のバッファ部を解放する
Definition: buffer.c:128
Buffer init_Buffer()
初期化したBuffer型変数を返す.
Definition: buffer.c:47
Buffer dup_Buffer(Buffer buf)
Buffer型変数のコピーをつくる.
Definition: buffer.c:211
int cat_Buffer(Buffer *src, Buffer *dst)
Buffer変数 srcから dstへバッファを catする.
Definition: buffer.c:384
#define cat_s2Buffer(src, dst)
cat_b2Buffer()
Definition: buffer.h:122
#define make_Buffer_bystr(str)
set_Buffer()
Definition: buffer.h:57
#define RECVBUFSZ
256K
Definition: common.h:134
#define UNUSED(x)
Definition: common.h:264
#define LBUF
Definition: common.h:146
#define TRUE
Definition: common.h:226
#define FALSE
Definition: common.h:223
#define BUFSZ
16K
Definition: common.h:138
int gz_encode_gzfp(FILE *fp, gzFile *gf)
GZIPのファイルポインタを用いた ファイルの圧縮
Definition: gz_tool.c:197
int gz_encode_file(const char *fmfn, const char *tofn)
ファイル名による ファイルの圧縮
Definition: gz_tool.c:255
Buffer gz_decode_data(Buffer enc)
圧縮データ encを解凍する.
Definition: gz_tool.c:32
void deflate2gzip(Buffer *def)
deflateデータを gzipのデータ構造に変換する.
Definition: gz_tool.c:99
void extract_tTar_file(const char *fn)
Definition: gz_tool.c:459
int gz_decode_file(const char *fmfn, const char *tofn)
ファイル名による ファイルの解凍
Definition: gz_tool.c:296
int gz_decode_gzfp(gzFile *gf, FILE *fp)
GZIPのファイルポインタを用いた ファイルの解凍
Definition: gz_tool.c:226
int is_gz_data(Buffer enc)
Definition: gz_tool.c:379
int gz_decode_fp(FILE *infp, FILE *otfp)
ファイルポインタによるファイルの解凍
Definition: gz_tool.c:133
int gz_decode_file_replace(const char *fn, const char *tempdir)
ファイル名による ファイルの解凍.ファイルを置き換える.
Definition: gz_tool.c:358
void extract_tTar(Buffer tardata, Buffer prefix, mode_t mode)
Definition: gz_tool.c:393
gzツールプログラム ヘッダ (-lz)
#define GZIP_DEFLATE_ID2
Definition: gz_tool.h:27
#define GZIP_DEFLATE_ID1
Definition: gz_tool.h:26
JunkBox_Lib 状態ヘッダ
#define JBXL_ERROR
エラー
Definition: jbxl_state.h:34
#define JBXL_ARGS_ERROR
不正な引数(NULLなど)
Definition: jbxl_state.h:42
#define JBXL_FILE_DESTOPEN_ERROR
ディスティネーションファイルのオープン失敗
Definition: jbxl_state.h:50
#define JBXL_FILE_OPEN_ERROR
ファイルオープン エラー
Definition: jbxl_state.h:44
unsigned char ** buf
Definition: jpeg_tool.h:96
unsigned char unsigned long * len
Definition: jpeg_tool.h:96
Definition: buffer.h:35
int bufsz
確保してあるバッファの大きさ - 1.
Definition: buffer.h:36
int vldsz
データの長さ.バイナリデータの場合も使用可能.文字列の場合は 0x00 を含まない.
Definition: buffer.h:37
int state
変数の状態を表す.正常は JBXL_NORMAL
Definition: buffer.h:38
unsigned char * buf
バッファの先頭へのポインタ.str[bufsz]は必ず 0x00となる.
Definition: buffer.h:39
long unsigned int write_file(const char *fname, unsigned char *buf, long unsigned int size)
ファイルにデータを書き込む
Definition: tools.c:2497
int mkdirp(const char *path, mode_t mode)
mkdir -p path 相当.
Definition: tools.c:2511
char * temp_filename(const char *dir, int flen)
/dev/urandom を利用して作業用ファイルのランダムなファイル名を得る.
Definition: tools.c:2397
#define freeNull(p)
Definition: tools.h:201
#define PRINT_MESG
環境依存用の出力関数.print_message()
Definition: tools.h:475
#define DEBUG_MODE
Definition: tools.h:502
void canonical_filename_Buffer(Buffer *fname, int no_dir)
fname の問題になりそうな ASCII文字を '_' に変換する.
Definition: xtools.c:2057