forked from Imagelibrary/rtems
untar: do not exit with error when created directory already exists.
The problem exists for both RTEMS untar implementations and their variants: Untar_FromMemory(), Untar_FromFile() and rtems_tarfs_load(). If filesystem object already exists at extracted directory path then if it is directory, creation is ignored. Attempt to delete/unlink object and make directory is tried for other cases. This simple approach problem reported in ticket fixes #2413. Behavior follows GNU tar and BSD tar practice for directories but much more work is required to achieve full semantics of the full featured tar implementation still.
This commit is contained in:
@@ -103,8 +103,24 @@ int rtems_tarfs_load(
|
||||
strcat(full_filename, "/");
|
||||
++len;
|
||||
strncat(full_filename, filename, 256-len-1);
|
||||
rv = mkdir(full_filename, S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
if ( mkdir(full_filename, S_IRWXU | S_IRWXG | S_IRWXO) != 0 ) {
|
||||
if (errno == EEXIST) {
|
||||
struct stat stat_buf;
|
||||
if ( stat(full_filename, &stat_buf) == 0 ) {
|
||||
if ( S_ISDIR(stat_buf.st_mode) ) {
|
||||
continue;
|
||||
} else {
|
||||
if ( unlink(full_filename) != -1 ) {
|
||||
if ( mkdir(full_filename, S_IRWXU | S_IRWXG | S_IRWXO) == 0 )
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rv = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a LINEAR_FILE node
|
||||
*/
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <rtems/untar.h>
|
||||
@@ -203,6 +204,19 @@ Untar_FromMemory(
|
||||
}
|
||||
} else if (linkflag == DIRTYPE) {
|
||||
if ( mkdir(fname, S_IRWXU | S_IRWXG | S_IRWXO) != 0 ) {
|
||||
if (errno == EEXIST) {
|
||||
struct stat stat_buf;
|
||||
if ( stat(fname, &stat_buf) == 0 ) {
|
||||
if ( S_ISDIR(stat_buf.st_mode) ) {
|
||||
continue;
|
||||
} else {
|
||||
if ( unlink(fname) != -1 ) {
|
||||
if ( mkdir(fname, S_IRWXU | S_IRWXG | S_IRWXO) == 0 )
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
printk("Untar: failed to create directory %s\n", fname);
|
||||
retval = UNTAR_FAIL;
|
||||
break;
|
||||
@@ -319,7 +333,21 @@ Untar_FromFile(
|
||||
close(out_fd);
|
||||
}
|
||||
} else if (linkflag == DIRTYPE) {
|
||||
(void) mkdir(fname, S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
if ( mkdir(fname, S_IRWXU | S_IRWXG | S_IRWXO) != 0 ) {
|
||||
if (errno == EEXIST) {
|
||||
struct stat stat_buf;
|
||||
if ( stat(fname, &stat_buf) == 0 ) {
|
||||
if ( S_ISDIR(stat_buf.st_mode) ) {
|
||||
continue;
|
||||
} else {
|
||||
if ( unlink(fname) != -1 ) {
|
||||
if ( mkdir(fname, S_IRWXU | S_IRWXG | S_IRWXO) == 0 )
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(bufr);
|
||||
|
||||
Reference in New Issue
Block a user