diff options
Diffstat (limited to 'cpukit/libmisc/untar')
-rw-r--r-- | cpukit/libmisc/untar/untar.c | 135 | ||||
-rw-r--r-- | cpukit/libmisc/untar/untar_tgz.c | 31 | ||||
-rw-r--r-- | cpukit/libmisc/untar/untar_txz.c | 25 |
3 files changed, 136 insertions, 55 deletions
diff --git a/cpukit/libmisc/untar/untar.c b/cpukit/libmisc/untar/untar.c index a2f09fb99f..fff737db68 100644 --- a/cpukit/libmisc/untar/untar.c +++ b/cpukit/libmisc/untar/untar.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /** * @file * @@ -11,9 +13,26 @@ * * Copyright 2016 Chris Johns <chrisj@rtems.org> * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H @@ -65,6 +84,14 @@ #define MAX_NAME_FIELD_SIZE 99 +#define TAR_BLOCK_SIZE 512 +#define TAR_BLOCK_SIZE_MASK (TAR_BLOCK_SIZE - 1) + +/* + * Number of blocks read or written + */ +#define TAR_WORK_BLOCKS 16 + static int _rtems_tar_header_checksum(const char *bufr); /* @@ -126,30 +153,25 @@ Make_Path(const rtems_printer *printer, char *path) *p = '\0'; if (p[1] == '\0') { - /* Speculatively unlink the last component so that it can be re-created */ - unlink(path); return 0; } if (mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO) != 0) { - if (errno == EEXIST || errno == EISDIR) { + if (errno == EEXIST) { + /* If it exists already: Check whether it is a directory */ struct stat sb; - - if (stat(path, &sb) != 0) { + if (lstat(path, &sb) != 0) { + Print_Error(printer, "lstat", path); + return -1; + } else if (!S_ISDIR(sb.st_mode)) { + rtems_printf(printer, + "untar: mkdir: %s: exists but is not a directory\n", + path); return -1; } - - if (!S_ISDIR(sb.st_mode)) { - if (unlink(path) != 0) { - Print_Error(printer, "unlink", path); - return -1; - } - - if (mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO) != 0) { - Print_Error(printer, "mkdir (unlink)", path); - return -1; - } - } + } else { + Print_Error(printer, "mkdir", path); + return -1; } } @@ -206,6 +228,12 @@ Untar_ProcessHeader( if (Make_Path(ctx->printer, ctx->file_path) != 0) { retval = UNTAR_FAIL; + } else { + /* + * Speculatively unlink. This should unlink everything but non-empty + * directories or write protected stuff. + */ + unlink(ctx->file_path); } if (ctx->linkflag == SYMTYPE) { @@ -220,13 +248,28 @@ Untar_ProcessHeader( } else if (ctx->linkflag == REGTYPE) { rtems_printf(ctx->printer, "untar: file: %s (s:%lu,m:%04lo)\n", ctx->file_path, ctx->file_size, ctx->mode); - ctx->nblocks = (((ctx->file_size) + 511) & ~511) / 512; + ctx->nblocks = + (((ctx->file_size) + TAR_BLOCK_SIZE_MASK) & ~TAR_BLOCK_SIZE_MASK) / TAR_BLOCK_SIZE; } else if (ctx->linkflag == DIRTYPE) { rtems_printf(ctx->printer, "untar: dir: %s\n", ctx->file_path); r = mkdir(ctx->file_path, ctx->mode); if (r != 0) { - Print_Error(ctx->printer, "mkdir", ctx->file_path); - retval = UNTAR_FAIL; + if (errno == EEXIST) { + /* If it exists already: Check whether it is a directory */ + struct stat sb; + if (lstat(ctx->file_path, &sb) != 0) { + Print_Error(ctx->printer, "lstat", ctx->file_path); + retval = UNTAR_FAIL; + } else if (!S_ISDIR(sb.st_mode)) { + rtems_printf(ctx->printer, + "untar: mkdir: %s: exists but is not a directory\n", + ctx->file_path); + retval = UNTAR_FAIL; + } + } else { + Print_Error(ctx->printer, "mkdir", ctx->file_path); + retval = UNTAR_FAIL; + } } } @@ -277,14 +320,14 @@ Untar_FromMemory_Print( ptr = 0; while (true) { - if (ptr + 512 > size) { + if (ptr + TAR_BLOCK_SIZE > size) { retval = UNTAR_SUCCESSFUL; break; } /* Read the header */ bufr = &tar_ptr[ptr]; - ptr += 512; + ptr += TAR_BLOCK_SIZE; retval = Untar_ProcessHeader(&ctx, bufr); @@ -295,27 +338,26 @@ Untar_FromMemory_Print( if ((fd = open(ctx.file_path, O_TRUNC | O_CREAT | O_WRONLY, ctx.mode)) == -1) { Print_Error(printer, "open", ctx.file_path); - ptr += 512 * ctx.nblocks; + ptr += TAR_BLOCK_SIZE * ctx.nblocks; } else { - unsigned long sizeToGo = ctx.file_size; - ssize_t len; - ssize_t i; - ssize_t n; - /* * Read out the data. There are nblocks of data where nblocks is the * file_size rounded to the nearest 512-byte boundary. */ - for (i = 0; i < ctx.nblocks; i++) { - len = ((sizeToGo < 512L) ? (sizeToGo) : (512L)); - n = write(fd, &tar_ptr[ptr], len); + ssize_t file_size = ctx.file_size; + size_t blocks = ctx.nblocks; + while (blocks > 0) { + size_t blks = blocks > TAR_WORK_BLOCKS ? TAR_WORK_BLOCKS : blocks; + ssize_t len = MIN(blks * TAR_BLOCK_SIZE, file_size); + ssize_t n = write(fd, &tar_ptr[ptr], len); if (n != len) { Print_Error(printer, "write", ctx.file_path); retval = UNTAR_FAIL; break; } - ptr += 512; - sizeToGo -= n; + ptr += blks * TAR_BLOCK_SIZE; + file_size -= n; + blocks -= blks; } close(fd); } @@ -385,7 +427,6 @@ Untar_FromFile_Print( char *bufr; ssize_t n; int retval; - unsigned long i; char buf[UNTAR_FILE_NAME_SIZE]; Untar_HeaderContext ctx; @@ -395,7 +436,7 @@ Untar_FromFile_Print( return UNTAR_FAIL; } - bufr = (char *)malloc(512); + bufr = (char *)malloc(TAR_WORK_BLOCKS * TAR_BLOCK_SIZE); if (bufr == NULL) { close(fd); return(UNTAR_FAIL); @@ -408,7 +449,7 @@ Untar_FromFile_Print( while (1) { /* Read the header */ /* If the header read fails, we just consider it the end of the tarfile. */ - if ((n = read(fd, bufr, 512)) != 512) { + if ((n = read(fd, bufr, TAR_BLOCK_SIZE)) != TAR_BLOCK_SIZE) { break; } @@ -426,12 +467,20 @@ Untar_FromFile_Print( */ if ((out_fd = creat(ctx.file_path, ctx.mode)) == -1) { - (void) lseek(fd, SEEK_CUR, 512UL * ctx.nblocks); + /* Couldn't create that file. Abort. */ + retval = UNTAR_FAIL; + break; } else { - for (i = 0; i < ctx.nblocks; i++) { - n = read(fd, bufr, 512); - n = MIN(n, ctx.file_size - (i * 512UL)); + ssize_t file_size = ctx.file_size; + size_t blocks = ctx.nblocks; + while (blocks > 0) { + size_t blks = blocks > TAR_WORK_BLOCKS ? TAR_WORK_BLOCKS : blocks; + size_t bytes = blks * TAR_BLOCK_SIZE; + n = read(fd, bufr, bytes); + n = MIN(n, file_size); (void) write(out_fd, bufr, n); + file_size -= n; + blocks -= blks; } close(out_fd); } diff --git a/cpukit/libmisc/untar/untar_tgz.c b/cpukit/libmisc/untar/untar_tgz.c index 2afcc7f92e..d2612fd566 100644 --- a/cpukit/libmisc/untar/untar_tgz.c +++ b/cpukit/libmisc/untar/untar_tgz.c @@ -1,15 +1,28 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* - * Copyright (c) 2016 embedded brains GmbH. All rights reserved. + * Copyright (c) 2016 embedded brains GmbH & Co. KG * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * <info@embedded-brains.de> + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H diff --git a/cpukit/libmisc/untar/untar_txz.c b/cpukit/libmisc/untar/untar_txz.c index 0b0594c12e..62c2dd9c7c 100644 --- a/cpukit/libmisc/untar/untar_txz.c +++ b/cpukit/libmisc/untar/untar_txz.c @@ -1,9 +1,28 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * Copyright (c) 2016 Chris Johns <chrisj.rtems.org>. All rights reserved. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H |