Run through indent, use /* */ style comments, change extern to static

This commit is contained in:
Glenn L McGrath 2002-08-22 13:44:08 +00:00
parent 4176972db5
commit a0ee881ba4

View File

@ -56,8 +56,8 @@
#ifdef CONFIG_FEATURE_TAR_CREATE #ifdef CONFIG_FEATURE_TAR_CREATE
/* Tar file constants */ /* Tar file constants */
# define TAR_MAGIC "ustar" /* ustar and a null */ # define TAR_MAGIC "ustar" /* ustar and a null */
# define TAR_VERSION " " /* Be compatable with GNU tar format */ # define TAR_VERSION " " /* Be compatable with GNU tar format */
# ifndef MAJOR # ifndef MAJOR
# define MAJOR(dev) (((dev)>>8)&0xff) # define MAJOR(dev) (((dev)>>8)&0xff)
@ -69,26 +69,25 @@ static const int TAR_MAGIC_LEN = 6;
static const int TAR_VERSION_LEN = 2; static const int TAR_VERSION_LEN = 2;
/* POSIX tar Header Block, from POSIX 1003.1-1990 */ /* POSIX tar Header Block, from POSIX 1003.1-1990 */
enum { NAME_SIZE = 100 }; /* because gcc won't let me use 'static const int' */ enum { NAME_SIZE = 100 }; /* because gcc won't let me use 'static const int' */
struct TarHeader struct TarHeader { /* byte offset */
{ /* byte offset */ char name[NAME_SIZE]; /* 0-99 */
char name[NAME_SIZE]; /* 0-99 */ char mode[8]; /* 100-107 */
char mode[8]; /* 100-107 */ char uid[8]; /* 108-115 */
char uid[8]; /* 108-115 */ char gid[8]; /* 116-123 */
char gid[8]; /* 116-123 */ char size[12]; /* 124-135 */
char size[12]; /* 124-135 */ char mtime[12]; /* 136-147 */
char mtime[12]; /* 136-147 */ char chksum[8]; /* 148-155 */
char chksum[8]; /* 148-155 */ char typeflag; /* 156-156 */
char typeflag; /* 156-156 */ char linkname[NAME_SIZE]; /* 157-256 */
char linkname[NAME_SIZE]; /* 157-256 */ char magic[6]; /* 257-262 */
char magic[6]; /* 257-262 */ char version[2]; /* 263-264 */
char version[2]; /* 263-264 */ char uname[32]; /* 265-296 */
char uname[32]; /* 265-296 */ char gname[32]; /* 297-328 */
char gname[32]; /* 297-328 */ char devmajor[8]; /* 329-336 */
char devmajor[8]; /* 329-336 */ char devminor[8]; /* 337-344 */
char devminor[8]; /* 337-344 */ char prefix[155]; /* 345-499 */
char prefix[155]; /* 345-499 */ char padding[12]; /* 500-512 (pad to exactly the TAR_BLOCK_SIZE) */
char padding[12]; /* 500-512 (pad to exactly the TAR_BLOCK_SIZE) */
}; };
typedef struct TarHeader TarHeader; typedef struct TarHeader TarHeader;
@ -98,58 +97,56 @@ typedef struct TarHeader TarHeader;
** Even these functions use the xxxHardLinkInfo() functions. ** Even these functions use the xxxHardLinkInfo() functions.
*/ */
typedef struct HardLinkInfo HardLinkInfo; typedef struct HardLinkInfo HardLinkInfo;
struct HardLinkInfo struct HardLinkInfo {
{ HardLinkInfo *next; /* Next entry in list */
HardLinkInfo *next; /* Next entry in list */ dev_t dev; /* Device number */
dev_t dev; /* Device number */ ino_t ino; /* Inode number */
ino_t ino; /* Inode number */ short linkCount; /* (Hard) Link Count */
short linkCount; /* (Hard) Link Count */ char name[1]; /* Start of filename (must be last) */
char name[1]; /* Start of filename (must be last) */
}; };
/* Some info to be carried along when creating a new tarball */ /* Some info to be carried along when creating a new tarball */
struct TarBallInfo struct TarBallInfo {
{ char *fileName; /* File name of the tarball */
char* fileName; /* File name of the tarball */ int tarFd; /* Open-for-write file descriptor
int tarFd; /* Open-for-write file descriptor for the tarball */
for the tarball */ struct stat statBuf; /* Stat info for the tarball, letting
struct stat statBuf; /* Stat info for the tarball, letting us know the inode and device that the
us know the inode and device that the tarball lives, so we can avoid trying
tarball lives, so we can avoid trying to include the tarball into itself */
to include the tarball into itself */ int verboseFlag; /* Whether to print extra stuff or not */
int verboseFlag; /* Whether to print extra stuff or not */ char **excludeList; /* List of files to not include */
char** excludeList; /* List of files to not include */ HardLinkInfo *hlInfoHead; /* Hard Link Tracking Information */
HardLinkInfo *hlInfoHead; /* Hard Link Tracking Information */ HardLinkInfo *hlInfo; /* Hard Link Info for the current file */
HardLinkInfo *hlInfo; /* Hard Link Info for the current file */
}; };
typedef struct TarBallInfo TarBallInfo; typedef struct TarBallInfo TarBallInfo;
/* A nice enum with all the possible tar file content types */ /* A nice enum with all the possible tar file content types */
enum TarFileType enum TarFileType {
{ REGTYPE = '0', /* regular file */
REGTYPE = '0', /* regular file */ REGTYPE0 = '\0', /* regular file (ancient bug compat) */
REGTYPE0 = '\0', /* regular file (ancient bug compat)*/ LNKTYPE = '1', /* hard link */
LNKTYPE = '1', /* hard link */ SYMTYPE = '2', /* symbolic link */
SYMTYPE = '2', /* symbolic link */ CHRTYPE = '3', /* character special */
CHRTYPE = '3', /* character special */ BLKTYPE = '4', /* block special */
BLKTYPE = '4', /* block special */ DIRTYPE = '5', /* directory */
DIRTYPE = '5', /* directory */ FIFOTYPE = '6', /* FIFO special */
FIFOTYPE = '6', /* FIFO special */ CONTTYPE = '7', /* reserved */
CONTTYPE = '7', /* reserved */ GNULONGLINK = 'K', /* GNU long (>100 chars) link name */
GNULONGLINK = 'K', /* GNU long (>100 chars) link name */ GNULONGNAME = 'L', /* GNU long (>100 chars) file name */
GNULONGNAME = 'L', /* GNU long (>100 chars) file name */
}; };
typedef enum TarFileType TarFileType; typedef enum TarFileType TarFileType;
/* Might be faster (and bigger) if the dev/ino were stored in numeric order;) */ /* Might be faster (and bigger) if the dev/ino were stored in numeric order;) */
extern inline void static inline void addHardLinkInfo(HardLinkInfo ** hlInfoHeadPtr, dev_t dev,
addHardLinkInfo (HardLinkInfo **hlInfoHeadPtr, dev_t dev, ino_t ino, ino_t ino, short linkCount,
short linkCount, const char *name) const char *name)
{ {
/* Note: hlInfoHeadPtr can never be NULL! */ /* Note: hlInfoHeadPtr can never be NULL! */
HardLinkInfo *hlInfo; HardLinkInfo *hlInfo;
hlInfo = (HardLinkInfo *)xmalloc(sizeof(HardLinkInfo)+strlen(name)+1); hlInfo =
(HardLinkInfo *) xmalloc(sizeof(HardLinkInfo) + strlen(name) + 1);
if (hlInfo) { if (hlInfo) {
hlInfo->next = *hlInfoHeadPtr; hlInfo->next = *hlInfoHeadPtr;
*hlInfoHeadPtr = hlInfo; *hlInfoHeadPtr = hlInfo;
@ -161,8 +158,7 @@ addHardLinkInfo (HardLinkInfo **hlInfoHeadPtr, dev_t dev, ino_t ino,
return; return;
} }
static void static void freeHardLinkInfo(HardLinkInfo ** hlInfoHeadPtr)
freeHardLinkInfo (HardLinkInfo **hlInfoHeadPtr)
{ {
HardLinkInfo *hlInfo = NULL; HardLinkInfo *hlInfo = NULL;
HardLinkInfo *hlInfoNext = NULL; HardLinkInfo *hlInfoNext = NULL;
@ -180,21 +176,21 @@ freeHardLinkInfo (HardLinkInfo **hlInfoHeadPtr)
} }
/* Might be faster (and bigger) if the dev/ino were stored in numeric order;) */ /* Might be faster (and bigger) if the dev/ino were stored in numeric order;) */
extern inline HardLinkInfo * static inline HardLinkInfo *findHardLinkInfo(HardLinkInfo * hlInfo, dev_t dev,
findHardLinkInfo (HardLinkInfo *hlInfo, dev_t dev, ino_t ino) ino_t ino)
{ {
while(hlInfo) { while (hlInfo) {
if ((ino == hlInfo->ino) && (dev == hlInfo->dev)) if ((ino == hlInfo->ino) && (dev == hlInfo->dev))
break; break;
hlInfo = hlInfo->next; hlInfo = hlInfo->next;
} }
return(hlInfo); return (hlInfo);
} }
/* Put an octal string into the specified buffer. /* Put an octal string into the specified buffer.
* The number is zero and space padded and possibly null padded. * The number is zero and space padded and possibly null padded.
* Returns TRUE if successful. */ * Returns TRUE if successful. */
static int putOctal (char *cp, int len, long value) static int putOctal(char *cp, int len, long value)
{ {
int tempLength; int tempLength;
char tempBuffer[32]; char tempBuffer[32];
@ -202,10 +198,10 @@ static int putOctal (char *cp, int len, long value)
/* Create a string of the specified length with an initial space, /* Create a string of the specified length with an initial space,
* leading zeroes and the octal number, and a trailing null. */ * leading zeroes and the octal number, and a trailing null. */
sprintf (tempString, "%0*lo", len - 1, value); sprintf(tempString, "%0*lo", len - 1, value);
/* If the string is too large, suppress the leading space. */ /* If the string is too large, suppress the leading space. */
tempLength = strlen (tempString) + 1; tempLength = strlen(tempString) + 1;
if (tempLength > len) { if (tempLength > len) {
tempLength--; tempLength--;
tempString++; tempString++;
@ -220,71 +216,77 @@ static int putOctal (char *cp, int len, long value)
return FALSE; return FALSE;
/* Copy the string to the field. */ /* Copy the string to the field. */
memcpy (cp, tempString, len); memcpy(cp, tempString, len);
return TRUE; return TRUE;
} }
/* Write out a tar header for the specified file/directory/whatever */ /* Write out a tar header for the specified file/directory/whatever */
extern inline int static inline int writeTarHeader(struct TarBallInfo *tbInfo,
writeTarHeader(struct TarBallInfo *tbInfo, const char *header_name, const char *header_name,
const char *real_name, struct stat *statbuf) const char *real_name, struct stat *statbuf)
{ {
long chksum=0; long chksum = 0;
struct TarHeader header; struct TarHeader header;
const unsigned char *cp = (const unsigned char *) &header; const unsigned char *cp = (const unsigned char *) &header;
ssize_t size = sizeof(struct TarHeader); ssize_t size = sizeof(struct TarHeader);
memset( &header, 0, size); memset(&header, 0, size);
strncpy(header.name, header_name, sizeof(header.name)); strncpy(header.name, header_name, sizeof(header.name));
putOctal(header.mode, sizeof(header.mode), statbuf->st_mode); putOctal(header.mode, sizeof(header.mode), statbuf->st_mode);
putOctal(header.uid, sizeof(header.uid), statbuf->st_uid); putOctal(header.uid, sizeof(header.uid), statbuf->st_uid);
putOctal(header.gid, sizeof(header.gid), statbuf->st_gid); putOctal(header.gid, sizeof(header.gid), statbuf->st_gid);
putOctal(header.size, sizeof(header.size), 0); /* Regular file size is handled later */ putOctal(header.size, sizeof(header.size), 0); /* Regular file size is handled later */
putOctal(header.mtime, sizeof(header.mtime), statbuf->st_mtime); putOctal(header.mtime, sizeof(header.mtime), statbuf->st_mtime);
strncpy(header.magic, TAR_MAGIC TAR_VERSION, strncpy(header.magic, TAR_MAGIC TAR_VERSION,
TAR_MAGIC_LEN + TAR_VERSION_LEN ); TAR_MAGIC_LEN + TAR_VERSION_LEN);
/* Enter the user and group names (default to root if it fails) */ /* Enter the user and group names (default to root if it fails) */
my_getpwuid(header.uname, statbuf->st_uid); my_getpwuid(header.uname, statbuf->st_uid);
if (! *header.uname) if (!*header.uname)
strcpy(header.uname, "root"); strcpy(header.uname, "root");
my_getgrgid(header.gname, statbuf->st_gid); my_getgrgid(header.gname, statbuf->st_gid);
if (! *header.uname) if (!*header.uname)
strcpy(header.uname, "root"); strcpy(header.uname, "root");
if (tbInfo->hlInfo) { if (tbInfo->hlInfo) {
/* This is a hard link */ /* This is a hard link */
header.typeflag = LNKTYPE; header.typeflag = LNKTYPE;
strncpy(header.linkname, tbInfo->hlInfo->name, sizeof(header.linkname)); strncpy(header.linkname, tbInfo->hlInfo->name,
sizeof(header.linkname));
} else if (S_ISLNK(statbuf->st_mode)) { } else if (S_ISLNK(statbuf->st_mode)) {
char *lpath = xreadlink(real_name); char *lpath = xreadlink(real_name);
if (!lpath) /* Already printed err msg inside xreadlink() */
return ( FALSE); if (!lpath) /* Already printed err msg inside xreadlink() */
header.typeflag = SYMTYPE; return (FALSE);
header.typeflag = SYMTYPE;
strncpy(header.linkname, lpath, sizeof(header.linkname)); strncpy(header.linkname, lpath, sizeof(header.linkname));
free(lpath); free(lpath);
} else if (S_ISDIR(statbuf->st_mode)) { } else if (S_ISDIR(statbuf->st_mode)) {
header.typeflag = DIRTYPE; header.typeflag = DIRTYPE;
strncat(header.name, "/", sizeof(header.name)); strncat(header.name, "/", sizeof(header.name));
} else if (S_ISCHR(statbuf->st_mode)) { } else if (S_ISCHR(statbuf->st_mode)) {
header.typeflag = CHRTYPE; header.typeflag = CHRTYPE;
putOctal(header.devmajor, sizeof(header.devmajor), MAJOR(statbuf->st_rdev)); putOctal(header.devmajor, sizeof(header.devmajor),
putOctal(header.devminor, sizeof(header.devminor), MINOR(statbuf->st_rdev)); MAJOR(statbuf->st_rdev));
putOctal(header.devminor, sizeof(header.devminor),
MINOR(statbuf->st_rdev));
} else if (S_ISBLK(statbuf->st_mode)) { } else if (S_ISBLK(statbuf->st_mode)) {
header.typeflag = BLKTYPE; header.typeflag = BLKTYPE;
putOctal(header.devmajor, sizeof(header.devmajor), MAJOR(statbuf->st_rdev)); putOctal(header.devmajor, sizeof(header.devmajor),
putOctal(header.devminor, sizeof(header.devminor), MINOR(statbuf->st_rdev)); MAJOR(statbuf->st_rdev));
putOctal(header.devminor, sizeof(header.devminor),
MINOR(statbuf->st_rdev));
} else if (S_ISFIFO(statbuf->st_mode)) { } else if (S_ISFIFO(statbuf->st_mode)) {
header.typeflag = FIFOTYPE; header.typeflag = FIFOTYPE;
} else if (S_ISREG(statbuf->st_mode)) { } else if (S_ISREG(statbuf->st_mode)) {
header.typeflag = REGTYPE; header.typeflag = REGTYPE;
putOctal(header.size, sizeof(header.size), statbuf->st_size); putOctal(header.size, sizeof(header.size), statbuf->st_size);
} else { } else {
error_msg("%s: Unknown file type", real_name); error_msg("%s: Unknown file type", real_name);
return ( FALSE); return (FALSE);
} }
/* Calculate and store the checksum (i.e., the sum of all of the bytes of /* Calculate and store the checksum (i.e., the sum of all of the bytes of
@ -299,28 +301,31 @@ writeTarHeader(struct TarBallInfo *tbInfo, const char *header_name,
putOctal(header.chksum, 7, chksum); putOctal(header.chksum, 7, chksum);
/* Now write the header out to disk */ /* Now write the header out to disk */
if ((size=full_write(tbInfo->tarFd, (char*)&header, sizeof(struct TarHeader))) < 0) { if ((size =
full_write(tbInfo->tarFd, (char *) &header,
sizeof(struct TarHeader))) < 0) {
error_msg(io_error, real_name, strerror(errno)); error_msg(io_error, real_name, strerror(errno));
return ( FALSE); return (FALSE);
} }
/* Pad the header up to the tar block size */ /* Pad the header up to the tar block size */
for (; size<TAR_BLOCK_SIZE; size++) { for (; size < TAR_BLOCK_SIZE; size++) {
write(tbInfo->tarFd, "\0", 1); write(tbInfo->tarFd, "\0", 1);
} }
/* Now do the verbose thing (or not) */ /* Now do the verbose thing (or not) */
if (tbInfo->verboseFlag) { if (tbInfo->verboseFlag) {
FILE *vbFd = stdout; FILE *vbFd = stdout;
if (tbInfo->verboseFlag == 2) // If the archive goes to stdout, verbose to stderr
if (tbInfo->verboseFlag == 2) /* If the archive goes to stdout, verbose to stderr */
vbFd = stderr; vbFd = stderr;
fprintf(vbFd, "%s\n", header.name); fprintf(vbFd, "%s\n", header.name);
} }
return ( TRUE); return (TRUE);
} }
# if defined CONFIG_FEATURE_TAR_EXCLUDE # if defined CONFIG_FEATURE_TAR_EXCLUDE
extern inline int exclude_file(char **excluded_files, const char *file) static inline int exclude_file(char **excluded_files, const char *file)
{ {
int i; int i;
@ -337,7 +342,7 @@ extern inline int exclude_file(char **excluded_files, const char *file)
for (p = file; p[0] != '\0'; p++) { for (p = file; p[0] != '\0'; p++) {
if ((p == file || p[-1] == '/') && p[0] != '/' && if ((p == file || p[-1] == '/') && p[0] != '/' &&
fnmatch(excluded_files[i], p, fnmatch(excluded_files[i], p,
FNM_PATHNAME | FNM_LEADING_DIR) == 0) FNM_PATHNAME | FNM_LEADING_DIR) == 0)
return 1; return 1;
} }
@ -348,55 +353,57 @@ extern inline int exclude_file(char **excluded_files, const char *file)
} }
#endif #endif
static int writeFileToTarball(const char *fileName, struct stat *statbuf, void* userData) static int writeFileToTarball(const char *fileName, struct stat *statbuf,
void *userData)
{ {
struct TarBallInfo *tbInfo = (struct TarBallInfo *)userData; struct TarBallInfo *tbInfo = (struct TarBallInfo *) userData;
const char *header_name; const char *header_name;
/* /*
** Check to see if we are dealing with a hard link. ** Check to see if we are dealing with a hard link.
** If so - ** If so -
** Treat the first occurance of a given dev/inode as a file while ** Treat the first occurance of a given dev/inode as a file while
** treating any additional occurances as hard links. This is done ** treating any additional occurances as hard links. This is done
** by adding the file information to the HardLinkInfo linked list. ** by adding the file information to the HardLinkInfo linked list.
*/ */
tbInfo->hlInfo = NULL; tbInfo->hlInfo = NULL;
if (statbuf->st_nlink > 1) { if (statbuf->st_nlink > 1) {
tbInfo->hlInfo = findHardLinkInfo(tbInfo->hlInfoHead, statbuf->st_dev, tbInfo->hlInfo = findHardLinkInfo(tbInfo->hlInfoHead, statbuf->st_dev,
statbuf->st_ino); statbuf->st_ino);
if (tbInfo->hlInfo == NULL) if (tbInfo->hlInfo == NULL)
addHardLinkInfo (&tbInfo->hlInfoHead, statbuf->st_dev, addHardLinkInfo(&tbInfo->hlInfoHead, statbuf->st_dev,
statbuf->st_ino, statbuf->st_nlink, fileName); statbuf->st_ino, statbuf->st_nlink, fileName);
} }
/* It is against the rules to archive a socket */ /* It is against the rules to archive a socket */
if (S_ISSOCK(statbuf->st_mode)) { if (S_ISSOCK(statbuf->st_mode)) {
error_msg("%s: socket ignored", fileName); error_msg("%s: socket ignored", fileName);
return( TRUE); return (TRUE);
} }
/* It is a bad idea to store the archive we are in the process of creating, /* It is a bad idea to store the archive we are in the process of creating,
* so check the device and inode to be sure that this particular file isn't * so check the device and inode to be sure that this particular file isn't
* the new tarball */ * the new tarball */
if (tbInfo->statBuf.st_dev == statbuf->st_dev && if (tbInfo->statBuf.st_dev == statbuf->st_dev &&
tbInfo->statBuf.st_ino == statbuf->st_ino) { tbInfo->statBuf.st_ino == statbuf->st_ino) {
error_msg("%s: file is the archive; skipping", fileName); error_msg("%s: file is the archive; skipping", fileName);
return( TRUE); return (TRUE);
} }
header_name = fileName; header_name = fileName;
while (header_name[0] == '/') { while (header_name[0] == '/') {
static int alreadyWarned=FALSE; static int alreadyWarned = FALSE;
if (alreadyWarned==FALSE) {
if (alreadyWarned == FALSE) {
error_msg("Removing leading '/' from member names"); error_msg("Removing leading '/' from member names");
alreadyWarned=TRUE; alreadyWarned = TRUE;
} }
header_name++; header_name++;
} }
if (strlen(fileName) >= NAME_SIZE) { if (strlen(fileName) >= NAME_SIZE) {
error_msg(name_longer_than_foo, NAME_SIZE); error_msg(name_longer_than_foo, NAME_SIZE);
return ( TRUE); return (TRUE);
} }
if (header_name[0] == '\0') if (header_name[0] == '\0')
@ -406,60 +413,61 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf, void*
if (exclude_file(tbInfo->excludeList, header_name)) { if (exclude_file(tbInfo->excludeList, header_name)) {
return SKIP; return SKIP;
} }
# endif //CONFIG_FEATURE_TAR_EXCLUDE # endif /* CONFIG_FEATURE_TAR_EXCLUDE */
if (writeTarHeader(tbInfo, header_name, fileName, statbuf)==FALSE) { if (writeTarHeader(tbInfo, header_name, fileName, statbuf) == FALSE) {
return( FALSE); return (FALSE);
} }
/* Now, if the file is a regular file, copy it out to the tarball */ /* Now, if the file is a regular file, copy it out to the tarball */
if ((tbInfo->hlInfo == NULL) if ((tbInfo->hlInfo == NULL)
&& (S_ISREG(statbuf->st_mode))) { && (S_ISREG(statbuf->st_mode))) {
int inputFileFd; int inputFileFd;
char buffer[BUFSIZ]; char buffer[BUFSIZ];
ssize_t size=0, readSize=0; ssize_t size = 0, readSize = 0;
/* open the file we want to archive, and make sure all is well */ /* open the file we want to archive, and make sure all is well */
if ((inputFileFd = open(fileName, O_RDONLY)) < 0) { if ((inputFileFd = open(fileName, O_RDONLY)) < 0) {
error_msg("%s: Cannot open: %s", fileName, strerror(errno)); error_msg("%s: Cannot open: %s", fileName, strerror(errno));
return( FALSE); return (FALSE);
} }
/* write the file to the archive */ /* write the file to the archive */
while ( (size = full_read(inputFileFd, buffer, sizeof(buffer))) > 0 ) { while ((size = full_read(inputFileFd, buffer, sizeof(buffer))) > 0) {
if (full_write(tbInfo->tarFd, buffer, size) != size ) { if (full_write(tbInfo->tarFd, buffer, size) != size) {
/* Output file seems to have a problem */ /* Output file seems to have a problem */
error_msg(io_error, fileName, strerror(errno)); error_msg(io_error, fileName, strerror(errno));
return( FALSE); return (FALSE);
} }
readSize+=size; readSize += size;
} }
if (size == -1) { if (size == -1) {
error_msg(io_error, fileName, strerror(errno)); error_msg(io_error, fileName, strerror(errno));
return( FALSE); return (FALSE);
} }
/* Pad the file up to the tar block size */ /* Pad the file up to the tar block size */
for (; (readSize%TAR_BLOCK_SIZE) != 0; readSize++) { for (; (readSize % TAR_BLOCK_SIZE) != 0; readSize++) {
write(tbInfo->tarFd, "\0", 1); write(tbInfo->tarFd, "\0", 1);
} }
close( inputFileFd); close(inputFileFd);
} }
return( TRUE); return (TRUE);
} }
extern inline int writeTarFile(const char* tarName, int verboseFlag, char **argv, static inline int writeTarFile(const char *tarName, int verboseFlag,
char** excludeList, int gzip) char **argv, char **excludeList, int gzip)
{ {
#ifdef CONFIG_FEATURE_TAR_GZIP #ifdef CONFIG_FEATURE_TAR_GZIP
int gzipDataPipe [2] = { -1, -1 }; int gzipDataPipe[2] = { -1, -1 };
int gzipStatusPipe [2] = { -1, -1 }; int gzipStatusPipe[2] = { -1, -1 };
pid_t gzipPid = 0; pid_t gzipPid = 0;
#endif #endif
int errorFlag=FALSE; int errorFlag = FALSE;
ssize_t size; ssize_t size;
struct TarBallInfo tbInfo; struct TarBallInfo tbInfo;
tbInfo.hlInfoHead = NULL; tbInfo.hlInfoHead = NULL;
/* Make sure there is at least one file to tar up. */ /* Make sure there is at least one file to tar up. */
@ -470,16 +478,15 @@ extern inline int writeTarFile(const char* tarName, int verboseFlag, char **argv
if (tarName == NULL) { if (tarName == NULL) {
tbInfo.tarFd = fileno(stdout); tbInfo.tarFd = fileno(stdout);
tbInfo.verboseFlag = verboseFlag ? 2 : 0; tbInfo.verboseFlag = verboseFlag ? 2 : 0;
} } else {
else { tbInfo.tarFd = open(tarName, O_WRONLY | O_CREAT | O_TRUNC, 0644);
tbInfo.tarFd = open (tarName, O_WRONLY | O_CREAT | O_TRUNC, 0644);
tbInfo.verboseFlag = verboseFlag ? 1 : 0; tbInfo.verboseFlag = verboseFlag ? 1 : 0;
} }
if (tbInfo.tarFd < 0) { if (tbInfo.tarFd < 0) {
perror_msg( "Error opening '%s'", tarName); perror_msg("Error opening '%s'", tarName);
freeHardLinkInfo(&tbInfo.hlInfoHead); freeHardLinkInfo(&tbInfo.hlInfoHead);
return ( FALSE); return (FALSE);
} }
/* Store the stat info for the tarball's file, so /* Store the stat info for the tarball's file, so
@ -488,67 +495,67 @@ extern inline int writeTarFile(const char* tarName, int verboseFlag, char **argv
error_msg_and_die(io_error, tarName, strerror(errno)); error_msg_and_die(io_error, tarName, strerror(errno));
#ifdef CONFIG_FEATURE_TAR_GZIP #ifdef CONFIG_FEATURE_TAR_GZIP
if ( gzip ) { if (gzip) {
if ( socketpair ( AF_UNIX, SOCK_STREAM, 0, gzipDataPipe ) < 0 || pipe ( gzipStatusPipe ) < 0 ) if (socketpair(AF_UNIX, SOCK_STREAM, 0, gzipDataPipe) < 0
perror_msg_and_die ( "Failed to create gzip pipe" ); || pipe(gzipStatusPipe) < 0)
perror_msg_and_die("Failed to create gzip pipe");
signal ( SIGPIPE, SIG_IGN ); // we only want EPIPE on errors signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */
gzipPid = fork ( ); gzipPid = fork();
if ( gzipPid == 0 ) { if (gzipPid == 0) {
dup2 ( gzipDataPipe [0], 0 ); dup2(gzipDataPipe[0], 0);
close ( gzipDataPipe [1] ); close(gzipDataPipe[1]);
if ( tbInfo. tarFd != 1 ); if (tbInfo.tarFd != 1);
dup2 ( tbInfo. tarFd, 1 ); dup2(tbInfo.tarFd, 1);
close ( gzipStatusPipe [0] ); close(gzipStatusPipe[0]);
fcntl( gzipStatusPipe [1], F_SETFD, FD_CLOEXEC ); // close on exec shows sucess fcntl(gzipStatusPipe[1], F_SETFD, FD_CLOEXEC); /* close on exec shows sucess */
execl ( "/bin/gzip", "gzip", "-f", 0 ); execl("/bin/gzip", "gzip", "-f", 0);
write ( gzipStatusPipe [1], "", 1 ); write(gzipStatusPipe[1], "", 1);
close ( gzipStatusPipe [1] ); close(gzipStatusPipe[1]);
exit ( -1 ); exit(-1);
} } else if (gzipPid > 0) {
else if ( gzipPid > 0 ) { close(gzipDataPipe[0]);
close ( gzipDataPipe [0] ); close(gzipStatusPipe[1]);
close ( gzipStatusPipe [1] );
while ( 1 ) { while (1) {
char buf; char buf;
int n = read ( gzipStatusPipe [0], &buf, 1 ); int n = read(gzipStatusPipe[0], &buf, 1);
if ( n == 1 )
error_msg_and_die ( "Could not exec gzip process" ); // socket was not closed => error
else if (( n < 0 ) && ( errno==EAGAIN || errno==EINTR ))
continue; // try it again
break;
}
close ( gzipStatusPipe [0] );
tbInfo. tarFd = gzipDataPipe [1]; if (n == 1)
} error_msg_and_die("Could not exec gzip process"); /* socket was not closed => error */
else { else if ((n < 0) && (errno == EAGAIN || errno == EINTR))
perror_msg_and_die ( "Failed to fork gzip process" ); continue; /* try it again */
break;
}
close(gzipStatusPipe[0]);
tbInfo.tarFd = gzipDataPipe[1];
} else {
perror_msg_and_die("Failed to fork gzip process");
} }
} }
#endif #endif
tbInfo.excludeList=excludeList; tbInfo.excludeList = excludeList;
/* Read the directory/files and iterate over them one at a time */ /* Read the directory/files and iterate over them one at a time */
while (*argv != NULL) { while (*argv != NULL) {
if (! recursive_action(*argv++, TRUE, FALSE, FALSE, if (!recursive_action(*argv++, TRUE, FALSE, FALSE,
writeFileToTarball, writeFileToTarball, writeFileToTarball, writeFileToTarball,
(void*) &tbInfo)) { (void *) &tbInfo)) {
errorFlag = TRUE; errorFlag = TRUE;
} }
} }
/* Write two empty blocks to the end of the archive */ /* Write two empty blocks to the end of the archive */
for (size=0; size<(2*TAR_BLOCK_SIZE); size++) { for (size = 0; size < (2 * TAR_BLOCK_SIZE); size++) {
write(tbInfo.tarFd, "\0", 1); write(tbInfo.tarFd, "\0", 1);
} }
@ -565,15 +572,15 @@ extern inline int writeTarFile(const char* tarName, int verboseFlag, char **argv
freeHardLinkInfo(&tbInfo.hlInfoHead); freeHardLinkInfo(&tbInfo.hlInfoHead);
#ifdef CONFIG_FEATURE_TAR_GZIP #ifdef CONFIG_FEATURE_TAR_GZIP
if ( gzip && gzipPid ) { if (gzip && gzipPid) {
if ( waitpid ( gzipPid, NULL, 0 ) == -1 ) if (waitpid(gzipPid, NULL, 0) == -1)
printf ( "Couldnt wait ?" ); printf("Couldnt wait ?");
} }
#endif #endif
return !errorFlag; return !errorFlag;
} }
#endif //tar_create #endif /* tar_create */
void append_file_to_list(const char *new_name, char ***list, int *list_count) void append_file_to_list(const char *new_name, char ***list, int *list_count)
{ {
@ -583,62 +590,21 @@ void append_file_to_list(const char *new_name, char ***list, int *list_count)
(*list)[*list_count] = NULL; (*list)[*list_count] = NULL;
} }
void append_file_list_to_list(char *filename, char ***name_list, int *num_of_entries) void append_file_list_to_list(char *filename, char ***name_list,
int *num_of_entries)
{ {
FILE *src_stream; FILE *src_stream;
char *line; char *line;
src_stream = xfopen(filename, "r"); src_stream = xfopen(filename, "r");
while ((line = get_line_from_file(src_stream)) != NULL) { while ((line = get_line_from_file(src_stream)) != NULL) {
chomp (line); chomp(line);
append_file_to_list(line, name_list, num_of_entries); append_file_to_list(line, name_list, num_of_entries);
free(line); free(line);
} }
fclose(src_stream); fclose(src_stream);
} }
#ifdef CONFIG_FEATURE_TAR_EXCLUDE
/*
* Create a list of names that are in the include list AND NOT in the exclude lists
*/
#if 0 /* this is unused */
char **list_and_not_list(char **include_list, char **exclude_list)
{
char **new_include_list = NULL;
int new_include_count = 0;
int include_count = 0;
int exclude_count;
if (include_list == NULL) {
return(NULL);
}
while (include_list[include_count] != NULL) {
int found = FALSE;
exclude_count = 0;
while (exclude_list[exclude_count] != NULL) {
if (strcmp(include_list[include_count], exclude_list[exclude_count]) == 0) {
found = TRUE;
break;
}
exclude_count++;
}
if (! found) {
new_include_list = realloc(new_include_list, sizeof(char *) * (include_count + 2));
new_include_list[new_include_count] = include_list[include_count];
new_include_count++;
} else {
free(include_list[include_count]);
}
include_count++;
}
new_include_list[new_include_count] = NULL;
return(new_include_list);
}
#endif
#endif
int tar_main(int argc, char **argv) int tar_main(int argc, char **argv)
{ {
enum untar_funct_e { enum untar_funct_e {
@ -661,6 +627,7 @@ int tar_main(int argc, char **argv)
unsigned short untar_funct_required = 0; unsigned short untar_funct_required = 0;
unsigned short extract_function = 0; unsigned short extract_function = 0;
int include_list_count = 0; int include_list_count = 0;
#ifdef CONFIG_FEATURE_TAR_EXCLUDE #ifdef CONFIG_FEATURE_TAR_EXCLUDE
int exclude_list_count = 0; int exclude_list_count = 0;
#endif #endif
@ -676,6 +643,7 @@ int tar_main(int argc, char **argv)
/* Prepend '-' to the first argument if required */ /* Prepend '-' to the first argument if required */
if (argv[1][0] != '-') { if (argv[1][0] != '-') {
char *tmp = xmalloc(strlen(argv[1]) + 2); char *tmp = xmalloc(strlen(argv[1]) + 2);
tmp[0] = '-'; tmp[0] = '-';
strcpy(tmp + 1, argv[1]); strcpy(tmp + 1, argv[1]);
argv[1] = tmp; argv[1] = tmp;
@ -684,36 +652,40 @@ int tar_main(int argc, char **argv)
while ((opt = getopt(argc, argv, "ctxT:X:C:f:Opvz")) != -1) { while ((opt = getopt(argc, argv, "ctxT:X:C:f:Opvz")) != -1) {
switch (opt) { switch (opt) {
/* One and only one of these is required */ /* One and only one of these is required */
case 'c': case 'c':
untar_funct_required |= untar_create; untar_funct_required |= untar_create;
break; break;
case 't': case 't':
untar_funct_required |= untar_list; untar_funct_required |= untar_list;
extract_function |= extract_list |extract_unconditional; extract_function |= extract_list | extract_unconditional;
break; break;
case 'x': case 'x':
untar_funct_required |= untar_extract; untar_funct_required |= untar_extract;
extract_function |= (extract_all_to_fs | extract_unconditional | extract_create_leading_dirs); extract_function |=
(extract_all_to_fs | extract_unconditional |
extract_create_leading_dirs);
break; break;
/* These are optional */ /* These are optional */
/* Exclude or Include files listed in <filename>*/ /* Exclude or Include files listed in <filename> */
#ifdef CONFIG_FEATURE_TAR_EXCLUDE #ifdef CONFIG_FEATURE_TAR_EXCLUDE
case 'X': case 'X':
append_file_list_to_list(optarg, &exclude_list, &exclude_list_count); append_file_list_to_list(optarg, &exclude_list,
&exclude_list_count);
break; break;
#endif #endif
case 'T': case 'T':
// by default a list is an include list /* by default a list is an include list */
append_file_list_to_list(optarg, &include_list, &include_list_count); append_file_list_to_list(optarg, &include_list,
&include_list_count);
break; break;
case 'C': // Change to dir <optarg> case 'C': /* Change to dir <optarg> */
/* Make sure dst_prefix ends in a '/' */ /* Make sure dst_prefix ends in a '/' */
dst_prefix = concat_path_file(optarg, "/"); dst_prefix = concat_path_file(optarg, "/");
break; break;
case 'f': // archive filename case 'f': /* archive filename */
if (strcmp(optarg, "-") == 0) { if (strcmp(optarg, "-") == 0) {
src_filename = NULL; src_filename = NULL;
} else { } else {
@ -743,8 +715,8 @@ int tar_main(int argc, char **argv)
error_msg_and_die("You must specify one of the `-ctx' options"); error_msg_and_die("You must specify one of the `-ctx' options");
} }
if ((untar_funct_required != untar_create) && if ((untar_funct_required != untar_create) &&
(untar_funct_required != untar_extract) && (untar_funct_required != untar_extract) &&
(untar_funct_required != untar_list)) { (untar_funct_required != untar_list)) {
error_msg_and_die("You may not specify more than one `ctx' option."); error_msg_and_die("You may not specify more than one `ctx' option.");
} }
untar_funct |= untar_funct_required; untar_funct |= untar_funct_required;
@ -770,11 +742,12 @@ int tar_main(int argc, char **argv)
if (untar_funct & untar_unzip) { if (untar_funct & untar_unzip) {
uncompressed_stream = gz_open(src_stream, &gunzip_pid); uncompressed_stream = gz_open(src_stream, &gunzip_pid);
} else } else
#endif // CONFIG_FEATURE_TAR_GZIP #endif /* CONFIG_FEATURE_TAR_GZIP */
uncompressed_stream = src_stream; uncompressed_stream = src_stream;
/* extract or list archive */ /* extract or list archive */
unarchive(uncompressed_stream, stdout, &get_header_tar, extract_function, dst_prefix, include_list, exclude_list); unarchive(uncompressed_stream, stdout, &get_header_tar,
extract_function, dst_prefix, include_list, exclude_list);
fclose(uncompressed_stream); fclose(uncompressed_stream);
} }
#ifdef CONFIG_FEATURE_TAR_CREATE #ifdef CONFIG_FEATURE_TAR_CREATE
@ -787,26 +760,27 @@ int tar_main(int argc, char **argv)
if (untar_funct & untar_unzip) if (untar_funct & untar_unzip)
gzipFlag = TRUE; gzipFlag = TRUE;
#endif // CONFIG_FEATURE_TAR_GZIP #endif /* CONFIG_FEATURE_TAR_GZIP */
if (extract_function & extract_verbose_list) if (extract_function & extract_verbose_list)
verboseFlag = TRUE; verboseFlag = TRUE;
writeTarFile(src_filename, verboseFlag, include_list, exclude_list, gzipFlag); writeTarFile(src_filename, verboseFlag, include_list, exclude_list,
gzipFlag);
} }
#endif // CONFIG_FEATURE_TAR_CREATE #endif /* CONFIG_FEATURE_TAR_CREATE */
/* Cleanups */ /* Cleanups */
#ifdef CONFIG_FEATURE_TAR_GZIP #ifdef CONFIG_FEATURE_TAR_GZIP
if ( !( untar_funct & untar_create ) && ( untar_funct & untar_unzip )) { if (!(untar_funct & untar_create) && (untar_funct & untar_unzip)) {
fclose(src_stream); fclose(src_stream);
close(gz_fd); close(gz_fd);
gz_close(gunzip_pid); gz_close(gunzip_pid);
} }
#endif // CONFIG_FEATURE_TAR_GZIP #endif /* CONFIG_FEATURE_TAR_GZIP */
#ifdef CONFIG_FEATURE_CLEAN_UP #ifdef CONFIG_FEATURE_CLEAN_UP
if (src_filename) { if (src_filename) {
free(src_filename); free(src_filename);
} }
#endif #endif
return(EXIT_SUCCESS); return (EXIT_SUCCESS);
} }