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.
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
+