aboutsummaryrefslogtreecommitdiff
path: root/tar.c
diff options
context:
space:
mode:
Diffstat (limited to 'tar.c')
-rw-r--r--tar.c86
1 files changed, 74 insertions, 12 deletions
diff --git a/tar.c b/tar.c
index 37a28a3d0..af0e4f8ef 100644
--- a/tar.c
+++ b/tar.c
@@ -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 */
441static int 442static int
442parseTarHeader(struct TarHeader *rawHeader, struct TarInfo *header) 443readTarHeader(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
664static int fileAction(const char *fileName, struct stat *statbuf) 665/* Write out a tar header for the specified file */
666static int
667writeTarHeader(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
713static 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
670static int writeTarFile(const char* tarName, int extractFlag, int listFlag, 720static 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}