aboutsummaryrefslogtreecommitdiff
path: root/tar.c
diff options
context:
space:
mode:
Diffstat (limited to 'tar.c')
-rw-r--r--tar.c41
1 files changed, 32 insertions, 9 deletions
diff --git a/tar.c b/tar.c
index ed6f3b6b5..5478af86e 100644
--- a/tar.c
+++ b/tar.c
@@ -10,6 +10,9 @@
10 * Modified for busybox by Erik Andersen <andersee@debian.org> 10 * Modified for busybox by Erik Andersen <andersee@debian.org>
11 * Adjusted to grok stdin/stdout options. 11 * Adjusted to grok stdin/stdout options.
12 * 12 *
13 * Modified to handle device special files by Matt Porter
14 * <porter@debian.org>
15 *
13 * This program is free software; you can redistribute it and/or modify 16 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by 17 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or 18 * the Free Software Foundation; either version 2 of the License, or
@@ -34,6 +37,7 @@
34#include <fcntl.h> 37#include <fcntl.h>
35#include <signal.h> 38#include <signal.h>
36#include <time.h> 39#include <time.h>
40#include <sys/types.h>
37 41
38 42
39static const char tar_usage[] = 43static const char tar_usage[] =
@@ -377,12 +381,15 @@ readHeader (const TarHeader * hp, int fileCount, char **fileTable)
377 int uid; 381 int uid;
378 int gid; 382 int gid;
379 int checkSum; 383 int checkSum;
384 int major;
385 int minor;
380 long size; 386 long size;
381 time_t mtime; 387 time_t mtime;
382 const char *name; 388 const char *name;
383 int cc; 389 int cc;
384 int hardLink; 390 int hardLink;
385 int softLink; 391 int softLink;
392 int devFileFlag;
386 393
387 /* 394 /*
388 * If the block is completely empty, then this is the end of the 395 * If the block is completely empty, then this is the end of the
@@ -411,6 +418,8 @@ readHeader (const TarHeader * hp, int fileCount, char **fileTable)
411 size = getOctal (hp->size, sizeof (hp->size)); 418 size = getOctal (hp->size, sizeof (hp->size));
412 mtime = getOctal (hp->mtime, sizeof (hp->mtime)); 419 mtime = getOctal (hp->mtime, sizeof (hp->mtime));
413 checkSum = getOctal (hp->checkSum, sizeof (hp->checkSum)); 420 checkSum = getOctal (hp->checkSum, sizeof (hp->checkSum));
421 major = getOctal (hp->devMajor, sizeof (hp->devMajor));
422 minor = getOctal (hp->devMinor, sizeof (hp->devMinor));
414 423
415 if ((mode < 0) || (uid < 0) || (gid < 0) || (size < 0)) { 424 if ((mode < 0) || (uid < 0) || (gid < 0) || (size < 0)) {
416 if (badHeader==FALSE) 425 if (badHeader==FALSE)
@@ -423,6 +432,7 @@ readHeader (const TarHeader * hp, int fileCount, char **fileTable)
423 432
424 badHeader = FALSE; 433 badHeader = FALSE;
425 skipFileFlag = FALSE; 434 skipFileFlag = FALSE;
435 devFileFlag = FALSE;
426 436
427 /* 437 /*
428 * Check for the file modes. 438 * Check for the file modes.
@@ -434,12 +444,10 @@ readHeader (const TarHeader * hp, int fileCount, char **fileTable)
434 (hp->typeFlag == TAR_TYPE_SOFT_LINK - '0')); 444 (hp->typeFlag == TAR_TYPE_SOFT_LINK - '0'));
435 445
436 /* 446 /*
437 * Check for a directory or a regular file. 447 * Check for a directory.
438 */ 448 */
439 if (name[strlen (name) - 1] == '/') 449 if (name[strlen (name) - 1] == '/')
440 mode |= S_IFDIR; 450 mode |= S_IFDIR;
441 else if ((mode & S_IFMT) == 0)
442 mode |= S_IFREG;
443 451
444 /* 452 /*
445 * Check for absolute paths in the file. 453 * Check for absolute paths in the file.
@@ -462,7 +470,8 @@ readHeader (const TarHeader * hp, int fileCount, char **fileTable)
462 * If not, then set up to skip it. 470 * If not, then set up to skip it.
463 */ 471 */
464 if (wantFileName (name, fileCount, fileTable) == FALSE) { 472 if (wantFileName (name, fileCount, fileTable) == FALSE) {
465 if (!hardLink && !softLink && S_ISREG (mode)) { 473 if ( !hardLink && !softLink && (S_ISREG (mode) || S_ISCHR (mode)
474 || S_ISBLK (mode) || S_ISSOCK(mode) || S_ISFIFO(mode) ) ) {
466 inHeader = (size == 0)? TRUE : FALSE; 475 inHeader = (size == 0)? TRUE : FALSE;
467 dataCc = size; 476 dataCc = size;
468 } 477 }
@@ -487,7 +496,8 @@ readHeader (const TarHeader * hp, int fileCount, char **fileTable)
487 printf (" (link to \"%s\")", hp->linkName); 496 printf (" (link to \"%s\")", hp->linkName);
488 else if (softLink) 497 else if (softLink)
489 printf (" (symlink to \"%s\")", hp->linkName); 498 printf (" (symlink to \"%s\")", hp->linkName);
490 else if (S_ISREG (mode)) { 499 else if (S_ISREG (mode) || S_ISCHR (mode) || S_ISBLK (mode) ||
500 S_ISSOCK(mode) || S_ISFIFO(mode) ) {
491 inHeader = (size == 0)? TRUE : FALSE; 501 inHeader = (size == 0)? TRUE : FALSE;
492 dataCc = size; 502 dataCc = size;
493 } 503 }
@@ -543,8 +553,17 @@ readHeader (const TarHeader * hp, int fileCount, char **fileTable)
543 */ 553 */
544 if (tostdoutFlag == TRUE) 554 if (tostdoutFlag == TRUE)
545 outFd = STDOUT; 555 outFd = STDOUT;
546 else 556 else {
547 outFd = open (name, O_WRONLY | O_CREAT | O_TRUNC, mode); 557 if ( S_ISCHR(mode) || S_ISBLK(mode) || S_ISSOCK(mode) ) {
558 devFileFlag = TRUE;
559 outFd = mknod (name, mode, makedev(major, minor) );
560 }
561 else if (S_ISFIFO(mode) ) {
562 outFd = mkfifo(name, mode);
563 } else {
564 outFd = open (name, O_WRONLY | O_CREAT | O_TRUNC, mode);
565 }
566 }
548 567
549 if (outFd < 0) { 568 if (outFd < 0) {
550 perror (name); 569 perror (name);
@@ -555,7 +574,7 @@ readHeader (const TarHeader * hp, int fileCount, char **fileTable)
555 /* 574 /*
556 * If the file is empty, then that's all we need to do. 575 * If the file is empty, then that's all we need to do.
557 */ 576 */
558 if (size == 0 && tostdoutFlag == FALSE) { 577 if (size == 0 && (tostdoutFlag == FALSE) && (devFileFlag == FALSE)) {
559 (void) close (outFd); 578 (void) close (outFd);
560 outFd = -1; 579 outFd = -1;
561 } 580 }
@@ -735,12 +754,16 @@ static void saveFile (const char *fileName, int seeLinks)
735 754
736 return; 755 return;
737 } 756 }
738
739 if (S_ISREG (mode)) { 757 if (S_ISREG (mode)) {
740 saveRegularFile (fileName, &statbuf); 758 saveRegularFile (fileName, &statbuf);
741 759
742 return; 760 return;
743 } 761 }
762
763 /* Some day add support for tarring these up... but not today. :) */
764// if (S_ISLNK(mode) || S_ISFIFO(mode) || S_ISBLK(mode) || S_ISCHR (mode) ) {
765// fprintf (stderr, "%s: This version of tar can't store this type of file\n", fileName);
766// }
744 767
745 /* 768 /*
746 * The file is a strange type of file, ignore it. 769 * The file is a strange type of file, ignore it.