summaryrefslogtreecommitdiff
path: root/onlineupdate
diff options
context:
space:
mode:
authorRas-al-Ghul <dipankar1995@gmail.com>2016-03-12 23:30:22 +0530
committerJan Holesovsky <kendy@collabora.com>2016-03-14 09:15:09 +0000
commite60506acc53098b4b479d565048c316562657cec (patch)
tree9c7b457f4e875e24471990490173934c2452642e /onlineupdate
parent60286229fa54b71c67a5d25a7cce59e54b6b8680 (diff)
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 <ci@libreoffice.org> Reviewed-by: Jan Holesovsky <kendy@collabora.com>
Diffstat (limited to 'onlineupdate')
-rw-r--r--onlineupdate/Executable_mar.mk8
-rw-r--r--onlineupdate/Executable_updater.mk11
-rw-r--r--onlineupdate/Module_onlineupdate.mk1
-rw-r--r--onlineupdate/StaticLibrary_libmar.mk23
-rw-r--r--onlineupdate/source/update/src/Makefile.in13
-rw-r--r--onlineupdate/source/update/src/mar.h198
-rw-r--r--onlineupdate/source/update/src/mar_cmdline.h110
-rw-r--r--onlineupdate/source/update/src/mar_create.c398
-rw-r--r--onlineupdate/source/update/src/mar_extract.c85
-rw-r--r--onlineupdate/source/update/src/mar_private.h79
-rw-r--r--onlineupdate/source/update/src/mar_read.c572
11 files changed, 32 insertions, 1466 deletions
diff --git a/onlineupdate/Executable_mar.mk b/onlineupdate/Executable_mar.mk
index c2dccafc38b8..3000a1c70d30 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 fba7e3c7bcd7..6ba6d4df8897 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 113c03179815..19b8529fc466 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 000000000000..3c85b739bc3c
--- /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 1da582e5be03..000000000000
--- 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 0e21efb920a5..000000000000
--- 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 ef6867f06fc3..000000000000
--- 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 4e4e2b4058c2..000000000000
--- 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 75cbd645f296..000000000000
--- 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 a770998da6fe..000000000000
--- 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 0ed8c6be6ea9..000000000000
--- 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;
-}