aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn L McGrath <bug1@ihug.co.nz>2002-08-22 13:44:08 +0000
committerGlenn L McGrath <bug1@ihug.co.nz>2002-08-22 13:44:08 +0000
commita0ee881ba446ceab5f6b3dcb51429091ecd22ff8 (patch)
treea771443a62ba6c7c6b8aac0f62545a84f520c870
parent4176972db5a65af78d13fed97ab84bf4fceaee2c (diff)
downloadbusybox-w32-a0ee881ba446ceab5f6b3dcb51429091ecd22ff8.tar.gz
busybox-w32-a0ee881ba446ceab5f6b3dcb51429091ecd22ff8.tar.bz2
busybox-w32-a0ee881ba446ceab5f6b3dcb51429091ecd22ff8.zip
Run through indent, use /* */ style comments, change extern to static
-rw-r--r--archival/tar.c546
1 files changed, 260 insertions, 286 deletions
diff --git a/archival/tar.c b/archival/tar.c
index b68882b52..2ab022954 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -56,8 +56,8 @@
56#ifdef CONFIG_FEATURE_TAR_CREATE 56#ifdef CONFIG_FEATURE_TAR_CREATE
57 57
58/* Tar file constants */ 58/* Tar file constants */
59# define TAR_MAGIC "ustar" /* ustar and a null */ 59# define TAR_MAGIC "ustar" /* ustar and a null */
60# define TAR_VERSION " " /* Be compatable with GNU tar format */ 60# define TAR_VERSION " " /* Be compatable with GNU tar format */
61 61
62# ifndef MAJOR 62# ifndef MAJOR
63# define MAJOR(dev) (((dev)>>8)&0xff) 63# define MAJOR(dev) (((dev)>>8)&0xff)
@@ -69,26 +69,25 @@ static const int TAR_MAGIC_LEN = 6;
69static const int TAR_VERSION_LEN = 2; 69static const int TAR_VERSION_LEN = 2;
70 70
71/* POSIX tar Header Block, from POSIX 1003.1-1990 */ 71/* POSIX tar Header Block, from POSIX 1003.1-1990 */
72enum { NAME_SIZE = 100 }; /* because gcc won't let me use 'static const int' */ 72enum { NAME_SIZE = 100 }; /* because gcc won't let me use 'static const int' */
73struct TarHeader 73struct TarHeader { /* byte offset */
74{ /* byte offset */ 74 char name[NAME_SIZE]; /* 0-99 */
75 char name[NAME_SIZE]; /* 0-99 */ 75 char mode[8]; /* 100-107 */
76 char mode[8]; /* 100-107 */ 76 char uid[8]; /* 108-115 */
77 char uid[8]; /* 108-115 */ 77 char gid[8]; /* 116-123 */
78 char gid[8]; /* 116-123 */ 78 char size[12]; /* 124-135 */
79 char size[12]; /* 124-135 */ 79 char mtime[12]; /* 136-147 */
80 char mtime[12]; /* 136-147 */ 80 char chksum[8]; /* 148-155 */
81 char chksum[8]; /* 148-155 */ 81 char typeflag; /* 156-156 */
82 char typeflag; /* 156-156 */ 82 char linkname[NAME_SIZE]; /* 157-256 */
83 char linkname[NAME_SIZE]; /* 157-256 */ 83 char magic[6]; /* 257-262 */
84 char magic[6]; /* 257-262 */ 84 char version[2]; /* 263-264 */
85 char version[2]; /* 263-264 */ 85 char uname[32]; /* 265-296 */
86 char uname[32]; /* 265-296 */ 86 char gname[32]; /* 297-328 */
87 char gname[32]; /* 297-328 */ 87 char devmajor[8]; /* 329-336 */
88 char devmajor[8]; /* 329-336 */ 88 char devminor[8]; /* 337-344 */
89 char devminor[8]; /* 337-344 */ 89 char prefix[155]; /* 345-499 */
90 char prefix[155]; /* 345-499 */ 90 char padding[12]; /* 500-512 (pad to exactly the TAR_BLOCK_SIZE) */
91 char padding[12]; /* 500-512 (pad to exactly the TAR_BLOCK_SIZE) */
92}; 91};
93typedef struct TarHeader TarHeader; 92typedef struct TarHeader TarHeader;
94 93
@@ -98,58 +97,56 @@ typedef struct TarHeader TarHeader;
98** Even these functions use the xxxHardLinkInfo() functions. 97** Even these functions use the xxxHardLinkInfo() functions.
99*/ 98*/
100typedef struct HardLinkInfo HardLinkInfo; 99typedef struct HardLinkInfo HardLinkInfo;
101struct HardLinkInfo 100struct HardLinkInfo {
102{ 101 HardLinkInfo *next; /* Next entry in list */
103 HardLinkInfo *next; /* Next entry in list */ 102 dev_t dev; /* Device number */
104 dev_t dev; /* Device number */ 103 ino_t ino; /* Inode number */
105 ino_t ino; /* Inode number */ 104 short linkCount; /* (Hard) Link Count */
106 short linkCount; /* (Hard) Link Count */ 105 char name[1]; /* Start of filename (must be last) */
107 char name[1]; /* Start of filename (must be last) */
108}; 106};
109 107
110/* Some info to be carried along when creating a new tarball */ 108/* Some info to be carried along when creating a new tarball */
111struct TarBallInfo 109struct TarBallInfo {
112{ 110 char *fileName; /* File name of the tarball */
113 char* fileName; /* File name of the tarball */ 111 int tarFd; /* Open-for-write file descriptor
114 int tarFd; /* Open-for-write file descriptor 112 for the tarball */
115 for the tarball */ 113 struct stat statBuf; /* Stat info for the tarball, letting
116 struct stat statBuf; /* Stat info for the tarball, letting 114 us know the inode and device that the
117 us know the inode and device that the 115 tarball lives, so we can avoid trying
118 tarball lives, so we can avoid trying 116 to include the tarball into itself */
119 to include the tarball into itself */ 117 int verboseFlag; /* Whether to print extra stuff or not */
120 int verboseFlag; /* Whether to print extra stuff or not */ 118 char **excludeList; /* List of files to not include */
121 char** excludeList; /* List of files to not include */ 119 HardLinkInfo *hlInfoHead; /* Hard Link Tracking Information */
122 HardLinkInfo *hlInfoHead; /* Hard Link Tracking Information */ 120 HardLinkInfo *hlInfo; /* Hard Link Info for the current file */
123 HardLinkInfo *hlInfo; /* Hard Link Info for the current file */
124}; 121};
125typedef struct TarBallInfo TarBallInfo; 122typedef struct TarBallInfo TarBallInfo;
126 123
127/* A nice enum with all the possible tar file content types */ 124/* A nice enum with all the possible tar file content types */
128enum TarFileType 125enum TarFileType {
129{ 126 REGTYPE = '0', /* regular file */
130 REGTYPE = '0', /* regular file */ 127 REGTYPE0 = '\0', /* regular file (ancient bug compat) */
131 REGTYPE0 = '\0', /* regular file (ancient bug compat)*/ 128 LNKTYPE = '1', /* hard link */
132 LNKTYPE = '1', /* hard link */ 129 SYMTYPE = '2', /* symbolic link */
133 SYMTYPE = '2', /* symbolic link */ 130 CHRTYPE = '3', /* character special */
134 CHRTYPE = '3', /* character special */ 131 BLKTYPE = '4', /* block special */
135 BLKTYPE = '4', /* block special */ 132 DIRTYPE = '5', /* directory */
136 DIRTYPE = '5', /* directory */ 133 FIFOTYPE = '6', /* FIFO special */
137 FIFOTYPE = '6', /* FIFO special */ 134 CONTTYPE = '7', /* reserved */
138 CONTTYPE = '7', /* reserved */ 135 GNULONGLINK = 'K', /* GNU long (>100 chars) link name */
139 GNULONGLINK = 'K', /* GNU long (>100 chars) link name */ 136 GNULONGNAME = 'L', /* GNU long (>100 chars) file name */
140 GNULONGNAME = 'L', /* GNU long (>100 chars) file name */
141}; 137};
142typedef enum TarFileType TarFileType; 138typedef enum TarFileType TarFileType;
143 139
144/* Might be faster (and bigger) if the dev/ino were stored in numeric order;) */ 140/* Might be faster (and bigger) if the dev/ino were stored in numeric order;) */
145extern inline void 141static inline void addHardLinkInfo(HardLinkInfo ** hlInfoHeadPtr, dev_t dev,
146addHardLinkInfo (HardLinkInfo **hlInfoHeadPtr, dev_t dev, ino_t ino, 142 ino_t ino, short linkCount,
147 short linkCount, const char *name) 143 const char *name)
148{ 144{
149 /* Note: hlInfoHeadPtr can never be NULL! */ 145 /* Note: hlInfoHeadPtr can never be NULL! */
150 HardLinkInfo *hlInfo; 146 HardLinkInfo *hlInfo;
151 147
152 hlInfo = (HardLinkInfo *)xmalloc(sizeof(HardLinkInfo)+strlen(name)+1); 148 hlInfo =
149 (HardLinkInfo *) xmalloc(sizeof(HardLinkInfo) + strlen(name) + 1);
153 if (hlInfo) { 150 if (hlInfo) {
154 hlInfo->next = *hlInfoHeadPtr; 151 hlInfo->next = *hlInfoHeadPtr;
155 *hlInfoHeadPtr = hlInfo; 152 *hlInfoHeadPtr = hlInfo;
@@ -161,8 +158,7 @@ addHardLinkInfo (HardLinkInfo **hlInfoHeadPtr, dev_t dev, ino_t ino,
161 return; 158 return;
162} 159}
163 160
164static void 161static void freeHardLinkInfo(HardLinkInfo ** hlInfoHeadPtr)
165freeHardLinkInfo (HardLinkInfo **hlInfoHeadPtr)
166{ 162{
167 HardLinkInfo *hlInfo = NULL; 163 HardLinkInfo *hlInfo = NULL;
168 HardLinkInfo *hlInfoNext = NULL; 164 HardLinkInfo *hlInfoNext = NULL;
@@ -180,21 +176,21 @@ freeHardLinkInfo (HardLinkInfo **hlInfoHeadPtr)
180} 176}
181 177
182/* Might be faster (and bigger) if the dev/ino were stored in numeric order;) */ 178/* Might be faster (and bigger) if the dev/ino were stored in numeric order;) */
183extern inline HardLinkInfo * 179static inline HardLinkInfo *findHardLinkInfo(HardLinkInfo * hlInfo, dev_t dev,
184findHardLinkInfo (HardLinkInfo *hlInfo, dev_t dev, ino_t ino) 180 ino_t ino)
185{ 181{
186 while(hlInfo) { 182 while (hlInfo) {
187 if ((ino == hlInfo->ino) && (dev == hlInfo->dev)) 183 if ((ino == hlInfo->ino) && (dev == hlInfo->dev))
188 break; 184 break;
189 hlInfo = hlInfo->next; 185 hlInfo = hlInfo->next;
190 } 186 }
191 return(hlInfo); 187 return (hlInfo);
192} 188}
193 189
194/* Put an octal string into the specified buffer. 190/* Put an octal string into the specified buffer.
195 * The number is zero and space padded and possibly null padded. 191 * The number is zero and space padded and possibly null padded.
196 * Returns TRUE if successful. */ 192 * Returns TRUE if successful. */
197static int putOctal (char *cp, int len, long value) 193static int putOctal(char *cp, int len, long value)
198{ 194{
199 int tempLength; 195 int tempLength;
200 char tempBuffer[32]; 196 char tempBuffer[32];
@@ -202,10 +198,10 @@ static int putOctal (char *cp, int len, long value)
202 198
203 /* Create a string of the specified length with an initial space, 199 /* Create a string of the specified length with an initial space,
204 * leading zeroes and the octal number, and a trailing null. */ 200 * leading zeroes and the octal number, and a trailing null. */
205 sprintf (tempString, "%0*lo", len - 1, value); 201 sprintf(tempString, "%0*lo", len - 1, value);
206 202
207 /* If the string is too large, suppress the leading space. */ 203 /* If the string is too large, suppress the leading space. */
208 tempLength = strlen (tempString) + 1; 204 tempLength = strlen(tempString) + 1;
209 if (tempLength > len) { 205 if (tempLength > len) {
210 tempLength--; 206 tempLength--;
211 tempString++; 207 tempString++;
@@ -220,71 +216,77 @@ static int putOctal (char *cp, int len, long value)
220 return FALSE; 216 return FALSE;
221 217
222 /* Copy the string to the field. */ 218 /* Copy the string to the field. */
223 memcpy (cp, tempString, len); 219 memcpy(cp, tempString, len);
224 220
225 return TRUE; 221 return TRUE;
226} 222}
227 223
228/* Write out a tar header for the specified file/directory/whatever */ 224/* Write out a tar header for the specified file/directory/whatever */
229extern inline int 225static inline int writeTarHeader(struct TarBallInfo *tbInfo,
230writeTarHeader(struct TarBallInfo *tbInfo, const char *header_name, 226 const char *header_name,
231 const char *real_name, struct stat *statbuf) 227 const char *real_name, struct stat *statbuf)
232{ 228{
233 long chksum=0; 229 long chksum = 0;
234 struct TarHeader header; 230 struct TarHeader header;
235 const unsigned char *cp = (const unsigned char *) &header; 231 const unsigned char *cp = (const unsigned char *) &header;
236 ssize_t size = sizeof(struct TarHeader); 232 ssize_t size = sizeof(struct TarHeader);
237
238 memset( &header, 0, size);
239 233
240 strncpy(header.name, header_name, sizeof(header.name)); 234 memset(&header, 0, size);
235
236 strncpy(header.name, header_name, sizeof(header.name));
241 237
242 putOctal(header.mode, sizeof(header.mode), statbuf->st_mode); 238 putOctal(header.mode, sizeof(header.mode), statbuf->st_mode);
243 putOctal(header.uid, sizeof(header.uid), statbuf->st_uid); 239 putOctal(header.uid, sizeof(header.uid), statbuf->st_uid);
244 putOctal(header.gid, sizeof(header.gid), statbuf->st_gid); 240 putOctal(header.gid, sizeof(header.gid), statbuf->st_gid);
245 putOctal(header.size, sizeof(header.size), 0); /* Regular file size is handled later */ 241 putOctal(header.size, sizeof(header.size), 0); /* Regular file size is handled later */
246 putOctal(header.mtime, sizeof(header.mtime), statbuf->st_mtime); 242 putOctal(header.mtime, sizeof(header.mtime), statbuf->st_mtime);
247 strncpy(header.magic, TAR_MAGIC TAR_VERSION, 243 strncpy(header.magic, TAR_MAGIC TAR_VERSION,
248 TAR_MAGIC_LEN + TAR_VERSION_LEN ); 244 TAR_MAGIC_LEN + TAR_VERSION_LEN);
249 245
250 /* Enter the user and group names (default to root if it fails) */ 246 /* Enter the user and group names (default to root if it fails) */
251 my_getpwuid(header.uname, statbuf->st_uid); 247 my_getpwuid(header.uname, statbuf->st_uid);
252 if (! *header.uname) 248 if (!*header.uname)
253 strcpy(header.uname, "root"); 249 strcpy(header.uname, "root");
254 my_getgrgid(header.gname, statbuf->st_gid); 250 my_getgrgid(header.gname, statbuf->st_gid);
255 if (! *header.uname) 251 if (!*header.uname)
256 strcpy(header.uname, "root"); 252 strcpy(header.uname, "root");
257 253
258 if (tbInfo->hlInfo) { 254 if (tbInfo->hlInfo) {
259 /* This is a hard link */ 255 /* This is a hard link */
260 header.typeflag = LNKTYPE; 256 header.typeflag = LNKTYPE;
261 strncpy(header.linkname, tbInfo->hlInfo->name, sizeof(header.linkname)); 257 strncpy(header.linkname, tbInfo->hlInfo->name,
258 sizeof(header.linkname));
262 } else if (S_ISLNK(statbuf->st_mode)) { 259 } else if (S_ISLNK(statbuf->st_mode)) {
263 char *lpath = xreadlink(real_name); 260 char *lpath = xreadlink(real_name);
264 if (!lpath) /* Already printed err msg inside xreadlink() */ 261
265 return ( FALSE); 262 if (!lpath) /* Already printed err msg inside xreadlink() */
266 header.typeflag = SYMTYPE; 263 return (FALSE);
267 strncpy(header.linkname, lpath, sizeof(header.linkname)); 264 header.typeflag = SYMTYPE;
265 strncpy(header.linkname, lpath, sizeof(header.linkname));
268 free(lpath); 266 free(lpath);
269 } else if (S_ISDIR(statbuf->st_mode)) { 267 } else if (S_ISDIR(statbuf->st_mode)) {
270 header.typeflag = DIRTYPE; 268 header.typeflag = DIRTYPE;
271 strncat(header.name, "/", sizeof(header.name)); 269 strncat(header.name, "/", sizeof(header.name));
272 } else if (S_ISCHR(statbuf->st_mode)) { 270 } else if (S_ISCHR(statbuf->st_mode)) {
273 header.typeflag = CHRTYPE; 271 header.typeflag = CHRTYPE;
274 putOctal(header.devmajor, sizeof(header.devmajor), MAJOR(statbuf->st_rdev)); 272 putOctal(header.devmajor, sizeof(header.devmajor),
275 putOctal(header.devminor, sizeof(header.devminor), MINOR(statbuf->st_rdev)); 273 MAJOR(statbuf->st_rdev));
274 putOctal(header.devminor, sizeof(header.devminor),
275 MINOR(statbuf->st_rdev));
276 } else if (S_ISBLK(statbuf->st_mode)) { 276 } else if (S_ISBLK(statbuf->st_mode)) {
277 header.typeflag = BLKTYPE; 277 header.typeflag = BLKTYPE;
278 putOctal(header.devmajor, sizeof(header.devmajor), MAJOR(statbuf->st_rdev)); 278 putOctal(header.devmajor, sizeof(header.devmajor),
279 putOctal(header.devminor, sizeof(header.devminor), MINOR(statbuf->st_rdev)); 279 MAJOR(statbuf->st_rdev));
280 putOctal(header.devminor, sizeof(header.devminor),
281 MINOR(statbuf->st_rdev));
280 } else if (S_ISFIFO(statbuf->st_mode)) { 282 } else if (S_ISFIFO(statbuf->st_mode)) {
281 header.typeflag = FIFOTYPE; 283 header.typeflag = FIFOTYPE;
282 } else if (S_ISREG(statbuf->st_mode)) { 284 } else if (S_ISREG(statbuf->st_mode)) {
283 header.typeflag = REGTYPE; 285 header.typeflag = REGTYPE;
284 putOctal(header.size, sizeof(header.size), statbuf->st_size); 286 putOctal(header.size, sizeof(header.size), statbuf->st_size);
285 } else { 287 } else {
286 error_msg("%s: Unknown file type", real_name); 288 error_msg("%s: Unknown file type", real_name);
287 return ( FALSE); 289 return (FALSE);
288 } 290 }
289 291
290 /* Calculate and store the checksum (i.e., the sum of all of the bytes of 292 /* Calculate and store the checksum (i.e., the sum of all of the bytes of
@@ -297,30 +299,33 @@ writeTarHeader(struct TarBallInfo *tbInfo, const char *header_name,
297 while (size-- > 0) 299 while (size-- > 0)
298 chksum += *cp++; 300 chksum += *cp++;
299 putOctal(header.chksum, 7, chksum); 301 putOctal(header.chksum, 7, chksum);
300 302
301 /* Now write the header out to disk */ 303 /* Now write the header out to disk */
302 if ((size=full_write(tbInfo->tarFd, (char*)&header, sizeof(struct TarHeader))) < 0) { 304 if ((size =
303 error_msg(io_error, real_name, strerror(errno)); 305 full_write(tbInfo->tarFd, (char *) &header,
304 return ( FALSE); 306 sizeof(struct TarHeader))) < 0) {
307 error_msg(io_error, real_name, strerror(errno));
308 return (FALSE);
305 } 309 }
306 /* Pad the header up to the tar block size */ 310 /* Pad the header up to the tar block size */
307 for (; size<TAR_BLOCK_SIZE; size++) { 311 for (; size < TAR_BLOCK_SIZE; size++) {
308 write(tbInfo->tarFd, "\0", 1); 312 write(tbInfo->tarFd, "\0", 1);
309 } 313 }
310 /* Now do the verbose thing (or not) */ 314 /* Now do the verbose thing (or not) */
311 315
312 if (tbInfo->verboseFlag) { 316 if (tbInfo->verboseFlag) {
313 FILE *vbFd = stdout; 317 FILE *vbFd = stdout;
314 if (tbInfo->verboseFlag == 2) // If the archive goes to stdout, verbose to stderr 318
319 if (tbInfo->verboseFlag == 2) /* If the archive goes to stdout, verbose to stderr */
315 vbFd = stderr; 320 vbFd = stderr;
316 fprintf(vbFd, "%s\n", header.name); 321 fprintf(vbFd, "%s\n", header.name);
317 } 322 }
318 323
319 return ( TRUE); 324 return (TRUE);
320} 325}
321 326
322# if defined CONFIG_FEATURE_TAR_EXCLUDE 327# if defined CONFIG_FEATURE_TAR_EXCLUDE
323extern inline int exclude_file(char **excluded_files, const char *file) 328static inline int exclude_file(char **excluded_files, const char *file)
324{ 329{
325 int i; 330 int i;
326 331
@@ -337,7 +342,7 @@ extern inline int exclude_file(char **excluded_files, const char *file)
337 342
338 for (p = file; p[0] != '\0'; p++) { 343 for (p = file; p[0] != '\0'; p++) {
339 if ((p == file || p[-1] == '/') && p[0] != '/' && 344 if ((p == file || p[-1] == '/') && p[0] != '/' &&
340 fnmatch(excluded_files[i], p, 345 fnmatch(excluded_files[i], p,
341 FNM_PATHNAME | FNM_LEADING_DIR) == 0) 346 FNM_PATHNAME | FNM_LEADING_DIR) == 0)
342 return 1; 347 return 1;
343 } 348 }
@@ -348,55 +353,57 @@ extern inline int exclude_file(char **excluded_files, const char *file)
348} 353}
349#endif 354#endif
350 355
351static int writeFileToTarball(const char *fileName, struct stat *statbuf, void* userData) 356static int writeFileToTarball(const char *fileName, struct stat *statbuf,
357 void *userData)
352{ 358{
353 struct TarBallInfo *tbInfo = (struct TarBallInfo *)userData; 359 struct TarBallInfo *tbInfo = (struct TarBallInfo *) userData;
354 const char *header_name; 360 const char *header_name;
355 361
356 /* 362 /*
357 ** Check to see if we are dealing with a hard link. 363 ** Check to see if we are dealing with a hard link.
358 ** If so - 364 ** If so -
359 ** Treat the first occurance of a given dev/inode as a file while 365 ** Treat the first occurance of a given dev/inode as a file while
360 ** treating any additional occurances as hard links. This is done 366 ** treating any additional occurances as hard links. This is done
361 ** by adding the file information to the HardLinkInfo linked list. 367 ** by adding the file information to the HardLinkInfo linked list.
362 */ 368 */
363 tbInfo->hlInfo = NULL; 369 tbInfo->hlInfo = NULL;
364 if (statbuf->st_nlink > 1) { 370 if (statbuf->st_nlink > 1) {
365 tbInfo->hlInfo = findHardLinkInfo(tbInfo->hlInfoHead, statbuf->st_dev, 371 tbInfo->hlInfo = findHardLinkInfo(tbInfo->hlInfoHead, statbuf->st_dev,
366 statbuf->st_ino); 372 statbuf->st_ino);
367 if (tbInfo->hlInfo == NULL) 373 if (tbInfo->hlInfo == NULL)
368 addHardLinkInfo (&tbInfo->hlInfoHead, statbuf->st_dev, 374 addHardLinkInfo(&tbInfo->hlInfoHead, statbuf->st_dev,
369 statbuf->st_ino, statbuf->st_nlink, fileName); 375 statbuf->st_ino, statbuf->st_nlink, fileName);
370 } 376 }
371 377
372 /* It is against the rules to archive a socket */ 378 /* It is against the rules to archive a socket */
373 if (S_ISSOCK(statbuf->st_mode)) { 379 if (S_ISSOCK(statbuf->st_mode)) {
374 error_msg("%s: socket ignored", fileName); 380 error_msg("%s: socket ignored", fileName);
375 return( TRUE); 381 return (TRUE);
376 } 382 }
377 383
378 /* It is a bad idea to store the archive we are in the process of creating, 384 /* It is a bad idea to store the archive we are in the process of creating,
379 * so check the device and inode to be sure that this particular file isn't 385 * so check the device and inode to be sure that this particular file isn't
380 * the new tarball */ 386 * the new tarball */
381 if (tbInfo->statBuf.st_dev == statbuf->st_dev && 387 if (tbInfo->statBuf.st_dev == statbuf->st_dev &&
382 tbInfo->statBuf.st_ino == statbuf->st_ino) { 388 tbInfo->statBuf.st_ino == statbuf->st_ino) {
383 error_msg("%s: file is the archive; skipping", fileName); 389 error_msg("%s: file is the archive; skipping", fileName);
384 return( TRUE); 390 return (TRUE);
385 } 391 }
386 392
387 header_name = fileName; 393 header_name = fileName;
388 while (header_name[0] == '/') { 394 while (header_name[0] == '/') {
389 static int alreadyWarned=FALSE; 395 static int alreadyWarned = FALSE;
390 if (alreadyWarned==FALSE) { 396
397 if (alreadyWarned == FALSE) {
391 error_msg("Removing leading '/' from member names"); 398 error_msg("Removing leading '/' from member names");
392 alreadyWarned=TRUE; 399 alreadyWarned = TRUE;
393 } 400 }
394 header_name++; 401 header_name++;
395 } 402 }
396 403
397 if (strlen(fileName) >= NAME_SIZE) { 404 if (strlen(fileName) >= NAME_SIZE) {
398 error_msg(name_longer_than_foo, NAME_SIZE); 405 error_msg(name_longer_than_foo, NAME_SIZE);
399 return ( TRUE); 406 return (TRUE);
400 } 407 }
401 408
402 if (header_name[0] == '\0') 409 if (header_name[0] == '\0')
@@ -406,60 +413,61 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf, void*
406 if (exclude_file(tbInfo->excludeList, header_name)) { 413 if (exclude_file(tbInfo->excludeList, header_name)) {
407 return SKIP; 414 return SKIP;
408 } 415 }
409# endif //CONFIG_FEATURE_TAR_EXCLUDE 416# endif /* CONFIG_FEATURE_TAR_EXCLUDE */
410 417
411 if (writeTarHeader(tbInfo, header_name, fileName, statbuf)==FALSE) { 418 if (writeTarHeader(tbInfo, header_name, fileName, statbuf) == FALSE) {
412 return( FALSE); 419 return (FALSE);
413 } 420 }
414 421
415 /* Now, if the file is a regular file, copy it out to the tarball */ 422 /* Now, if the file is a regular file, copy it out to the tarball */
416 if ((tbInfo->hlInfo == NULL) 423 if ((tbInfo->hlInfo == NULL)
417 && (S_ISREG(statbuf->st_mode))) { 424 && (S_ISREG(statbuf->st_mode))) {
418 int inputFileFd; 425 int inputFileFd;
419 char buffer[BUFSIZ]; 426 char buffer[BUFSIZ];
420 ssize_t size=0, readSize=0; 427 ssize_t size = 0, readSize = 0;
421 428
422 /* open the file we want to archive, and make sure all is well */ 429 /* open the file we want to archive, and make sure all is well */
423 if ((inputFileFd = open(fileName, O_RDONLY)) < 0) { 430 if ((inputFileFd = open(fileName, O_RDONLY)) < 0) {
424 error_msg("%s: Cannot open: %s", fileName, strerror(errno)); 431 error_msg("%s: Cannot open: %s", fileName, strerror(errno));
425 return( FALSE); 432 return (FALSE);
426 } 433 }
427 434
428 /* write the file to the archive */ 435 /* write the file to the archive */
429 while ( (size = full_read(inputFileFd, buffer, sizeof(buffer))) > 0 ) { 436 while ((size = full_read(inputFileFd, buffer, sizeof(buffer))) > 0) {
430 if (full_write(tbInfo->tarFd, buffer, size) != size ) { 437 if (full_write(tbInfo->tarFd, buffer, size) != size) {
431 /* Output file seems to have a problem */ 438 /* Output file seems to have a problem */
432 error_msg(io_error, fileName, strerror(errno)); 439 error_msg(io_error, fileName, strerror(errno));
433 return( FALSE); 440 return (FALSE);
434 } 441 }
435 readSize+=size; 442 readSize += size;
436 } 443 }
437 if (size == -1) { 444 if (size == -1) {
438 error_msg(io_error, fileName, strerror(errno)); 445 error_msg(io_error, fileName, strerror(errno));
439 return( FALSE); 446 return (FALSE);
440 } 447 }
441 /* Pad the file up to the tar block size */ 448 /* Pad the file up to the tar block size */
442 for (; (readSize%TAR_BLOCK_SIZE) != 0; readSize++) { 449 for (; (readSize % TAR_BLOCK_SIZE) != 0; readSize++) {
443 write(tbInfo->tarFd, "\0", 1); 450 write(tbInfo->tarFd, "\0", 1);
444 } 451 }
445 close( inputFileFd); 452 close(inputFileFd);
446 } 453 }
447 454
448 return( TRUE); 455 return (TRUE);
449} 456}
450 457
451extern inline int writeTarFile(const char* tarName, int verboseFlag, char **argv, 458static inline int writeTarFile(const char *tarName, int verboseFlag,
452 char** excludeList, int gzip) 459 char **argv, char **excludeList, int gzip)
453{ 460{
454#ifdef CONFIG_FEATURE_TAR_GZIP 461#ifdef CONFIG_FEATURE_TAR_GZIP
455 int gzipDataPipe [2] = { -1, -1 }; 462 int gzipDataPipe[2] = { -1, -1 };
456 int gzipStatusPipe [2] = { -1, -1 }; 463 int gzipStatusPipe[2] = { -1, -1 };
457 pid_t gzipPid = 0; 464 pid_t gzipPid = 0;
458#endif 465#endif
459 466
460 int errorFlag=FALSE; 467 int errorFlag = FALSE;
461 ssize_t size; 468 ssize_t size;
462 struct TarBallInfo tbInfo; 469 struct TarBallInfo tbInfo;
470
463 tbInfo.hlInfoHead = NULL; 471 tbInfo.hlInfoHead = NULL;
464 472
465 /* Make sure there is at least one file to tar up. */ 473 /* Make sure there is at least one file to tar up. */
@@ -470,85 +478,84 @@ extern inline int writeTarFile(const char* tarName, int verboseFlag, char **argv
470 if (tarName == NULL) { 478 if (tarName == NULL) {
471 tbInfo.tarFd = fileno(stdout); 479 tbInfo.tarFd = fileno(stdout);
472 tbInfo.verboseFlag = verboseFlag ? 2 : 0; 480 tbInfo.verboseFlag = verboseFlag ? 2 : 0;
473 } 481 } else {
474 else { 482 tbInfo.tarFd = open(tarName, O_WRONLY | O_CREAT | O_TRUNC, 0644);
475 tbInfo.tarFd = open (tarName, O_WRONLY | O_CREAT | O_TRUNC, 0644);
476 tbInfo.verboseFlag = verboseFlag ? 1 : 0; 483 tbInfo.verboseFlag = verboseFlag ? 1 : 0;
477 } 484 }
478 485
479 if (tbInfo.tarFd < 0) { 486 if (tbInfo.tarFd < 0) {
480 perror_msg( "Error opening '%s'", tarName); 487 perror_msg("Error opening '%s'", tarName);
481 freeHardLinkInfo(&tbInfo.hlInfoHead); 488 freeHardLinkInfo(&tbInfo.hlInfoHead);
482 return ( FALSE); 489 return (FALSE);
483 } 490 }
484 491
485 /* Store the stat info for the tarball's file, so 492 /* Store the stat info for the tarball's file, so
486 * can avoid including the tarball into itself.... */ 493 * can avoid including the tarball into itself.... */
487 if (fstat(tbInfo.tarFd, &tbInfo.statBuf) < 0) 494 if (fstat(tbInfo.tarFd, &tbInfo.statBuf) < 0)
488 error_msg_and_die(io_error, tarName, strerror(errno)); 495 error_msg_and_die(io_error, tarName, strerror(errno));
489 496
490#ifdef CONFIG_FEATURE_TAR_GZIP 497#ifdef CONFIG_FEATURE_TAR_GZIP
491 if ( gzip ) { 498 if (gzip) {
492 if ( socketpair ( AF_UNIX, SOCK_STREAM, 0, gzipDataPipe ) < 0 || pipe ( gzipStatusPipe ) < 0 ) 499 if (socketpair(AF_UNIX, SOCK_STREAM, 0, gzipDataPipe) < 0
493 perror_msg_and_die ( "Failed to create gzip pipe" ); 500 || pipe(gzipStatusPipe) < 0)
494 501 perror_msg_and_die("Failed to create gzip pipe");
495 signal ( SIGPIPE, SIG_IGN ); // we only want EPIPE on errors 502
496 503 signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */
497 gzipPid = fork ( ); 504
498 505 gzipPid = fork();
499 if ( gzipPid == 0 ) { 506
500 dup2 ( gzipDataPipe [0], 0 ); 507 if (gzipPid == 0) {
501 close ( gzipDataPipe [1] ); 508 dup2(gzipDataPipe[0], 0);
502 509 close(gzipDataPipe[1]);
503 if ( tbInfo. tarFd != 1 ); 510
504 dup2 ( tbInfo. tarFd, 1 ); 511 if (tbInfo.tarFd != 1);
505 512 dup2(tbInfo.tarFd, 1);
506 close ( gzipStatusPipe [0] ); 513
507 fcntl( gzipStatusPipe [1], F_SETFD, FD_CLOEXEC ); // close on exec shows sucess 514 close(gzipStatusPipe[0]);
508 515 fcntl(gzipStatusPipe[1], F_SETFD, FD_CLOEXEC); /* close on exec shows sucess */
509 execl ( "/bin/gzip", "gzip", "-f", 0 ); 516
510 517 execl("/bin/gzip", "gzip", "-f", 0);
511 write ( gzipStatusPipe [1], "", 1 ); 518
512 close ( gzipStatusPipe [1] ); 519 write(gzipStatusPipe[1], "", 1);
513 520 close(gzipStatusPipe[1]);
514 exit ( -1 ); 521
515 } 522 exit(-1);
516 else if ( gzipPid > 0 ) { 523 } else if (gzipPid > 0) {
517 close ( gzipDataPipe [0] ); 524 close(gzipDataPipe[0]);
518 close ( gzipStatusPipe [1] ); 525 close(gzipStatusPipe[1]);
519 526
520 while ( 1 ) { 527 while (1) {
521 char buf; 528 char buf;
522 529
523 int n = read ( gzipStatusPipe [0], &buf, 1 ); 530 int n = read(gzipStatusPipe[0], &buf, 1);
524 if ( n == 1 ) 531
525 error_msg_and_die ( "Could not exec gzip process" ); // socket was not closed => error 532 if (n == 1)
526 else if (( n < 0 ) && ( errno==EAGAIN || errno==EINTR )) 533 error_msg_and_die("Could not exec gzip process"); /* socket was not closed => error */
527 continue; // try it again 534 else if ((n < 0) && (errno == EAGAIN || errno == EINTR))
528 break; 535 continue; /* try it again */
536 break;
529 } 537 }
530 close ( gzipStatusPipe [0] ); 538 close(gzipStatusPipe[0]);
531 539
532 tbInfo. tarFd = gzipDataPipe [1]; 540 tbInfo.tarFd = gzipDataPipe[1];
533 } 541 } else {
534 else { 542 perror_msg_and_die("Failed to fork gzip process");
535 perror_msg_and_die ( "Failed to fork gzip process" );
536 } 543 }
537 } 544 }
538#endif 545#endif
539 546
540 tbInfo.excludeList=excludeList; 547 tbInfo.excludeList = excludeList;
541 548
542 /* Read the directory/files and iterate over them one at a time */ 549 /* Read the directory/files and iterate over them one at a time */
543 while (*argv != NULL) { 550 while (*argv != NULL) {
544 if (! recursive_action(*argv++, TRUE, FALSE, FALSE, 551 if (!recursive_action(*argv++, TRUE, FALSE, FALSE,
545 writeFileToTarball, writeFileToTarball, 552 writeFileToTarball, writeFileToTarball,
546 (void*) &tbInfo)) { 553 (void *) &tbInfo)) {
547 errorFlag = TRUE; 554 errorFlag = TRUE;
548 } 555 }
549 } 556 }
550 /* Write two empty blocks to the end of the archive */ 557 /* Write two empty blocks to the end of the archive */
551 for (size=0; size<(2*TAR_BLOCK_SIZE); size++) { 558 for (size = 0; size < (2 * TAR_BLOCK_SIZE); size++) {
552 write(tbInfo.tarFd, "\0", 1); 559 write(tbInfo.tarFd, "\0", 1);
553 } 560 }
554 561
@@ -559,21 +566,21 @@ extern inline int writeTarFile(const char* tarName, int verboseFlag, char **argv
559 566
560 /* Hang up the tools, close up shop, head home */ 567 /* Hang up the tools, close up shop, head home */
561 close(tbInfo.tarFd); 568 close(tbInfo.tarFd);
562 if (errorFlag) 569 if (errorFlag)
563 error_msg("Error exit delayed from previous errors"); 570 error_msg("Error exit delayed from previous errors");
564 571
565 freeHardLinkInfo(&tbInfo.hlInfoHead); 572 freeHardLinkInfo(&tbInfo.hlInfoHead);
566 573
567#ifdef CONFIG_FEATURE_TAR_GZIP 574#ifdef CONFIG_FEATURE_TAR_GZIP
568 if ( gzip && gzipPid ) { 575 if (gzip && gzipPid) {
569 if ( waitpid ( gzipPid, NULL, 0 ) == -1 ) 576 if (waitpid(gzipPid, NULL, 0) == -1)
570 printf ( "Couldnt wait ?" ); 577 printf("Couldnt wait ?");
571 } 578 }
572#endif 579#endif
573 580
574 return !errorFlag; 581 return !errorFlag;
575} 582}
576#endif //tar_create 583#endif /* tar_create */
577 584
578void append_file_to_list(const char *new_name, char ***list, int *list_count) 585void append_file_to_list(const char *new_name, char ***list, int *list_count)
579{ 586{
@@ -583,62 +590,21 @@ void append_file_to_list(const char *new_name, char ***list, int *list_count)
583 (*list)[*list_count] = NULL; 590 (*list)[*list_count] = NULL;
584} 591}
585 592
586void append_file_list_to_list(char *filename, char ***name_list, int *num_of_entries) 593void append_file_list_to_list(char *filename, char ***name_list,
594 int *num_of_entries)
587{ 595{
588 FILE *src_stream; 596 FILE *src_stream;
589 char *line; 597 char *line;
590 598
591 src_stream = xfopen(filename, "r"); 599 src_stream = xfopen(filename, "r");
592 while ((line = get_line_from_file(src_stream)) != NULL) { 600 while ((line = get_line_from_file(src_stream)) != NULL) {
593 chomp (line); 601 chomp(line);
594 append_file_to_list(line, name_list, num_of_entries); 602 append_file_to_list(line, name_list, num_of_entries);
595 free(line); 603 free(line);
596 } 604 }
597 fclose(src_stream); 605 fclose(src_stream);
598} 606}
599 607
600#ifdef CONFIG_FEATURE_TAR_EXCLUDE
601/*
602 * Create a list of names that are in the include list AND NOT in the exclude lists
603 */
604#if 0 /* this is unused */
605char **list_and_not_list(char **include_list, char **exclude_list)
606{
607 char **new_include_list = NULL;
608 int new_include_count = 0;
609 int include_count = 0;
610 int exclude_count;
611
612 if (include_list == NULL) {
613 return(NULL);
614 }
615
616 while (include_list[include_count] != NULL) {
617 int found = FALSE;
618 exclude_count = 0;
619 while (exclude_list[exclude_count] != NULL) {
620 if (strcmp(include_list[include_count], exclude_list[exclude_count]) == 0) {
621 found = TRUE;
622 break;
623 }
624 exclude_count++;
625 }
626
627 if (! found) {
628 new_include_list = realloc(new_include_list, sizeof(char *) * (include_count + 2));
629 new_include_list[new_include_count] = include_list[include_count];
630 new_include_count++;
631 } else {
632 free(include_list[include_count]);
633 }
634 include_count++;
635 }
636 new_include_list[new_include_count] = NULL;
637 return(new_include_list);
638}
639#endif
640#endif
641
642int tar_main(int argc, char **argv) 608int tar_main(int argc, char **argv)
643{ 609{
644 enum untar_funct_e { 610 enum untar_funct_e {
@@ -661,6 +627,7 @@ int tar_main(int argc, char **argv)
661 unsigned short untar_funct_required = 0; 627 unsigned short untar_funct_required = 0;
662 unsigned short extract_function = 0; 628 unsigned short extract_function = 0;
663 int include_list_count = 0; 629 int include_list_count = 0;
630
664#ifdef CONFIG_FEATURE_TAR_EXCLUDE 631#ifdef CONFIG_FEATURE_TAR_EXCLUDE
665 int exclude_list_count = 0; 632 int exclude_list_count = 0;
666#endif 633#endif
@@ -676,6 +643,7 @@ int tar_main(int argc, char **argv)
676 /* Prepend '-' to the first argument if required */ 643 /* Prepend '-' to the first argument if required */
677 if (argv[1][0] != '-') { 644 if (argv[1][0] != '-') {
678 char *tmp = xmalloc(strlen(argv[1]) + 2); 645 char *tmp = xmalloc(strlen(argv[1]) + 2);
646
679 tmp[0] = '-'; 647 tmp[0] = '-';
680 strcpy(tmp + 1, argv[1]); 648 strcpy(tmp + 1, argv[1]);
681 argv[1] = tmp; 649 argv[1] = tmp;
@@ -684,36 +652,40 @@ int tar_main(int argc, char **argv)
684 while ((opt = getopt(argc, argv, "ctxT:X:C:f:Opvz")) != -1) { 652 while ((opt = getopt(argc, argv, "ctxT:X:C:f:Opvz")) != -1) {
685 switch (opt) { 653 switch (opt) {
686 654
687 /* One and only one of these is required */ 655 /* One and only one of these is required */
688 case 'c': 656 case 'c':
689 untar_funct_required |= untar_create; 657 untar_funct_required |= untar_create;
690 break; 658 break;
691 case 't': 659 case 't':
692 untar_funct_required |= untar_list; 660 untar_funct_required |= untar_list;
693 extract_function |= extract_list |extract_unconditional; 661 extract_function |= extract_list | extract_unconditional;
694 break; 662 break;
695 case 'x': 663 case 'x':
696 untar_funct_required |= untar_extract; 664 untar_funct_required |= untar_extract;
697 extract_function |= (extract_all_to_fs | extract_unconditional | extract_create_leading_dirs); 665 extract_function |=
666 (extract_all_to_fs | extract_unconditional |
667 extract_create_leading_dirs);
698 break; 668 break;
699 669
700 /* These are optional */ 670 /* These are optional */
701 /* Exclude or Include files listed in <filename>*/ 671 /* Exclude or Include files listed in <filename> */
702#ifdef CONFIG_FEATURE_TAR_EXCLUDE 672#ifdef CONFIG_FEATURE_TAR_EXCLUDE
703 case 'X': 673 case 'X':
704 append_file_list_to_list(optarg, &exclude_list, &exclude_list_count); 674 append_file_list_to_list(optarg, &exclude_list,
675 &exclude_list_count);
705 break; 676 break;
706#endif 677#endif
707 case 'T': 678 case 'T':
708 // by default a list is an include list 679 /* by default a list is an include list */
709 append_file_list_to_list(optarg, &include_list, &include_list_count); 680 append_file_list_to_list(optarg, &include_list,
681 &include_list_count);
710 break; 682 break;
711 683
712 case 'C': // Change to dir <optarg> 684 case 'C': /* Change to dir <optarg> */
713 /* Make sure dst_prefix ends in a '/' */ 685 /* Make sure dst_prefix ends in a '/' */
714 dst_prefix = concat_path_file(optarg, "/"); 686 dst_prefix = concat_path_file(optarg, "/");
715 break; 687 break;
716 case 'f': // archive filename 688 case 'f': /* archive filename */
717 if (strcmp(optarg, "-") == 0) { 689 if (strcmp(optarg, "-") == 0) {
718 src_filename = NULL; 690 src_filename = NULL;
719 } else { 691 } else {
@@ -742,9 +714,9 @@ int tar_main(int argc, char **argv)
742 if (untar_funct_required == 0) { 714 if (untar_funct_required == 0) {
743 error_msg_and_die("You must specify one of the `-ctx' options"); 715 error_msg_and_die("You must specify one of the `-ctx' options");
744 } 716 }
745 if ((untar_funct_required != untar_create) && 717 if ((untar_funct_required != untar_create) &&
746 (untar_funct_required != untar_extract) && 718 (untar_funct_required != untar_extract) &&
747 (untar_funct_required != untar_list)) { 719 (untar_funct_required != untar_list)) {
748 error_msg_and_die("You may not specify more than one `ctx' option."); 720 error_msg_and_die("You may not specify more than one `ctx' option.");
749 } 721 }
750 untar_funct |= untar_funct_required; 722 untar_funct |= untar_funct_required;
@@ -770,11 +742,12 @@ int tar_main(int argc, char **argv)
770 if (untar_funct & untar_unzip) { 742 if (untar_funct & untar_unzip) {
771 uncompressed_stream = gz_open(src_stream, &gunzip_pid); 743 uncompressed_stream = gz_open(src_stream, &gunzip_pid);
772 } else 744 } else
773#endif // CONFIG_FEATURE_TAR_GZIP 745#endif /* CONFIG_FEATURE_TAR_GZIP */
774 uncompressed_stream = src_stream; 746 uncompressed_stream = src_stream;
775 747
776 /* extract or list archive */ 748 /* extract or list archive */
777 unarchive(uncompressed_stream, stdout, &get_header_tar, extract_function, dst_prefix, include_list, exclude_list); 749 unarchive(uncompressed_stream, stdout, &get_header_tar,
750 extract_function, dst_prefix, include_list, exclude_list);
778 fclose(uncompressed_stream); 751 fclose(uncompressed_stream);
779 } 752 }
780#ifdef CONFIG_FEATURE_TAR_CREATE 753#ifdef CONFIG_FEATURE_TAR_CREATE
@@ -787,26 +760,27 @@ int tar_main(int argc, char **argv)
787 if (untar_funct & untar_unzip) 760 if (untar_funct & untar_unzip)
788 gzipFlag = TRUE; 761 gzipFlag = TRUE;
789 762
790#endif // CONFIG_FEATURE_TAR_GZIP 763#endif /* CONFIG_FEATURE_TAR_GZIP */
791 if (extract_function & extract_verbose_list) 764 if (extract_function & extract_verbose_list)
792 verboseFlag = TRUE; 765 verboseFlag = TRUE;
793 766
794 writeTarFile(src_filename, verboseFlag, include_list, exclude_list, gzipFlag); 767 writeTarFile(src_filename, verboseFlag, include_list, exclude_list,
768 gzipFlag);
795 } 769 }
796#endif // CONFIG_FEATURE_TAR_CREATE 770#endif /* CONFIG_FEATURE_TAR_CREATE */
797 771
798 /* Cleanups */ 772 /* Cleanups */
799#ifdef CONFIG_FEATURE_TAR_GZIP 773#ifdef CONFIG_FEATURE_TAR_GZIP
800 if ( !( untar_funct & untar_create ) && ( untar_funct & untar_unzip )) { 774 if (!(untar_funct & untar_create) && (untar_funct & untar_unzip)) {
801 fclose(src_stream); 775 fclose(src_stream);
802 close(gz_fd); 776 close(gz_fd);
803 gz_close(gunzip_pid); 777 gz_close(gunzip_pid);
804 } 778 }
805#endif // CONFIG_FEATURE_TAR_GZIP 779#endif /* CONFIG_FEATURE_TAR_GZIP */
806#ifdef CONFIG_FEATURE_CLEAN_UP 780#ifdef CONFIG_FEATURE_CLEAN_UP
807 if (src_filename) { 781 if (src_filename) {
808 free(src_filename); 782 free(src_filename);
809 } 783 }
810#endif 784#endif
811 return(EXIT_SUCCESS); 785 return (EXIT_SUCCESS);
812} 786}