tarruby 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. data/README.txt +99 -0
  2. data/ext/extconf.rb +19 -0
  3. data/ext/libtar/COPYRIGHT +35 -0
  4. data/ext/libtar/ChangeLog +243 -0
  5. data/ext/libtar/ChangeLog-1.0.x +141 -0
  6. data/ext/libtar/INSTALL +183 -0
  7. data/ext/libtar/Makefile.in +51 -0
  8. data/ext/libtar/README +121 -0
  9. data/ext/libtar/TODO +10 -0
  10. data/ext/libtar/autoconf/ac_path_generic.m4 +136 -0
  11. data/ext/libtar/autoconf/aclocal.m4 +199 -0
  12. data/ext/libtar/autoconf/encap.m4 +133 -0
  13. data/ext/libtar/autoconf/install-sh +251 -0
  14. data/ext/libtar/autom4te.cache/output.0 +8102 -0
  15. data/ext/libtar/autom4te.cache/requests +112 -0
  16. data/ext/libtar/autom4te.cache/traces.0 +382 -0
  17. data/ext/libtar/compat/ChangeLog +31 -0
  18. data/ext/libtar/compat/README +12 -0
  19. data/ext/libtar/compat/TODO +4 -0
  20. data/ext/libtar/compat/basename.c +91 -0
  21. data/ext/libtar/compat/compat.h +260 -0
  22. data/ext/libtar/compat/dirname.c +96 -0
  23. data/ext/libtar/compat/fnmatch.c +237 -0
  24. data/ext/libtar/compat/gethostbyname_r.c +41 -0
  25. data/ext/libtar/compat/gethostname.c +36 -0
  26. data/ext/libtar/compat/getservbyname_r.c +41 -0
  27. data/ext/libtar/compat/glob.c +898 -0
  28. data/ext/libtar/compat/inet_aton.c +27 -0
  29. data/ext/libtar/compat/module.ac +591 -0
  30. data/ext/libtar/compat/snprintf.c +788 -0
  31. data/ext/libtar/compat/strdup.c +62 -0
  32. data/ext/libtar/compat/strlcat.c +72 -0
  33. data/ext/libtar/compat/strlcpy.c +68 -0
  34. data/ext/libtar/compat/strmode.c +199 -0
  35. data/ext/libtar/compat/strrstr.c +40 -0
  36. data/ext/libtar/compat/strsep.c +87 -0
  37. data/ext/libtar/config.h.in +187 -0
  38. data/ext/libtar/configure +8102 -0
  39. data/ext/libtar/configure.ac +114 -0
  40. data/ext/libtar/doc/Makefile.in +152 -0
  41. data/ext/libtar/doc/tar_append_file.3 +50 -0
  42. data/ext/libtar/doc/tar_block_read.3 +24 -0
  43. data/ext/libtar/doc/tar_extract_all.3 +43 -0
  44. data/ext/libtar/doc/tar_extract_file.3 +84 -0
  45. data/ext/libtar/doc/tar_open.3 +97 -0
  46. data/ext/libtar/doc/th_get_pathname.3 +63 -0
  47. data/ext/libtar/doc/th_print_long_ls.3 +22 -0
  48. data/ext/libtar/doc/th_read.3 +34 -0
  49. data/ext/libtar/doc/th_set_from_stat.3 +45 -0
  50. data/ext/libtar/lib/Makefile.in +92 -0
  51. data/ext/libtar/lib/append.c +272 -0
  52. data/ext/libtar/lib/block.c +384 -0
  53. data/ext/libtar/lib/decode.c +130 -0
  54. data/ext/libtar/lib/encode.c +237 -0
  55. data/ext/libtar/lib/extract.c +656 -0
  56. data/ext/libtar/lib/handle.c +150 -0
  57. data/ext/libtar/lib/internal.h +46 -0
  58. data/ext/libtar/lib/libtar.h +311 -0
  59. data/ext/libtar/lib/output.c +146 -0
  60. data/ext/libtar/lib/util.c +153 -0
  61. data/ext/libtar/lib/wrapper.c +175 -0
  62. data/ext/libtar/libtar/Makefile.in +73 -0
  63. data/ext/libtar/libtar/libtar.c +363 -0
  64. data/ext/libtar/listhash/ChangeLog +15 -0
  65. data/ext/libtar/listhash/TODO +21 -0
  66. data/ext/libtar/listhash/hash.c.in +344 -0
  67. data/ext/libtar/listhash/hash_new.3.in +74 -0
  68. data/ext/libtar/listhash/list.c.in +458 -0
  69. data/ext/libtar/listhash/list_new.3.in +86 -0
  70. data/ext/libtar/listhash/listhash.h.in +196 -0
  71. data/ext/libtar/listhash/module.ac +21 -0
  72. data/ext/libtar/win32/config.h +190 -0
  73. data/ext/libtar/win32/dirent.c +115 -0
  74. data/ext/libtar/win32/dirent.h +24 -0
  75. data/ext/libtar/win32/grp.h +4 -0
  76. data/ext/libtar/win32/listhash/libtar_hash.c +344 -0
  77. data/ext/libtar/win32/listhash/libtar_list.c +458 -0
  78. data/ext/libtar/win32/listhash/libtar_listhash.h +196 -0
  79. data/ext/libtar/win32/pwd.h +4 -0
  80. data/ext/libtar/win32/sys/param.h +8 -0
  81. data/ext/libtar/win32/tar.h +35 -0
  82. data/ext/libtar/win32/utime.h +6 -0
  83. data/ext/libtar/win32/win32/types.h +10 -0
  84. data/ext/tarruby.c +648 -0
  85. 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
+