diff options
Diffstat (limited to 'tar.c')
-rw-r--r-- | tar.c | 41 |
1 files changed, 32 insertions, 9 deletions
@@ -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 | ||
39 | static const char tar_usage[] = | 43 | static 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. |