The SWORD Project  1.9.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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
 

Macros

#define AREGTYPE   '\0' /* regular file */
 
#define BLKTYPE   '4' /* block special */
 
#define BLOCKSIZE   512
 
#define CHRTYPE   '3' /* character special */
 
#define CONTTYPE   '7' /* reserved */
 
#define DIRTYPE   '5' /* directory */
 
#define FIFOTYPE   '6' /* FIFO special */
 
#define ISSPECIAL(c)   (((c) == '*') || ((c) == '/'))
 
#define LNKTYPE   '1' /* link */
 
#define REGTYPE   '0' /* regular file */
 
#define SYMTYPE   '2' /* reserved */
 

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 *))
 
int getoct OF ((char *, int))
 
char *strtime OF ((time_t *))
 
int ExprMatch OF ((char *, char *))
 
int makedir OF ((char *))
 
int matchname OF ((int, int, char **, char *))
 
int tar OF ((gzFile, int, int, int, char **))
 
void help OF ((int))
 
int main OF ((int, char **))
 
void TGZnotfound OF ((const char *fname))
 
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 }
 

Macro Definition Documentation

#define AREGTYPE   '\0' /* regular file */

Definition at line 47 of file untgz.c.

#define BLKTYPE   '4' /* block special */

Definition at line 51 of file untgz.c.

#define BLOCKSIZE   512

Definition at line 56 of file untgz.c.

#define CHRTYPE   '3' /* character special */

Definition at line 50 of file untgz.c.

#define CONTTYPE   '7' /* reserved */

Definition at line 54 of file untgz.c.

#define DIRTYPE   '5' /* directory */

Definition at line 52 of file untgz.c.

#define FIFOTYPE   '6' /* FIFO special */

Definition at line 53 of file untgz.c.

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

Definition at line 159 of file untgz.c.

#define LNKTYPE   '1' /* link */

Definition at line 48 of file untgz.c.

#define REGTYPE   '0' /* regular file */

Definition at line 46 of file untgz.c.

#define SYMTYPE   '2' /* reserved */

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.

84 { TGZ_EXTRACT = 0, TGZ_LIST };
Definition: untgz.c:84

Function Documentation

void error ( const char *  msg)

Definition at line 404 of file untgz.c.

405 {
406  fprintf(stderr, "%s: %s\n", prog, msg);
407 // exit(1); // don't exit on error
408 }
char * prog
Definition: untgz.c:101
int ExprMatch ( char *  string,
char *  expr 
)

Definition at line 161 of file untgz.c.

162 {
163  while (1)
164  {
165  if (ISSPECIAL(*expr))
166  {
167  if (*expr == '/')
168  {
169  if (*string != '\\' && *string != '/')
170  return 0;
171  string ++; expr++;
172  }
173  else if (*expr == '*')
174  {
175  if (*expr ++ == 0)
176  return 1;
177  while (*++string != *expr)
178  if (*string == 0)
179  return 0;
180  }
181  }
182  else
183  {
184  if (*string != *expr)
185  return 0;
186  if (*expr++ == 0)
187  return 1;
188  string++;
189  }
190  }
191 }
#define ISSPECIAL(c)
Definition: untgz.c:159
int getoct ( char *  p,
int  width 
)

Definition at line 127 of file untgz.c.

128 {
129  int result = 0;
130  char c;
131 
132  while (width --)
133  {
134  c = *p++;
135  if (c == ' ')
136  continue;
137  if (c == 0)
138  break;
139  result = result * 8 + (c - '0');
140  }
141  return result;
142 }
result
Definition: regex.c:5545
void help ( int  exitval)

Definition at line 392 of file untgz.c.

393 {
394  fprintf(stderr,
395  "untgz v 0.1\n"
396  " an sample application of zlib 1.0.4\n\n"
397  "Usage : untgz TGZfile to extract all files\n"
398  " untgz TGZfile fname ... to extract selected files\n"
399  " untgz -l TGZfile to list archive contents\n"
400  " untgz -h to display this help\n\n");
401  exit(exitval);
402 }
int makedir ( char *  newdir)

Definition at line 200 of file untgz.c.

201 {
202  char *buffer = strdup(newdir);
203  char *p;
204  int len = (int)strlen(buffer);
205 
206  if (len <= 0) {
207  free(buffer);
208  return 0;
209  }
210  if (buffer[len-1] == '/') {
211  buffer[len-1] = '\0';
212  }
213  if (mkdir(buffer, 0775) == 0)
214  {
215  free(buffer);
216  return 1;
217  }
218 
219  p = buffer+1;
220  while (1)
221  {
222  char hold;
223 
224  while(*p && *p != '\\' && *p != '/')
225  p++;
226  hold = *p;
227  *p = 0;
228  if ((mkdir(buffer, 0775) == -1) && (errno == ENOENT))
229  {
230  fprintf(stderr,"%s: couldn't create directory %s\n",prog,buffer);
231  free(buffer);
232  return 0;
233  }
234  if (hold == 0)
235  break;
236  *p++ = hold;
237  }
238  free(buffer);
239  return 1;
240 }
char * prog
Definition: untgz.c:101
preg buffer
Definition: regex.c:8089
free(preg->fastmap)
unsigned long hold
Definition: inflate.h:98
int matchname ( int  arg,
int  argc,
char **  argv,
char *  fname 
)

Definition at line 242 of file untgz.c.

243 {
244  if (arg == argc) /* no arguments given (untgz tgzarchive) */
245  return 1;
246 
247  while (arg < argc)
248  if (ExprMatch(fname,argv[arg++]))
249  return 1;
250 
251  return 0; /* ignore this for the moment being */
252 }
int ExprMatch(char *string, char *expr)
Definition: untgz.c:161
void TGZnotfound OF ( (const char *)  )
int getoct OF ( (char *, int)  )
char* strtime OF ( (time_t *)  )
int ExprMatch OF ( (char *, char *)  )
int makedir OF ( (char *)  )
int matchname OF ( (int, int, char **, char *)  )
int tar OF ( (gzFile, int, int, int, char **)  )
void help OF ( (int)  )
int main OF ( (int, char **)  )
void TGZnotfound OF ( (const char *fname)  )

Definition at line 112 of file untgz.c.

113 {
114  int i;
115 
116  fprintf(stderr,"%s : couldn't find ",prog);
117  for (i=0;TGZprefix[i];i++)
118  fprintf(stderr,(TGZprefix[i+1]) ? "%s%s, " : "or %s%s\n",
119  fname,
120  TGZprefix[i]);
121  exit(1);
122 }
char * prog
Definition: untgz.c:101
static char * TGZprefix[]
Definition: untgz.c:105
char* strtime ( time_t *  t)

Definition at line 144 of file untgz.c.

145 {
146  struct tm *local;
147  static char result[32];
148 
149  local = localtime(t);
150  sprintf(result,"%2d/%02d/%4d %02d:%02d:%02d",
151  local->tm_mday, local->tm_mon+1, local->tm_year+1900,
152  local->tm_hour, local->tm_min, local->tm_sec);
153  return result;
154 }
#define local
Definition: adler32.c:10
result
Definition: regex.c:5545
int untar ( gzFile  in,
const char *  dest 
)

Definition at line 257 of file untgz.c.

257  {
258  union tar_buffer buffer;
259  int len;
260  int err;
261  int getheader = 1;
262  int remaining = 0;
263  FILE *outfile = NULL;
264  char fname[BLOCKSIZE];
265  time_t tartime;
266 
267  while (1) {
268  len = gzread(in, &buffer, BLOCKSIZE);
269  if (len < 0)
270  error (gzerror(in, &err));
271  /*
272  * Always expect complete blocks to process
273  * the tar information.
274  */
275  if (len != BLOCKSIZE)
276  error("gzread: incomplete block read");
277 
278  /*
279  * If we have to get a tar header
280  */
281  if (getheader == 1) {
282  /*
283  * if we met the end of the tar
284  * or the end-of-tar block,
285  * we are done
286  */
287  if ((len == 0) || (buffer.header.name[0]== 0)) break;
288 
289  tartime = (time_t)getoct(buffer.header.mtime,12);
290  strcpy(fname, dest);
291  if ((fname[strlen(fname)-1] != '/') && (fname[strlen(fname)-1] != '\\'))
292  strcat(fname, "/");
293  strcat(fname, buffer.header.name);
294 
295  switch (buffer.header.typeflag) {
296  case DIRTYPE:
297  makedir(fname);
298  break;
299  case REGTYPE:
300  case AREGTYPE:
301  remaining = getoct(buffer.header.size,12);
302  if (remaining) {
303  outfile = fopen(fname,"wb");
304  if (outfile == NULL) {
305  // try creating directory
306  char *p = strrchr(fname, '/');
307  if (p != NULL) {
308  *p = '\0';
309  makedir(fname);
310  *p = '/';
311  outfile = fopen(fname,"wb");
312  }
313  }
314 /*
315  fprintf(stderr,
316  "%s %s\n",
317  (outfile) ? "Extracting" : "Couldn't create",
318  fname);
319 */
320  }
321  else
322  outfile = NULL;
323  /*
324  * could have no contents
325  */
326  getheader = (remaining) ? 0 : 1;
327  break;
328  default:
329  break;
330  }
331  }
332  else {
333  unsigned int bytes = (remaining > BLOCKSIZE) ? BLOCKSIZE : remaining;
334 
335  if (outfile != NULL) {
336  if (fwrite(&buffer,sizeof(char),bytes,outfile) != bytes) {
337  fprintf(stderr,"%s : error writing %s skipping...\n",prog,fname);
338  fclose(outfile);
339  unlink(fname);
340  }
341  }
342  remaining -= bytes;
343  if (remaining == 0) {
344  getheader = 1;
345  if (outfile != NULL) {
346 #ifdef WIN32
347  HANDLE hFile;
348  FILETIME ftm,ftLocal;
349  SYSTEMTIME st;
350  struct tm localt;
351 
352  fclose(outfile);
353 
354  localt = *localtime(&tartime);
355 
356  hFile = CreateFile(fname, GENERIC_READ | GENERIC_WRITE,
357  0, NULL, OPEN_EXISTING, 0, NULL);
358 
359  st.wYear = (WORD)localt.tm_year+1900;
360  st.wMonth = (WORD)localt.tm_mon;
361  st.wDayOfWeek = (WORD)localt.tm_wday;
362  st.wDay = (WORD)localt.tm_mday;
363  st.wHour = (WORD)localt.tm_hour;
364  st.wMinute = (WORD)localt.tm_min;
365  st.wSecond = (WORD)localt.tm_sec;
366  st.wMilliseconds = 0;
367  SystemTimeToFileTime(&st,&ftLocal);
368  LocalFileTimeToFileTime(&ftLocal,&ftm);
369  SetFileTime(hFile,&ftm,NULL,&ftm);
370  CloseHandle(hFile);
371 
372  outfile = NULL;
373 #else
374  struct utimbuf settime;
375 
376  settime.actime = settime.modtime = tartime;
377 
378  fclose(outfile);
379  outfile = NULL;
380  utime(fname,&settime);
381 #endif
382  }
383  }
384  }
385  }
386  return 0;
387 }
#define AREGTYPE
Definition: untgz.c:47
char * prog
Definition: untgz.c:101
int makedir(char *newdir)
Definition: untgz.c:200
preg buffer
Definition: regex.c:8089
#define DIRTYPE
Definition: untgz.c:52
#define REGTYPE
Definition: untgz.c:46
#define BLOCKSIZE
Definition: untgz.c:56
return NULL
Definition: regex.c:7953
void error(const char *msg)
Definition: untgz.c:404
const char *ZEXPORT gzerror(gzFile file, int *errnum)
Definition: gzlib.c:536
int getoct(char *p, int width)
Definition: untgz.c:127
int ZEXPORT gzread(gzFile file, voidp buf, unsigned len)
Definition: gzread.c:295
int untargz ( int  fd,
const char *  dest 
)

Definition at line 411 of file untgz.c.

411  {
412  gzFile f;
413 
414  f = gzdopen(fd, "rb");
415  if (f == NULL) {
416  fprintf(stderr,"%s: Couldn't gzopen file\n", prog);
417  return 1;
418  }
419 
420  return untar(f, dest);
421 }
char * prog
Definition: untgz.c:101
return NULL
Definition: regex.c:7953
gzFile ZEXPORT gzdopen(int fd, const char *mode)
Definition: gzlib.c:292
int untar(gzFile in, const char *dest)
Definition: untgz.c:257

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.