forked from Imagelibrary/rtems
libmisc/untar: Set the perms to the value in the tar file.
This patch parses the mode field in the tar header and sets the directory or file to the mode value in the header. Closes #2768.
This commit is contained in:
@@ -250,6 +250,7 @@ static int
|
||||
Untar_ProcessHeader(
|
||||
const char *bufr,
|
||||
char *fname,
|
||||
unsigned long *mode,
|
||||
unsigned long *file_size,
|
||||
unsigned long *nblocks,
|
||||
unsigned char *linkflag,
|
||||
@@ -286,6 +287,8 @@ Untar_ProcessHeader(
|
||||
strncpy(fname, bufr, MAX_NAME_FIELD_SIZE);
|
||||
fname[MAX_NAME_FIELD_SIZE] = '\0';
|
||||
|
||||
*mode = strtoul(&bufr[100], NULL, 8);
|
||||
|
||||
*linkflag = bufr[156];
|
||||
*file_size = _rtems_octal2ulong(&bufr[124], 12);
|
||||
|
||||
@@ -299,7 +302,8 @@ Untar_ProcessHeader(
|
||||
rtems_printf(printer, "untar: symlink: %s -> %s\n", linkname, fname);
|
||||
symlink(linkname, fname);
|
||||
} else if (*linkflag == REGTYPE) {
|
||||
rtems_printf(printer, "untar: file: %s (%i)\n", fname, (int) *file_size);
|
||||
rtems_printf(printer, "untar: file: %s (s:%i,m:%04o)\n",
|
||||
fname, (int) *file_size, (int) *mode);
|
||||
*nblocks = (((*file_size) + 511) & ~511) / 512;
|
||||
if (Make_Path(printer, fname, false) < 0) {
|
||||
retval = UNTAR_FAIL;
|
||||
@@ -318,7 +322,7 @@ Untar_ProcessHeader(
|
||||
if (!S_ISDIR(stat_buf.st_mode)) {
|
||||
r = unlink(fname);
|
||||
if (r == 0) {
|
||||
r = mkdir(fname, S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
r = mkdir(fname, *mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -362,15 +366,16 @@ Untar_FromMemory_Print(
|
||||
const rtems_printer *printer
|
||||
)
|
||||
{
|
||||
FILE *fp;
|
||||
int fd;
|
||||
const char *tar_ptr = (const char *)tar_buf;
|
||||
const char *bufr;
|
||||
char fname[100];
|
||||
int retval = UNTAR_SUCCESSFUL;
|
||||
unsigned long ptr;
|
||||
unsigned long nblocks;
|
||||
unsigned long file_size;
|
||||
unsigned char linkflag;
|
||||
unsigned long nblocks = 0;
|
||||
unsigned long file_size = 0;
|
||||
unsigned long mode = 0;
|
||||
unsigned char linkflag = 0;
|
||||
|
||||
rtems_printf(printer, "untar: memory at %p (%zu)\n", tar_buf, size);
|
||||
|
||||
@@ -385,20 +390,21 @@ Untar_FromMemory_Print(
|
||||
bufr = &tar_ptr[ptr];
|
||||
ptr += 512;
|
||||
|
||||
retval = Untar_ProcessHeader(bufr, fname, &file_size, &nblocks, &linkflag, printer);
|
||||
retval = Untar_ProcessHeader(bufr, fname, &mode, &file_size,
|
||||
&nblocks, &linkflag, printer);
|
||||
|
||||
if (retval != UNTAR_SUCCESSFUL)
|
||||
break;
|
||||
|
||||
if (linkflag == REGTYPE) {
|
||||
if ((fp = fopen(fname, "w")) == NULL) {
|
||||
if ((fd = open(fname, O_TRUNC | O_CREAT | O_WRONLY, mode)) == -1) {
|
||||
Print_Error(printer, "open", fname);
|
||||
ptr += 512 * nblocks;
|
||||
} else {
|
||||
unsigned long sizeToGo = file_size;
|
||||
size_t len;
|
||||
size_t i;
|
||||
size_t n;
|
||||
ssize_t len;
|
||||
ssize_t i;
|
||||
ssize_t n;
|
||||
|
||||
/*
|
||||
* Read out the data. There are nblocks of data where nblocks is the
|
||||
@@ -406,7 +412,7 @@ Untar_FromMemory_Print(
|
||||
*/
|
||||
for (i = 0; i < nblocks; i++) {
|
||||
len = ((sizeToGo < 512L) ? (sizeToGo) : (512L));
|
||||
n = fwrite(&tar_ptr[ptr], 1, len, fp);
|
||||
n = write(fd, &tar_ptr[ptr], len);
|
||||
if (n != len) {
|
||||
Print_Error(printer, "write", fname);
|
||||
retval = UNTAR_FAIL;
|
||||
@@ -415,7 +421,7 @@ Untar_FromMemory_Print(
|
||||
ptr += 512;
|
||||
sizeToGo -= n;
|
||||
}
|
||||
fclose(fp);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -485,9 +491,10 @@ Untar_FromFile_Print(
|
||||
char fname[100];
|
||||
int retval;
|
||||
unsigned long i;
|
||||
unsigned long nblocks;
|
||||
unsigned long file_size;
|
||||
unsigned char linkflag;
|
||||
unsigned long nblocks = 0;
|
||||
unsigned long file_size = 0;
|
||||
unsigned long mode = 0;
|
||||
unsigned char linkflag = 0;
|
||||
|
||||
retval = UNTAR_SUCCESSFUL;
|
||||
|
||||
@@ -508,7 +515,8 @@ Untar_FromFile_Print(
|
||||
break;
|
||||
}
|
||||
|
||||
retval = Untar_ProcessHeader(bufr, fname, &file_size, &nblocks, &linkflag, printer);
|
||||
retval = Untar_ProcessHeader(bufr, fname, &mode, &file_size,
|
||||
&nblocks, &linkflag, printer);
|
||||
|
||||
if (retval != UNTAR_SUCCESSFUL)
|
||||
break;
|
||||
@@ -521,7 +529,7 @@ Untar_FromFile_Print(
|
||||
* is the size rounded to the nearest 512-byte boundary.
|
||||
*/
|
||||
|
||||
if ((out_fd = creat(fname, 0644)) == -1) {
|
||||
if ((out_fd = creat(fname, mode)) == -1) {
|
||||
(void) lseek(fd, SEEK_CUR, 512UL * nblocks);
|
||||
} else {
|
||||
for (i = 0; i < nblocks; i++) {
|
||||
@@ -579,6 +587,7 @@ int Untar_FromChunk_Print(
|
||||
retval = Untar_ProcessHeader(
|
||||
&context->header[0],
|
||||
&context->fname[0],
|
||||
&context->mode,
|
||||
&context->todo_bytes,
|
||||
&context->todo_blocks,
|
||||
&linkflag,
|
||||
@@ -591,7 +600,7 @@ int Untar_FromChunk_Print(
|
||||
}
|
||||
|
||||
if (linkflag == REGTYPE) {
|
||||
context->out_fd = creat(&context->fname[0], 0644);
|
||||
context->out_fd = creat(&context->fname[0], context->mode);
|
||||
|
||||
if (context->out_fd >= 0) {
|
||||
context->state = UNTAR_CHUNK_WRITE;
|
||||
|
||||
@@ -73,10 +73,15 @@ typedef struct {
|
||||
*/
|
||||
size_t done_bytes;
|
||||
|
||||
/**
|
||||
* @brief Mode of the file.
|
||||
*/
|
||||
unsigned long mode;
|
||||
|
||||
/**
|
||||
* @brief Overall amount of bytes to be processed.
|
||||
*/
|
||||
long unsigned todo_bytes;
|
||||
unsigned long todo_bytes;
|
||||
|
||||
/**
|
||||
* @brief Overall amount of blocks to be processed.
|
||||
|
||||
@@ -9,7 +9,7 @@ tar01_SOURCES += initial_filesystem_tar_gz.c
|
||||
tar01_SOURCES += initial_filesystem_tar_gz.h
|
||||
|
||||
tar01_LDADD = -lrtemscpu -lz
|
||||
|
||||
|
||||
BUILT_SOURCES =
|
||||
BUILT_SOURCES += initial_filesystem_tar.c
|
||||
BUILT_SOURCES += initial_filesystem_tar.h
|
||||
@@ -57,6 +57,9 @@ initial_filesystem.tar:
|
||||
$(MKDIR_P) initial_fs/home
|
||||
(echo "This is a test of loading an RTEMS filesystem from an" ; \
|
||||
echo "initial tar image.") >initial_fs/home/test_file
|
||||
(echo "#! joel" ; \
|
||||
echo "ls -las /dev") >initial_fs/home/test_script
|
||||
chmod +x initial_fs/home/test_script
|
||||
(cd initial_fs; \
|
||||
$(LN_S) home/test_file symlink; \
|
||||
$(PAX) -w -f ../initial_filesystem.tar home symlink)
|
||||
|
||||
@@ -46,6 +46,16 @@ void test_cat(
|
||||
int length
|
||||
);
|
||||
|
||||
static void test_untar_check_mode(const char* file, int mode)
|
||||
{
|
||||
struct stat sb;
|
||||
int fmode;
|
||||
rtems_test_assert(stat(file, &sb) == 0);
|
||||
fmode = sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
printf(" %s: mode: %04o want: %04o\n", file, fmode, mode);
|
||||
rtems_test_assert(fmode == mode);
|
||||
}
|
||||
|
||||
void test_untar_from_memory(void)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
@@ -65,6 +75,11 @@ void test_untar_from_memory(void)
|
||||
printf( "========= /home/test_file =========\n" );
|
||||
test_cat( "/home/test_file", 0, 0 );
|
||||
|
||||
/******************/
|
||||
printf( "========= /home/test_script =========\n" );
|
||||
test_cat( "/home/test_script", 0, 0 );
|
||||
test_untar_check_mode("/home/test_script", 0755);
|
||||
|
||||
/******************/
|
||||
printf( "========= /symlink =========\n" );
|
||||
test_cat( "/symlink", 0, 0 );
|
||||
@@ -106,6 +121,11 @@ void test_untar_from_file(void)
|
||||
printf( "========= /dest/home/test_file =========\n" );
|
||||
test_cat( "/dest/home/test_file", 0, 0 );
|
||||
|
||||
/******************/
|
||||
printf( "========= /dest/home/test_script =========\n" );
|
||||
test_cat( "/dest/home/test_script", 0, 0 );
|
||||
test_untar_check_mode("/dest/home/test_script", 0755);
|
||||
|
||||
/******************/
|
||||
printf( "========= /dest/symlink =========\n" );
|
||||
test_cat( "/dest/symlink", 0, 0 );
|
||||
@@ -143,6 +163,11 @@ void test_untar_chunks_from_memory(void)
|
||||
printf( "========= /dest2/home/test_file =========\n" );
|
||||
test_cat( "/dest2/home/test_file", 0, 0 );
|
||||
|
||||
/******************/
|
||||
printf( "========= /dest2/home/test_script =========\n" );
|
||||
test_cat( "/dest2/home/test_script", 0, 0 );
|
||||
test_untar_check_mode("/dest2/home/test_script", 0755);
|
||||
|
||||
/******************/
|
||||
printf( "========= /dest2/symlink =========\n" );
|
||||
test_cat( "/dest2/symlink", 0, 0 );
|
||||
@@ -183,6 +208,11 @@ void test_untar_unzip_tgz(void)
|
||||
printf( "========= /dest3/home/test_file =========\n" );
|
||||
test_cat( "/dest3/home/test_file", 0, 0 );
|
||||
|
||||
/******************/
|
||||
printf( "========= /dest3/home/test_script =========\n" );
|
||||
test_cat( "/dest3/home/test_script", 0, 0 );
|
||||
test_untar_check_mode("/dest3/home/test_script", 0755);
|
||||
|
||||
/******************/
|
||||
printf( "========= /dest3/symlink =========\n" );
|
||||
test_cat( "/dest3/symlink", 0, 0 );
|
||||
|
||||
Reference in New Issue
Block a user