17#include <netinet/in.h>
26 for (c = (
unsigned char *)
name; *c; ++c)
33 uint32_t offset, uint32_t length, uint32_t flags) {
44 memcpy(item->
name,
name, namelen + 1);
75 if ((buf_end - *buf) < (
int)(3*
sizeof(uint32_t) + 2))
78 memcpy(&offset, *buf,
sizeof(offset));
79 *buf +=
sizeof(offset);
84 memcpy(&flags, *buf,
sizeof(flags));
85 *buf +=
sizeof(flags);
87 offset =
ntohl(offset);
98 namelen = (*buf -
name);
109 uint32_t offset_to_index, size_of_index;
117 if (fread(&offset_to_index,
sizeof(uint32_t), 1, mar->
fp) != 1)
119 offset_to_index =
ntohl(offset_to_index);
121 if (fseek(mar->
fp, offset_to_index, SEEK_SET))
123 if (fread(&size_of_index,
sizeof(uint32_t), 1, mar->
fp) != 1)
125 size_of_index =
ntohl(size_of_index);
127 buf = (
char *) malloc(size_of_index);
130 if (fread(buf, size_of_index, 1, mar->
fp) != 1) {
136 bufend = buf + size_of_index;
140 return (bufptr == bufend) ? 0 : -1;
151 mar = (
MarFile *) malloc(
sizeof(*mar));
170 fp = fopen(path,
"rb");
172 fprintf(stderr,
"ERROR: could not open file in mar_open()\n");
181MarFile *mar_wopen(
const wchar_t *path) {
184 _wfopen_s(&fp, path, L
"rb");
186 fprintf(stderr,
"ERROR: could not open file in mar_wopen()\n");
232 int *hasSignatureBlock,
233 uint32_t *numSignatures,
234 int *hasAdditionalBlocks,
235 uint32_t *offsetAdditionalBlocks,
236 uint32_t *numAdditionalBlocks)
238 uint32_t offsetToIndex, offsetToContent, signatureCount, signatureLen,
i;
241 if (!hasSignatureBlock && !hasAdditionalBlocks) {
252 if (fread(&offsetToIndex,
sizeof(offsetToIndex), 1, fp) != 1) {
255 offsetToIndex =
ntohl(offsetToIndex);
259 if (fseek(fp,
sizeof(uint64_t), SEEK_CUR)) {
264 if (fread(numSignatures,
sizeof(*numSignatures), 1, fp) != 1) {
267 *numSignatures =
ntohl(*numSignatures);
273 if (fseek(fp, offsetToIndex, SEEK_SET)) {
277 if (fseek(fp,
sizeof(uint32_t), SEEK_CUR)) {
282 if (fread(&offsetToContent,
sizeof(offsetToContent), 1, fp) != 1) {
285 offsetToContent =
ntohl(offsetToContent);
288 if (hasSignatureBlock) {
289 if (offsetToContent ==
MAR_ID_SIZE +
sizeof(uint32_t)) {
290 *hasSignatureBlock = 0;
292 *hasSignatureBlock = 1;
298 if (!hasAdditionalBlocks) {
308 if (fread(&signatureCount,
sizeof(signatureCount), 1, fp) != 1) {
311 signatureCount =
ntohl(signatureCount);
320 for (
i = 0;
i < signatureCount;
i++) {
322 if (fseek(fp,
sizeof(uint32_t), SEEK_CUR)) {
327 if (fread(&signatureLen,
sizeof(uint32_t), 1, fp) != 1) {
330 signatureLen =
ntohl(signatureLen);
331 if (fseek(fp, signatureLen, SEEK_CUR)) {
336 if (ftell(fp) == (
long)offsetToContent) {
337 *hasAdditionalBlocks = 0;
339 if (numAdditionalBlocks) {
342 *hasAdditionalBlocks = 1;
343 if (fread(numAdditionalBlocks,
sizeof(uint32_t), 1, fp) != 1) {
346 *numAdditionalBlocks =
ntohl(*numAdditionalBlocks);
347 if (offsetAdditionalBlocks) {
348 *offsetAdditionalBlocks = ftell(fp);
350 }
else if (offsetAdditionalBlocks) {
353 *offsetAdditionalBlocks = ftell(fp) +
sizeof(uint32_t);
374 mar.
fp = fopen(path,
"rb");
376 fprintf(stderr,
"ERROR: could not open file in read_product_info_block()\n");
397 uint32_t
i, offsetAdditionalBlocks, numAdditionalBlocks,
398 additionalBlockSize, additionalBlockID;
399 int hasAdditionalBlocks;
403 char buf[97] = {
'\0' };
405 &hasAdditionalBlocks,
406 &offsetAdditionalBlocks,
407 &numAdditionalBlocks);
410 for (
i = 0;
i < numAdditionalBlocks; ++
i) {
412 if (fread(&additionalBlockSize,
413 sizeof(additionalBlockSize),
417 additionalBlockSize =
ntohl(additionalBlockSize) -
418 sizeof(additionalBlockSize) -
419 sizeof(additionalBlockID);
422 if (fread(&additionalBlockID,
423 sizeof(additionalBlockID),
427 additionalBlockID =
ntohl(additionalBlockID);
430 const char *location;
438 if (additionalBlockSize > 96) {
442 if (fread(buf, additionalBlockSize, 1, mar->
fp) != 1) {
450 len = strlen(location);
459 len = strlen(location);
474 if (fseek(mar->
fp, additionalBlockSize, SEEK_CUR)) {
491 while (item && strcmp(item->
name,
name) != 0)
504 int rv = callback(mar, item, closure);
518 if (offset == (
int) item->
length)
520 if (offset > (
int) item->
length)
523 nr = item->
length - offset;
527 if (fseek(mar->
fp, item->
offset + offset, SEEK_SET))
530 return fread(buf, 1, nr, mar->
fp);
552 int *hasSignatureBlock,
553 uint32_t *numSignatures,
554 int *hasAdditionalBlocks,
555 uint32_t *offsetAdditionalBlocks,
556 uint32_t *numAdditionalBlocks)
559 FILE *fp = fopen(path,
"rb");
561 fprintf(stderr,
"ERROR: could not open file in get_mar_file_info()\n");
567 numSignatures, hasAdditionalBlocks,
568 offsetAdditionalBlocks, numAdditionalBlocks);
int(* MarItemCallback)(MarFile *mar, const MarItem *item, void *data)
Signature of callback function passed to mar_enum_items.
#define PRODUCT_INFO_BLOCK_ID
#define SIGNATURE_BLOCK_OFFSET
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.
static uint32_t mar_hash_name(const char *name)
static int mar_read_index(MarFile *mar)
int mar_read(MarFile *mar, const MarItem *item, int offset, char *buf, int bufsize)
Read from MAR item at given offset up to bufsize bytes.
void mar_close(MarFile *mar)
Close a MAR file that was opened using mar_open.
int mar_enum_items(MarFile *mar, MarItemCallback callback, void *closure)
Enumerate all MAR items via callback function.
int get_mar_file_info_fp(FILE *fp, int *hasSignatureBlock, uint32_t *numSignatures, int *hasAdditionalBlocks, uint32_t *offsetAdditionalBlocks, uint32_t *numAdditionalBlocks)
Determines the MAR file information.
MarFile * mar_open(const char *path)
Open a MAR file for reading.
int read_product_info_block(char *path, struct ProductInformationBlock *infoBlock)
Reads the product info block from the MAR file's additional block section.
static MarFile * mar_fpopen(FILE *fp)
Internal shared code for mar_open and mar_wopen.
const MarItem * mar_find_item(MarFile *mar, const char *name)
Find an item in the MAR file by name.
static int mar_insert_item(MarFile *mar, const char *name, int namelen, uint32_t offset, uint32_t length, uint32_t flags)
int mar_read_product_info_block(MarFile *mar, struct ProductInformationBlock *infoBlock)
Reads the product info block from the MAR file's additional block section.
static int mar_consume_index(MarFile *mar, char **buf, const char *buf_end)
sal_uInt32 ntohl(sal_uInt32 n)
MarItem * item_table[TABLESIZE]
The MAR item data structure.