/*
* untgz.c -- Display contents and extract files from a gzip'd TAR file
*
* 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>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include "zlib.h"
#ifdef unix
# include <unistd.h>
#else
# include <direct.h>
# include <io.h>
#endif
#ifdef WIN32
#include <windows.h>
# ifndef F_OK
# define F_OK 0
# endif
# ifdef _MSC_VER
# endif
#else
# include <utime.h>
#endif
/* values used in typeflag field */
/* GNU tar extensions */
/* tar header */
struct tar_header
{ /* byte offset */
/* 500 */
};
union tar_buffer
{
};
struct attr_item
{
char *fname;
int mode;
};
void TGZnotfound OF((const char *));
char *prog;
/* return the file name of the TGZ archive */
/* or NULL if it does not exist */
{
int origlen,i;
for (i=0; TGZsuffix[i]; i++)
{
return buffer;
}
return NULL;
}
/* error message for the filename */
{
int i;
for (i=0;TGZsuffix[i];i++)
TGZsuffix[i]);
exit(1);
}
/* convert octal digits to int */
/* on error return -1 */
{
int result = 0;
char c;
while (width--)
{
c = *p++;
if (c == 0)
break;
if (c == ' ')
continue;
if (c < '0' || c > '7')
return -1;
}
return result;
}
/* convert time_t to string */
{
return result;
}
/* set file time */
{
#ifdef WIN32
int result;
return -1;
st.wMilliseconds = 0;
return -1;
if (isWinNT < 0)
(isWinNT ? FILE_FLAG_BACKUP_SEMANTICS : 0),
NULL);
if (hFile == INVALID_HANDLE_VALUE)
return -1;
return result;
#else
#endif
}
/* push file attributes */
{
error("Out of memory");
}
/* restore file attributes */
{
{
}
}
/* match regular expression */
{
while (1)
{
{
if (*expr == '/')
{
return 0;
}
else if (*expr == '*')
{
if (*expr ++ == 0)
return 1;
if (*string == 0)
return 0;
}
}
else
{
return 0;
if (*expr++ == 0)
return 1;
string++;
}
}
}
/* recursive mkdir */
/* abort on ENOENT; ignore other errors like "directory already exists" */
/* return 1 if OK */
/* 0 on error */
{
char *p;
if (len <= 0) {
return 0;
}
}
{
return 1;
}
p = buffer+1;
while (1)
{
char hold;
while(*p && *p != '\\' && *p != '/')
p++;
hold = *p;
*p = 0;
{
return 0;
}
if (hold == 0)
break;
*p++ = hold;
}
return 1;
}
{
return 1;
return 1;
return 0; /* ignore this for the moment being */
}
/* tar file list or extract */
{
int len;
int err;
int remaining = 0;
int tarmode;
printf(" date time size file\n"
" ---------- -------- --------- -------------------------------------\n");
while (1)
{
if (len < 0)
/*
* Always expect complete blocks to process
* the tar information.
*/
{
remaining = 0; /* force I/O cleanup */
}
/*
* If we have to get a tar header
*/
if (getheader >= 1)
{
/*
* if we met the end of the tar
* or the end-of-tar block,
* we are done
*/
break;
{
}
if (getheader == 1)
{
fname[SHORTNAMESIZE] = 0;
}
else
{
/*
* The file name is longer than SHORTNAMESIZE
*/
error("bad long name");
getheader = 1;
}
/*
* Act according to the type flag
*/
{
case DIRTYPE:
if (action == TGZ_EXTRACT)
{
}
break;
case REGTYPE:
case AREGTYPE:
if (remaining == -1)
{
break;
}
else if (action == TGZ_EXTRACT)
{
{
/* try creating directory */
if (p != NULL) {
*p = '\0';
*p = '/';
}
}
else
}
else
}
getheader = 0;
break;
case GNUTYPE_LONGLINK:
case GNUTYPE_LONGNAME:
{
break;
}
if (len < 0)
{
break;
}
getheader = 2;
break;
default:
break;
}
}
else
{
{
{
}
}
}
if (remaining == 0)
{
getheader = 1;
{
if (action != TGZ_INVALID)
}
}
/*
* Abandon if errors are found
*/
if (action == TGZ_INVALID)
{
error("broken archive");
break;
}
}
/*
* Restore file modes and time stamps
*/
error("failed gzclose");
return 0;
}
/* ============================================================ */
{
printf("untgz version 0.2.1\n"
" using zlib version %s\n\n",
zlibVersion());
" untgz file.tgz fname ... extract selected files\n"
" untgz -l file.tgz list archive contents\n"
" untgz -h display this help\n");
}
{
exit(1);
}
/* ============================================================ */
#endif
{
char *TGZfile;
gzFile *f;
{
{
else
prog++;
}
else
prog++;
}
else
prog++;
if (argc == 1)
help(0);
{
help(0);
}
{
help(0);
}
++arg;
help(1);
/*
* Process the TGZ file
*/
switch(action)
{
case TGZ_LIST:
case TGZ_EXTRACT:
if (f == NULL)
{
return 1;
}
break;
default:
error("Unknown option");
exit(1);
}
return 0;
}