Rizin
unix-like reverse engineering framework and cli tools
untgz.c
Go to the documentation of this file.
1 /*
2  * untgz.c -- Display contents and extract files from a gzip'd TAR file
3  *
4  * written by Pedro A. Aranda Gutierrez <paag@tid.es>
5  * adaptation to Unix by Jean-loup Gailly <jloup@gzip.org>
6  * various fixes by Cosmin Truta <cosmint@cs.ubbcluj.ro>
7  */
8 
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <time.h>
13 #include <errno.h>
14 
15 #include "zlib.h"
16 
17 #ifdef unix
18 # include <unistd.h>
19 #else
20 # include <direct.h>
21 # include <io.h>
22 #endif
23 
24 #ifdef WIN32
25 #include <windows.h>
26 # ifndef F_OK
27 # define F_OK 0
28 # endif
29 # define mkdir(dirname,mode) _mkdir(dirname)
30 # ifdef _MSC_VER
31 # define access(path,mode) _access(path,mode)
32 # define chmod(path,mode) _chmod(path,mode)
33 # define strdup(str) _strdup(str)
34 # endif
35 #else
36 # include <utime.h>
37 #endif
38 
39 
40 /* values used in typeflag field */
41 
42 #define REGTYPE '0' /* regular file */
43 #define AREGTYPE '\0' /* regular file */
44 #define LNKTYPE '1' /* link */
45 #define SYMTYPE '2' /* reserved */
46 #define CHRTYPE '3' /* character special */
47 #define BLKTYPE '4' /* block special */
48 #define DIRTYPE '5' /* directory */
49 #define FIFOTYPE '6' /* FIFO special */
50 #define CONTTYPE '7' /* reserved */
51 
52 /* GNU tar extensions */
53 
54 #define GNUTYPE_DUMPDIR 'D' /* file names from dumped directory */
55 #define GNUTYPE_LONGLINK 'K' /* long link name */
56 #define GNUTYPE_LONGNAME 'L' /* long file name */
57 #define GNUTYPE_MULTIVOL 'M' /* continuation of file from another volume */
58 #define GNUTYPE_NAMES 'N' /* file name that does not fit into main hdr */
59 #define GNUTYPE_SPARSE 'S' /* sparse file */
60 #define GNUTYPE_VOLHDR 'V' /* tape/volume header */
61 
62 
63 /* tar header */
64 
65 #define BLOCKSIZE 512
66 #define SHORTNAMESIZE 100
67 
68 struct tar_header
69 { /* byte offset */
70  char name[100]; /* 0 */
71  char mode[8]; /* 100 */
72  char uid[8]; /* 108 */
73  char gid[8]; /* 116 */
74  char size[12]; /* 124 */
75  char mtime[12]; /* 136 */
76  char chksum[8]; /* 148 */
77  char typeflag; /* 156 */
78  char linkname[100]; /* 157 */
79  char magic[6]; /* 257 */
80  char version[2]; /* 263 */
81  char uname[32]; /* 265 */
82  char gname[32]; /* 297 */
83  char devmajor[8]; /* 329 */
84  char devminor[8]; /* 337 */
85  char prefix[155]; /* 345 */
86  /* 500 */
87 };
88 
90 {
92  struct tar_header header;
93 };
94 
95 struct attr_item
96 {
97  struct attr_item *next;
98  char *fname;
99  int mode;
101 };
102 
104 
105 char *TGZfname OF((const char *));
106 void TGZnotfound OF((const char *));
107 
108 int getoct OF((char *, int));
109 char *strtime OF((time_t *));
110 int setfiletime OF((char *, time_t));
111 void push_attr OF((struct attr_item **, char *, int, time_t));
112 void restore_attr OF((struct attr_item **));
113 
114 int ExprMatch OF((char *, char *));
115 
116 int makedir OF((char *));
117 int matchname OF((int, int, char **, char *));
118 
119 void error OF((const char *));
120 int tar OF((gzFile, int, int, int, char **));
121 
122 void help OF((int));
123 int main OF((int, char **));
124 
125 char *prog;
126 
127 const char *TGZsuffix[] = { "\0", ".tar", ".tar.gz", ".taz", ".tgz", NULL };
128 
129 /* return the file name of the TGZ archive */
130 /* or NULL if it does not exist */
131 
132 char *TGZfname (const char *arcname)
133 {
134  static char buffer[1024];
135  int origlen,i;
136 
137  strcpy(buffer,arcname);
138  origlen = strlen(buffer);
139 
140  for (i=0; TGZsuffix[i]; i++)
141  {
142  strcpy(buffer+origlen,TGZsuffix[i]);
143  if (access(buffer,F_OK) == 0)
144  return buffer;
145  }
146  return NULL;
147 }
148 
149 
150 /* error message for the filename */
151 
152 void TGZnotfound (const char *arcname)
153 {
154  int i;
155 
156  fprintf(stderr,"%s: Couldn't find ",prog);
157  for (i=0;TGZsuffix[i];i++)
158  fprintf(stderr,(TGZsuffix[i+1]) ? "%s%s, " : "or %s%s\n",
159  arcname,
160  TGZsuffix[i]);
161  exit(1);
162 }
163 
164 
165 /* convert octal digits to int */
166 /* on error return -1 */
167 
168 int getoct (char *p,int width)
169 {
170  int result = 0;
171  char c;
172 
173  while (width--)
174  {
175  c = *p++;
176  if (c == 0)
177  break;
178  if (c == ' ')
179  continue;
180  if (c < '0' || c > '7')
181  return -1;
182  result = result * 8 + (c - '0');
183  }
184  return result;
185 }
186 
187 
188 /* convert time_t to string */
189 /* use the "YYYY/MM/DD hh:mm:ss" format */
190 
191 char *strtime (time_t *t)
192 {
193  struct tm *local;
194  static char result[32];
195 
196  local = localtime(t);
197  sprintf(result,"%4d/%02d/%02d %02d:%02d:%02d",
198  local->tm_year+1900, local->tm_mon+1, local->tm_mday,
199  local->tm_hour, local->tm_min, local->tm_sec);
200  return result;
201 }
202 
203 
204 /* set file time */
205 
206 int setfiletime (char *fname,time_t ftime)
207 {
208 #ifdef WIN32
209  static int isWinNT = -1;
210  SYSTEMTIME st;
211  FILETIME locft, modft;
212  struct tm *loctm;
213  HANDLE hFile;
214  int result;
215 
216  loctm = localtime(&ftime);
217  if (loctm == NULL)
218  return -1;
219 
220  st.wYear = (WORD)loctm->tm_year + 1900;
221  st.wMonth = (WORD)loctm->tm_mon + 1;
222  st.wDayOfWeek = (WORD)loctm->tm_wday;
223  st.wDay = (WORD)loctm->tm_mday;
224  st.wHour = (WORD)loctm->tm_hour;
225  st.wMinute = (WORD)loctm->tm_min;
226  st.wSecond = (WORD)loctm->tm_sec;
227  st.wMilliseconds = 0;
228  if (!SystemTimeToFileTime(&st, &locft) ||
229  !LocalFileTimeToFileTime(&locft, &modft))
230  return -1;
231 
232  if (isWinNT < 0)
233  isWinNT = (GetVersion() < 0x80000000) ? 1 : 0;
234  hFile = CreateFile(fname, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
235  (isWinNT ? FILE_FLAG_BACKUP_SEMANTICS : 0),
236  NULL);
237  if (hFile == INVALID_HANDLE_VALUE)
238  return -1;
239  result = SetFileTime(hFile, NULL, NULL, &modft) ? 0 : -1;
240  CloseHandle(hFile);
241  return result;
242 #else
243  struct utimbuf settime;
244 
245  settime.actime = settime.modtime = ftime;
246  return utime(fname,&settime);
247 #endif
248 }
249 
250 
251 /* push file attributes */
252 
253 void push_attr(struct attr_item **list,char *fname,int mode,time_t time)
254 {
255  struct attr_item *item;
256 
257  item = (struct attr_item *)malloc(sizeof(struct attr_item));
258  if (item == NULL)
259  error("Out of memory");
260  item->fname = strdup(fname);
261  item->mode = mode;
262  item->time = time;
263  item->next = *list;
264  *list = item;
265 }
266 
267 
268 /* restore file attributes */
269 
271 {
272  struct attr_item *item, *prev;
273 
274  for (item = *list; item != NULL; )
275  {
276  setfiletime(item->fname,item->time);
277  chmod(item->fname,item->mode);
278  prev = item;
279  item = item->next;
280  free(prev);
281  }
282  *list = NULL;
283 }
284 
285 
286 /* match regular expression */
287 
288 #define ISSPECIAL(c) (((c) == '*') || ((c) == '/'))
289 
290 int ExprMatch (char *string,char *expr)
291 {
292  while (1)
293  {
294  if (ISSPECIAL(*expr))
295  {
296  if (*expr == '/')
297  {
298  if (*string != '\\' && *string != '/')
299  return 0;
300  string ++; expr++;
301  }
302  else if (*expr == '*')
303  {
304  if (*expr ++ == 0)
305  return 1;
306  while (*++string != *expr)
307  if (*string == 0)
308  return 0;
309  }
310  }
311  else
312  {
313  if (*string != *expr)
314  return 0;
315  if (*expr++ == 0)
316  return 1;
317  string++;
318  }
319  }
320 }
321 
322 
323 /* recursive mkdir */
324 /* abort on ENOENT; ignore other errors like "directory already exists" */
325 /* return 1 if OK */
326 /* 0 on error */
327 
328 int makedir (char *newdir)
329 {
330  char *buffer = strdup(newdir);
331  char *p;
332  int len = strlen(buffer);
333 
334  if (len <= 0) {
335  free(buffer);
336  return 0;
337  }
338  if (buffer[len-1] == '/') {
339  buffer[len-1] = '\0';
340  }
341  if (mkdir(buffer, 0755) == 0)
342  {
343  free(buffer);
344  return 1;
345  }
346 
347  p = buffer+1;
348  while (1)
349  {
350  char hold;
351 
352  while(*p && *p != '\\' && *p != '/')
353  p++;
354  hold = *p;
355  *p = 0;
356  if ((mkdir(buffer, 0755) == -1) && (errno == ENOENT))
357  {
358  fprintf(stderr,"%s: Couldn't create directory %s\n",prog,buffer);
359  free(buffer);
360  return 0;
361  }
362  if (hold == 0)
363  break;
364  *p++ = hold;
365  }
366  free(buffer);
367  return 1;
368 }
369 
370 
371 int matchname (int arg,int argc,char **argv,char *fname)
372 {
373  if (arg == argc) /* no arguments given (untgz tgzarchive) */
374  return 1;
375 
376  while (arg < argc)
377  if (ExprMatch(fname,argv[arg++]))
378  return 1;
379 
380  return 0; /* ignore this for the moment being */
381 }
382 
383 
384 /* tar file list or extract */
385 
386 int tar (gzFile in,int action,int arg,int argc,char **argv)
387 {
388  union tar_buffer buffer;
389  int len;
390  int err;
391  int getheader = 1;
392  int remaining = 0;
393  FILE *outfile = NULL;
394  char fname[BLOCKSIZE];
395  int tarmode;
396  time_t tartime;
397  struct attr_item *attributes = NULL;
398 
399  if (action == TGZ_LIST)
400  printf(" date time size file\n"
401  " ---------- -------- --------- -------------------------------------\n");
402  while (1)
403  {
404  len = gzread(in, &buffer, BLOCKSIZE);
405  if (len < 0)
406  error(gzerror(in, &err));
407  /*
408  * Always expect complete blocks to process
409  * the tar information.
410  */
411  if (len != BLOCKSIZE)
412  {
413  action = TGZ_INVALID; /* force error exit */
414  remaining = 0; /* force I/O cleanup */
415  }
416 
417  /*
418  * If we have to get a tar header
419  */
420  if (getheader >= 1)
421  {
422  /*
423  * if we met the end of the tar
424  * or the end-of-tar block,
425  * we are done
426  */
427  if (len == 0 || buffer.header.name[0] == 0)
428  break;
429 
430  tarmode = getoct(buffer.header.mode,8);
431  tartime = (time_t)getoct(buffer.header.mtime,12);
432  if (tarmode == -1 || tartime == (time_t)-1)
433  {
434  buffer.header.name[0] = 0;
436  }
437 
438  if (getheader == 1)
439  {
440  strncpy(fname,buffer.header.name,SHORTNAMESIZE);
441  if (fname[SHORTNAMESIZE-1] != 0)
442  fname[SHORTNAMESIZE] = 0;
443  }
444  else
445  {
446  /*
447  * The file name is longer than SHORTNAMESIZE
448  */
449  if (strncmp(fname,buffer.header.name,SHORTNAMESIZE-1) != 0)
450  error("bad long name");
451  getheader = 1;
452  }
453 
454  /*
455  * Act according to the type flag
456  */
457  switch (buffer.header.typeflag)
458  {
459  case DIRTYPE:
460  if (action == TGZ_LIST)
461  printf(" %s <dir> %s\n",strtime(&tartime),fname);
462  if (action == TGZ_EXTRACT)
463  {
464  makedir(fname);
465  push_attr(&attributes,fname,tarmode,tartime);
466  }
467  break;
468  case REGTYPE:
469  case AREGTYPE:
470  remaining = getoct(buffer.header.size,12);
471  if (remaining == -1)
472  {
474  break;
475  }
476  if (action == TGZ_LIST)
477  printf(" %s %9d %s\n",strtime(&tartime),remaining,fname);
478  else if (action == TGZ_EXTRACT)
479  {
480  if (matchname(arg,argc,argv,fname))
481  {
482  outfile = fopen(fname,"wb");
483  if (outfile == NULL) {
484  /* try creating directory */
485  char *p = strrchr(fname, '/');
486  if (p != NULL) {
487  *p = '\0';
488  makedir(fname);
489  *p = '/';
490  outfile = fopen(fname,"wb");
491  }
492  }
493  if (outfile != NULL)
494  printf("Extracting %s\n",fname);
495  else
496  fprintf(stderr, "%s: Couldn't create %s",prog,fname);
497  }
498  else
499  outfile = NULL;
500  }
501  getheader = 0;
502  break;
503  case GNUTYPE_LONGLINK:
504  case GNUTYPE_LONGNAME:
505  remaining = getoct(buffer.header.size,12);
506  if (remaining < 0 || remaining >= BLOCKSIZE)
507  {
509  break;
510  }
511  len = gzread(in, fname, BLOCKSIZE);
512  if (len < 0)
513  error(gzerror(in, &err));
514  if (fname[BLOCKSIZE-1] != 0 || (int)strlen(fname) > remaining)
515  {
517  break;
518  }
519  getheader = 2;
520  break;
521  default:
522  if (action == TGZ_LIST)
523  printf(" %s <---> %s\n",strtime(&tartime),fname);
524  break;
525  }
526  }
527  else
528  {
529  unsigned int bytes = (remaining > BLOCKSIZE) ? BLOCKSIZE : remaining;
530 
531  if (outfile != NULL)
532  {
533  if (fwrite(&buffer,sizeof(char),bytes,outfile) != bytes)
534  {
535  fprintf(stderr,
536  "%s: Error writing %s -- skipping\n",prog,fname);
537  fclose(outfile);
538  outfile = NULL;
539  remove(fname);
540  }
541  }
542  remaining -= bytes;
543  }
544 
545  if (remaining == 0)
546  {
547  getheader = 1;
548  if (outfile != NULL)
549  {
550  fclose(outfile);
551  outfile = NULL;
552  if (action != TGZ_INVALID)
553  push_attr(&attributes,fname,tarmode,tartime);
554  }
555  }
556 
557  /*
558  * Abandon if errors are found
559  */
560  if (action == TGZ_INVALID)
561  {
562  error("broken archive");
563  break;
564  }
565  }
566 
567  /*
568  * Restore file modes and time stamps
569  */
570  restore_attr(&attributes);
571 
572  if (gzclose(in) != Z_OK)
573  error("failed gzclose");
574 
575  return 0;
576 }
577 
578 
579 /* ============================================================ */
580 
581 void help(int exitval)
582 {
583  printf("untgz version 0.2.1\n"
584  " using zlib version %s\n\n",
585  zlibVersion());
586  printf("Usage: untgz file.tgz extract all files\n"
587  " untgz file.tgz fname ... extract selected files\n"
588  " untgz -l file.tgz list archive contents\n"
589  " untgz -h display this help\n");
590  exit(exitval);
591 }
592 
593 void error(const char *msg)
594 {
595  fprintf(stderr, "%s: %s\n", prog, msg);
596  exit(1);
597 }
598 
599 
600 /* ============================================================ */
601 
602 #if defined(WIN32) && defined(__GNUC__)
603 int _CRT_glob = 0; /* disable argument globbing in MinGW */
604 #endif
605 
606 int main(int argc,char **argv)
607 {
608  int action = TGZ_EXTRACT;
609  int arg = 1;
610  char *TGZfile;
611  gzFile *f;
612 
613  prog = strrchr(argv[0],'\\');
614  if (prog == NULL)
615  {
616  prog = strrchr(argv[0],'/');
617  if (prog == NULL)
618  {
619  prog = strrchr(argv[0],':');
620  if (prog == NULL)
621  prog = argv[0];
622  else
623  prog++;
624  }
625  else
626  prog++;
627  }
628  else
629  prog++;
630 
631  if (argc == 1)
632  help(0);
633 
634  if (strcmp(argv[arg],"-l") == 0)
635  {
636  action = TGZ_LIST;
637  if (argc == ++arg)
638  help(0);
639  }
640  else if (strcmp(argv[arg],"-h") == 0)
641  {
642  help(0);
643  }
644 
645  if ((TGZfile = TGZfname(argv[arg])) == NULL)
646  TGZnotfound(argv[arg]);
647 
648  ++arg;
649  if ((action == TGZ_LIST) && (arg != argc))
650  help(1);
651 
652 /*
653  * Process the TGZ file
654  */
655  switch(action)
656  {
657  case TGZ_LIST:
658  case TGZ_EXTRACT:
659  f = gzopen(TGZfile,"rb");
660  if (f == NULL)
661  {
662  fprintf(stderr,"%s: Couldn't gzopen %s\n",prog,TGZfile);
663  return 1;
664  }
665  exit(tar(f, action, arg, argc, argv));
666  break;
667 
668  default:
669  error("Unknown option");
670  exit(1);
671  }
672 
673  return 0;
674 }
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
static const char * arg(RzAnalysis *a, csh *handle, cs_insn *insn, char *buf, int n)
Definition: arm_esil32.c:136
static bool err
Definition: armass.c:435
static ut8 bytes[32]
Definition: asm_arc.c:23
#define local
Definition: blast.c:36
const lzma_allocator const uint8_t * in
Definition: block.h:527
struct buffer buffer
static RzNumCalcValue expr(RzNum *, RzNumCalc *, int)
Definition: calc.c:167
#define NULL
Definition: cris-opc.c:27
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
static static fork const void static count static fd const char const char static newpath const char static path chmod
Definition: sflib.h:35
FILE * outfile
Definition: fuzz_diff.c:16
int ZEXPORT gzclose(gzFile file)
Definition: gzclose.c:11
gzFile ZEXPORT gzopen(char *path, const char *mode) const
Definition: gzlib.c:272
const char *ZEXPORT gzerror(gzFile file, int *errnum)
Definition: gzlib.c:534
int ZEXPORT gzread(gzFile file, voidp buf, unsigned len)
Definition: gzread.c:375
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
const char int mode
Definition: ioapi.h:137
#define INVALID_HANDLE_VALUE
Definition: iowin32.c:21
sprintf
Definition: kernel.h:365
void * p
Definition: libc.cpp:67
static void list(RzEgg *egg)
Definition: rz-gg.c:52
void * malloc(size_t size)
Definition: malloc.c:123
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig mkdir
Definition: sflib.h:66
static static fork const void static count static fd const char const char static newpath char char char static envp time
Definition: sflib.h:42
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds utime
Definition: sflib.h:57
static static fork const void static count static fd const char const char static newpath char char argv
Definition: sflib.h:40
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
static static fork const void static count static fd const char static mode const char static pathname const char static path const char static dev const char static group static getpid static getuid void void static data static pause access
Definition: sflib.h:64
string FILE
Definition: benchmark.py:21
static struct sockaddr static addrlen static backlog const void msg
Definition: sfsocketcall.h:119
#define ENOENT
Definition: sftypes.h:112
int time_t
Definition: sftypes.h:66
#define f(i)
Definition: sha256.c:46
#define c(i)
Definition: sha256.c:43
char * fname
Definition: untgz.c:98
time_t time
Definition: untgz.c:100
int mode
Definition: untgz.c:99
struct attr_item * next
Definition: untgz.c:97
Definition: buffer.h:15
zip_uint64_t size
Definition: z80asm.h:102
char chksum[8]
Definition: untgz.c:76
char devmajor[8]
Definition: untgz.c:83
char linkname[100]
Definition: untgz.c:78
char uname[32]
Definition: untgz.c:81
char uid[8]
Definition: untgz.c:72
char devminor[8]
Definition: untgz.c:84
char gname[32]
Definition: untgz.c:82
char prefix[155]
Definition: untgz.c:85
char typeflag
Definition: untgz.c:77
char gid[8]
Definition: untgz.c:73
char mtime[12]
Definition: untgz.c:75
char magic[6]
Definition: untgz.c:79
int width
Definition: main.c:10
struct tar_header header
Definition: untgz.c:92
void TGZnotfound(const char *arcname)
Definition: untgz.c:152
#define DIRTYPE
Definition: untgz.c:48
int setfiletime(char *fname, time_t ftime)
Definition: untgz.c:206
int main(int argc, char **argv)
Definition: untgz.c:606
int getoct(char *p, int width)
Definition: untgz.c:168
void error(const char *msg)
Definition: untgz.c:593
int tar(gzFile in, int action, int arg, int argc, char **argv)
Definition: untgz.c:386
@ TGZ_LIST
Definition: untgz.c:103
@ TGZ_INVALID
Definition: untgz.c:103
@ TGZ_EXTRACT
Definition: untgz.c:103
#define SHORTNAMESIZE
Definition: untgz.c:66
#define ISSPECIAL(c)
Definition: untgz.c:288
#define GNUTYPE_LONGLINK
Definition: untgz.c:55
int makedir(char *newdir)
Definition: untgz.c:328
char *TGZfname OF((const char *))
#define REGTYPE
Definition: untgz.c:42
void restore_attr(struct attr_item **list)
Definition: untgz.c:270
#define GNUTYPE_LONGNAME
Definition: untgz.c:56
void help(int exitval)
Definition: untgz.c:581
int matchname(int arg, int argc, char **argv, char *fname)
Definition: untgz.c:371
char * TGZfname(const char *arcname)
Definition: untgz.c:132
char * prog
Definition: untgz.c:125
int ExprMatch(char *string, char *expr)
Definition: untgz.c:290
void push_attr(struct attr_item **list, char *fname, int mode, time_t time)
Definition: untgz.c:253
#define AREGTYPE
Definition: untgz.c:43
const char * TGZsuffix[]
Definition: untgz.c:127
#define BLOCKSIZE
Definition: untgz.c:65
char * strtime(time_t *t)
Definition: untgz.c:191
#define F_OK
Definition: win.h:655
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4
DWORD * HANDLE
#define Z_OK
Definition: zlib.h:177
const char *ZEXPORT zlibVersion()
Definition: zutil.c:27