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