zlib 1.2.1.2
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* untgz.c -- Display contents and extract files from a gzip'd TAR file
|
||||
*
|
||||
* written by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
|
||||
* written by Pedro A. Aranda Gutierrez <paag@tid.es>
|
||||
* adaptation to Unix by Jean-loup Gailly <jloup@gzip.org>
|
||||
* various fixes by Cosmin Truta <cosmint@cs.ubbcluj.ro>
|
||||
*/
|
||||
@@ -15,10 +15,10 @@
|
||||
#include "zlib.h"
|
||||
|
||||
#ifdef unix
|
||||
# include <unistd.h>
|
||||
# include <unistd.h>
|
||||
#else
|
||||
# include <direct.h>
|
||||
# include <io.h>
|
||||
# include <direct.h>
|
||||
# include <io.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
@@ -28,8 +28,9 @@
|
||||
# endif
|
||||
# define mkdir(dirname,mode) _mkdir(dirname)
|
||||
# ifdef _MSC_VER
|
||||
# define strdup(str) _strdup(str)
|
||||
# define access(path,mode) _access(path,mode)
|
||||
# define chmod(path,mode) _chmod(path,mode)
|
||||
# define strdup(str) _strdup(str)
|
||||
# endif
|
||||
#else
|
||||
# include <utime.h>
|
||||
@@ -48,7 +49,21 @@
|
||||
#define FIFOTYPE '6' /* FIFO special */
|
||||
#define CONTTYPE '7' /* reserved */
|
||||
|
||||
#define BLOCKSIZE 512
|
||||
/* GNU tar extensions */
|
||||
|
||||
#define GNUTYPE_DUMPDIR 'D' /* file names from dumped directory */
|
||||
#define GNUTYPE_LONGLINK 'K' /* long link name */
|
||||
#define GNUTYPE_LONGNAME 'L' /* long file name */
|
||||
#define GNUTYPE_MULTIVOL 'M' /* continuation of file from another volume */
|
||||
#define GNUTYPE_NAMES 'N' /* file name that does not fit into main hdr */
|
||||
#define GNUTYPE_SPARSE 'S' /* sparse file */
|
||||
#define GNUTYPE_VOLHDR 'V' /* tape/volume header */
|
||||
|
||||
|
||||
/* tar header */
|
||||
|
||||
#define BLOCKSIZE 512
|
||||
#define SHORTNAMESIZE 100
|
||||
|
||||
struct tar_header
|
||||
{ /* byte offset */
|
||||
@@ -71,11 +86,20 @@ struct tar_header
|
||||
/* 500 */
|
||||
};
|
||||
|
||||
union tar_buffer {
|
||||
union tar_buffer
|
||||
{
|
||||
char buffer[BLOCKSIZE];
|
||||
struct tar_header header;
|
||||
};
|
||||
|
||||
struct attr_item
|
||||
{
|
||||
struct attr_item *next;
|
||||
char *fname;
|
||||
int mode;
|
||||
time_t time;
|
||||
};
|
||||
|
||||
enum { TGZ_EXTRACT, TGZ_LIST, TGZ_INVALID };
|
||||
|
||||
char *TGZfname OF((const char *));
|
||||
@@ -84,6 +108,9 @@ void TGZnotfound OF((const char *));
|
||||
int getoct OF((char *, int));
|
||||
char *strtime OF((time_t *));
|
||||
int setfiletime OF((char *, time_t));
|
||||
void push_attr OF((struct attr_item **, char *, int, time_t));
|
||||
void restore_attr OF((struct attr_item **));
|
||||
|
||||
int ExprMatch OF((char *, char *));
|
||||
|
||||
int makedir OF((char *));
|
||||
@@ -221,7 +248,42 @@ int setfiletime (char *fname,time_t ftime)
|
||||
}
|
||||
|
||||
|
||||
/* regular expression matching */
|
||||
/* push file attributes */
|
||||
|
||||
void push_attr(struct attr_item **list,char *fname,int mode,time_t time)
|
||||
{
|
||||
struct attr_item *item;
|
||||
|
||||
item = (struct attr_item *)malloc(sizeof(struct attr_item));
|
||||
if (item == NULL)
|
||||
error("Out of memory");
|
||||
item->fname = strdup(fname);
|
||||
item->mode = mode;
|
||||
item->time = time;
|
||||
item->next = *list;
|
||||
*list = item;
|
||||
}
|
||||
|
||||
|
||||
/* restore file attributes */
|
||||
|
||||
void restore_attr(struct attr_item **list)
|
||||
{
|
||||
struct attr_item *item, *prev;
|
||||
|
||||
for (item = *list; item != NULL; )
|
||||
{
|
||||
setfiletime(item->fname,item->time);
|
||||
chmod(item->fname,item->mode);
|
||||
prev = item;
|
||||
item = item->next;
|
||||
free(prev);
|
||||
}
|
||||
*list = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* match regular expression */
|
||||
|
||||
#define ISSPECIAL(c) (((c) == '*') || ((c) == '/'))
|
||||
|
||||
@@ -332,6 +394,7 @@ int tar (gzFile in,int action,int arg,int argc,char **argv)
|
||||
char fname[BLOCKSIZE];
|
||||
int tarmode;
|
||||
time_t tartime;
|
||||
struct attr_item *attributes = NULL;
|
||||
|
||||
if (action == TGZ_LIST)
|
||||
printf(" date time size file\n"
|
||||
@@ -354,14 +417,15 @@ int tar (gzFile in,int action,int arg,int argc,char **argv)
|
||||
/*
|
||||
* If we have to get a tar header
|
||||
*/
|
||||
if (getheader == 1)
|
||||
if (getheader >= 1)
|
||||
{
|
||||
/*
|
||||
* if we met the end of the tar
|
||||
* or the end-of-tar block,
|
||||
* we are done
|
||||
*/
|
||||
if ((len == 0) || (buffer.header.name[0] == 0)) break;
|
||||
if (len == 0 || buffer.header.name[0] == 0)
|
||||
break;
|
||||
|
||||
tarmode = getoct(buffer.header.mode,8);
|
||||
tartime = (time_t)getoct(buffer.header.mtime,12);
|
||||
@@ -371,8 +435,25 @@ int tar (gzFile in,int action,int arg,int argc,char **argv)
|
||||
action = TGZ_INVALID;
|
||||
}
|
||||
|
||||
strcpy(fname,buffer.header.name);
|
||||
if (getheader == 1)
|
||||
{
|
||||
strncpy(fname,buffer.header.name,SHORTNAMESIZE);
|
||||
if (fname[SHORTNAMESIZE-1] != 0)
|
||||
fname[SHORTNAMESIZE] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* The file name is longer than SHORTNAMESIZE
|
||||
*/
|
||||
if (strncmp(fname,buffer.header.name,SHORTNAMESIZE-1) != 0)
|
||||
error("bad long name");
|
||||
getheader = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Act according to the type flag
|
||||
*/
|
||||
switch (buffer.header.typeflag)
|
||||
{
|
||||
case DIRTYPE:
|
||||
@@ -381,7 +462,7 @@ int tar (gzFile in,int action,int arg,int argc,char **argv)
|
||||
if (action == TGZ_EXTRACT)
|
||||
{
|
||||
makedir(fname);
|
||||
setfiletime(fname,tartime);
|
||||
push_attr(&attributes,fname,tarmode,tartime);
|
||||
}
|
||||
break;
|
||||
case REGTYPE:
|
||||
@@ -419,6 +500,24 @@ int tar (gzFile in,int action,int arg,int argc,char **argv)
|
||||
}
|
||||
getheader = 0;
|
||||
break;
|
||||
case GNUTYPE_LONGLINK:
|
||||
case GNUTYPE_LONGNAME:
|
||||
remaining = getoct(buffer.header.size,12);
|
||||
if (remaining < 0 || remaining >= BLOCKSIZE)
|
||||
{
|
||||
action = TGZ_INVALID;
|
||||
break;
|
||||
}
|
||||
len = gzread(in, fname, BLOCKSIZE);
|
||||
if (len < 0)
|
||||
error(gzerror(in, &err));
|
||||
if (fname[BLOCKSIZE-1] != 0 || (int)strlen(fname) > remaining)
|
||||
{
|
||||
action = TGZ_INVALID;
|
||||
break;
|
||||
}
|
||||
getheader = 2;
|
||||
break;
|
||||
default:
|
||||
if (action == TGZ_LIST)
|
||||
printf(" %s <---> %s\n",strtime(&tartime),fname);
|
||||
@@ -433,7 +532,8 @@ int tar (gzFile in,int action,int arg,int argc,char **argv)
|
||||
{
|
||||
if (fwrite(&buffer,sizeof(char),bytes,outfile) != bytes)
|
||||
{
|
||||
fprintf(stderr,"%s: Error writing %s -- skipping\n",prog,fname);
|
||||
fprintf(stderr,
|
||||
"%s: Error writing %s -- skipping\n",prog,fname);
|
||||
fclose(outfile);
|
||||
outfile = NULL;
|
||||
remove(fname);
|
||||
@@ -450,7 +550,7 @@ int tar (gzFile in,int action,int arg,int argc,char **argv)
|
||||
fclose(outfile);
|
||||
outfile = NULL;
|
||||
if (action != TGZ_INVALID)
|
||||
setfiletime(fname,tartime);
|
||||
push_attr(&attributes,fname,tarmode,tartime);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -464,6 +564,11 @@ int tar (gzFile in,int action,int arg,int argc,char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore file modes and time stamps
|
||||
*/
|
||||
restore_attr(&attributes);
|
||||
|
||||
if (gzclose(in) != Z_OK)
|
||||
error("failed gzclose");
|
||||
|
||||
@@ -475,7 +580,7 @@ int tar (gzFile in,int action,int arg,int argc,char **argv)
|
||||
|
||||
void help(int exitval)
|
||||
{
|
||||
printf("untgz version 0.2\n"
|
||||
printf("untgz version 0.2.1\n"
|
||||
" using zlib version %s\n\n",
|
||||
zlibVersion());
|
||||
printf("Usage: untgz file.tgz extract all files\n"
|
||||
|
||||
Reference in New Issue
Block a user