19e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/*
29e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * untgz.c -- Display contents and extract files from a gzip'd TAR file
39e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *
49e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * written by Pedro A. Aranda Gutierrez <paag@tid.es>
59e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * adaptation to Unix by Jean-loup Gailly <jloup@gzip.org>
69e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * various fixes by Cosmin Truta <cosmint@cs.ubbcluj.ro>
79e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */
89e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
99e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <stdio.h>
109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <stdlib.h>
119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <string.h>
129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <time.h>
139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <errno.h>
149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include "zlib.h"
169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef unix
189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  include <unistd.h>
199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#else
209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  include <direct.h>
219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  include <io.h>
229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef WIN32
259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <windows.h>
269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  ifndef F_OK
279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#    define F_OK  0
289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  endif
299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  define mkdir(dirname,mode)   _mkdir(dirname)
309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  ifdef _MSC_VER
319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#    define access(path,mode)   _access(path,mode)
329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#    define chmod(path,mode)    _chmod(path,mode)
339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#    define strdup(str)         _strdup(str)
349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  endif
359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#else
369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  include <utime.h>
379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* values used in typeflag field */
419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define REGTYPE  '0'            /* regular file */
439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define AREGTYPE '\0'           /* regular file */
449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define LNKTYPE  '1'            /* link */
459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define SYMTYPE  '2'            /* reserved */
469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define CHRTYPE  '3'            /* character special */
479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define BLKTYPE  '4'            /* block special */
489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define DIRTYPE  '5'            /* directory */
499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define FIFOTYPE '6'            /* FIFO special */
509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define CONTTYPE '7'            /* reserved */
519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* GNU tar extensions */
539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define GNUTYPE_DUMPDIR  'D'    /* file names from dumped directory */
559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define GNUTYPE_LONGLINK 'K'    /* long link name */
569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define GNUTYPE_LONGNAME 'L'    /* long file name */
579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define GNUTYPE_MULTIVOL 'M'    /* continuation of file from another volume */
589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define GNUTYPE_NAMES    'N'    /* file name that does not fit into main hdr */
599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define GNUTYPE_SPARSE   'S'    /* sparse file */
609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define GNUTYPE_VOLHDR   'V'    /* tape/volume header */
619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* tar header */
649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define BLOCKSIZE     512
669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define SHORTNAMESIZE 100
679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectstruct tar_header
699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{                               /* byte offset */
709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  char name[100];               /*   0 */
719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  char mode[8];                 /* 100 */
729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  char uid[8];                  /* 108 */
739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  char gid[8];                  /* 116 */
749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  char size[12];                /* 124 */
759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  char mtime[12];               /* 136 */
769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  char chksum[8];               /* 148 */
779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  char typeflag;                /* 156 */
789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  char linkname[100];           /* 157 */
799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  char magic[6];                /* 257 */
809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  char version[2];              /* 263 */
819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  char uname[32];               /* 265 */
829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  char gname[32];               /* 297 */
839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  char devmajor[8];             /* 329 */
849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  char devminor[8];             /* 337 */
859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  char prefix[155];             /* 345 */
869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                                /* 500 */
879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project};
889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectunion tar_buffer
909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  char               buffer[BLOCKSIZE];
929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  struct tar_header  header;
939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project};
949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectstruct attr_item
969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  struct attr_item  *next;
989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  char              *fname;
999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  int                mode;
1009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  time_t             time;
1019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project};
1029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectenum { TGZ_EXTRACT, TGZ_LIST, TGZ_INVALID };
1049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectchar *TGZfname          OF((const char *));
1069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid TGZnotfound        OF((const char *));
1079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint getoct              OF((char *, int));
1099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectchar *strtime           OF((time_t *));
1109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint setfiletime         OF((char *, time_t));
1119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid push_attr          OF((struct attr_item **, char *, int, time_t));
1129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid restore_attr       OF((struct attr_item **));
1139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint ExprMatch           OF((char *, char *));
1159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint makedir             OF((char *));
1179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint matchname           OF((int, int, char **, char *));
1189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid error              OF((const char *));
1209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint tar                 OF((gzFile, int, int, int, char **));
1219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid help               OF((int));
1239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint main                OF((int, char **));
1249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectchar *prog;
1269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectconst char *TGZsuffix[] = { "\0", ".tar", ".tar.gz", ".taz", ".tgz", NULL };
1289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* return the file name of the TGZ archive */
1309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* or NULL if it does not exist */
1319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectchar *TGZfname (const char *arcname)
1339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
1349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  static char buffer[1024];
1359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  int origlen,i;
1369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  strcpy(buffer,arcname);
1389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  origlen = strlen(buffer);
1399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  for (i=0; TGZsuffix[i]; i++)
1419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
1429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project       strcpy(buffer+origlen,TGZsuffix[i]);
1439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project       if (access(buffer,F_OK) == 0)
1449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project         return buffer;
1459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
1469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  return NULL;
1479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
1489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* error message for the filename */
1519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid TGZnotfound (const char *arcname)
1539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
1549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  int i;
1559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  fprintf(stderr,"%s: Couldn't find ",prog);
1579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  for (i=0;TGZsuffix[i];i++)
1589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    fprintf(stderr,(TGZsuffix[i+1]) ? "%s%s, " : "or %s%s\n",
1599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            arcname,
1609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            TGZsuffix[i]);
1619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  exit(1);
1629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
1639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* convert octal digits to int */
1669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* on error return -1 */
1679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint getoct (char *p,int width)
1699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
1709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  int result = 0;
1719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  char c;
1729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  while (width--)
1749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
1759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      c = *p++;
1769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      if (c == 0)
1779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        break;
1789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      if (c == ' ')
1799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        continue;
1809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      if (c < '0' || c > '7')
1819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        return -1;
1829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      result = result * 8 + (c - '0');
1839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
1849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  return result;
1859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
1869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* convert time_t to string */
1899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* use the "YYYY/MM/DD hh:mm:ss" format */
1909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectchar *strtime (time_t *t)
1929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
1939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  struct tm   *local;
1949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  static char result[32];
1959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  local = localtime(t);
1979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  sprintf(result,"%4d/%02d/%02d %02d:%02d:%02d",
1989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          local->tm_year+1900, local->tm_mon+1, local->tm_mday,
1999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          local->tm_hour, local->tm_min, local->tm_sec);
2009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  return result;
2019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
2029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* set file time */
2059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint setfiletime (char *fname,time_t ftime)
2079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
2089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef WIN32
2099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  static int isWinNT = -1;
2109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  SYSTEMTIME st;
2119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  FILETIME locft, modft;
2129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  struct tm *loctm;
2139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  HANDLE hFile;
2149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  int result;
2159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  loctm = localtime(&ftime);
2179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (loctm == NULL)
2189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return -1;
2199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  st.wYear         = (WORD)loctm->tm_year + 1900;
2219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  st.wMonth        = (WORD)loctm->tm_mon + 1;
2229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  st.wDayOfWeek    = (WORD)loctm->tm_wday;
2239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  st.wDay          = (WORD)loctm->tm_mday;
2249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  st.wHour         = (WORD)loctm->tm_hour;
2259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  st.wMinute       = (WORD)loctm->tm_min;
2269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  st.wSecond       = (WORD)loctm->tm_sec;
2279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  st.wMilliseconds = 0;
2289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (!SystemTimeToFileTime(&st, &locft) ||
2299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      !LocalFileTimeToFileTime(&locft, &modft))
2309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return -1;
2319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (isWinNT < 0)
2339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    isWinNT = (GetVersion() < 0x80000000) ? 1 : 0;
2349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  hFile = CreateFile(fname, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
2359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                     (isWinNT ? FILE_FLAG_BACKUP_SEMANTICS : 0),
2369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                     NULL);
2379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (hFile == INVALID_HANDLE_VALUE)
2389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return -1;
2399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  result = SetFileTime(hFile, NULL, NULL, &modft) ? 0 : -1;
2409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  CloseHandle(hFile);
2419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  return result;
2429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#else
2439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  struct utimbuf settime;
2449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  settime.actime = settime.modtime = ftime;
2469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  return utime(fname,&settime);
2479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
2489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
2499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* push file attributes */
2529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid push_attr(struct attr_item **list,char *fname,int mode,time_t time)
2549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
2559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  struct attr_item *item;
2569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  item = (struct attr_item *)malloc(sizeof(struct attr_item));
2589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (item == NULL)
2599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    error("Out of memory");
2609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  item->fname = strdup(fname);
2619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  item->mode  = mode;
2629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  item->time  = time;
2639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  item->next  = *list;
2649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  *list       = item;
2659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
2669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* restore file attributes */
2699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid restore_attr(struct attr_item **list)
2719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
2729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  struct attr_item *item, *prev;
2739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  for (item = *list; item != NULL; )
2759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
2769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      setfiletime(item->fname,item->time);
2779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      chmod(item->fname,item->mode);
2789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      prev = item;
2799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      item = item->next;
2809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      free(prev);
2819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
2829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  *list = NULL;
2839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
2849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* match regular expression */
2879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define ISSPECIAL(c) (((c) == '*') || ((c) == '/'))
2899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint ExprMatch (char *string,char *expr)
2919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
2929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  while (1)
2939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
2949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      if (ISSPECIAL(*expr))
2959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
2969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          if (*expr == '/')
2979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            {
2989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              if (*string != '\\' && *string != '/')
2999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                return 0;
3009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              string ++; expr++;
3019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            }
3029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          else if (*expr == '*')
3039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            {
3049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              if (*expr ++ == 0)
3059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                return 1;
3069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              while (*++string != *expr)
3079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                if (*string == 0)
3089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                  return 0;
3099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            }
3109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
3119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      else
3129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
3139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          if (*string != *expr)
3149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            return 0;
3159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          if (*expr++ == 0)
3169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            return 1;
3179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          string++;
3189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
3199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
3209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
3219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* recursive mkdir */
3249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* abort on ENOENT; ignore other errors like "directory already exists" */
3259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* return 1 if OK */
3269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/*        0 on error */
3279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint makedir (char *newdir)
3299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
3309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  char *buffer = strdup(newdir);
3319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  char *p;
3329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  int  len = strlen(buffer);
3339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (len <= 0) {
3359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    free(buffer);
3369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return 0;
3379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  }
3389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (buffer[len-1] == '/') {
3399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    buffer[len-1] = '\0';
3409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  }
3419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (mkdir(buffer, 0755) == 0)
3429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
3439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      free(buffer);
3449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      return 1;
3459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
3469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  p = buffer+1;
3489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  while (1)
3499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
3509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      char hold;
3519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      while(*p && *p != '\\' && *p != '/')
3539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        p++;
3549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      hold = *p;
3559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      *p = 0;
3569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      if ((mkdir(buffer, 0755) == -1) && (errno == ENOENT))
3579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
3589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          fprintf(stderr,"%s: Couldn't create directory %s\n",prog,buffer);
3599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          free(buffer);
3609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          return 0;
3619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
3629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      if (hold == 0)
3639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        break;
3649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      *p++ = hold;
3659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
3669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  free(buffer);
3679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  return 1;
3689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
3699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint matchname (int arg,int argc,char **argv,char *fname)
3729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
3739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (arg == argc)      /* no arguments given (untgz tgzarchive) */
3749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return 1;
3759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  while (arg < argc)
3779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (ExprMatch(fname,argv[arg++]))
3789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      return 1;
3799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  return 0; /* ignore this for the moment being */
3819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
3829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* tar file list or extract */
3859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint tar (gzFile in,int action,int arg,int argc,char **argv)
3879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
3889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  union  tar_buffer buffer;
3899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  int    len;
3909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  int    err;
3919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  int    getheader = 1;
3929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  int    remaining = 0;
3939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  FILE   *outfile = NULL;
3949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  char   fname[BLOCKSIZE];
3959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  int    tarmode;
3969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  time_t tartime;
3979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  struct attr_item *attributes = NULL;
3989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (action == TGZ_LIST)
4009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    printf("    date      time     size                       file\n"
4019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project           " ---------- -------- --------- -------------------------------------\n");
4029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  while (1)
4039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
4049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      len = gzread(in, &buffer, BLOCKSIZE);
4059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      if (len < 0)
4069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        error(gzerror(in, &err));
4079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      /*
4089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project       * Always expect complete blocks to process
4099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project       * the tar information.
4109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project       */
4119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      if (len != BLOCKSIZE)
4129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
4139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          action = TGZ_INVALID; /* force error exit */
4149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          remaining = 0;        /* force I/O cleanup */
4159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
4169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      /*
4189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project       * If we have to get a tar header
4199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project       */
4209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      if (getheader >= 1)
4219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
4229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          /*
4239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project           * if we met the end of the tar
4249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project           * or the end-of-tar block,
4259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project           * we are done
4269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project           */
4279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          if (len == 0 || buffer.header.name[0] == 0)
4289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            break;
4299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          tarmode = getoct(buffer.header.mode,8);
4319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          tartime = (time_t)getoct(buffer.header.mtime,12);
4329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          if (tarmode == -1 || tartime == (time_t)-1)
4339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            {
4349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              buffer.header.name[0] = 0;
4359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              action = TGZ_INVALID;
4369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            }
4379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          if (getheader == 1)
4399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            {
4409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              strncpy(fname,buffer.header.name,SHORTNAMESIZE);
4419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              if (fname[SHORTNAMESIZE-1] != 0)
4429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                  fname[SHORTNAMESIZE] = 0;
4439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            }
4449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          else
4459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            {
4469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              /*
4479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project               * The file name is longer than SHORTNAMESIZE
4489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project               */
4499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              if (strncmp(fname,buffer.header.name,SHORTNAMESIZE-1) != 0)
4509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                  error("bad long name");
4519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              getheader = 1;
4529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            }
4539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          /*
4559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project           * Act according to the type flag
4569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project           */
4579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          switch (buffer.header.typeflag)
4589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            {
4599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            case DIRTYPE:
4609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              if (action == TGZ_LIST)
4619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                printf(" %s     <dir> %s\n",strtime(&tartime),fname);
4629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              if (action == TGZ_EXTRACT)
4639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                {
4649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                  makedir(fname);
4659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                  push_attr(&attributes,fname,tarmode,tartime);
4669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                }
4679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              break;
4689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            case REGTYPE:
4699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            case AREGTYPE:
4709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              remaining = getoct(buffer.header.size,12);
4719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              if (remaining == -1)
4729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                {
4739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                  action = TGZ_INVALID;
4749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                  break;
4759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                }
4769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              if (action == TGZ_LIST)
4779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                printf(" %s %9d %s\n",strtime(&tartime),remaining,fname);
4789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              else if (action == TGZ_EXTRACT)
4799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                {
4809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                  if (matchname(arg,argc,argv,fname))
4819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                    {
4829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                      outfile = fopen(fname,"wb");
4839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                      if (outfile == NULL) {
4849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                        /* try creating directory */
4859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                        char *p = strrchr(fname, '/');
4869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                        if (p != NULL) {
4879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                          *p = '\0';
4889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                          makedir(fname);
4899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                          *p = '/';
4909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                          outfile = fopen(fname,"wb");
4919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                        }
4929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                      }
4939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                      if (outfile != NULL)
4949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                        printf("Extracting %s\n",fname);
4959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                      else
4969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                        fprintf(stderr, "%s: Couldn't create %s",prog,fname);
4979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                    }
4989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                  else
4999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                    outfile = NULL;
5009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                }
5019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              getheader = 0;
5029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              break;
5039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            case GNUTYPE_LONGLINK:
5049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            case GNUTYPE_LONGNAME:
5059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              remaining = getoct(buffer.header.size,12);
5069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              if (remaining < 0 || remaining >= BLOCKSIZE)
5079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                {
5089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                  action = TGZ_INVALID;
5099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                  break;
5109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                }
5119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              len = gzread(in, fname, BLOCKSIZE);
5129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              if (len < 0)
5139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                error(gzerror(in, &err));
5149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              if (fname[BLOCKSIZE-1] != 0 || (int)strlen(fname) > remaining)
5159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                {
5169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                  action = TGZ_INVALID;
5179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                  break;
5189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                }
5199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              getheader = 2;
5209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              break;
5219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            default:
5229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              if (action == TGZ_LIST)
5239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                printf(" %s     <---> %s\n",strtime(&tartime),fname);
5249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              break;
5259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            }
5269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
5279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      else
5289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
5299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          unsigned int bytes = (remaining > BLOCKSIZE) ? BLOCKSIZE : remaining;
5309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          if (outfile != NULL)
5329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            {
5339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              if (fwrite(&buffer,sizeof(char),bytes,outfile) != bytes)
5349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                {
5359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                  fprintf(stderr,
5369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                    "%s: Error writing %s -- skipping\n",prog,fname);
5379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                  fclose(outfile);
5389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                  outfile = NULL;
5399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                  remove(fname);
5409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                }
5419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            }
5429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          remaining -= bytes;
5439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
5449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      if (remaining == 0)
5469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
5479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          getheader = 1;
5489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          if (outfile != NULL)
5499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            {
5509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              fclose(outfile);
5519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              outfile = NULL;
5529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              if (action != TGZ_INVALID)
5539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                push_attr(&attributes,fname,tarmode,tartime);
5549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            }
5559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
5569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      /*
5589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project       * Abandon if errors are found
5599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project       */
5609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      if (action == TGZ_INVALID)
5619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
5629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          error("broken archive");
5639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          break;
5649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
5659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
5669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  /*
5689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project   * Restore file modes and time stamps
5699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project   */
5709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  restore_attr(&attributes);
5719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (gzclose(in) != Z_OK)
5739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    error("failed gzclose");
5749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  return 0;
5769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
5779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ============================================================ */
5809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid help(int exitval)
5829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
5839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  printf("untgz version 0.2.1\n"
5849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project         "  using zlib version %s\n\n",
5859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project         zlibVersion());
5869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  printf("Usage: untgz file.tgz            extract all files\n"
5879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project         "       untgz file.tgz fname ...  extract selected files\n"
5889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project         "       untgz -l file.tgz         list archive contents\n"
5899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project         "       untgz -h                  display this help\n");
5909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  exit(exitval);
5919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
5929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid error(const char *msg)
5949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
5959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  fprintf(stderr, "%s: %s\n", prog, msg);
5969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  exit(1);
5979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
5989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
6009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ============================================================ */
6019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
6029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#if defined(WIN32) && defined(__GNUC__)
6039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint _CRT_glob = 0;      /* disable argument globbing in MinGW */
6049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
6059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
6069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint main(int argc,char **argv)
6079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
6089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int         action = TGZ_EXTRACT;
6099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int         arg = 1;
6109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    char        *TGZfile;
6119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    gzFile      *f;
6129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
6139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    prog = strrchr(argv[0],'\\');
6149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (prog == NULL)
6159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      {
6169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        prog = strrchr(argv[0],'/');
6179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (prog == NULL)
6189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          {
6199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            prog = strrchr(argv[0],':');
6209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            if (prog == NULL)
6219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              prog = argv[0];
6229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            else
6239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              prog++;
6249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          }
6259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        else
6269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          prog++;
6279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      }
6289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    else
6299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      prog++;
6309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
6319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (argc == 1)
6329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      help(0);
6339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
6349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (strcmp(argv[arg],"-l") == 0)
6359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      {
6369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        action = TGZ_LIST;
6379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (argc == ++arg)
6389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          help(0);
6399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      }
6409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    else if (strcmp(argv[arg],"-h") == 0)
6419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      {
6429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        help(0);
6439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      }
6449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
6459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if ((TGZfile = TGZfname(argv[arg])) == NULL)
6469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      TGZnotfound(argv[arg]);
6479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
6489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    ++arg;
6499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if ((action == TGZ_LIST) && (arg != argc))
6509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      help(1);
6519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
6529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/*
6539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *  Process the TGZ file
6549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */
6559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    switch(action)
6569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      {
6579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      case TGZ_LIST:
6589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      case TGZ_EXTRACT:
6599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        f = gzopen(TGZfile,"rb");
6609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (f == NULL)
6619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          {
6629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            fprintf(stderr,"%s: Couldn't gzopen %s\n",prog,TGZfile);
6639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            return 1;
6649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          }
6659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        exit(tar(f, action, arg, argc, argv));
6669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      break;
6679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
6689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      default:
6699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        error("Unknown option");
6709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        exit(1);
6719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      }
6729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
6739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return 0;
6749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
675