diff options
Diffstat (limited to 'tar.c')
-rw-r--r-- | tar.c | 86 |
1 files changed, 74 insertions, 12 deletions
@@ -228,6 +228,7 @@ extern int tar_main(int argc, char **argv) | |||
228 | 228 | ||
229 | case 'O': | 229 | case 'O': |
230 | tostdoutFlag = TRUE; | 230 | tostdoutFlag = TRUE; |
231 | tarName = "-"; | ||
231 | break; | 232 | break; |
232 | 233 | ||
233 | case '-': | 234 | case '-': |
@@ -439,7 +440,7 @@ static long getOctal(const char *cp, int size) | |||
439 | 440 | ||
440 | /* Parse the tar header and fill in the nice struct with the details */ | 441 | /* Parse the tar header and fill in the nice struct with the details */ |
441 | static int | 442 | static int |
442 | parseTarHeader(struct TarHeader *rawHeader, struct TarInfo *header) | 443 | readTarHeader(struct TarHeader *rawHeader, struct TarInfo *header) |
443 | { | 444 | { |
444 | int i; | 445 | int i; |
445 | long chksum, sum; | 446 | long chksum, sum; |
@@ -502,7 +503,7 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag, | |||
502 | while ( (status = fullRead(tarFd, (char*)&rawHeader, TAR_BLOCK_SIZE)) == TAR_BLOCK_SIZE ) { | 503 | while ( (status = fullRead(tarFd, (char*)&rawHeader, TAR_BLOCK_SIZE)) == TAR_BLOCK_SIZE ) { |
503 | 504 | ||
504 | /* First, try to read the header */ | 505 | /* First, try to read the header */ |
505 | if ( parseTarHeader(&rawHeader, &header) == FALSE ) { | 506 | if ( readTarHeader(&rawHeader, &header) == FALSE ) { |
506 | close( tarFd); | 507 | close( tarFd); |
507 | if ( *(header.name) == '\0' ) { | 508 | if ( *(header.name) == '\0' ) { |
508 | goto endgame; | 509 | goto endgame; |
@@ -661,25 +662,80 @@ static int putOctal (char *cp, int len, long value) | |||
661 | return TRUE; | 662 | return TRUE; |
662 | } | 663 | } |
663 | 664 | ||
664 | static int fileAction(const char *fileName, struct stat *statbuf) | 665 | /* Write out a tar header for the specified file */ |
666 | static int | ||
667 | writeTarHeader(struct TarHeader *rawHeader, struct TarInfo *header) | ||
665 | { | 668 | { |
666 | fprintf(stdout, "%s\n", fileName); | 669 | int i; |
670 | long chksum, sum; | ||
671 | unsigned char *s = (unsigned char *)rawHeader; | ||
672 | |||
673 | struct TarHeader header; | ||
674 | |||
675 | strcpy(header.name, fileName); | ||
676 | putOctal(header.mode, sizeof(header.mode), statbuf->st_mode & 0777); | ||
677 | putOctal(header.uid, sizeof(header.uid), statbuf->st_uid); | ||
678 | putOctal(header.gid, sizeof(header.gid), statbuf->st_gid); | ||
679 | putOctal(header.size, sizeof(header.size), statbuf->st_size); | ||
680 | putOctal(header.mtime, sizeof(header.mtime), statbuf->st_mtime); | ||
681 | |||
682 | if (S_ISLNK(statbuf.st_mode)) { | ||
683 | header.type = LNKTYPE; | ||
684 | // Handle SYMTYPE | ||
685 | } else if (S_ISDIR(statbuf.st_mode)) { | ||
686 | header.type = DIRTYPE; | ||
687 | } else if (S_ISCHR(statbuf.st_mode)) { | ||
688 | header.type = CHRTYPE; | ||
689 | } else if (S_ISBLK(statbuf.st_mode)) { | ||
690 | header.type = BLKTYPE; | ||
691 | } else if (S_ISFIFO(statbuf.st_mode)) { | ||
692 | header.type = FIFOTYPE; | ||
693 | } else if (S_ISSOCK(statbuf.st_mode)) { | ||
694 | header.type = S_ISSOCK; | ||
695 | } else if (S_ISLNK(statbuf.st_mode)) { | ||
696 | header.type = LNKTYPE; | ||
697 | } else if (S_ISLNK(statbuf.st_mode)) { | ||
698 | header.type = REGTYPE; | ||
699 | } | ||
700 | #if 0 | ||
701 | header->linkname = rawHeader->linkname; | ||
702 | header->devmajor = getOctal(rawHeader->devmajor, sizeof(rawHeader->devmajor)); | ||
703 | header->devminor = getOctal(rawHeader->devminor, sizeof(rawHeader->devminor)); | ||
704 | |||
705 | /* Write out the checksum */ | ||
706 | chksum = getOctal(rawHeader->chksum, sizeof(rawHeader->chksum)); | ||
707 | #endif | ||
708 | |||
709 | return ( TRUE); | ||
710 | } | ||
711 | |||
712 | |||
713 | static int fileAction(const char *fileName, struct stat *statbuf, void* userData) | ||
714 | { | ||
715 | int *tarFd=(int*)userData; | ||
716 | dprintf(*tarFd, "%s\n", fileName); | ||
667 | return (TRUE); | 717 | return (TRUE); |
668 | } | 718 | } |
669 | 719 | ||
670 | static int writeTarFile(const char* tarName, int extractFlag, int listFlag, | 720 | static int writeTarFile(const char* tarName, int extractFlag, int listFlag, |
671 | int tostdoutFlag, int verboseFlag, int argc, char **argv) | 721 | int tostdoutFlag, int verboseFlag, int argc, char **argv) |
672 | { | 722 | { |
673 | int tarFd=0; | 723 | int tarFd=-1; |
674 | //int errorFlag=FALSE; | 724 | //int errorFlag=FALSE; |
675 | //TarHeader rawHeader; | 725 | //TarHeader rawHeader; |
676 | //TarInfo header; | 726 | //TarInfo header; |
677 | //int alreadyWarned=FALSE; | 727 | //int alreadyWarned=FALSE; |
678 | char *directory = "."; | ||
679 | //int skipFileFlag=FALSE; | 728 | //int skipFileFlag=FALSE; |
729 | struct stat tarballStat; | ||
730 | dev_t tarDev = 0; | ||
731 | ino_t tarInode = 0; | ||
732 | |||
733 | /* Make sure there is at least one file to tar up. */ | ||
734 | if (argc <= 0) | ||
735 | fatalError("tar: Cowardly refusing to create an empty archive\n"); | ||
680 | 736 | ||
681 | /* Open the tar file for writing. */ | 737 | /* Open the tar file for writing. */ |
682 | if (!strcmp(tarName, "-")) | 738 | if (tostdoutFlag == TRUE) |
683 | tarFd = fileno(stdout); | 739 | tarFd = fileno(stdout); |
684 | else | 740 | else |
685 | tarFd = open (tarName, O_WRONLY | O_CREAT | O_TRUNC, 0644); | 741 | tarFd = open (tarName, O_WRONLY | O_CREAT | O_TRUNC, 0644); |
@@ -687,19 +743,25 @@ static int writeTarFile(const char* tarName, int extractFlag, int listFlag, | |||
687 | errorMsg( "Error opening '%s': %s\n", tarName, strerror(errno)); | 743 | errorMsg( "Error opening '%s': %s\n", tarName, strerror(errno)); |
688 | return ( FALSE); | 744 | return ( FALSE); |
689 | } | 745 | } |
746 | /* Store the device and inode of the tarball, so we can be sure | ||
747 | * not to try and include it into itself.... */ | ||
748 | if (fstat(tarFd, &tarballStat) < 0) | ||
749 | fatalError(io_error, tarName, strerror(errno)); | ||
750 | tarDev = tarballStat.st_dev; | ||
751 | tarInode = tarballStat.st_ino; | ||
690 | 752 | ||
691 | /* Set the umask for this process so it doesn't | 753 | /* Set the umask for this process so it doesn't |
692 | * screw up permission setting for us later. */ | 754 | * screw up permission setting for us later. */ |
693 | umask(0); | 755 | umask(0); |
694 | 756 | ||
695 | /* Read the directory/files and iterate over them one at a time */ | 757 | /* Read the directory/files and iterate over them one at a time */ |
696 | if (recursiveAction(directory, TRUE, FALSE, FALSE, | 758 | while (argc-- > 0) { |
697 | fileAction, fileAction) == FALSE) { | 759 | if (recursiveAction(*argv++, TRUE, FALSE, FALSE, |
698 | exit(FALSE); | 760 | fileAction, fileAction, (void*) &tarFd) == FALSE) { |
761 | exit(FALSE); | ||
762 | } | ||
699 | } | 763 | } |
700 | 764 | ||
701 | |||
702 | // TODO: DO STUFF HERE | ||
703 | close(tarFd); | 765 | close(tarFd); |
704 | return( TRUE); | 766 | return( TRUE); |
705 | } | 767 | } |