onlineupdate/Executable_mar.mk | 8 onlineupdate/Executable_updater.mk | 11 onlineupdate/Module_onlineupdate.mk | 1 onlineupdate/StaticLibrary_libmar.mk | 23 + onlineupdate/source/update/src/Makefile.in | 13 onlineupdate/source/update/src/mar.h | 198 --------- onlineupdate/source/update/src/mar_cmdline.h | 110 ----- onlineupdate/source/update/src/mar_create.c | 398 ------------------ onlineupdate/source/update/src/mar_extract.c | 85 ---- onlineupdate/source/update/src/mar_private.h | 79 --- onlineupdate/source/update/src/mar_read.c | 572 --------------------------- 11 files changed, 32 insertions(+), 1466 deletions(-)
New commits: commit e60506acc53098b4b479d565048c316562657cec Author: Ras-al-Ghul <dipankar1...@gmail.com> Date: Sat Mar 12 23:30:22 2016 +0530 tdf#98602 Duplicate code in onlineupdate/ Converted libmar into static library and removed duplicated code Change-Id: I6a6c8ce24103a400e1835ccf7e6421024f5cec4b Reviewed-on: https://gerrit.libreoffice.org/23179 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Jan Holesovsky <ke...@collabora.com> diff --git a/onlineupdate/Executable_mar.mk b/onlineupdate/Executable_mar.mk index c2dccaf..3000a1c 100644 --- a/onlineupdate/Executable_mar.mk +++ b/onlineupdate/Executable_mar.mk @@ -11,12 +11,15 @@ $(eval $(call gb_Executable_Executable,mar)) $(eval $(call gb_Executable_set_include,mar,\ -I$(SRCDIR)/onlineupdate/source/libmar/inc/ \ - -I$(SRCDIR)/onlineupdate/source/libmar/src/ \ -I$(SRCDIR)/onlineupdate/source/libmar/verify/ \ -I$(SRCDIR)/onlineupdate/source/libmar/sign/ \ $$(INCLUDE) \ )) +$(eval $(call gb_Library_use_static_libraries,Executable_mar,\ + libmar \ +)) + ifeq ($(OS),WNT) $(eval $(call gb_Executable_add_libs,mar,\ ws2_32.lib \ @@ -30,9 +33,6 @@ $(eval $(call gb_Executable_add_defs,mar,-DMAR_NSS)) endif $(eval $(call gb_Executable_add_cobjects,mar,\ - onlineupdate/source/libmar/src/mar_create \ - onlineupdate/source/libmar/src/mar_extract \ - onlineupdate/source/libmar/src/mar_read \ onlineupdate/source/libmar/sign/nss_secutil \ onlineupdate/source/libmar/sign/mar_sign \ onlineupdate/source/libmar/verify/cryptox \ diff --git a/onlineupdate/Executable_updater.mk b/onlineupdate/Executable_updater.mk index fba7e3c..6ba6d4d 100644 --- a/onlineupdate/Executable_updater.mk +++ b/onlineupdate/Executable_updater.mk @@ -10,13 +10,16 @@ $(eval $(call gb_Executable_Executable,updater)) $(eval $(call gb_Executable_set_include,updater,\ - -I$(SRCDIR)/onlineupdate/source/update/src \ -I$(SRCDIR)/onlineupdate/source/update/inc \ -I$(SRCDIR)/onlineupdate/source/update/common \ -I$(SRCDIR)/onlineupdate/source/update/updater/xpcom/glue \ $$(INCLUDE) \ )) +$(eval $(call gb_Library_use_static_libraries,Executable_updater,\ + libmar \ +)) + ifeq ($(OS),WNT) $(eval $(call gb_Executable_add_libs,updater,\ Ws2_32.lib \ @@ -64,10 +67,4 @@ $(eval $(call gb_Executable_add_exception_objects,updater,\ onlineupdate/source/update/common/updatelogging \ )) -$(eval $(call gb_Executable_add_cobjects,updater,\ - onlineupdate/source/update/src/mar_create \ - onlineupdate/source/update/src/mar_extract \ - onlineupdate/source/update/src/mar_read \ -)) - # vim:set shiftwidth=4 tabstop=4 noexpandtab: */ diff --git a/onlineupdate/Module_onlineupdate.mk b/onlineupdate/Module_onlineupdate.mk index 113c031..19b8529 100644 --- a/onlineupdate/Module_onlineupdate.mk +++ b/onlineupdate/Module_onlineupdate.mk @@ -14,6 +14,7 @@ ifneq ($(ENABLE_ONLINE_UPDATE_MAR),) $(eval $(call gb_Module_add_targets,onlineupdate,\ Executable_mar \ Executable_updater \ + StaticLibrary_libmar \ )) endif diff --git a/onlineupdate/StaticLibrary_libmar.mk b/onlineupdate/StaticLibrary_libmar.mk new file mode 100644 index 0000000..3c85b73 --- /dev/null +++ b/onlineupdate/StaticLibrary_libmar.mk @@ -0,0 +1,23 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +$(eval $(call gb_StaticLibrary_StaticLibrary,libmar)) + +$(eval $(call gb_StaticLibrary_set_include,libmar,\ + -I$(SRCDIR)/onlineupdate/source/libmar/src/ \ + $$(INCLUDE) \ +)) + +$(eval $(call gb_StaticLibrary_add_cobjects,libmar,\ + onlineupdate/source/libmar/src/mar_create \ + onlineupdate/source/libmar/src/mar_extract \ + onlineupdate/source/libmar/src/mar_read \ +)) + +# vim:set shiftwidth=4 tabstop=4 noexpandtab: */ diff --git a/onlineupdate/source/update/src/Makefile.in b/onlineupdate/source/update/src/Makefile.in deleted file mode 100644 index 1da582e..0000000 --- a/onlineupdate/source/update/src/Makefile.in +++ /dev/null @@ -1,13 +0,0 @@ -# vim:set ts=8 sw=8 sts=8 noet: -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# This makefile just builds support for reading archives. - -include $(topsrcdir)/config/rules.mk - -# The intermediate (.ii/.s) files for host and target can have the same name... -# disable parallel builds -.NOTPARALLEL: diff --git a/onlineupdate/source/update/src/mar.h b/onlineupdate/source/update/src/mar.h deleted file mode 100644 index 0e21efb..0000000 --- a/onlineupdate/source/update/src/mar.h +++ /dev/null @@ -1,198 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef MAR_H__ -#define MAR_H__ - -#include "mozilla/Assertions.h" -#include <stdint.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* We have a MAX_SIGNATURES limit so that an invalid MAR will never - * waste too much of either updater's or signmar's time. - * It is also used at various places internally and will affect memory usage. - * If you want to increase this value above 9 then you need to adjust parsing - * code in tool/mar.c. -*/ -#define MAX_SIGNATURES 8 -#ifdef __cplusplus -static_assert(MAX_SIGNATURES <= 9, "too many signatures"); -#else -MOZ_STATIC_ASSERT(MAX_SIGNATURES <= 9, "too many signatures"); -#endif - -struct ProductInformationBlock { - const char *MARChannelID; - const char *productVersion; -}; - -/** - * The MAR item data structure. - */ -typedef struct MarItem_ { - struct MarItem_ *next; /* private field */ - uint32_t offset; /* offset into archive */ - uint32_t length; /* length of data in bytes */ - uint32_t flags; /* contains file mode bits */ - char name[1]; /* file path */ -} MarItem; - -#define TABLESIZE 256 - -struct MarFile_ { - FILE *fp; - MarItem *item_table[TABLESIZE]; -}; - -typedef struct MarFile_ MarFile; - -/** - * Signature of callback function passed to mar_enum_items. - * @param mar The MAR file being visited. - * @param item The MAR item being visited. - * @param data The data parameter passed by the caller of mar_enum_items. - * @return A non-zero value to stop enumerating. - */ -typedef int (* MarItemCallback)(MarFile *mar, const MarItem *item, void *data); - -/** - * Open a MAR file for reading. - * @param path Specifies the path to the MAR file to open. This path must - * be compatible with fopen. - * @return NULL if an error occurs. - */ -MarFile *mar_open(const char *path); - -#ifdef _WIN32 -MarFile *mar_wopen(const wchar_t *path); -#endif - -/** - * Close a MAR file that was opened using mar_open. - * @param mar The MarFile object to close. - */ -void mar_close(MarFile *mar); - -/** - * Find an item in the MAR file by name. - * @param mar The MarFile object to query. - * @param item The name of the item to query. - * @return A const reference to a MAR item or NULL if not found. - */ -const MarItem *mar_find_item(MarFile *mar, const char *item); - -/** - * Enumerate all MAR items via callback function. - * @param mar The MAR file to enumerate. - * @param callback The function to call for each MAR item. - * @param data A caller specified value that is passed along to the - * callback function. - * @return 0 if the enumeration ran to completion. Otherwise, any - * non-zero return value from the callback is returned. - */ -int mar_enum_items(MarFile *mar, MarItemCallback callback, void *data); - -/** - * Read from MAR item at given offset up to bufsize bytes. - * @param mar The MAR file to read. - * @param item The MAR item to read. - * @param offset The byte offset relative to the start of the item. - * @param buf A pointer to a buffer to copy the data into. - * @param bufsize The length of the buffer to copy the data into. - * @return The number of bytes written or a negative value if an - * error occurs. - */ -int mar_read(MarFile *mar, const MarItem *item, int offset, char *buf, - int bufsize); - -/** - * Create a MAR file from a set of files. - * @param dest The path to the file to create. This path must be - * compatible with fopen. - * @param numfiles The number of files to store in the archive. - * @param files The list of null-terminated file paths. Each file - * path must be compatible with fopen. - * @param infoBlock The information to store in the product information block. - * @return A non-zero value if an error occurs. - */ -int mar_create(const char *dest, - int numfiles, - char **files, - struct ProductInformationBlock *infoBlock); - -/** - * Extract a MAR file to the current working directory. - * @param path The path to the MAR file to extract. This path must be - * compatible with fopen. - * @return A non-zero value if an error occurs. - */ -int mar_extract(const char *path); - -#define MAR_MAX_CERT_SIZE (16*1024) // Way larger than necessary - -/* Read the entire file (not a MAR file) into a newly-allocated buffer. - * This function does not write to stderr. Instead, the caller should - * write whatever error messages it sees fit. The caller must free the returned - * buffer using free(). - * - * @param filePath The path to the file that should be read. - * @param maxSize The maximum valid file size. - * @param data On success, *data will point to a newly-allocated buffer - * with the file's contents in it. - * @param size On success, *size will be the size of the created buffer. - * - * @return 0 on success, -1 on error - */ -int mar_read_entire_file(const char * filePath, - uint32_t maxSize, - /*out*/ const uint8_t * *data, - /*out*/ uint32_t *size); - -/** - * Verifies a MAR file by verifying each signature with the corresponding - * certificate. That is, the first signature will be verified using the first - * certificate given, the second signature will be verified using the second - * certificate given, etc. The signature count must exactly match the number of - * certificates given, and all signature verifications must succeed. - * We do not check that the certificate was issued by any trusted authority. - * We assume it to be self-signed. We do not check whether the certificate - * is valid for this usage. - * - * @param mar The already opened MAR file. - * @param certData Pointer to the first element in an array of certificate - * file data. - * @param certDataSizes Pointer to the first element in an array for size of - * the cert data. - * @param certCount The number of elements in certData and certDataSizes - * @return 0 on success - * a negative number if there was an error - * a positive number if the signature does not verify - */ -int mar_verify_signatures(MarFile *mar, - const uint8_t * const *certData, - const uint32_t *certDataSizes, - uint32_t certCount); - -/** - * Reads the product info block from the MAR file's additional block section. - * The caller is responsible for freeing the fields in infoBlock - * if the return is successful. - * - * @param infoBlock Out parameter for where to store the result to - * @return 0 on success, -1 on failure -*/ -int -mar_read_product_info_block(MarFile *mar, - struct ProductInformationBlock *infoBlock); - -#ifdef __cplusplus -} -#endif - -#endif /* MAR_H__ */ diff --git a/onlineupdate/source/update/src/mar_cmdline.h b/onlineupdate/source/update/src/mar_cmdline.h deleted file mode 100644 index ef6867f..0000000 --- a/onlineupdate/source/update/src/mar_cmdline.h +++ /dev/null @@ -1,110 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef MAR_CMDLINE_H__ -#define MAR_CMDLINE_H__ - -/* We use NSPR here just to import the definition of uint32_t */ - -#ifdef __cplusplus -extern "C" { -#endif - -struct ProductInformationBlock; - -/** - * Determines MAR file information. - * - * @param path The path of the MAR file to check. - * @param hasSignatureBlock Optional out parameter specifying if the MAR - * file has a signature block or not. - * @param numSignatures Optional out parameter for storing the number - * of signatures in the MAR file. - * @param hasAdditionalBlocks Optional out parameter specifying if the MAR - * file has additional blocks or not. - * @param offsetAdditionalBlocks Optional out parameter for the offset to the - * first additional block. Value is only valid if - * hasAdditionalBlocks is not equal to 0. - * @param numAdditionalBlocks Optional out parameter for the number of - * additional blocks. Value is only valid if - * has_additional_blocks is not equal to 0. - * @return 0 on success and non-zero on failure. - */ -int get_mar_file_info(const char *path, - int *hasSignatureBlock, - uint32_t *numSignatures, - int *hasAdditionalBlocks, - uint32_t *offsetAdditionalBlocks, - uint32_t *numAdditionalBlocks); - -/** - * Reads the product info block from the MAR file's additional block section. - * The caller is responsible for freeing the fields in infoBlock - * if the return is successful. - * - * @param infoBlock Out parameter for where to store the result to - * @return 0 on success, -1 on failure -*/ -int -read_product_info_block(char *path, - struct ProductInformationBlock *infoBlock); - -/** - * Refreshes the product information block with the new information. - * The input MAR must not be signed or the function call will fail. - * - * @param path The path to the MAR file whose product info block - * should be refreshed. - * @param infoBlock Out parameter for where to store the result to - * @return 0 on success, -1 on failure -*/ -int -refresh_product_info_block(const char *path, - struct ProductInformationBlock *infoBlock); - -/** - * Writes out a copy of the MAR at src but with the signature block stripped. - * - * @param src The path of the source MAR file - * @param dest The path of the MAR file to write out that - has no signature block - * @return 0 on success - * -1 on error -*/ -int -strip_signature_block(const char *src, const char * dest); - -/** - * Extracts a signature from a MAR file, base64 encodes it, and writes it out - * - * @param src The path of the source MAR file - * @param sigIndex The index of the signature to extract - * @param dest The path of file to write the signature to - * @return 0 on success - * -1 on error -*/ -int -extract_signature(const char *src, uint32_t sigIndex, const char * dest); - -/** - * Imports a base64 encoded signature into a MAR file - * - * @param src The path of the source MAR file - * @param sigIndex The index of the signature to import - * @param base64SigFile A file which contains the signature to import - * @param dest The path of the destination MAR file with replaced signature - * @return 0 on success - * -1 on error -*/ -int -import_signature(const char *src, - uint32_t sigIndex, - const char * base64SigFile, - const char *dest); - -#ifdef __cplusplus -} -#endif - -#endif /* MAR_CMDLINE_H__ */ diff --git a/onlineupdate/source/update/src/mar_create.c b/onlineupdate/source/update/src/mar_create.c deleted file mode 100644 index 4e4e2b4..0000000 --- a/onlineupdate/source/update/src/mar_create.c +++ /dev/null @@ -1,398 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#include "mar_private.h" -#include "mar_cmdline.h" -#include "mar.h" - -#ifdef _WIN32 -#include <winsock2.h> -#else -#include <netinet/in.h> -#include <unistd.h> -#endif - -struct MarItemStack { - void *head; - uint32_t size_used; - uint32_t size_allocated; - uint32_t last_offset; -}; - -/** - * Push a new item onto the stack of items. The stack is a single block - * of memory. - */ -static int mar_push(struct MarItemStack *stack, uint32_t length, uint32_t flags, - const char *name) { - int namelen; - uint32_t n_offset, n_length, n_flags; - uint32_t size; - char *data; - - namelen = strlen(name); - size = MAR_ITEM_SIZE(namelen); - - if (stack->size_allocated - stack->size_used < size) { - /* increase size of stack */ - size_t size_needed = ROUND_UP(stack->size_used + size, BLOCKSIZE); - stack->head = realloc(stack->head, size_needed); - if (!stack->head) - return -1; - stack->size_allocated = size_needed; - } - - data = (((char *) stack->head) + stack->size_used); - - n_offset = htonl(stack->last_offset); - n_length = htonl(length); - n_flags = htonl(flags); - - memcpy(data, &n_offset, sizeof(n_offset)); - data += sizeof(n_offset); - - memcpy(data, &n_length, sizeof(n_length)); - data += sizeof(n_length); - - memcpy(data, &n_flags, sizeof(n_flags)); - data += sizeof(n_flags); - - memcpy(data, name, namelen + 1); - - stack->size_used += size; - stack->last_offset += length; - return 0; -} - -static int mar_concat_file(FILE *fp, const char *path) { - FILE *in; - char buf[BLOCKSIZE]; - size_t len; - int rv = 0; - - in = fopen(path, "rb"); - if (!in) { - fprintf(stderr, "ERROR: could not open file in mar_concat_file()\n"); - perror(path); - return -1; - } - - while ((len = fread(buf, 1, BLOCKSIZE, in)) > 0) { - if (fwrite(buf, len, 1, fp) != 1) { - rv = -1; - break; - } - } - - fclose(in); - return rv; -} - -/** - * Writes out the product information block to the specified file. - * - * @param fp The opened MAR file being created. - * @param stack A pointer to the MAR item stack being used to create - * the MAR - * @param infoBlock The product info block to store in the file. - * @return 0 on success. -*/ -static int -mar_concat_product_info_block(FILE *fp, - struct MarItemStack *stack, - struct ProductInformationBlock *infoBlock) -{ - char buf[PIB_MAX_MAR_CHANNEL_ID_SIZE + PIB_MAX_PRODUCT_VERSION_SIZE]; - uint32_t additionalBlockID = 1, infoBlockSize, unused; - if (!fp || !infoBlock || - !infoBlock->MARChannelID || - !infoBlock->productVersion) { - return -1; - } - - /* The MAR channel name must be < 64 bytes per the spec */ - if (strlen(infoBlock->MARChannelID) > PIB_MAX_MAR_CHANNEL_ID_SIZE) { - return -1; - } - - /* The product version must be < 32 bytes per the spec */ - if (strlen(infoBlock->productVersion) > PIB_MAX_PRODUCT_VERSION_SIZE) { - return -1; - } - - /* Although we don't need the product information block size to include the - maximum MAR channel name and product version, we allocate the maximum - amount to make it easier to modify the MAR file for repurposing MAR files - to different MAR channels. + 2 is for the NULL terminators. */ - infoBlockSize = sizeof(infoBlockSize) + - sizeof(additionalBlockID) + - PIB_MAX_MAR_CHANNEL_ID_SIZE + - PIB_MAX_PRODUCT_VERSION_SIZE + 2; - if (stack) { - stack->last_offset += infoBlockSize; - } - - /* Write out the product info block size */ - infoBlockSize = htonl(infoBlockSize); - if (fwrite(&infoBlockSize, - sizeof(infoBlockSize), 1, fp) != 1) { - return -1; - } - infoBlockSize = ntohl(infoBlockSize); - - /* Write out the product info block ID */ - additionalBlockID = htonl(additionalBlockID); - if (fwrite(&additionalBlockID, - sizeof(additionalBlockID), 1, fp) != 1) { - return -1; - } - additionalBlockID = ntohl(additionalBlockID); - - /* Write out the channel name and NULL terminator */ - if (fwrite(infoBlock->MARChannelID, - strlen(infoBlock->MARChannelID) + 1, 1, fp) != 1) { - return -1; - } - - /* Write out the product version string and NULL terminator */ - if (fwrite(infoBlock->productVersion, - strlen(infoBlock->productVersion) + 1, 1, fp) != 1) { - return -1; - } - - /* Write out the rest of the block that is unused */ - unused = infoBlockSize - (sizeof(infoBlockSize) + - sizeof(additionalBlockID) + - strlen(infoBlock->MARChannelID) + - strlen(infoBlock->productVersion) + 2); - memset(buf, 0, sizeof(buf)); - if (fwrite(buf, unused, 1, fp) != 1) { - return -1; - } - return 0; -} - -/** - * Refreshes the product information block with the new information. - * The input MAR must not be signed or the function call will fail. - * - * @param path The path to the MAR file whose product info block - * should be refreshed. - * @param infoBlock Out parameter for where to store the result to - * @return 0 on success, -1 on failure -*/ -int -refresh_product_info_block(const char *path, - struct ProductInformationBlock *infoBlock) -{ - FILE *fp ; - int rv; - uint32_t numSignatures, additionalBlockSize, additionalBlockID, - offsetAdditionalBlocks, numAdditionalBlocks, i; - int additionalBlocks, hasSignatureBlock; - - rv = get_mar_file_info(path, - &hasSignatureBlock, - &numSignatures, - &additionalBlocks, - &offsetAdditionalBlocks, - &numAdditionalBlocks); - if (rv) { - fprintf(stderr, "ERROR: Could not obtain MAR information.\n"); - return -1; - } - - if (hasSignatureBlock && numSignatures) { - fprintf(stderr, "ERROR: Cannot refresh a signed MAR\n"); - return -1; - } - - fp = fopen(path, "r+b"); - if (!fp) { - fprintf(stderr, "ERROR: could not open target file: %s\n", path); - return -1; - } - - if (fseeko(fp, offsetAdditionalBlocks, SEEK_SET)) { - fprintf(stderr, "ERROR: could not seek to additional blocks\n"); - fclose(fp); - return -1; - } - - for (i = 0; i < numAdditionalBlocks; ++i) { - /* Get the position of the start of this block */ - int64_t oldPos = ftello(fp); - - /* Read the additional block size */ - if (fread(&additionalBlockSize, - sizeof(additionalBlockSize), - 1, fp) != 1) { - fclose(fp); - return -1; - } - additionalBlockSize = ntohl(additionalBlockSize); - - /* Read the additional block ID */ - if (fread(&additionalBlockID, - sizeof(additionalBlockID), - 1, fp) != 1) { - fclose(fp); - return -1; - } - additionalBlockID = ntohl(additionalBlockID); - - if (PRODUCT_INFO_BLOCK_ID == additionalBlockID) { - if (fseeko(fp, oldPos, SEEK_SET)) { - fprintf(stderr, "Could not seek back to Product Information Block\n"); - fclose(fp); - return -1; - } - - if (mar_concat_product_info_block(fp, NULL, infoBlock)) { - fprintf(stderr, "Could not concat Product Information Block\n"); - fclose(fp); - return -1; - } - - fclose(fp); - return 0; - } else { - /* This is not the additional block you're looking for. Move along. */ - if (fseek(fp, additionalBlockSize, SEEK_CUR)) { - fprintf(stderr, "ERROR: Could not seek past current block.\n"); - fclose(fp); - return -1; - } - } - } - - /* If we had a product info block we would have already returned */ - fclose(fp); - fprintf(stderr, "ERROR: Could not refresh because block does not exist\n"); - return -1; -} - -/** - * Create a MAR file from a set of files. - * @param dest The path to the file to create. This path must be - * compatible with fopen. - * @param numfiles The number of files to store in the archive. - * @param files The list of null-terminated file paths. Each file - * path must be compatible with fopen. - * @param infoBlock The information to store in the product information block. - * @return A non-zero value if an error occurs. - */ -int mar_create(const char *dest, int - num_files, char **files, - struct ProductInformationBlock *infoBlock) { - struct MarItemStack stack; - uint32_t offset_to_index = 0, size_of_index, - numSignatures, numAdditionalSections; - uint64_t sizeOfEntireMAR = 0; - struct stat st; - FILE *fp; - int i, rv = -1; - - memset(&stack, 0, sizeof(stack)); - - fp = fopen(dest, "wb"); - if (!fp) { - fprintf(stderr, "ERROR: could not create target file: %s\n", dest); - return -1; - } - - if (fwrite(MAR_ID, MAR_ID_SIZE, 1, fp) != 1) - goto failure; - if (fwrite(&offset_to_index, sizeof(uint32_t), 1, fp) != 1) - goto failure; - - stack.last_offset = MAR_ID_SIZE + - sizeof(offset_to_index) + - sizeof(numSignatures) + - sizeof(numAdditionalSections) + - sizeof(sizeOfEntireMAR); - - /* We will circle back on this at the end of the MAR creation to fill it */ - if (fwrite(&sizeOfEntireMAR, sizeof(sizeOfEntireMAR), 1, fp) != 1) { - goto failure; - } - - /* Write out the number of signatures, for now only at most 1 is supported */ - numSignatures = 0; - if (fwrite(&numSignatures, sizeof(numSignatures), 1, fp) != 1) { - goto failure; - } - - /* Write out the number of additional sections, for now just 1 - for the product info block */ - numAdditionalSections = htonl(1); - if (fwrite(&numAdditionalSections, - sizeof(numAdditionalSections), 1, fp) != 1) { - goto failure; - } - numAdditionalSections = ntohl(numAdditionalSections); - - if (mar_concat_product_info_block(fp, &stack, infoBlock)) { - goto failure; - } - - for (i = 0; i < num_files; ++i) { - if (stat(files[i], &st)) { - fprintf(stderr, "ERROR: file not found: %s\n", files[i]); - goto failure; - } - - if (mar_push(&stack, st.st_size, st.st_mode & 0777, files[i])) - goto failure; - - /* concatenate input file to archive */ - if (mar_concat_file(fp, files[i])) - goto failure; - } - - /* write out the index (prefixed with length of index) */ - size_of_index = htonl(stack.size_used); - if (fwrite(&size_of_index, sizeof(size_of_index), 1, fp) != 1) - goto failure; - if (fwrite(stack.head, stack.size_used, 1, fp) != 1) - goto failure; - - /* To protect against invalid MAR files, we assumes that the MAR file - size is less than or equal to MAX_SIZE_OF_MAR_FILE. */ - if (ftell(fp) > MAX_SIZE_OF_MAR_FILE) { - goto failure; - } - - /* write out offset to index file in network byte order */ - offset_to_index = htonl(stack.last_offset); - if (fseek(fp, MAR_ID_SIZE, SEEK_SET)) - goto failure; - if (fwrite(&offset_to_index, sizeof(offset_to_index), 1, fp) != 1) - goto failure; - offset_to_index = ntohl(stack.last_offset); - - sizeOfEntireMAR = ((uint64_t)stack.last_offset) + - stack.size_used + - sizeof(size_of_index); - sizeOfEntireMAR = HOST_TO_NETWORK64(sizeOfEntireMAR); - if (fwrite(&sizeOfEntireMAR, sizeof(sizeOfEntireMAR), 1, fp) != 1) - goto failure; - sizeOfEntireMAR = NETWORK_TO_HOST64(sizeOfEntireMAR); - - rv = 0; -failure: - if (stack.head) - free(stack.head); - fclose(fp); - if (rv) - remove(dest); - return rv; -} diff --git a/onlineupdate/source/update/src/mar_extract.c b/onlineupdate/source/update/src/mar_extract.c deleted file mode 100644 index 75cbd64..0000000 --- a/onlineupdate/source/update/src/mar_extract.c +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <string.h> -#include <stdlib.h> -#include "mar_private.h" -#include "mar.h" - -#ifdef _WIN32 -#include <io.h> -#include <direct.h> -#endif - -/* Ensure that the directory containing this file exists */ -static int mar_ensure_parent_dir(const char *path) -{ - char *slash = strrchr(path, '/'); - if (slash) - { - *slash = '\0'; - mar_ensure_parent_dir(path); -#ifdef _WIN32 - _mkdir(path); -#else - mkdir(path, 0755); -#endif - *slash = '/'; - } - return 0; -} - -static int mar_test_callback(MarFile *mar, const MarItem *item, void *unused) { - FILE *fp; - char buf[BLOCKSIZE]; - int fd, len, offset = 0; - - (void) unused; // avoid warnings - - if (mar_ensure_parent_dir(item->name)) - return -1; - -#ifdef _WIN32 - fd = _open(item->name, _O_BINARY|_O_CREAT|_O_TRUNC|_O_WRONLY, item->flags); -#else - fd = creat(item->name, item->flags); -#endif - if (fd == -1) { - fprintf(stderr, "ERROR: could not create file in mar_test_callback()\n"); - perror(item->name); - return -1; - } - - fp = fdopen(fd, "wb"); - if (!fp) - return -1; - - while ((len = mar_read(mar, item, offset, buf, sizeof(buf))) > 0) { - if (fwrite(buf, len, 1, fp) != 1) - break; - offset += len; - } - - fclose(fp); - return len == 0 ? 0 : -1; -} - -int mar_extract(const char *path) { - MarFile *mar; - int rv; - - mar = mar_open(path); - if (!mar) - return -1; - - rv = mar_enum_items(mar, mar_test_callback, NULL); - - mar_close(mar); - return rv; -} diff --git a/onlineupdate/source/update/src/mar_private.h b/onlineupdate/source/update/src/mar_private.h deleted file mode 100644 index a770998..0000000 --- a/onlineupdate/source/update/src/mar_private.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef MAR_PRIVATE_H__ -#define MAR_PRIVATE_H__ - -#include "limits.h" -#include "mozilla/Assertions.h" -#include <stdint.h> - -#define BLOCKSIZE 4096 -#define ROUND_UP(n, incr) (((n) / (incr) + 1) * (incr)) - -#define MAR_ID "MAR1" -#define MAR_ID_SIZE 4 - -/* The signature block comes directly after the header block - which is 16 bytes */ -#define SIGNATURE_BLOCK_OFFSET 16 - -/* Make sure the file is less than 500MB. We do this to protect against - invalid MAR files. */ -#define MAX_SIZE_OF_MAR_FILE ((int64_t)524288000) - -/* Existing code makes assumptions that the file size is - smaller than LONG_MAX. */ -MOZ_STATIC_ASSERT(MAX_SIZE_OF_MAR_FILE < ((int64_t)LONG_MAX), - "max mar file size is too big"); - -/* We store at most the size up to the signature block + 4 - bytes per BLOCKSIZE bytes */ -MOZ_STATIC_ASSERT(sizeof(BLOCKSIZE) < \ - (SIGNATURE_BLOCK_OFFSET + sizeof(uint32_t)), - "BLOCKSIZE is too big"); - -/* The maximum size of any signature supported by current and future - implementations of the signmar program. */ -#define MAX_SIGNATURE_LENGTH 2048 - -/* Each additional block has a unique ID. - The product information block has an ID of 1. */ -#define PRODUCT_INFO_BLOCK_ID 1 - -#define MAR_ITEM_SIZE(namelen) (3*sizeof(uint32_t) + (namelen) + 1) - -/* Product Information Block (PIB) constants */ -#define PIB_MAX_MAR_CHANNEL_ID_SIZE 63 -#define PIB_MAX_PRODUCT_VERSION_SIZE 31 - -/* The mar program is compiled as a host bin so we don't have access to NSPR at - runtime. For that reason we use ntohl, htonl, and define HOST_TO_NETWORK64 - instead of the NSPR equivalents. */ -#ifdef _WIN32 -#include <winsock2.h> -#define ftello _ftelli64 -#define fseeko _fseeki64 -#else -#define _FILE_OFFSET_BITS 64 -#include <netinet/in.h> -#include <unistd.h> -#endif - -#include <stdio.h> - -#define HOST_TO_NETWORK64(x) ( \ - ((((uint64_t) x) & 0xFF) << 56) | \ - ((((uint64_t) x) >> 8) & 0xFF) << 48) | \ - (((((uint64_t) x) >> 16) & 0xFF) << 40) | \ - (((((uint64_t) x) >> 24) & 0xFF) << 32) | \ - (((((uint64_t) x) >> 32) & 0xFF) << 24) | \ - (((((uint64_t) x) >> 40) & 0xFF) << 16) | \ - (((((uint64_t) x) >> 48) & 0xFF) << 8) | \ - (((uint64_t) x) >> 56) -#define NETWORK_TO_HOST64 HOST_TO_NETWORK64 - -#endif /* MAR_PRIVATE_H__ */ diff --git a/onlineupdate/source/update/src/mar_read.c b/onlineupdate/source/update/src/mar_read.c deleted file mode 100644 index 0ed8c6b..0000000 --- a/onlineupdate/source/update/src/mar_read.c +++ /dev/null @@ -1,572 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <sys/types.h> -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#include "mar_private.h" -#include "mar.h" - -#ifdef _WIN32 -#include <winsock2.h> -#else -#include <netinet/in.h> -#endif - - -/* this is the same hash algorithm used by nsZipArchive.cpp */ -static uint32_t mar_hash_name(const char *name) { - uint32_t val = 0; - unsigned char* c; - - for (c = (unsigned char *) name; *c; ++c) - val = val*37 + *c; - - return val % TABLESIZE; -} - -static int mar_insert_item(MarFile *mar, const char *name, int namelen, - uint32_t offset, uint32_t length, uint32_t flags) { - MarItem *item, *root; - uint32_t hash; - - item = (MarItem *) malloc(sizeof(MarItem) + namelen); - if (!item) - return -1; - item->next = NULL; - item->offset = offset; - item->length = length; - item->flags = flags; - memcpy(item->name, name, namelen + 1); - - hash = mar_hash_name(name); - - root = mar->item_table[hash]; - if (!root) { - mar->item_table[hash] = item; - } else { - /* append item */ - while (root->next) - root = root->next; - root->next = item; - } - return 0; -} - -static int mar_consume_index(MarFile *mar, char **buf, const char *buf_end) { - /* - * Each item has the following structure: - * uint32_t offset (network byte order) - * uint32_t length (network byte order) - * uint32_t flags (network byte order) - * char name[N] (where N >= 1) - * char null_byte; - */ - uint32_t offset; - uint32_t length; - uint32_t flags; - const char *name; - int namelen; - - if ((buf_end - *buf) < (int)(3*sizeof(uint32_t) + 2)) - return -1; - - memcpy(&offset, *buf, sizeof(offset)); - *buf += sizeof(offset); - - memcpy(&length, *buf, sizeof(length)); - *buf += sizeof(length); - - memcpy(&flags, *buf, sizeof(flags)); - *buf += sizeof(flags); - - offset = ntohl(offset); - length = ntohl(length); - flags = ntohl(flags); - - name = *buf; - /* find namelen; must take care not to read beyond buf_end */ - while (**buf) { - if (*buf == buf_end) - return -1; - ++(*buf); - } - namelen = (*buf - name); - /* consume null byte */ - if (*buf == buf_end) - return -1; - ++(*buf); - - return mar_insert_item(mar, name, namelen, offset, length, flags); -} - -static int mar_read_index(MarFile *mar) { - char id[MAR_ID_SIZE], *buf, *bufptr, *bufend; - uint32_t offset_to_index, size_of_index; - - /* verify MAR ID */ - if (fread(id, MAR_ID_SIZE, 1, mar->fp) != 1) - return -1; - if (memcmp(id, MAR_ID, MAR_ID_SIZE) != 0) - return -1; - - if (fread(&offset_to_index, sizeof(uint32_t), 1, mar->fp) != 1) - return -1; - offset_to_index = ntohl(offset_to_index); - - if (fseek(mar->fp, offset_to_index, SEEK_SET)) - return -1; - if (fread(&size_of_index, sizeof(uint32_t), 1, mar->fp) != 1) - return -1; - size_of_index = ntohl(size_of_index); - - buf = (char *) malloc(size_of_index); - if (!buf) - return -1; - if (fread(buf, size_of_index, 1, mar->fp) != 1) { - free(buf); - return -1; - } - - bufptr = buf; - bufend = buf + size_of_index; - while (bufptr < bufend && mar_consume_index(mar, &bufptr, bufend) == 0); - - free(buf); - return (bufptr == bufend) ? 0 : -1; -} - -/** - * Internal shared code for mar_open and mar_wopen. - * On failure, will fclose(fp). - */ -static MarFile *mar_fpopen(FILE *fp) -{ - MarFile *mar; - - mar = (MarFile *) malloc(sizeof(*mar)); - if (!mar) { - fclose(fp); - return NULL; - } - - mar->fp = fp; - memset(mar->item_table, 0, sizeof(mar->item_table)); - if (mar_read_index(mar)) { - mar_close(mar); - return NULL; - } - - return mar; -} - -MarFile *mar_open(const char *path) { - FILE *fp; - - fp = fopen(path, "rb"); - if (!fp) { - fprintf(stderr, "ERROR: could not open file in mar_open()\n"); - perror(path); - return NULL; - } - - return mar_fpopen(fp); -} - -#ifdef _WIN32 -MarFile *mar_wopen(const wchar_t *path) { - FILE *fp; - - _wfopen_s(&fp, path, L"rb"); - if (!fp) { - fprintf(stderr, "ERROR: could not open file in mar_wopen()\n"); - _wperror(path); - return NULL; - } - - return mar_fpopen(fp); -} -#endif - -void mar_close(MarFile *mar) { - MarItem *item; - int i; - - fclose(mar->fp); - - for (i = 0; i < TABLESIZE; ++i) { - item = mar->item_table[i]; - while (item) { - MarItem *temp = item; - item = item->next; - free(temp); - } - } - - free(mar); -} - -/** - * Determines the MAR file information. - * - * @param fp An opened MAR file in read mode. - * @param hasSignatureBlock Optional out parameter specifying if the MAR - * file has a signature block or not. - * @param numSignatures Optional out parameter for storing the number - * of signatures in the MAR file. - * @param hasAdditionalBlocks Optional out parameter specifying if the MAR - * file has additional blocks or not. - * @param offsetAdditionalBlocks Optional out parameter for the offset to the - * first additional block. Value is only valid if - * hasAdditionalBlocks is not equal to 0. - * @param numAdditionalBlocks Optional out parameter for the number of - * additional blocks. Value is only valid if - * hasAdditionalBlocks is not equal to 0. - * @return 0 on success and non-zero on failure. - */ -int get_mar_file_info_fp(FILE *fp, - int *hasSignatureBlock, - uint32_t *numSignatures, - int *hasAdditionalBlocks, - uint32_t *offsetAdditionalBlocks, - uint32_t *numAdditionalBlocks) -{ - uint32_t offsetToIndex, offsetToContent, signatureCount, signatureLen, i; - - /* One of hasSignatureBlock or hasAdditionalBlocks must be non NULL */ - if (!hasSignatureBlock && !hasAdditionalBlocks) { - return -1; - } - - - /* Skip to the start of the offset index */ - if (fseek(fp, MAR_ID_SIZE, SEEK_SET)) { - return -1; - } - - /* Read the offset to the index. */ - if (fread(&offsetToIndex, sizeof(offsetToIndex), 1, fp) != 1) { - return -1; - } - offsetToIndex = ntohl(offsetToIndex); - - if (numSignatures) { - /* Skip past the MAR file size field */ - if (fseek(fp, sizeof(uint64_t), SEEK_CUR)) { - return -1; - } - - /* Read the number of signatures field */ - if (fread(numSignatures, sizeof(*numSignatures), 1, fp) != 1) { - return -1; - } - *numSignatures = ntohl(*numSignatures); - } - - /* Skip to the first index entry past the index size field - We do it in 2 calls because offsetToIndex + sizeof(uint32_t) - could oerflow in theory. */ - if (fseek(fp, offsetToIndex, SEEK_SET)) { - return -1; - } - - if (fseek(fp, sizeof(uint32_t), SEEK_CUR)) { - return -1; - } - - /* Read the first offset to content field. */ - if (fread(&offsetToContent, sizeof(offsetToContent), 1, fp) != 1) { - return -1; - } - offsetToContent = ntohl(offsetToContent); - - /* Check if we have a new or old MAR file */ - if (hasSignatureBlock) { - if (offsetToContent == MAR_ID_SIZE + sizeof(uint32_t)) { - *hasSignatureBlock = 0; - } else { - *hasSignatureBlock = 1; - } - } - - /* If the caller doesn't care about the product info block - value, then just return */ - if (!hasAdditionalBlocks) { - return 0; - } - - /* Skip to the start of the signature block */ - if (fseeko(fp, SIGNATURE_BLOCK_OFFSET, SEEK_SET)) { - return -1; - } - - /* Get the number of signatures */ - if (fread(&signatureCount, sizeof(signatureCount), 1, fp) != 1) { - return -1; - } - signatureCount = ntohl(signatureCount); - - /* Check that we have less than the max amount of signatures so we don't - waste too much of either updater's or signmar's time. */ - if (signatureCount > MAX_SIGNATURES) { - return -1; - } - - /* Skip past the whole signature block */ - for (i = 0; i < signatureCount; i++) { - /* Skip past the signature algorithm ID */ - if (fseek(fp, sizeof(uint32_t), SEEK_CUR)) { - return -1; - } - - /* Read the signature length and skip past the signature */ - if (fread(&signatureLen, sizeof(uint32_t), 1, fp) != 1) { - return -1; - } - signatureLen = ntohl(signatureLen); - if (fseek(fp, signatureLen, SEEK_CUR)) { - return -1; - } - } - - if (ftell(fp) == offsetToContent) { - *hasAdditionalBlocks = 0; - } else { - if (numAdditionalBlocks) { - /* We have an additional block, so read in the number of additional blocks - and set the offset. */ - *hasAdditionalBlocks = 1; - if (fread(numAdditionalBlocks, sizeof(uint32_t), 1, fp) != 1) { - return -1; - } - *numAdditionalBlocks = ntohl(*numAdditionalBlocks); - if (offsetAdditionalBlocks) { - *offsetAdditionalBlocks = ftell(fp); - } - } else if (offsetAdditionalBlocks) { - /* numAdditionalBlocks is not specified but offsetAdditionalBlocks - is, so fill it! */ - *offsetAdditionalBlocks = ftell(fp) + sizeof(uint32_t); - } - } - - return 0; -} - -/** - * Reads the product info block from the MAR file's additional block section. - * The caller is responsible for freeing the fields in infoBlock - * if the return is successful. - * - * @param infoBlock Out parameter for where to store the result to - * @return 0 on success, -1 on failure -*/ -int -read_product_info_block(char *path, - struct ProductInformationBlock *infoBlock) -{ - int rv; - MarFile mar; - mar.fp = fopen(path, "rb"); - if (!mar.fp) { - fprintf(stderr, "ERROR: could not open file in read_product_info_block()\n"); - perror(path); - return -1; - } - rv = mar_read_product_info_block(&mar, infoBlock); - fclose(mar.fp); - return rv; -} - -/** - * Reads the product info block from the MAR file's additional block section. - * The caller is responsible for freeing the fields in infoBlock - * if the return is successful. - * - * @param infoBlock Out parameter for where to store the result to - * @return 0 on success, -1 on failure -*/ -int -mar_read_product_info_block(MarFile *mar, - struct ProductInformationBlock *infoBlock) -{ - uint32_t i, offsetAdditionalBlocks, numAdditionalBlocks, - additionalBlockSize, additionalBlockID; - int hasAdditionalBlocks; - - /* The buffer size is 97 bytes because the MAR channel name < 64 bytes, and - product version < 32 bytes + 3 NULL terminator bytes. */ - char buf[97] = { '\0' }; - int ret = get_mar_file_info_fp(mar->fp, NULL, NULL, - &hasAdditionalBlocks, - &offsetAdditionalBlocks, - &numAdditionalBlocks); - if (ret) - return ret; - for (i = 0; i < numAdditionalBlocks; ++i) { - /* Read the additional block size */ - if (fread(&additionalBlockSize, - sizeof(additionalBlockSize), - 1, mar->fp) != 1) { - return -1; - } - additionalBlockSize = ntohl(additionalBlockSize) - - sizeof(additionalBlockSize) - - sizeof(additionalBlockID); - - /* Read the additional block ID */ - if (fread(&additionalBlockID, - sizeof(additionalBlockID), - 1, mar->fp) != 1) { - return -1; - } - additionalBlockID = ntohl(additionalBlockID); - - if (PRODUCT_INFO_BLOCK_ID == additionalBlockID) { - const char *location; - int len; - - /* This block must be at most 104 bytes. - MAR channel name < 64 bytes, and product version < 32 bytes + 3 NULL - terminator bytes. We only check for 96 though because we remove 8 - bytes above from the additionalBlockSize: We subtract - sizeof(additionalBlockSize) and sizeof(additionalBlockID) */ - if (additionalBlockSize > 96) { - return -1; - } - - if (fread(buf, additionalBlockSize, 1, mar->fp) != 1) { - return -1; - } - - /* Extract the MAR channel name from the buffer. For now we - point to the stack allocated buffer but we strdup this - if we are within bounds of each field's max length. */ - location = buf; - len = strlen(location); - infoBlock->MARChannelID = location; - location += len + 1; - if (len >= 64) { - infoBlock->MARChannelID = NULL; - return -1; - } - - /* Extract the version from the buffer */ - len = strlen(location); - infoBlock->productVersion = location; - location += len + 1; - if (len >= 32) { - infoBlock->MARChannelID = NULL; - infoBlock->productVersion = NULL; - return -1; - } - infoBlock->MARChannelID = - strdup(infoBlock->MARChannelID); - infoBlock->productVersion = - strdup(infoBlock->productVersion); - return 0; - } else { - /* This is not the additional block you're looking for. Move along. */ - if (fseek(mar->fp, additionalBlockSize, SEEK_CUR)) { - return -1; - } - } - } - - /* If we had a product info block we would have already returned */ - return -1; -} - -const MarItem *mar_find_item(MarFile *mar, const char *name) { - uint32_t hash; - const MarItem *item; - - hash = mar_hash_name(name); - - item = mar->item_table[hash]; - while (item && strcmp(item->name, name) != 0) - item = item->next; - - return item; -} - -int mar_enum_items(MarFile *mar, MarItemCallback callback, void *closure) { - MarItem *item; - int i; - - for (i = 0; i < TABLESIZE; ++i) { - item = mar->item_table[i]; - while (item) { - int rv = callback(mar, item, closure); - if (rv) - return rv; - item = item->next; - } - } - - return 0; -} - -int mar_read(MarFile *mar, const MarItem *item, int offset, char *buf, - int bufsize) { - int nr; - - if (offset == (int) item->length) - return 0; - if (offset > (int) item->length) - return -1; - - nr = item->length - offset; - if (nr > bufsize) - nr = bufsize; - - if (fseek(mar->fp, item->offset + offset, SEEK_SET)) - return -1; - - return fread(buf, 1, nr, mar->fp); -} - -/** - * Determines the MAR file information. - * - * @param path The path of the MAR file to check. - * @param hasSignatureBlock Optional out parameter specifying if the MAR - * file has a signature block or not. - * @param numSignatures Optional out parameter for storing the number - * of signatures in the MAR file. - * @param hasAdditionalBlocks Optional out parameter specifying if the MAR - * file has additional blocks or not. - * @param offsetAdditionalBlocks Optional out parameter for the offset to the - * first additional block. Value is only valid if - * hasAdditionalBlocks is not equal to 0. - * @param numAdditionalBlocks Optional out parameter for the number of - * additional blocks. Value is only valid if - * has_additional_blocks is not equal to 0. - * @return 0 on success and non-zero on failure. - */ -int get_mar_file_info(const char *path, - int *hasSignatureBlock, - uint32_t *numSignatures, - int *hasAdditionalBlocks, - uint32_t *offsetAdditionalBlocks, - uint32_t *numAdditionalBlocks) -{ - int rv; - FILE *fp = fopen(path, "rb"); - if (!fp) { - fprintf(stderr, "ERROR: could not open file in get_mar_file_info()\n"); - perror(path); - return -1; - } - - rv = get_mar_file_info_fp(fp, hasSignatureBlock, - numSignatures, hasAdditionalBlocks, - offsetAdditionalBlocks, numAdditionalBlocks); - - fclose(fp); - return rv; -} _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits