2 /* Minitar: extract .tar.gz files on Win32 platforms.
3 Uses zlib for decompression.
5 This is very simple-minded, it ignores checksums, and any type of file
6 that is not a plain file or a directory. Nonetheless it is useful.
8 Author: Charles G. Waldman (cgw@pgt.com), Aug 4 1998
10 This file is placed in the public domain; you can
11 do whatever you like with it. There is NO WARRANTY.
12 If it breaks, you get to keep both pieces */
21 # include <direct.h> /* For mkdir */
29 fprintf (stderr, "Usage: %s file.tar.gz [base-dir]\n", name);
30 fprintf (stderr, "\tExtracts the contents compressed tar file to base-dir\n");
36 #define MAXNAMELEN 1024
42 sscanf (str, "%o", &ret);
46 /* this is like mkdir -p, except if there is no trailing slash,
47 the final component is assumed to be a file, rather than a
48 path component, so it is not created as a directory */
56 for (cp=path; cp; cp = (char*)strchr (cp+1, '/'))
62 strncpy (tmp, path, cp-path);
64 if (strlen (tmp) == 0)
69 if (mkdir (tmp, 0777))
84 main (int argc, char **argv)
86 char fullname[MAXNAMELEN];
95 gzFile *infile = (gzFile*)0;
96 FILE *outfile = (FILE*)0;
98 char block[BLOCKSIZE];
99 int nbytes, nread, nwritten;
104 if (argc < 2 || argc > 3)
111 if (! (infile = gzopen (tarfile, "rb")))
113 fprintf (stderr, "Cannot open %s\n", tarfile);
119 nread = gzread (infile, block, 512);
121 if (!in_block && nread == 0)
124 if (nread != BLOCKSIZE)
126 fprintf (stderr, "Error: incomplete block read. Exiting.\n");
132 if (block[0]=='\0') /* We're done */
135 strncpy (magic, block+257, 6);
137 if (strcmp (magic, "ustar "))
140 "Error: incorrect magic number in tar header. Exiting\n");
144 strncpy (name, block, 100);
146 sprintf (fullname, "%s/%s", basedir, name);
147 printf ("%s\n", fullname);
160 fprintf (stderr, "Error: unknown type flag %c. Exiting.\n", type);
169 /* makepath will ignore the final path component, so make sure
170 dirnames have a trailing slash */
172 if (fullname[strlen (fullname)-1] != '/')
173 strcat (fullname, "/");
174 if (makepath (fullname))
176 fprintf (stderr, "Error: cannot create directory %s. Exiting.\n",
187 if (fclose (outfile))
189 fprintf (stderr, "Error: cannot close file %s. Exiting.\n",
196 if (!(outfile = fopen (fullname, "wb")))
198 /*try creating the directory, maybe it's not there */
199 if (makepath (fullname))
201 fprintf (stderr, "Error: cannot create file %s. Exiting.\n",
205 /* now try again to open the file */
206 if (!(outfile = fopen (fullname, "wb")))
208 fprintf (stderr, "Error: cannot create file %s. Exiting.\n",
214 strncpy (osize, block+124, 12);
216 size = octal (osize);
219 fprintf (stderr, "Error: invalid size in tar header. Exiting.\n");
222 if (size==0) /* file of size 0 is done */
227 { /* write or continue writing file contents */
228 nbytes = size>512? 512:size;
230 nwritten = fwrite (block, 1, nbytes, outfile);
231 if (nwritten != nbytes)
233 fprintf (stderr, "Error: only wrote %d bytes to file %s. Exiting.\n",