src/utilfuns/zlib/untgz.c File Reference

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <fcntl.h>
#include <direct.h>
#include <io.h>
#include "zlib.h"
#include <utime.h>
Include dependency graph for untgz.c:

Go to the source code of this file.

Classes

union  tar_buffer
struct  tar_header

Defines

#define AREGTYPE   '\0'
#define BLKTYPE   '4'
#define BLOCKSIZE   512
#define CHRTYPE   '3'
#define CONTTYPE   '7'
#define DIRTYPE   '5'
#define FIFOTYPE   '6'
#define ISSPECIAL(c)   (((c) == '*') || ((c) == '/'))
#define LNKTYPE   '1'
#define REGTYPE   '0'
#define SYMTYPE   '2'

Enumerations

enum  { TGZ_EXTRACT = 0, TGZ_LIST }

Functions

void error (const char *msg)
int ExprMatch (char *string, char *expr)
int getoct (char *p, int width)
void help (int exitval)
int makedir (char *newdir)
int matchname (int arg, int argc, char **argv, char *fname)
void TGZnotfound OF ((const char *fname))
int main OF ((int, char **))
void help OF ((int))
int tar OF ((gzFile, int, int, int, char **))
int matchname OF ((int, int, char **, char *))
int makedir OF ((char *))
int ExprMatch OF ((char *, char *))
char *strtime OF ((time_t *))
int getoct OF ((char *, int))
void TGZnotfound OF ((const char *))
char * strtime (time_t *t)
int untar (gzFile in, const char *dest)
int untargz (int fd, const char *dest)

Variables

char * prog
static char * TGZprefix [] = { "\0", ".tgz", ".tar.gz", ".tar", NULL }

Define Documentation

#define AREGTYPE   '\0'

Definition at line 47 of file untgz.c.

#define BLKTYPE   '4'

Definition at line 51 of file untgz.c.

#define BLOCKSIZE   512

Definition at line 56 of file untgz.c.

#define CHRTYPE   '3'

Definition at line 50 of file untgz.c.

#define CONTTYPE   '7'

Definition at line 54 of file untgz.c.

#define DIRTYPE   '5'

Definition at line 52 of file untgz.c.

#define FIFOTYPE   '6'

Definition at line 53 of file untgz.c.

#define ISSPECIAL (  )     (((c) == '*') || ((c) == '/'))

Definition at line 159 of file untgz.c.

#define LNKTYPE   '1'

Definition at line 48 of file untgz.c.

#define REGTYPE   '0'

Definition at line 46 of file untgz.c.

#define SYMTYPE   '2'

Definition at line 49 of file untgz.c.


Enumeration Type Documentation

anonymous enum
Enumerator:
TGZ_EXTRACT 
TGZ_LIST 

Definition at line 84 of file untgz.c.

00084 { TGZ_EXTRACT = 0, TGZ_LIST };


Function Documentation

void error ( const char *  msg  ) 

Definition at line 404 of file untgz.c.

00405 {
00406     fprintf(stderr, "%s: %s\n", prog, msg);
00407     exit(1);
00408 }

int ExprMatch ( char *  string,
char *  expr 
)

Definition at line 161 of file untgz.c.

00162 {
00163   while (1)
00164     {
00165       if (ISSPECIAL(*expr))
00166     {
00167       if (*expr == '/')
00168         {
00169           if (*string != '\\' && *string != '/')
00170         return 0;
00171           string ++; expr++;
00172         }
00173       else if (*expr == '*')
00174         {
00175           if (*expr ++ == 0)
00176         return 1;
00177           while (*++string != *expr)
00178         if (*string == 0)
00179           return 0;
00180         }
00181     }
00182       else
00183     {
00184       if (*string != *expr)
00185         return 0;
00186       if (*expr++ == 0)
00187         return 1;
00188       string++;
00189     }
00190     }
00191 }

int getoct ( char *  p,
int  width 
)

Definition at line 127 of file untgz.c.

00128 {
00129   int result = 0;
00130   char c;
00131   
00132   while (width --)
00133     {
00134       c = *p++;
00135       if (c == ' ')
00136     continue;
00137       if (c == 0)
00138     break;
00139       result = result * 8 + (c - '0');
00140     }
00141   return result;
00142 }

void help ( int  exitval  ) 

Definition at line 392 of file untgz.c.

00393 {
00394   fprintf(stderr,
00395       "untgz v 0.1\n"
00396       " an sample application of zlib 1.0.4\n\n"
00397         "Usage : untgz TGZfile            to extract all files\n"
00398         "        untgz TGZfile fname ...  to extract selected files\n"
00399         "        untgz -l TGZfile         to list archive contents\n"
00400         "        untgz -h                 to display this help\n\n");
00401   exit(exitval);
00402 }

int makedir ( char *  newdir  ) 

Definition at line 200 of file untgz.c.

00201 {
00202   char *buffer = strdup(newdir);
00203   char *p;
00204   int  len = strlen(buffer);
00205   
00206   if (len <= 0) {
00207     free(buffer);
00208     return 0;
00209   }
00210   if (buffer[len-1] == '/') {
00211     buffer[len-1] = '\0';
00212   }
00213   if (mkdir(buffer, 0775) == 0)
00214     {
00215       free(buffer);
00216       return 1;
00217     }
00218 
00219   p = buffer+1;
00220   while (1)
00221     {
00222       char hold;
00223       
00224       while(*p && *p != '\\' && *p != '/')
00225     p++;
00226       hold = *p;
00227       *p = 0;
00228       if ((mkdir(buffer, 0775) == -1) && (errno == ENOENT))
00229     {
00230       fprintf(stderr,"%s: couldn't create directory %s\n",prog,buffer);
00231       free(buffer);
00232       return 0;
00233     }
00234       if (hold == 0)
00235     break;
00236       *p++ = hold;
00237     }
00238   free(buffer);
00239   return 1;
00240 }

int matchname ( int  arg,
int  argc,
char **  argv,
char *  fname 
)

Definition at line 242 of file untgz.c.

00243 {
00244   if (arg == argc)      /* no arguments given (untgz tgzarchive) */
00245     return 1;
00246 
00247   while (arg < argc)
00248     if (ExprMatch(fname,argv[arg++]))
00249      return 1;
00250 
00251   return 0; /* ignore this for the moment being */
00252 }

void TGZnotfound OF ( (const char *fname)   ) 

Definition at line 112 of file untgz.c.

00113 {
00114   int i;
00115 
00116   fprintf(stderr,"%s : couldn't find ",prog);
00117   for (i=0;TGZprefix[i];i++)
00118     fprintf(stderr,(TGZprefix[i+1]) ? "%s%s, " : "or %s%s\n",
00119             fname,
00120             TGZprefix[i]);
00121   exit(1);
00122 }

int main OF ( (int, char **)   ) 
void help OF ( (int)   ) 
int tar OF ( (gzFile, int, int, int, char **)   ) 
int matchname OF ( (int, int, char **, char *)   ) 
int makedir OF ( (char *)   ) 
int ExprMatch OF ( (char *, char *)   ) 
char* strtime OF ( (time_t *)   ) 
int getoct OF ( (char *, int)   ) 
void TGZnotfound OF ( (const char *)   ) 
char* strtime ( time_t *  t  ) 

Definition at line 144 of file untgz.c.

00145 {
00146   struct tm   *local;
00147   static char result[32];
00148 
00149   local = localtime(t);
00150   sprintf(result,"%2d/%02d/%4d %02d:%02d:%02d",
00151       local->tm_mday, local->tm_mon+1, local->tm_year+1900,
00152       local->tm_hour, local->tm_min,   local->tm_sec);
00153   return result;
00154 }

int untar ( gzFile  in,
const char *  dest 
)

Definition at line 257 of file untgz.c.

00257                                         {
00258     union  tar_buffer buffer;
00259     int    len;
00260     int    err;
00261     int    getheader = 1;
00262     int    remaining = 0;
00263     FILE   *outfile = NULL;
00264     char   fname[BLOCKSIZE];
00265     time_t tartime;
00266   
00267     while (1) {
00268         len = gzread(in, &buffer, BLOCKSIZE);
00269         if (len < 0)
00270             error (gzerror(in, &err));
00271         /*
00272         * Always expect complete blocks to process
00273         * the tar information.
00274         */
00275         if (len != BLOCKSIZE)
00276             error("gzread: incomplete block read");
00277      
00278         /*
00279         * If we have to get a tar header
00280         */
00281         if (getheader == 1) {
00282             /*
00283             * if we met the end of the tar
00284             * or the end-of-tar block,
00285             * we are done
00286             */
00287             if ((len == 0)  || (buffer.header.name[0]== 0)) break;
00288 
00289             tartime = (time_t)getoct(buffer.header.mtime,12);
00290             strcpy(fname, dest);
00291             if ((fname[strlen(fname)-1] != '/') && (fname[strlen(fname)-1] != '\\'))
00292                     strcat(fname, "/");
00293             strcat(fname, buffer.header.name);
00294       
00295             switch (buffer.header.typeflag) {
00296             case DIRTYPE:
00297                 makedir(fname);
00298                 break;
00299             case REGTYPE:
00300             case AREGTYPE:
00301                 remaining = getoct(buffer.header.size,12);
00302                 if (remaining) {
00303                     outfile = fopen(fname,"wb");
00304                     if (outfile == NULL) {
00305                         // try creating directory
00306                         char *p = strrchr(fname, '/');
00307                         if (p != NULL) {
00308                             *p = '\0';
00309                             makedir(fname);
00310                             *p = '/';
00311                             outfile = fopen(fname,"wb");
00312                         }
00313                     }
00314 /*
00315                     fprintf(stderr,
00316                         "%s %s\n",
00317                         (outfile) ? "Extracting" : "Couldn't create",
00318                         fname);
00319 */
00320                 }
00321                 else
00322                     outfile = NULL;
00323                 /*
00324                 * could have no contents
00325                 */
00326                 getheader = (remaining) ? 0 : 1;
00327                 break;
00328             default:
00329                 break;
00330             }
00331         }
00332         else    {
00333             unsigned int bytes = (remaining > BLOCKSIZE) ? BLOCKSIZE : remaining;
00334 
00335             if (outfile != NULL) {
00336                 if (fwrite(&buffer,sizeof(char),bytes,outfile) != bytes) {
00337                     fprintf(stderr,"%s : error writing %s skipping...\n",prog,fname);
00338                     fclose(outfile);
00339                     unlink(fname);
00340                 }
00341             }
00342             remaining -= bytes;
00343             if (remaining == 0) {
00344                 getheader = 1;
00345                 if (outfile != NULL) {
00346 #ifdef WIN32
00347                     HANDLE hFile;
00348                     FILETIME ftm,ftLocal;
00349                     SYSTEMTIME st;
00350                     struct tm localt;
00351  
00352                     fclose(outfile);
00353 
00354                     localt = *localtime(&tartime);
00355 
00356                     hFile = CreateFile(fname, GENERIC_READ | GENERIC_WRITE,
00357                     0, NULL, OPEN_EXISTING, 0, NULL);
00358           
00359                     st.wYear = (WORD)localt.tm_year+1900;
00360                     st.wMonth = (WORD)localt.tm_mon;
00361                     st.wDayOfWeek = (WORD)localt.tm_wday;
00362                     st.wDay = (WORD)localt.tm_mday;
00363                     st.wHour = (WORD)localt.tm_hour;
00364                     st.wMinute = (WORD)localt.tm_min;
00365                     st.wSecond = (WORD)localt.tm_sec;
00366                     st.wMilliseconds = 0;
00367                     SystemTimeToFileTime(&st,&ftLocal);
00368                     LocalFileTimeToFileTime(&ftLocal,&ftm);
00369                     SetFileTime(hFile,&ftm,NULL,&ftm);
00370                     CloseHandle(hFile);
00371 
00372                     outfile = NULL;
00373 #else
00374                     struct utimbuf settime;
00375 
00376                     settime.actime = settime.modtime = tartime;
00377 
00378                     fclose(outfile);
00379                     outfile = NULL;
00380                     utime(fname,&settime);
00381 #endif
00382                 }
00383             }
00384         }
00385     }
00386     return 0;
00387 }

int untargz ( int  fd,
const char *  dest 
)

Definition at line 411 of file untgz.c.

00411                                       {
00412     gzFile  *f;
00413 
00414     f = gzdopen(fd, "rb");
00415     if (f == NULL) {
00416         fprintf(stderr,"%s: Couldn't gzopen file\n",    prog);
00417         return 1;
00418     }
00419 
00420     return untar(f, dest);
00421 }


Variable Documentation

char* prog

Definition at line 101 of file untgz.c.

char* TGZprefix[] = { "\0", ".tgz", ".tar.gz", ".tar", NULL } [static]

Definition at line 105 of file untgz.c.


Generated on 18 Mar 2013 for The SWORD Project by  doxygen 1.6.1