19#include <netinet/in.h>
37 uint32_t n_offset, n_length, n_flags;
41 namelen = strlen(
name);
47 stack->
head = realloc(stack->
head, size_needed);
57 n_flags =
htonl(flags);
59 memcpy(data, &n_offset,
sizeof(n_offset));
60 data +=
sizeof(n_offset);
62 memcpy(data, &n_length,
sizeof(n_length));
63 data +=
sizeof(n_length);
65 memcpy(data, &n_flags,
sizeof(n_flags));
66 data +=
sizeof(n_flags);
68 memcpy(data,
name, namelen + 1);
81 in = fopen(path,
"rb");
83 fprintf(stderr,
"ERROR: could not open file in mar_concat_file()\n");
89 if (fwrite(buf, len, 1, fp) != 1) {
114 uint32_t additionalBlockID = 1, infoBlockSize, unused;
115 if (!fp || !infoBlock ||
135 infoBlockSize =
sizeof(infoBlockSize) +
136 sizeof(additionalBlockID) +
144 infoBlockSize =
htonl(infoBlockSize);
145 if (fwrite(&infoBlockSize,
146 sizeof(infoBlockSize), 1, fp) != 1) {
149 infoBlockSize =
ntohl(infoBlockSize);
152 additionalBlockID =
htonl(additionalBlockID);
153 if (fwrite(&additionalBlockID,
154 sizeof(additionalBlockID), 1, fp) != 1) {
157 additionalBlockID =
ntohl(additionalBlockID);
172 unused = infoBlockSize - (
sizeof(infoBlockSize) +
173 sizeof(additionalBlockID) +
176 memset(buf, 0,
sizeof(buf));
177 if (fwrite(buf, unused, 1, fp) != 1) {
198 uint32_t numSignatures, additionalBlockSize, additionalBlockID,
199 offsetAdditionalBlocks, numAdditionalBlocks,
i;
200 int additionalBlocks, hasSignatureBlock;
206 &offsetAdditionalBlocks,
207 &numAdditionalBlocks);
209 fprintf(stderr,
"ERROR: Could not obtain MAR information.\n");
213 if (hasSignatureBlock && numSignatures) {
214 fprintf(stderr,
"ERROR: Cannot refresh a signed MAR\n");
218 fp = fopen(path,
"r+b");
220 fprintf(stderr,
"ERROR: could not open target file: %s\n", path);
224 if (fseeko(fp, offsetAdditionalBlocks, SEEK_SET)) {
225 fprintf(stderr,
"ERROR: could not seek to additional blocks\n");
230 for (
i = 0;
i < numAdditionalBlocks; ++
i) {
232 int64_t oldPos = ftello(fp);
235 if (fread(&additionalBlockSize,
236 sizeof(additionalBlockSize),
241 additionalBlockSize =
ntohl(additionalBlockSize);
244 if (fread(&additionalBlockID,
245 sizeof(additionalBlockID),
250 additionalBlockID =
ntohl(additionalBlockID);
253 if (fseeko(fp, oldPos, SEEK_SET)) {
254 fprintf(stderr,
"Could not seek back to Product Information Block\n");
260 fprintf(stderr,
"Could not concat Product Information Block\n");
269 if (fseek(fp, additionalBlockSize, SEEK_CUR)) {
270 fprintf(stderr,
"ERROR: Could not seek past current block.\n");
279 fprintf(stderr,
"ERROR: Could not refresh because block does not exist\n");
294 num_files,
char **files,
297 uint32_t offset_to_index = 0, size_of_index,
298 numSignatures, numAdditionalSections;
299 uint64_t sizeOfEntireMAR = 0;
304 memset(&stack, 0,
sizeof(stack));
306 fp = fopen(dest,
"wb");
308 fprintf(stderr,
"ERROR: could not create target file: %s\n", dest);
314 if (fwrite(&offset_to_index,
sizeof(uint32_t), 1, fp) != 1)
318 sizeof(offset_to_index) +
319 sizeof(numSignatures) +
320 sizeof(numAdditionalSections) +
321 sizeof(sizeOfEntireMAR);
324 if (fwrite(&sizeOfEntireMAR,
sizeof(sizeOfEntireMAR), 1, fp) != 1) {
330 if (fwrite(&numSignatures,
sizeof(numSignatures), 1, fp) != 1) {
336 numAdditionalSections =
htonl(1);
337 if (fwrite(&numAdditionalSections,
338 sizeof(numAdditionalSections), 1, fp) != 1) {
341 numAdditionalSections =
ntohl(numAdditionalSections);
347 for (
i = 0;
i < num_files; ++
i) {
348 if (stat(files[
i], &st)) {
349 fprintf(stderr,
"ERROR: file not found: %s\n", files[
i]);
353 if (
mar_push(&stack, st.st_size, st.st_mode & 0777, files[
i]))
363 if (fwrite(&size_of_index,
sizeof(size_of_index), 1, fp) != 1)
378 if (fwrite(&offset_to_index,
sizeof(offset_to_index), 1, fp) != 1)
384 sizeof(size_of_index);
386 if (fwrite(&sizeOfEntireMAR,
sizeof(sizeOfEntireMAR), 1, fp) != 1)
static int mar_push(struct MarItemStack *stack, uint32_t length, uint32_t flags, const char *name)
Push a new item onto the stack of items.
static int mar_concat_file(FILE *fp, const char *path)
static int mar_concat_product_info_block(FILE *fp, struct MarItemStack *stack, struct ProductInformationBlock *infoBlock)
Writes out the product information block to the specified file.
int refresh_product_info_block(const char *path, struct ProductInformationBlock *infoBlock)
Refreshes the product information block with the new information.
int mar_create(const char *dest, int num_files, char **files, struct ProductInformationBlock *infoBlock)
Create a MAR file from a set of files.
#define NETWORK_TO_HOST64
#define MAX_SIZE_OF_MAR_FILE
#define PRODUCT_INFO_BLOCK_ID
#define PIB_MAX_PRODUCT_VERSION_SIZE
#define ROUND_UP(n, incr)
#define MAR_ITEM_SIZE(namelen)
#define HOST_TO_NETWORK64(x)
#define PIB_MAX_MAR_CHANNEL_ID_SIZE
int get_mar_file_info(const char *path, int *hasSignatureBlock, uint32_t *numSignatures, int *hasAdditionalBlocks, uint32_t *offsetAdditionalBlocks, uint32_t *numAdditionalBlocks)
Determines the MAR file information.
OUStringBuffer & remove(OUStringBuffer &rIn, sal_Unicode c)
sal_uInt32 htonl(sal_uInt32 h)
sal_uInt32 ntohl(sal_uInt32 n)