Tar now works perfectly. It behaves much better now then it

used to.  Only thing left to do is add in exclude (-X) option.
 -Erik
This commit is contained in:
Erik Andersen 2000-04-05 01:00:52 +00:00
parent cbb0a4b40d
commit 5661fe078e
8 changed files with 245 additions and 178 deletions

53
TODO
View File

@ -15,15 +15,12 @@ around to it some time. If you have any good ideas, please let me know.
-----------
* Allow tar to create archives with sockets, devices, and other special files
* Make insmod actually work
* dnsdomainname
* traceroute/netstat
* rdate
* hwclock
* killall
* stty
* tr
* cut
* expr (maybe?) (ash builtin?)
@ -40,58 +37,17 @@ and then start with the biggest things and make them smaller...
busybox.defs.h is too big and hard to follow.
I either need to add a better build system (like the Linux kernel?)
or I need to split up busybox.defs.h into coherent chunks (i.e.
busybox.defs.h just has a bunch of:
#include "fileutils.h"
#include "shellutils.h"
which would then have smaller sets of #defines...
Hmm. Needs to be carefully thought out.
Perhaps I need to add a better build system (like the Linux kernel?)
-----------------------
-rw-r--r-- 1000/1000 4398 2000-01-06 21:55 uniq.c
-rw-r--r-- 1000/1000 1568 1999-10-20 18:08 update.c
-rw-r----- 0/1000 1168 2000-01-29 21:03 update.o
-rw-r--r-- 1000/1000 22820 2000-01-05 11:36 utility.c
-rw-r----- 0/1000 7372 2000-01-29 21:03 utility.o
tar: Skipping to next file header
tar: Skipping to next file header
tar: Archive - EOF not on block boundary
tar: Error is not recoverable: exiting now
#1 You are storing by id instead of name like normal tar. Did you realize this?
(or am I missing some compile option? )ctar did not do this, and I don't think
it's a good idea for LRP.
#2
ctar did not produce the EOF error like your tar does. I believe you need to
pad the end of the archive with at least 2 tarsized (512byte) blocks. (I
think???)
#3
There is no exclude file(s) option to tar. LRP's packaging system can not
function without this. Will you have the time to add this soon?
-----------------------
cd /mnt
mkdir BACKUP
mv * BACKUP
Today, "mv" behaved as a cp -a and my disk becomed full. It does not
work properly either when renaming a directory into something else
(it produces a lot of disk activity when doing this).
-----------------------
Feature request:
/bin/busybox --install -s which makes all links to commands that it
@ -114,13 +70,6 @@ I'll add this to the TODO list,
-----------------------
In utility.c:copyFile: It uses followLinks for both source and
destination files... is that right for `mv'? Will need to revisit
the GNU, freeBSD, and MINIX versions for this... Should read the
Unix98 and POSIX specs also.
-----------------------
I think that the add_inode &c in utility.c needs to also stow the
st_dev field, and that du.c should NOT call `reset_inode_list'
because there can be hard links from inside one argv/ to inside

View File

@ -382,8 +382,8 @@ int busybox_main(int argc, char **argv)
fprintf(stderr, "Usage: busybox [function] [arguments]...\n");
fprintf(stderr, " or: [function] [arguments]...\n\n");
fprintf(stderr,
"\tMost people will create a link to busybox for each\n"
"\tfunction name, and busybox will act like whatever you invoke it as.\n");
"\tMost people will create a link to busybox for each function\n"
"\tname, and busybox will act like whatever you invoke it as.\n");
fprintf(stderr, "\nCurrently defined functions:\n");
while (a->name != 0) {

View File

@ -56,7 +56,8 @@
static const char tar_usage[] =
"tar -[cxtvOf] [tarFileName] [FILE] ...\n\n"
"Create, extract, or list files from a tar file.\n\n"
"Create, extract, or list files from a tar file. Note that\n"
"this version of tar packs hard links as separate files.\n\n"
"Options:\n"
"\tc=create, x=extract, t=list contents, v=verbose,\n"
@ -110,10 +111,10 @@ typedef struct TarHeader TarHeader;
/* A few useful constants */
#define TAR_MAGIC "ustar" /* ustar and a null */
#define TAR_VERSION "00" /* 00 and no null */
//#define TAR_VERSION "00" /* 00 and no null */
#define TAR_VERSION " " /* Be compatable with old GNU format */
#define TAR_MAGIC_LEN 6
#define TAR_VERSION_LEN 2
#define TAR_NAME_LEN 100
#define TAR_BLOCK_SIZE 512
/* A nice enum with all the possible tar file content types */
@ -366,7 +367,8 @@ tarExtractHardLink(TarInfo *header, int extractFlag, int tostdoutFlag)
return;
if (link(header->linkname, header->name) < 0) {
errorMsg("Error creating hard link '%s': %s\n", header->linkname, strerror(errno));
errorMsg("Error creating hard link '%s' to '%s': %s\n",
header->name, header->linkname, strerror(errno));
return;
}
@ -382,7 +384,8 @@ tarExtractSymLink(TarInfo *header, int extractFlag, int tostdoutFlag)
#ifdef S_ISLNK
if (symlink(header->linkname, header->name) < 0) {
errorMsg("Error creating symlink '%s': %s\n", header->linkname, strerror(errno));
errorMsg("Error creating symlink '%s' to '%s': %s\n",
header->name, header->linkname, strerror(errno));
return;
}
/* Try to change ownership of the symlink.
@ -644,18 +647,15 @@ typedef struct TarBallInfo TarBallInfo;
static int putOctal (char *cp, int len, long value)
{
int tempLength;
char *tempString;
char tempBuffer[32];
char *tempString = tempBuffer;
/* Create a string of the specified length with an initial space,
* leading zeroes and the octal number, and a trailing null. */
tempString = tempBuffer;
sprintf (tempString, " %0*lo", len - 2, value);
tempLength = strlen (tempString) + 1;
sprintf (tempString, "%0*lo", len - 1, value);
/* If the string is too large, suppress the leading space. */
tempLength = strlen (tempString) + 1;
if (tempLength > len) {
tempLength--;
tempString++;
@ -677,10 +677,14 @@ static int putOctal (char *cp, int len, long value)
/* Write out a tar header for the specified file/directory/whatever */
static int
writeTarHeader(struct TarHeader *header, const char *fileName, struct stat *statbuf)
writeTarHeader(struct TarBallInfo *tbInfo, const char *fileName, struct stat *statbuf)
{
//int i;
//long chksum, sum;
long chksum=0;
struct TarHeader header;
const unsigned char *cp = (const unsigned char *) &header;
ssize_t size = sizeof(struct TarHeader);
memset( &header, 0, size);
if (*fileName=='/') {
static int alreadyWarned=FALSE;
@ -688,66 +692,88 @@ writeTarHeader(struct TarHeader *header, const char *fileName, struct stat *stat
errorMsg("tar: Removing leading '/' from member names\n");
alreadyWarned=TRUE;
}
strcpy(header->name, fileName+1);
strcpy(header.name, fileName+1);
}
else {
strcpy(header->name, fileName);
strcpy(header.name, fileName);
}
putOctal(header->mode, sizeof(header->mode), statbuf->st_mode & 0777);
putOctal(header->uid, sizeof(header->uid), statbuf->st_uid);
putOctal(header->gid, sizeof(header->gid), statbuf->st_gid);
putOctal(header->size, sizeof(header->size), statbuf->st_size);
putOctal(header->mtime, sizeof(header->mtime), statbuf->st_mtime);
putOctal(header.mode, sizeof(header.mode), statbuf->st_mode);
putOctal(header.uid, sizeof(header.uid), statbuf->st_uid);
putOctal(header.gid, sizeof(header.gid), statbuf->st_gid);
putOctal(header.size, sizeof(header.size), 0); /* Regular file size is handled later */
putOctal(header.mtime, sizeof(header.mtime), statbuf->st_mtime);
strncpy(header.magic, TAR_MAGIC TAR_VERSION,
TAR_MAGIC_LEN + TAR_VERSION_LEN );
my_getpwuid(header.uname, statbuf->st_uid);
/* Put some sort of sane fallback in place... */
if (! *header.uname)
strncpy(header.uname, "root", 5);
my_getgrgid(header.gname, statbuf->st_gid);
if (! *header.uname)
strncpy(header.uname, "root", 5);
// FIXME: (or most likely not) I break Hard Links
if (S_ISLNK(statbuf->st_mode)) {
header->typeflag = LNKTYPE;
// TODO -- Handle SYMTYPE
char buffer[BUFSIZ];
header.typeflag = SYMTYPE;
if ( readlink(fileName, buffer, sizeof(buffer) - 1) < 0) {
errorMsg("Error reading symlink '%s': %s\n", header.name, strerror(errno));
return ( FALSE);
}
strncpy(header.linkname, buffer, sizeof(header.linkname));
} else if (S_ISDIR(statbuf->st_mode)) {
header->typeflag = DIRTYPE;
strncat(header->name, "/", sizeof(header->name));
header.typeflag = DIRTYPE;
strncat(header.name, "/", sizeof(header.name));
} else if (S_ISCHR(statbuf->st_mode)) {
header->typeflag = CHRTYPE;
putOctal(header->devmajor, sizeof(header->devmajor), MAJOR(statbuf->st_rdev));
putOctal(header->devminor, sizeof(header->devminor), MINOR(statbuf->st_rdev));
header.typeflag = CHRTYPE;
putOctal(header.devmajor, sizeof(header.devmajor), MAJOR(statbuf->st_rdev));
putOctal(header.devminor, sizeof(header.devminor), MINOR(statbuf->st_rdev));
} else if (S_ISBLK(statbuf->st_mode)) {
header->typeflag = BLKTYPE;
putOctal(header->devmajor, sizeof(header->devmajor), MAJOR(statbuf->st_rdev));
putOctal(header->devminor, sizeof(header->devminor), MINOR(statbuf->st_rdev));
header.typeflag = BLKTYPE;
putOctal(header.devmajor, sizeof(header.devmajor), MAJOR(statbuf->st_rdev));
putOctal(header.devminor, sizeof(header.devminor), MINOR(statbuf->st_rdev));
} else if (S_ISFIFO(statbuf->st_mode)) {
header->typeflag = FIFOTYPE;
} else if (S_ISLNK(statbuf->st_mode)) {
header->typeflag = LNKTYPE;
} else if (S_ISLNK(statbuf->st_mode)) {
header->typeflag = REGTYPE;
header.typeflag = FIFOTYPE;
} else if (S_ISREG(statbuf->st_mode)) {
header.typeflag = REGTYPE;
putOctal(header.size, sizeof(header.size), statbuf->st_size);
} else {
errorMsg("tar: %s: Unknown file type\n", fileName);
return ( FALSE);
}
return ( TRUE);
#if 0
header->linkname = rawHeader->linkname;
header->devmajor = getOctal(rawHeader->devmajor, sizeof(rawHeader->devmajor));
header->devminor = getOctal(rawHeader->devminor, sizeof(rawHeader->devminor));
/* Write out the checksum */
chksum = getOctal(rawHeader->chksum, sizeof(rawHeader->chksum));
/* Calculate and store the checksum (i.e. the sum of all of the bytes of
* the header). The checksum field must be filled with blanks for the
* calculation. The checksum field is formatted differently from the
* other fields: it has [6] digits, a null, then a space -- rather than
* digits, followed by a null like the other fields... */
memset(header.chksum, ' ', sizeof(header.chksum));
cp = (const unsigned char *) &header;
while (size-- > 0)
chksum += *cp++;
putOctal(header.chksum, 7, chksum);
/* Now write the header out to disk */
if ((size=fullWrite(tbInfo->tarFd, (char*)&header, sizeof(struct TarHeader))) < 0) {
errorMsg(io_error, fileName, strerror(errno));
return ( FALSE);
}
/* Pad the header up to the tar block size */
for (; size<TAR_BLOCK_SIZE; size++) {
write(tbInfo->tarFd, "\0", 1);
}
/* Now do the verbose thing (or not) */
if (tbInfo->verboseFlag==TRUE)
fprintf(stdout, "%s\n", header.name);
return ( TRUE);
#endif
}
static int writeFileToTarball(const char *fileName, struct stat *statbuf, void* userData)
{
int inputFileFd;
struct TarBallInfo *tbInfo = (struct TarBallInfo *)userData;
char header[sizeof(struct TarHeader)];
/* First open the file we want to archive, and make sure all is well */
if ((inputFileFd = open(fileName, O_RDONLY)) < 0) {
errorMsg("tar: %s: Cannot open: %s\n", fileName, strerror(errno));
return( TRUE);
}
/* It is against the rules to archive a socket */
if (S_ISSOCK(statbuf->st_mode)) {
@ -764,13 +790,41 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf, void*
return( TRUE);
}
memset( header, 0, sizeof(struct TarHeader));
if (writeTarHeader((struct TarHeader *)header, fileName, statbuf)==FALSE) {
dprintf(tbInfo->tarFd, "%s", header);
if (writeTarHeader(tbInfo, fileName, statbuf)==FALSE) {
return( FALSE);
}
/* Now do the verbose thing (or not) */
if (tbInfo->verboseFlag==TRUE)
fprintf(stdout, "%s\n", ((struct TarHeader *)header)->name);
/* Now, if the file is a regular file, copy it out to the tarball */
if (S_ISREG(statbuf->st_mode)) {
int inputFileFd;
char buffer[BUFSIZ];
ssize_t size=0, readSize=0;
/* open the file we want to archive, and make sure all is well */
if ((inputFileFd = open(fileName, O_RDONLY)) < 0) {
errorMsg("tar: %s: Cannot open: %s\n", fileName, strerror(errno));
return( FALSE);
}
/* write the file to the archive */
while ( (size = fullRead(inputFileFd, buffer, sizeof(buffer))) > 0 ) {
if (fullWrite(tbInfo->tarFd, buffer, size) != size ) {
/* Output file seems to have a problem */
errorMsg(io_error, fileName, strerror(errno));
return( FALSE);
}
readSize+=size;
}
if (size == -1) {
errorMsg(io_error, fileName, strerror(errno));
return( FALSE);
}
/* Pad the file up to the tar block size */
for (; (readSize%TAR_BLOCK_SIZE) != 0; readSize++) {
write(tbInfo->tarFd, "\0", 1);
}
close( inputFileFd);
}
return( TRUE);
}
@ -780,6 +834,7 @@ static int writeTarFile(const char* tarName, int tostdoutFlag,
{
int tarFd=-1;
int errorFlag=FALSE;
ssize_t size;
//int skipFileFlag=FALSE;
struct TarBallInfo tbInfo;
tbInfo.verboseFlag = verboseFlag;
@ -814,6 +869,10 @@ static int writeTarFile(const char* tarName, int tostdoutFlag,
errorFlag = TRUE;
}
}
/* Write two empty blocks to the end of the archive */
for (size=0; size<(2*TAR_BLOCK_SIZE); size++) {
write(tbInfo.tarFd, "\0", 1);
}
/* Hang up the tools, close up shop, head home */
close(tarFd);
if (errorFlag == TRUE) {

View File

@ -382,8 +382,8 @@ int busybox_main(int argc, char **argv)
fprintf(stderr, "Usage: busybox [function] [arguments]...\n");
fprintf(stderr, " or: [function] [arguments]...\n\n");
fprintf(stderr,
"\tMost people will create a link to busybox for each\n"
"\tfunction name, and busybox will act like whatever you invoke it as.\n");
"\tMost people will create a link to busybox for each function\n"
"\tname, and busybox will act like whatever you invoke it as.\n");
fprintf(stderr, "\nCurrently defined functions:\n");
while (a->name != 0) {

2
kill.c
View File

@ -1,6 +1,6 @@
/* vi: set sw=4 ts=4: */
/*
* Mini kill implementation for busybox
* Mini kill/killall implementation for busybox
*
* Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
*

View File

@ -1,6 +1,6 @@
/* vi: set sw=4 ts=4: */
/*
* Mini kill implementation for busybox
* Mini kill/killall implementation for busybox
*
* Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
*

177
tar.c
View File

@ -56,7 +56,8 @@
static const char tar_usage[] =
"tar -[cxtvOf] [tarFileName] [FILE] ...\n\n"
"Create, extract, or list files from a tar file.\n\n"
"Create, extract, or list files from a tar file. Note that\n"
"this version of tar packs hard links as separate files.\n\n"
"Options:\n"
"\tc=create, x=extract, t=list contents, v=verbose,\n"
@ -110,10 +111,10 @@ typedef struct TarHeader TarHeader;
/* A few useful constants */
#define TAR_MAGIC "ustar" /* ustar and a null */
#define TAR_VERSION "00" /* 00 and no null */
//#define TAR_VERSION "00" /* 00 and no null */
#define TAR_VERSION " " /* Be compatable with old GNU format */
#define TAR_MAGIC_LEN 6
#define TAR_VERSION_LEN 2
#define TAR_NAME_LEN 100
#define TAR_BLOCK_SIZE 512
/* A nice enum with all the possible tar file content types */
@ -366,7 +367,8 @@ tarExtractHardLink(TarInfo *header, int extractFlag, int tostdoutFlag)
return;
if (link(header->linkname, header->name) < 0) {
errorMsg("Error creating hard link '%s': %s\n", header->linkname, strerror(errno));
errorMsg("Error creating hard link '%s' to '%s': %s\n",
header->name, header->linkname, strerror(errno));
return;
}
@ -382,7 +384,8 @@ tarExtractSymLink(TarInfo *header, int extractFlag, int tostdoutFlag)
#ifdef S_ISLNK
if (symlink(header->linkname, header->name) < 0) {
errorMsg("Error creating symlink '%s': %s\n", header->linkname, strerror(errno));
errorMsg("Error creating symlink '%s' to '%s': %s\n",
header->name, header->linkname, strerror(errno));
return;
}
/* Try to change ownership of the symlink.
@ -644,18 +647,15 @@ typedef struct TarBallInfo TarBallInfo;
static int putOctal (char *cp, int len, long value)
{
int tempLength;
char *tempString;
char tempBuffer[32];
char *tempString = tempBuffer;
/* Create a string of the specified length with an initial space,
* leading zeroes and the octal number, and a trailing null. */
tempString = tempBuffer;
sprintf (tempString, " %0*lo", len - 2, value);
tempLength = strlen (tempString) + 1;
sprintf (tempString, "%0*lo", len - 1, value);
/* If the string is too large, suppress the leading space. */
tempLength = strlen (tempString) + 1;
if (tempLength > len) {
tempLength--;
tempString++;
@ -677,10 +677,14 @@ static int putOctal (char *cp, int len, long value)
/* Write out a tar header for the specified file/directory/whatever */
static int
writeTarHeader(struct TarHeader *header, const char *fileName, struct stat *statbuf)
writeTarHeader(struct TarBallInfo *tbInfo, const char *fileName, struct stat *statbuf)
{
//int i;
//long chksum, sum;
long chksum=0;
struct TarHeader header;
const unsigned char *cp = (const unsigned char *) &header;
ssize_t size = sizeof(struct TarHeader);
memset( &header, 0, size);
if (*fileName=='/') {
static int alreadyWarned=FALSE;
@ -688,66 +692,88 @@ writeTarHeader(struct TarHeader *header, const char *fileName, struct stat *stat
errorMsg("tar: Removing leading '/' from member names\n");
alreadyWarned=TRUE;
}
strcpy(header->name, fileName+1);
strcpy(header.name, fileName+1);
}
else {
strcpy(header->name, fileName);
strcpy(header.name, fileName);
}
putOctal(header->mode, sizeof(header->mode), statbuf->st_mode & 0777);
putOctal(header->uid, sizeof(header->uid), statbuf->st_uid);
putOctal(header->gid, sizeof(header->gid), statbuf->st_gid);
putOctal(header->size, sizeof(header->size), statbuf->st_size);
putOctal(header->mtime, sizeof(header->mtime), statbuf->st_mtime);
putOctal(header.mode, sizeof(header.mode), statbuf->st_mode);
putOctal(header.uid, sizeof(header.uid), statbuf->st_uid);
putOctal(header.gid, sizeof(header.gid), statbuf->st_gid);
putOctal(header.size, sizeof(header.size), 0); /* Regular file size is handled later */
putOctal(header.mtime, sizeof(header.mtime), statbuf->st_mtime);
strncpy(header.magic, TAR_MAGIC TAR_VERSION,
TAR_MAGIC_LEN + TAR_VERSION_LEN );
my_getpwuid(header.uname, statbuf->st_uid);
/* Put some sort of sane fallback in place... */
if (! *header.uname)
strncpy(header.uname, "root", 5);
my_getgrgid(header.gname, statbuf->st_gid);
if (! *header.uname)
strncpy(header.uname, "root", 5);
// FIXME: (or most likely not) I break Hard Links
if (S_ISLNK(statbuf->st_mode)) {
header->typeflag = LNKTYPE;
// TODO -- Handle SYMTYPE
char buffer[BUFSIZ];
header.typeflag = SYMTYPE;
if ( readlink(fileName, buffer, sizeof(buffer) - 1) < 0) {
errorMsg("Error reading symlink '%s': %s\n", header.name, strerror(errno));
return ( FALSE);
}
strncpy(header.linkname, buffer, sizeof(header.linkname));
} else if (S_ISDIR(statbuf->st_mode)) {
header->typeflag = DIRTYPE;
strncat(header->name, "/", sizeof(header->name));
header.typeflag = DIRTYPE;
strncat(header.name, "/", sizeof(header.name));
} else if (S_ISCHR(statbuf->st_mode)) {
header->typeflag = CHRTYPE;
putOctal(header->devmajor, sizeof(header->devmajor), MAJOR(statbuf->st_rdev));
putOctal(header->devminor, sizeof(header->devminor), MINOR(statbuf->st_rdev));
header.typeflag = CHRTYPE;
putOctal(header.devmajor, sizeof(header.devmajor), MAJOR(statbuf->st_rdev));
putOctal(header.devminor, sizeof(header.devminor), MINOR(statbuf->st_rdev));
} else if (S_ISBLK(statbuf->st_mode)) {
header->typeflag = BLKTYPE;
putOctal(header->devmajor, sizeof(header->devmajor), MAJOR(statbuf->st_rdev));
putOctal(header->devminor, sizeof(header->devminor), MINOR(statbuf->st_rdev));
header.typeflag = BLKTYPE;
putOctal(header.devmajor, sizeof(header.devmajor), MAJOR(statbuf->st_rdev));
putOctal(header.devminor, sizeof(header.devminor), MINOR(statbuf->st_rdev));
} else if (S_ISFIFO(statbuf->st_mode)) {
header->typeflag = FIFOTYPE;
} else if (S_ISLNK(statbuf->st_mode)) {
header->typeflag = LNKTYPE;
} else if (S_ISLNK(statbuf->st_mode)) {
header->typeflag = REGTYPE;
header.typeflag = FIFOTYPE;
} else if (S_ISREG(statbuf->st_mode)) {
header.typeflag = REGTYPE;
putOctal(header.size, sizeof(header.size), statbuf->st_size);
} else {
errorMsg("tar: %s: Unknown file type\n", fileName);
return ( FALSE);
}
return ( TRUE);
#if 0
header->linkname = rawHeader->linkname;
header->devmajor = getOctal(rawHeader->devmajor, sizeof(rawHeader->devmajor));
header->devminor = getOctal(rawHeader->devminor, sizeof(rawHeader->devminor));
/* Write out the checksum */
chksum = getOctal(rawHeader->chksum, sizeof(rawHeader->chksum));
/* Calculate and store the checksum (i.e. the sum of all of the bytes of
* the header). The checksum field must be filled with blanks for the
* calculation. The checksum field is formatted differently from the
* other fields: it has [6] digits, a null, then a space -- rather than
* digits, followed by a null like the other fields... */
memset(header.chksum, ' ', sizeof(header.chksum));
cp = (const unsigned char *) &header;
while (size-- > 0)
chksum += *cp++;
putOctal(header.chksum, 7, chksum);
/* Now write the header out to disk */
if ((size=fullWrite(tbInfo->tarFd, (char*)&header, sizeof(struct TarHeader))) < 0) {
errorMsg(io_error, fileName, strerror(errno));
return ( FALSE);
}
/* Pad the header up to the tar block size */
for (; size<TAR_BLOCK_SIZE; size++) {
write(tbInfo->tarFd, "\0", 1);
}
/* Now do the verbose thing (or not) */
if (tbInfo->verboseFlag==TRUE)
fprintf(stdout, "%s\n", header.name);
return ( TRUE);
#endif
}
static int writeFileToTarball(const char *fileName, struct stat *statbuf, void* userData)
{
int inputFileFd;
struct TarBallInfo *tbInfo = (struct TarBallInfo *)userData;
char header[sizeof(struct TarHeader)];
/* First open the file we want to archive, and make sure all is well */
if ((inputFileFd = open(fileName, O_RDONLY)) < 0) {
errorMsg("tar: %s: Cannot open: %s\n", fileName, strerror(errno));
return( TRUE);
}
/* It is against the rules to archive a socket */
if (S_ISSOCK(statbuf->st_mode)) {
@ -764,13 +790,41 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf, void*
return( TRUE);
}
memset( header, 0, sizeof(struct TarHeader));
if (writeTarHeader((struct TarHeader *)header, fileName, statbuf)==FALSE) {
dprintf(tbInfo->tarFd, "%s", header);
if (writeTarHeader(tbInfo, fileName, statbuf)==FALSE) {
return( FALSE);
}
/* Now do the verbose thing (or not) */
if (tbInfo->verboseFlag==TRUE)
fprintf(stdout, "%s\n", ((struct TarHeader *)header)->name);
/* Now, if the file is a regular file, copy it out to the tarball */
if (S_ISREG(statbuf->st_mode)) {
int inputFileFd;
char buffer[BUFSIZ];
ssize_t size=0, readSize=0;
/* open the file we want to archive, and make sure all is well */
if ((inputFileFd = open(fileName, O_RDONLY)) < 0) {
errorMsg("tar: %s: Cannot open: %s\n", fileName, strerror(errno));
return( FALSE);
}
/* write the file to the archive */
while ( (size = fullRead(inputFileFd, buffer, sizeof(buffer))) > 0 ) {
if (fullWrite(tbInfo->tarFd, buffer, size) != size ) {
/* Output file seems to have a problem */
errorMsg(io_error, fileName, strerror(errno));
return( FALSE);
}
readSize+=size;
}
if (size == -1) {
errorMsg(io_error, fileName, strerror(errno));
return( FALSE);
}
/* Pad the file up to the tar block size */
for (; (readSize%TAR_BLOCK_SIZE) != 0; readSize++) {
write(tbInfo->tarFd, "\0", 1);
}
close( inputFileFd);
}
return( TRUE);
}
@ -780,6 +834,7 @@ static int writeTarFile(const char* tarName, int tostdoutFlag,
{
int tarFd=-1;
int errorFlag=FALSE;
ssize_t size;
//int skipFileFlag=FALSE;
struct TarBallInfo tbInfo;
tbInfo.verboseFlag = verboseFlag;
@ -814,6 +869,10 @@ static int writeTarFile(const char* tarName, int tostdoutFlag,
errorFlag = TRUE;
}
}
/* Write two empty blocks to the end of the archive */
for (size=0; size<(2*TAR_BLOCK_SIZE); size++) {
write(tbInfo.tarFd, "\0", 1);
}
/* Hang up the tools, close up shop, head home */
close(tarFd);
if (errorFlag == TRUE) {

View File

@ -783,7 +783,7 @@ extern int parse_mode(const char *s, mode_t * theMode)
#if defined (BB_CHMOD_CHOWN_CHGRP) || defined (BB_PS)
#if defined BB_CHMOD_CHOWN_CHGRP || defined BB_PS || defined BB_LS || defined BB_TAR
/* Use this to avoid needing the glibc NSS stuff
* This uses storage buf to hold things.
@ -858,7 +858,7 @@ void my_getgrgid(char *group, gid_t gid)
}
#endif /* BB_CHMOD_CHOWN_CHGRP || BB_PS */
#endif /* BB_CHMOD_CHOWN_CHGRP || BB_PS || BB_LS || BB_TAR */