summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cpukit/libmisc/untar/untar.c47
-rw-r--r--cpukit/libmisc/untar/untar.h7
-rw-r--r--testsuites/libtests/tar01/Makefile.am5
-rw-r--r--testsuites/libtests/tar01/init.c30
4 files changed, 68 insertions, 21 deletions
diff --git a/cpukit/libmisc/untar/untar.c b/cpukit/libmisc/untar/untar.c
index 9a14f67e4e..ecf1877a24 100644
--- a/cpukit/libmisc/untar/untar.c
+++ b/cpukit/libmisc/untar/untar.c
@@ -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;
diff --git a/cpukit/libmisc/untar/untar.h b/cpukit/libmisc/untar/untar.h
index 4d00d369b2..3c8bb74130 100644
--- a/cpukit/libmisc/untar/untar.h
+++ b/cpukit/libmisc/untar/untar.h
@@ -74,9 +74,14 @@ 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.
diff --git a/testsuites/libtests/tar01/Makefile.am b/testsuites/libtests/tar01/Makefile.am
index d7257bc69f..8b03e59c2d 100644
--- a/testsuites/libtests/tar01/Makefile.am
+++ b/testsuites/libtests/tar01/Makefile.am
@@ -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)
diff --git a/testsuites/libtests/tar01/init.c b/testsuites/libtests/tar01/init.c
index 4bfa29c636..7d4f1b9a2a 100644
--- a/testsuites/libtests/tar01/init.c
+++ b/testsuites/libtests/tar01/init.c
@@ -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;
@@ -66,6 +76,11 @@ void test_untar_from_memory(void)
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 );
@@ -107,6 +122,11 @@ void test_untar_from_file(void)
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 );
}
@@ -144,6 +164,11 @@ void test_untar_chunks_from_memory(void)
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 );
@@ -184,6 +209,11 @@ void test_untar_unzip_tgz(void)
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 );
}