tarruby 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.txt +99 -0
- data/ext/extconf.rb +19 -0
- data/ext/libtar/COPYRIGHT +35 -0
- data/ext/libtar/ChangeLog +243 -0
- data/ext/libtar/ChangeLog-1.0.x +141 -0
- data/ext/libtar/INSTALL +183 -0
- data/ext/libtar/Makefile.in +51 -0
- data/ext/libtar/README +121 -0
- data/ext/libtar/TODO +10 -0
- data/ext/libtar/autoconf/ac_path_generic.m4 +136 -0
- data/ext/libtar/autoconf/aclocal.m4 +199 -0
- data/ext/libtar/autoconf/encap.m4 +133 -0
- data/ext/libtar/autoconf/install-sh +251 -0
- data/ext/libtar/autom4te.cache/output.0 +8102 -0
- data/ext/libtar/autom4te.cache/requests +112 -0
- data/ext/libtar/autom4te.cache/traces.0 +382 -0
- data/ext/libtar/compat/ChangeLog +31 -0
- data/ext/libtar/compat/README +12 -0
- data/ext/libtar/compat/TODO +4 -0
- data/ext/libtar/compat/basename.c +91 -0
- data/ext/libtar/compat/compat.h +260 -0
- data/ext/libtar/compat/dirname.c +96 -0
- data/ext/libtar/compat/fnmatch.c +237 -0
- data/ext/libtar/compat/gethostbyname_r.c +41 -0
- data/ext/libtar/compat/gethostname.c +36 -0
- data/ext/libtar/compat/getservbyname_r.c +41 -0
- data/ext/libtar/compat/glob.c +898 -0
- data/ext/libtar/compat/inet_aton.c +27 -0
- data/ext/libtar/compat/module.ac +591 -0
- data/ext/libtar/compat/snprintf.c +788 -0
- data/ext/libtar/compat/strdup.c +62 -0
- data/ext/libtar/compat/strlcat.c +72 -0
- data/ext/libtar/compat/strlcpy.c +68 -0
- data/ext/libtar/compat/strmode.c +199 -0
- data/ext/libtar/compat/strrstr.c +40 -0
- data/ext/libtar/compat/strsep.c +87 -0
- data/ext/libtar/config.h.in +187 -0
- data/ext/libtar/configure +8102 -0
- data/ext/libtar/configure.ac +114 -0
- data/ext/libtar/doc/Makefile.in +152 -0
- data/ext/libtar/doc/tar_append_file.3 +50 -0
- data/ext/libtar/doc/tar_block_read.3 +24 -0
- data/ext/libtar/doc/tar_extract_all.3 +43 -0
- data/ext/libtar/doc/tar_extract_file.3 +84 -0
- data/ext/libtar/doc/tar_open.3 +97 -0
- data/ext/libtar/doc/th_get_pathname.3 +63 -0
- data/ext/libtar/doc/th_print_long_ls.3 +22 -0
- data/ext/libtar/doc/th_read.3 +34 -0
- data/ext/libtar/doc/th_set_from_stat.3 +45 -0
- data/ext/libtar/lib/Makefile.in +92 -0
- data/ext/libtar/lib/append.c +272 -0
- data/ext/libtar/lib/block.c +384 -0
- data/ext/libtar/lib/decode.c +130 -0
- data/ext/libtar/lib/encode.c +237 -0
- data/ext/libtar/lib/extract.c +656 -0
- data/ext/libtar/lib/handle.c +150 -0
- data/ext/libtar/lib/internal.h +46 -0
- data/ext/libtar/lib/libtar.h +311 -0
- data/ext/libtar/lib/output.c +146 -0
- data/ext/libtar/lib/util.c +153 -0
- data/ext/libtar/lib/wrapper.c +175 -0
- data/ext/libtar/libtar/Makefile.in +73 -0
- data/ext/libtar/libtar/libtar.c +363 -0
- data/ext/libtar/listhash/ChangeLog +15 -0
- data/ext/libtar/listhash/TODO +21 -0
- data/ext/libtar/listhash/hash.c.in +344 -0
- data/ext/libtar/listhash/hash_new.3.in +74 -0
- data/ext/libtar/listhash/list.c.in +458 -0
- data/ext/libtar/listhash/list_new.3.in +86 -0
- data/ext/libtar/listhash/listhash.h.in +196 -0
- data/ext/libtar/listhash/module.ac +21 -0
- data/ext/libtar/win32/config.h +190 -0
- data/ext/libtar/win32/dirent.c +115 -0
- data/ext/libtar/win32/dirent.h +24 -0
- data/ext/libtar/win32/grp.h +4 -0
- data/ext/libtar/win32/listhash/libtar_hash.c +344 -0
- data/ext/libtar/win32/listhash/libtar_list.c +458 -0
- data/ext/libtar/win32/listhash/libtar_listhash.h +196 -0
- data/ext/libtar/win32/pwd.h +4 -0
- data/ext/libtar/win32/sys/param.h +8 -0
- data/ext/libtar/win32/tar.h +35 -0
- data/ext/libtar/win32/utime.h +6 -0
- data/ext/libtar/win32/win32/types.h +10 -0
- data/ext/tarruby.c +648 -0
- metadata +150 -0
@@ -0,0 +1,656 @@
|
|
1
|
+
/*
|
2
|
+
** Copyright 1998-2003 University of Illinois Board of Trustees
|
3
|
+
** Copyright 1998-2003 Mark D. Roth
|
4
|
+
** All rights reserved.
|
5
|
+
**
|
6
|
+
** extract.c - libtar code to extract a file from a tar archive
|
7
|
+
**
|
8
|
+
** Mark D. Roth <roth@uiuc.edu>
|
9
|
+
** Campus Information Technologies and Educational Services
|
10
|
+
** University of Illinois at Urbana-Champaign
|
11
|
+
*/
|
12
|
+
|
13
|
+
#include <internal.h>
|
14
|
+
|
15
|
+
#include <stdio.h>
|
16
|
+
#include <sys/param.h>
|
17
|
+
#include <sys/types.h>
|
18
|
+
#include <fcntl.h>
|
19
|
+
#include <errno.h>
|
20
|
+
#include <utime.h>
|
21
|
+
|
22
|
+
#ifdef STDC_HEADERS
|
23
|
+
# include <stdlib.h>
|
24
|
+
# include <string.h>
|
25
|
+
#endif
|
26
|
+
|
27
|
+
#ifdef HAVE_UNISTD_H
|
28
|
+
# include <unistd.h>
|
29
|
+
#endif
|
30
|
+
|
31
|
+
|
32
|
+
struct linkname
|
33
|
+
{
|
34
|
+
char ln_save[MAXPATHLEN];
|
35
|
+
char ln_real[MAXPATHLEN];
|
36
|
+
};
|
37
|
+
typedef struct linkname linkname_t;
|
38
|
+
|
39
|
+
|
40
|
+
static int
|
41
|
+
tar_set_file_perms(TAR *t, char *realname)
|
42
|
+
{
|
43
|
+
mode_t mode;
|
44
|
+
uid_t uid;
|
45
|
+
gid_t gid;
|
46
|
+
struct utimbuf ut;
|
47
|
+
char *filename;
|
48
|
+
|
49
|
+
filename = (realname ? realname : th_get_pathname(t));
|
50
|
+
mode = th_get_mode(t);
|
51
|
+
uid = th_get_uid(t);
|
52
|
+
gid = th_get_gid(t);
|
53
|
+
ut.modtime = ut.actime = th_get_mtime(t);
|
54
|
+
|
55
|
+
/* change owner/group */
|
56
|
+
if (geteuid() == 0)
|
57
|
+
#ifdef HAVE_LCHOWN
|
58
|
+
if (lchown(filename, uid, gid) == -1)
|
59
|
+
{
|
60
|
+
# ifdef DEBUG
|
61
|
+
fprintf(stderr, "lchown(\"%s\", %d, %d): %s\n",
|
62
|
+
filename, uid, gid, strerror(errno));
|
63
|
+
# endif
|
64
|
+
#else /* ! HAVE_LCHOWN */
|
65
|
+
if (!TH_ISSYM(t) && chown(filename, uid, gid) == -1)
|
66
|
+
{
|
67
|
+
# ifdef DEBUG
|
68
|
+
fprintf(stderr, "chown(\"%s\", %d, %d): %s\n",
|
69
|
+
filename, uid, gid, strerror(errno));
|
70
|
+
# endif
|
71
|
+
#endif /* HAVE_LCHOWN */
|
72
|
+
if (!realname) free (filename);
|
73
|
+
return -1;
|
74
|
+
}
|
75
|
+
|
76
|
+
/* change access/modification time */
|
77
|
+
if (!TH_ISSYM(t) && utime(filename, &ut) == -1)
|
78
|
+
{
|
79
|
+
#ifdef DEBUG
|
80
|
+
perror("utime()");
|
81
|
+
#endif
|
82
|
+
if (!realname) free(filename);
|
83
|
+
return -1;
|
84
|
+
}
|
85
|
+
|
86
|
+
/* change permissions */
|
87
|
+
if (!TH_ISSYM(t) && chmod(filename, mode) == -1)
|
88
|
+
{
|
89
|
+
#ifdef DEBUG
|
90
|
+
perror("chmod()");
|
91
|
+
#endif
|
92
|
+
if (!realname) free(filename);
|
93
|
+
return -1;
|
94
|
+
}
|
95
|
+
|
96
|
+
if (!realname) free(filename);
|
97
|
+
return 0;
|
98
|
+
}
|
99
|
+
|
100
|
+
|
101
|
+
/* switchboard */
|
102
|
+
int
|
103
|
+
tar_extract_file(TAR *t, char *realname)
|
104
|
+
{
|
105
|
+
int i;
|
106
|
+
linkname_t *lnp;
|
107
|
+
char *filename;
|
108
|
+
|
109
|
+
if (t->options & TAR_NOOVERWRITE)
|
110
|
+
{
|
111
|
+
struct stat s;
|
112
|
+
|
113
|
+
if (lstat(realname, &s) == 0 || errno != ENOENT)
|
114
|
+
{
|
115
|
+
errno = EEXIST;
|
116
|
+
return -1;
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
if (TH_ISDIR(t))
|
121
|
+
{
|
122
|
+
i = tar_extract_dir(t, realname);
|
123
|
+
if (i == 1)
|
124
|
+
i = 0;
|
125
|
+
}
|
126
|
+
#ifndef _WIN32 // modified by SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
|
127
|
+
else if (TH_ISLNK(t))
|
128
|
+
i = tar_extract_hardlink(t, realname);
|
129
|
+
#endif
|
130
|
+
#ifndef _WIN32 // modified by SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
|
131
|
+
else if (TH_ISSYM(t))
|
132
|
+
i = tar_extract_symlink(t, realname);
|
133
|
+
#endif
|
134
|
+
else if (TH_ISCHR(t))
|
135
|
+
i = tar_extract_chardev(t, realname);
|
136
|
+
#ifndef _WIN32 // modified by SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
|
137
|
+
else if (TH_ISBLK(t))
|
138
|
+
i = tar_extract_blockdev(t, realname);
|
139
|
+
#endif
|
140
|
+
else if (TH_ISFIFO(t))
|
141
|
+
i = tar_extract_fifo(t, realname);
|
142
|
+
else /* if (TH_ISREG(t)) */
|
143
|
+
i = tar_extract_regfile(t, realname);
|
144
|
+
|
145
|
+
if (i != 0)
|
146
|
+
return i;
|
147
|
+
|
148
|
+
i = tar_set_file_perms(t, realname);
|
149
|
+
if (i != 0)
|
150
|
+
return i;
|
151
|
+
|
152
|
+
lnp = (linkname_t *)calloc(1, sizeof(linkname_t));
|
153
|
+
if (lnp == NULL)
|
154
|
+
return -1;
|
155
|
+
filename = th_get_pathname(t);
|
156
|
+
strlcpy(lnp->ln_save, filename, sizeof(lnp->ln_save));
|
157
|
+
free(filename);
|
158
|
+
strlcpy(lnp->ln_real, realname, sizeof(lnp->ln_real));
|
159
|
+
#ifdef DEBUG
|
160
|
+
filename = th_get_pathname(t);
|
161
|
+
printf("tar_extract_file(): calling libtar_hash_add(): key=\"%s\", "
|
162
|
+
"value=\"%s\"\n", filename, realname);
|
163
|
+
free(filename);
|
164
|
+
#endif
|
165
|
+
if (libtar_hash_add(t->h, lnp) != 0)
|
166
|
+
return -1;
|
167
|
+
|
168
|
+
return 0;
|
169
|
+
}
|
170
|
+
|
171
|
+
|
172
|
+
/* extract regular file */
|
173
|
+
int
|
174
|
+
tar_extract_regfile(TAR *t, char *realname)
|
175
|
+
{
|
176
|
+
mode_t mode;
|
177
|
+
size_t size;
|
178
|
+
uid_t uid;
|
179
|
+
gid_t gid;
|
180
|
+
int fdout;
|
181
|
+
int i, k;
|
182
|
+
char buf[T_BLOCKSIZE];
|
183
|
+
char *filename;
|
184
|
+
|
185
|
+
#ifdef DEBUG
|
186
|
+
printf("==> tar_extract_regfile(t=0x%lx, realname=\"%s\")\n", t,
|
187
|
+
realname);
|
188
|
+
#endif
|
189
|
+
|
190
|
+
if (!TH_ISREG(t))
|
191
|
+
{
|
192
|
+
errno = EINVAL;
|
193
|
+
return -1;
|
194
|
+
}
|
195
|
+
|
196
|
+
filename = (realname ? realname : th_get_pathname(t));
|
197
|
+
mode = th_get_mode(t);
|
198
|
+
size = th_get_size(t);
|
199
|
+
uid = th_get_uid(t);
|
200
|
+
gid = th_get_gid(t);
|
201
|
+
|
202
|
+
/* Make a copy of the string because dirname and mkdirhier may modify the
|
203
|
+
* string */
|
204
|
+
strncpy(buf, filename, sizeof(buf) - 1);
|
205
|
+
buf[sizeof(buf) - 1] = 0;
|
206
|
+
|
207
|
+
if (mkdirhier(dirname(filename)) == -1)
|
208
|
+
return -1;
|
209
|
+
|
210
|
+
#ifdef DEBUG
|
211
|
+
printf(" ==> extracting: %s (mode %04o, uid %d, gid %d, %d bytes)\n",
|
212
|
+
filename, mode, uid, gid, size);
|
213
|
+
#endif
|
214
|
+
fdout = open(filename, O_WRONLY | O_CREAT | O_TRUNC
|
215
|
+
#ifdef O_BINARY
|
216
|
+
| O_BINARY
|
217
|
+
#endif
|
218
|
+
, 0666);
|
219
|
+
if (fdout == -1)
|
220
|
+
{
|
221
|
+
#ifdef DEBUG
|
222
|
+
perror("open()");
|
223
|
+
#endif
|
224
|
+
if (!realname) free(filename);
|
225
|
+
return -1;
|
226
|
+
}
|
227
|
+
|
228
|
+
#if 0
|
229
|
+
/* change the owner. (will only work if run as root) */
|
230
|
+
if (fchown(fdout, uid, gid) == -1 && errno != EPERM)
|
231
|
+
{
|
232
|
+
#ifdef DEBUG
|
233
|
+
perror("fchown()");
|
234
|
+
#endif
|
235
|
+
return -1;
|
236
|
+
}
|
237
|
+
|
238
|
+
/* make sure the mode isn't inheritted from a file we're overwriting */
|
239
|
+
if (fchmod(fdout, mode & 07777) == -1)
|
240
|
+
{
|
241
|
+
#ifdef DEBUG
|
242
|
+
perror("fchmod()");
|
243
|
+
#endif
|
244
|
+
return -1;
|
245
|
+
}
|
246
|
+
#endif
|
247
|
+
|
248
|
+
/* extract the file */
|
249
|
+
for (i = size; i > 0; i -= T_BLOCKSIZE)
|
250
|
+
{
|
251
|
+
k = tar_block_read(t, buf);
|
252
|
+
if (k != T_BLOCKSIZE)
|
253
|
+
{
|
254
|
+
if (k != -1)
|
255
|
+
errno = EINVAL;
|
256
|
+
if (!realname) free(filename);
|
257
|
+
return -1;
|
258
|
+
}
|
259
|
+
|
260
|
+
/* write block to output file */
|
261
|
+
if (write(fdout, buf,
|
262
|
+
((i > T_BLOCKSIZE) ? T_BLOCKSIZE : i)) == -1){
|
263
|
+
if (!realname) free(filename);
|
264
|
+
return -1;
|
265
|
+
}
|
266
|
+
}
|
267
|
+
|
268
|
+
/* close output file */
|
269
|
+
if (close(fdout) == -1){
|
270
|
+
if (!realname) free(filename);
|
271
|
+
return -1;
|
272
|
+
}
|
273
|
+
|
274
|
+
#ifdef DEBUG
|
275
|
+
printf("### done extracting %s\n", filename);
|
276
|
+
#endif
|
277
|
+
|
278
|
+
if (!realname) free(filename);
|
279
|
+
return 0;
|
280
|
+
}
|
281
|
+
|
282
|
+
// modified by SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
|
283
|
+
int tar_extract_function(TAR *t, void *data, int (*f)(char *b, int l, void *d)) {
|
284
|
+
size_t size;
|
285
|
+
int i, k;
|
286
|
+
char buf[T_BLOCKSIZE];
|
287
|
+
|
288
|
+
if (!TH_ISREG(t)) {
|
289
|
+
return 1;
|
290
|
+
}
|
291
|
+
|
292
|
+
size = th_get_size(t);
|
293
|
+
|
294
|
+
for (i = size; i > 0; i -= T_BLOCKSIZE) {
|
295
|
+
k = tar_block_read(t, buf);
|
296
|
+
|
297
|
+
if (k != T_BLOCKSIZE) {
|
298
|
+
if (k != -1) { errno = EINVAL; }
|
299
|
+
return -1;
|
300
|
+
}
|
301
|
+
|
302
|
+
if (f(buf, ((i > T_BLOCKSIZE) ? T_BLOCKSIZE : i), data) == -1) {
|
303
|
+
return -1;
|
304
|
+
}
|
305
|
+
}
|
306
|
+
|
307
|
+
return 0;
|
308
|
+
}
|
309
|
+
|
310
|
+
/* skip regfile */
|
311
|
+
int
|
312
|
+
tar_skip_regfile(TAR *t)
|
313
|
+
{
|
314
|
+
int i, k;
|
315
|
+
size_t size;
|
316
|
+
char buf[T_BLOCKSIZE];
|
317
|
+
|
318
|
+
if (!TH_ISREG(t))
|
319
|
+
{
|
320
|
+
errno = EINVAL;
|
321
|
+
return -1;
|
322
|
+
}
|
323
|
+
|
324
|
+
size = th_get_size(t);
|
325
|
+
for (i = size; i > 0; i -= T_BLOCKSIZE)
|
326
|
+
{
|
327
|
+
k = tar_block_read(t, buf);
|
328
|
+
if (k != T_BLOCKSIZE)
|
329
|
+
{
|
330
|
+
if (k != -1)
|
331
|
+
errno = EINVAL;
|
332
|
+
return -1;
|
333
|
+
}
|
334
|
+
}
|
335
|
+
|
336
|
+
return 0;
|
337
|
+
}
|
338
|
+
|
339
|
+
|
340
|
+
/* hardlink */
|
341
|
+
int
|
342
|
+
tar_extract_hardlink(TAR * t, char *realname)
|
343
|
+
{
|
344
|
+
#ifndef _WIN32 // modified by SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
|
345
|
+
char *filename;
|
346
|
+
char *linktgt = NULL;
|
347
|
+
linkname_t *lnp;
|
348
|
+
libtar_hashptr_t hp;
|
349
|
+
char buf[T_BLOCKSIZE];
|
350
|
+
|
351
|
+
if (!TH_ISLNK(t))
|
352
|
+
{
|
353
|
+
errno = EINVAL;
|
354
|
+
return -1;
|
355
|
+
}
|
356
|
+
|
357
|
+
filename = (realname ? realname : th_get_pathname(t));
|
358
|
+
|
359
|
+
/* Make a copy of the string because dirname and mkdirhier may modify the
|
360
|
+
* string */
|
361
|
+
strncpy(buf, filename, sizeof(buf) - 1);
|
362
|
+
buf[sizeof(buf) - 1] = 0;
|
363
|
+
|
364
|
+
if (mkdirhier(dirname(filename)) == -1){
|
365
|
+
if (!realname) free(filename);
|
366
|
+
return -1;
|
367
|
+
}
|
368
|
+
libtar_hashptr_reset(&hp);
|
369
|
+
if (libtar_hash_getkey(t->h, &hp, th_get_linkname(t),
|
370
|
+
(libtar_matchfunc_t)libtar_str_match) != 0)
|
371
|
+
{
|
372
|
+
lnp = (linkname_t *)libtar_hashptr_data(&hp);
|
373
|
+
linktgt = lnp->ln_real;
|
374
|
+
}
|
375
|
+
else
|
376
|
+
linktgt = th_get_linkname(t);
|
377
|
+
|
378
|
+
#ifdef DEBUG
|
379
|
+
printf(" ==> extracting: %s (link to %s)\n", filename, linktgt);
|
380
|
+
#endif
|
381
|
+
if (link(linktgt, filename) == -1)
|
382
|
+
{
|
383
|
+
#ifdef DEBUG
|
384
|
+
perror("link()");
|
385
|
+
#endif
|
386
|
+
if (!realname) free(filename);
|
387
|
+
return -1;
|
388
|
+
}
|
389
|
+
|
390
|
+
if (!realname) free(filename);
|
391
|
+
#endif
|
392
|
+
return 0;
|
393
|
+
}
|
394
|
+
|
395
|
+
|
396
|
+
/* symlink */
|
397
|
+
int
|
398
|
+
tar_extract_symlink(TAR *t, char *realname)
|
399
|
+
{
|
400
|
+
#ifndef _WIN32 // modified by SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
|
401
|
+
char *filename;
|
402
|
+
char buf[T_BLOCKSIZE];
|
403
|
+
|
404
|
+
if (!TH_ISSYM(t))
|
405
|
+
{
|
406
|
+
errno = EINVAL;
|
407
|
+
return -1;
|
408
|
+
}
|
409
|
+
|
410
|
+
filename = (realname ? realname : th_get_pathname(t));
|
411
|
+
|
412
|
+
/* Make a copy of the string because dirname and mkdirhier may modify the
|
413
|
+
* string */
|
414
|
+
strncpy(buf, filename, sizeof(buf) - 1);
|
415
|
+
buf[sizeof(buf) - 1] = 0;
|
416
|
+
|
417
|
+
if (mkdirhier(dirname(filename)) == -1){
|
418
|
+
if (!realname) free(filename);
|
419
|
+
return -1;
|
420
|
+
}
|
421
|
+
|
422
|
+
if (unlink(filename) == -1 && errno != ENOENT){
|
423
|
+
if (!realname) free(filename);
|
424
|
+
return -1;
|
425
|
+
}
|
426
|
+
|
427
|
+
#ifdef DEBUG
|
428
|
+
printf(" ==> extracting: %s (symlink to %s)\n",
|
429
|
+
filename, th_get_linkname(t));
|
430
|
+
#endif
|
431
|
+
if (symlink(th_get_linkname(t), filename) == -1)
|
432
|
+
{
|
433
|
+
#ifdef DEBUG
|
434
|
+
perror("symlink()");
|
435
|
+
#endif
|
436
|
+
if (!realname) free(filename);
|
437
|
+
return -1;
|
438
|
+
}
|
439
|
+
|
440
|
+
if (!realname) free(filename);
|
441
|
+
#endif
|
442
|
+
return 0;
|
443
|
+
}
|
444
|
+
|
445
|
+
|
446
|
+
/* character device */
|
447
|
+
int
|
448
|
+
tar_extract_chardev(TAR *t, char *realname)
|
449
|
+
{
|
450
|
+
mode_t mode;
|
451
|
+
unsigned long devmaj, devmin;
|
452
|
+
char *filename;
|
453
|
+
char buf[T_BLOCKSIZE];
|
454
|
+
|
455
|
+
if (!TH_ISCHR(t))
|
456
|
+
{
|
457
|
+
errno = EINVAL;
|
458
|
+
return -1;
|
459
|
+
}
|
460
|
+
|
461
|
+
filename = (realname ? realname : th_get_pathname(t));
|
462
|
+
mode = th_get_mode(t);
|
463
|
+
devmaj = th_get_devmajor(t);
|
464
|
+
devmin = th_get_devminor(t);
|
465
|
+
|
466
|
+
/* Make a copy of the string because dirname and mkdirhier may modify the
|
467
|
+
* string */
|
468
|
+
strncpy(buf, filename, sizeof(buf) - 1);
|
469
|
+
buf[sizeof(buf) - 1] = 0;
|
470
|
+
|
471
|
+
if (mkdirhier(dirname(filename)) == -1){
|
472
|
+
if (!realname) free(filename);
|
473
|
+
return -1;
|
474
|
+
}
|
475
|
+
|
476
|
+
#ifdef DEBUG
|
477
|
+
printf(" ==> extracting: %s (character device %ld,%ld)\n",
|
478
|
+
filename, devmaj, devmin);
|
479
|
+
#endif
|
480
|
+
if (mknod(filename, mode | S_IFCHR,
|
481
|
+
compat_makedev(devmaj, devmin)) == -1)
|
482
|
+
{
|
483
|
+
#ifdef DEBUG
|
484
|
+
perror("mknod()");
|
485
|
+
#endif
|
486
|
+
if (!realname) free(filename);
|
487
|
+
return -1;
|
488
|
+
}
|
489
|
+
|
490
|
+
if (!realname) free(filename);
|
491
|
+
return 0;
|
492
|
+
}
|
493
|
+
|
494
|
+
|
495
|
+
/* block device */
|
496
|
+
int
|
497
|
+
tar_extract_blockdev(TAR *t, char *realname)
|
498
|
+
{
|
499
|
+
#ifndef _WIN32 // modified by SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
|
500
|
+
mode_t mode;
|
501
|
+
unsigned long devmaj, devmin;
|
502
|
+
char *filename;
|
503
|
+
char buf[T_BLOCKSIZE];
|
504
|
+
|
505
|
+
if (!TH_ISBLK(t))
|
506
|
+
{
|
507
|
+
errno = EINVAL;
|
508
|
+
return -1;
|
509
|
+
}
|
510
|
+
|
511
|
+
filename = (realname ? realname : th_get_pathname(t));
|
512
|
+
mode = th_get_mode(t);
|
513
|
+
devmaj = th_get_devmajor(t);
|
514
|
+
devmin = th_get_devminor(t);
|
515
|
+
|
516
|
+
/* Make a copy of the string because dirname and mkdirhier may modify the
|
517
|
+
* string */
|
518
|
+
strncpy(buf, filename, sizeof(buf) - 1);
|
519
|
+
buf[sizeof(buf) - 1] = 0;
|
520
|
+
|
521
|
+
if (mkdirhier(dirname(filename)) == -1){
|
522
|
+
if (!realname) free(filename);
|
523
|
+
return -1;
|
524
|
+
}
|
525
|
+
|
526
|
+
#ifdef DEBUG
|
527
|
+
printf(" ==> extracting: %s (block device %ld,%ld)\n",
|
528
|
+
filename, devmaj, devmin);
|
529
|
+
#endif
|
530
|
+
if (mknod(filename, mode | S_IFBLK,
|
531
|
+
compat_makedev(devmaj, devmin)) == -1)
|
532
|
+
{
|
533
|
+
#ifdef DEBUG
|
534
|
+
perror("mknod()");
|
535
|
+
#endif
|
536
|
+
if (!realname) free(filename);
|
537
|
+
return -1;
|
538
|
+
}
|
539
|
+
|
540
|
+
if (!realname) free(filename);
|
541
|
+
#endif
|
542
|
+
return 0;
|
543
|
+
}
|
544
|
+
|
545
|
+
|
546
|
+
/* directory */
|
547
|
+
int
|
548
|
+
tar_extract_dir(TAR *t, char *realname)
|
549
|
+
{
|
550
|
+
mode_t mode;
|
551
|
+
char *filename;
|
552
|
+
char buf[T_BLOCKSIZE];
|
553
|
+
|
554
|
+
if (!TH_ISDIR(t))
|
555
|
+
{
|
556
|
+
errno = EINVAL;
|
557
|
+
return -1;
|
558
|
+
}
|
559
|
+
|
560
|
+
filename = (realname ? realname : th_get_pathname(t));
|
561
|
+
mode = th_get_mode(t);
|
562
|
+
|
563
|
+
/* Make a copy of the string because dirname and mkdirhier may modify the
|
564
|
+
* string */
|
565
|
+
strncpy(buf, filename, sizeof(buf) - 1);
|
566
|
+
buf[sizeof(buf) - 1] = 0;
|
567
|
+
|
568
|
+
if (mkdirhier(dirname(filename)) == -1){
|
569
|
+
if (!realname) free(filename);
|
570
|
+
return -1;
|
571
|
+
}
|
572
|
+
|
573
|
+
#ifdef DEBUG
|
574
|
+
printf(" ==> extracting: %s (mode %04o, directory)\n", filename,
|
575
|
+
mode);
|
576
|
+
#endif
|
577
|
+
if (mkdir(filename, mode) == -1)
|
578
|
+
{
|
579
|
+
if (errno == EEXIST)
|
580
|
+
{
|
581
|
+
if (chmod(filename, mode) == -1)
|
582
|
+
{
|
583
|
+
#ifdef DEBUG
|
584
|
+
perror("chmod()");
|
585
|
+
#endif
|
586
|
+
if (!realname) free(filename);
|
587
|
+
return -1;
|
588
|
+
}
|
589
|
+
else
|
590
|
+
{
|
591
|
+
#ifdef DEBUG
|
592
|
+
puts(" *** using existing directory");
|
593
|
+
#endif
|
594
|
+
if (!realname) free(filename);
|
595
|
+
return 1;
|
596
|
+
}
|
597
|
+
}
|
598
|
+
else
|
599
|
+
{
|
600
|
+
#ifdef DEBUG
|
601
|
+
perror("mkdir()");
|
602
|
+
#endif
|
603
|
+
if (!realname) free(filename);
|
604
|
+
return -1;
|
605
|
+
}
|
606
|
+
}
|
607
|
+
|
608
|
+
if (!realname) free(filename);
|
609
|
+
return 0;
|
610
|
+
}
|
611
|
+
|
612
|
+
|
613
|
+
/* FIFO */
|
614
|
+
int
|
615
|
+
tar_extract_fifo(TAR *t, char *realname)
|
616
|
+
{
|
617
|
+
mode_t mode;
|
618
|
+
char *filename;
|
619
|
+
char buf[T_BLOCKSIZE];
|
620
|
+
|
621
|
+
if (!TH_ISFIFO(t))
|
622
|
+
{
|
623
|
+
errno = EINVAL;
|
624
|
+
return -1;
|
625
|
+
}
|
626
|
+
|
627
|
+
filename = (realname ? realname : th_get_pathname(t));
|
628
|
+
mode = th_get_mode(t);
|
629
|
+
|
630
|
+
/* Make a copy of the string because dirname and mkdirhier may modify the
|
631
|
+
* string */
|
632
|
+
strncpy(buf, filename, sizeof(buf) - 1);
|
633
|
+
buf[sizeof(buf) - 1] = 0;
|
634
|
+
|
635
|
+
if (mkdirhier(dirname(filename)) == -1){
|
636
|
+
if (!realname) free(filename);
|
637
|
+
return -1;
|
638
|
+
}
|
639
|
+
|
640
|
+
#ifdef DEBUG
|
641
|
+
printf(" ==> extracting: %s (fifo)\n", filename);
|
642
|
+
#endif
|
643
|
+
if (mkfifo(filename, mode) == -1)
|
644
|
+
{
|
645
|
+
#ifdef DEBUG
|
646
|
+
perror("mkfifo()");
|
647
|
+
#endif
|
648
|
+
if (!realname) free(filename);
|
649
|
+
return -1;
|
650
|
+
}
|
651
|
+
|
652
|
+
if (!realname) free(filename);
|
653
|
+
return 0;
|
654
|
+
}
|
655
|
+
|
656
|
+
|