/*
* @(#)parse_manifest.c 1.24 06/07/25
*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* If Windows is POSIX compliant, why isn't the prototype for lseek where
* POSIX says it should be?
*/
#ifdef _WIN32
#include <windows.h>
#include <io.h>
#else /* Unix */
#include <unistd.h>
#endif /* Unix */
#include <zlib.h>
#include "manifest_info.h"
/*
* On Windows, str[n]casecmp() are known as str[n]icmp().
*/
#ifdef _WIN32
#define strcasecmp(p1, p2) stricmp((p1), (p2))
#define strncasecmp(p1, p2, p3) strnicmp((p1), (p2), (p3))
#endif
static char *manifest;
static const char *manifest_name = "META-INF/MANIFEST.MF";
/*
* Inflate the manifest file (or any file for that matter).
*
* fd: File descriptor of the jar file.
* entry: Contains the information necessary to perform the inflation
* (the compressed and uncompressed sizes and the offset in
* the file where the compressed data is located).
* size_out: Returns the size of the inflated file.
*
* Upon success, it returns a pointer to a NUL-terminated malloc'd buffer
* containing the inflated manifest file. When the caller is done with it,
* this buffer should be released by a call to free(). Upon failure,
* returns NULL.
*/
static char *
inflate_file(int fd, zentry *entry, int *size_out)
{
char *in;
char *out;
z_stream zs;
if (entry->csize == 0xffffffff || entry->isize == 0xffffffff)
return (NULL);
if (lseek(fd, entry->offset, SEEK_SET) < (off_t)0)
return (NULL);
if ((in = malloc(entry->csize + 1)) == NULL)
return (NULL);
if ((size_t)(read(fd, in, (unsigned int)entry->csize)) != entry->csize) {
free(in);
return (NULL);
}
if (entry->how == STORED) {
*(char *)((size_t)in + entry->csize) = '\0';
if (size_out) {
*size_out = entry->csize;
}
return (in);
} else if (entry->how == DEFLATED) {
zs.zalloc = (alloc_func)Z_NULL;
zs.zfree = (free_func)Z_NULL;
zs.opaque = (voidpf)Z_NULL;
zs.next_in = (Byte*)in;
zs.avail_in = (uInt)entry->csize;
if (inflateInit2(&zs, -MAX_WBITS) < 0) {
free(in);
return (NULL);
}
if ((out = malloc(entry->isize + 1)) == NULL) {
free(in);
return (NULL);
}
zs.next_out = (Byte*)out;
zs.avail_out = (uInt)entry->isize;
if (inflate(&zs, Z_PARTIAL_FLUSH) < 0) {
free(in);
free(out);
return (NULL);
}
*(char *)((size_t)out + entry->isize) = '\0';
free(in);
=1= |