From 09220c8129ef563cc323f503f4aa355cc09517a7 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Sun, 14 Dec 2014 17:30:23 -0600 Subject: untar.c: Coverity ID 26151 and reformat The Coverity issue was an ignored return value from a read() in a loop which should have been a seek() since the data read was ignored. The file itself needed reformatting to conform to RTEMS style. --- cpukit/libmisc/untar/untar.c | 546 ++++++++++++++++++++----------------------- 1 file changed, 251 insertions(+), 295 deletions(-) diff --git a/cpukit/libmisc/untar/untar.c b/cpukit/libmisc/untar/untar.c index 04a2d89deb..aed8fed356 100644 --- a/cpukit/libmisc/untar/untar.c +++ b/cpukit/libmisc/untar/untar.c @@ -1,19 +1,19 @@ /** * @file - * + * @brief Untar an Image * @ingroup libmisc_untar_img Untar Image - * + * FIXME: * 1. Symbolic links are not created. * 2. Untar_FromMemory uses FILE *fp. * 3. How to determine end of archive? - * + */ /* * Written by: Jake Janovetz - * + * 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. @@ -34,9 +34,9 @@ #include -/************************************************************************** +/* * TAR file format: - * + * Offset Length Contents * 0 100 bytes File name ('\0' terminated, 99 maxmum length) * 100 8 bytes File mode (in octal ascii) @@ -63,333 +63,289 @@ * sum = 0; * for(i = 0; i < 512; i++) * sum += 0xFF & header[i]; - *************************************************************************/ + */ #define MAX_NAME_FIELD_SIZE 99 -/************************************************************************** +/* * This converts octal ASCII number representations into an * unsigned long. Only support 32-bit numbers for now. - *************************************************************************/ + */ unsigned long _rtems_octal2ulong( const char *octascii, size_t len ) { - size_t i; - unsigned long num; - - num = 0; - for (i=0; i < len; i++) - { - if ((octascii[i] < '0') || (octascii[i] > '9')) - { - continue; - } - num = num * 8 + ((unsigned long)(octascii[i] - '0')); - } - return(num); + size_t i; + unsigned long num; + + num = 0; + for (i=0; i < len; i++) { + if ((octascii[i] < '0') || (octascii[i] > '9')) { + continue; + } + num = num * 8 + ((unsigned long)(octascii[i] - '0')); + } + return(num); } - -/************************************************************************** - * Function: Untar_FromMemory * - ************************************************************************** - * Description: * - * * - * This is a simple subroutine used to rip links, directories, and * - * files out of a block of memory. * - * * - * * - * Inputs: * - * * - * void * tar_buf - Pointer to TAR buffer. * - * size_t size - Length of TAR buffer. * - * * - * * - * Output: * - * * - * int - UNTAR_SUCCESSFUL (0) on successful completion. * - * UNTAR_INVALID_CHECKSUM for an invalid header checksum. * - * UNTAR_INVALID_HEADER for an invalid header. * - * * - **************************************************************************/ +/* + * Function: Untar_FromMemory + * + * Description: + * + * This is a simple subroutine used to rip links, directories, and + * files out of a block of memory. + * + * + * Inputs: + * + * void * tar_buf - Pointer to TAR buffer. + * size_t size - Length of TAR buffer. + * + * + * Output: + * + * int - UNTAR_SUCCESSFUL (0) on successful completion. + * UNTAR_INVALID_CHECKSUM for an invalid header checksum. + * UNTAR_INVALID_HEADER for an invalid header. + * + */ int Untar_FromMemory( void *tar_buf, size_t size ) { - FILE *fp; - const char *tar_ptr = (const char *)tar_buf; - const char *bufr; - size_t n; - char fname[100]; - char linkname[100]; - int sum; - int hdr_chksum; - int retval; - unsigned long ptr; - unsigned long i; - unsigned long nblocks; - unsigned long file_size; - unsigned char linkflag; - - - ptr = 0; - while (1) - { - if (ptr + 512 > size) - { - retval = UNTAR_SUCCESSFUL; - break; + FILE *fp; + const char *tar_ptr = (const char *)tar_buf; + const char *bufr; + size_t n; + char fname[100]; + char linkname[100]; + int sum; + int hdr_chksum; + int retval; + unsigned long ptr; + unsigned long i; + unsigned long nblocks; + unsigned long file_size; + unsigned char linkflag; + + ptr = 0; + while (1) { + if (ptr + 512 > size) { + retval = UNTAR_SUCCESSFUL; + break; + } + + /* Read the header */ + bufr = &tar_ptr[ptr]; + ptr += 512; + if (strncmp(&bufr[257], "ustar", 5)) { + retval = UNTAR_SUCCESSFUL; + break; + } + + strncpy(fname, bufr, MAX_NAME_FIELD_SIZE); + fname[MAX_NAME_FIELD_SIZE] = '\0'; + + linkflag = bufr[156]; + file_size = _rtems_octal2ulong(&bufr[124], 12); + + /* + * Compute the TAR checksum and check with the value in + * the archive. The checksum is computed over the entire + * header, but the checksum field is substituted with blanks. + */ + hdr_chksum = _rtems_octal2ulong(&bufr[148], 8); + sum = _rtems_tar_header_checksum(bufr); + + if (sum != hdr_chksum) { + retval = UNTAR_INVALID_CHECKSUM; + break; + } + + /* + * We've decoded the header, now figure out what it contains and + * do something with it. + */ + if (linkflag == SYMTYPE) { + strncpy(linkname, &bufr[157], MAX_NAME_FIELD_SIZE); + linkname[MAX_NAME_FIELD_SIZE] = '\0'; + symlink(linkname, fname); + } else if (linkflag == REGTYPE) { + nblocks = (((file_size) + 511) & ~511) / 512; + if ((fp = fopen(fname, "w")) == NULL) { + printk("Untar: failed to create file %s\n", fname); + ptr += 512 * nblocks; + } else { + unsigned long sizeToGo = file_size; + size_t len; + + /* + * 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= 148) && (i < 156)) - sum += 0xff & ' '; - else - sum += 0xff & bufr[i]; - } - return(sum); + int i, sum; + + sum = 0; + for (i=0; i<512; i++) { + if ((i >= 148) && (i < 156)) + sum += 0xff & ' '; + else + sum += 0xff & bufr[i]; + } + return(sum); } -- cgit v1.2.3