/* cabextract 0.6 - a program to extract Microsoft Cabinet files
* (C) 2000-2002 Stuart Caie <kyzer@4u.net>
+ * Modifications for Captive project by:
+ * Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* Intel code.
*/
+#include "config.h" /* CAPTIVE */
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+#include <glib/gmessages.h>
+#include <ctype.h>
+#include "../cabinet.h"
+#include "cabextract.h"
+
#ifdef DEBUG
# define D(x) printf x ;
#else
#endif
-typedef unsigned char UBYTE; /* 8 bits exactly */
-typedef unsigned short UWORD; /* 16 bits (or more) */
-typedef unsigned int ULONG; /* 32 bits (or more) */
-typedef signed int LONG; /* 32 bits (or more) */
-
/* number of bits in a ULONG */
#ifndef CHAR_BIT
# define CHAR_BIT (8)
/* maximum number of cabinets any one folder can be split across */
#define CAB_SPLITMAX (10)
-struct cabinet {
- struct cabinet *next; /* for making a list of cabinets */
- char *filename; /* input name of cabinet */
- FILE *fh; /* open file handle or NULL */
- off_t filelen; /* length of cabinet file */
- off_t blocks_off; /* offset to data blocks in file */
- struct cabinet *prevcab, *nextcab; /* multipart cabinet chains */
- char *prevname, *nextname; /* and their filenames */
- char *previnfo, *nextinfo; /* and their visible names */
- struct folder *folders; /* first folder in this cabinet */
- struct file *files; /* first file in this cabinet */
- UBYTE block_resv; /* reserved space in datablocks */
- UBYTE flags; /* header flags */
-};
-
struct folder {
struct folder *next;
struct cabinet *cab[CAB_SPLITMAX]; /* cabinet(s) this folder spans */
struct file *contfile; /* the first split file */
};
-struct file {
- struct file *next; /* next file in sequence */
- struct folder *folder; /* folder that contains this file */
- char *filename; /* output name of file */
- FILE *fh; /* open file handle or NULL */
- ULONG length; /* uncompressed length of file */
- ULONG offset; /* uncompressed offset in folder */
- UWORD index; /* magic index number of folder */
- UWORD time, date, attribs; /* MS-DOS time/date/attributes */
-};
-
/* structure offsets */
#define cfhead_Signature (0x00)
#define CAB_BLOCKMAX (32768)
#define CAB_INPUTMAX (CAB_BLOCKMAX+6144)
-struct {
+static struct {
struct folder *current; /* current folder we're extracting from */
ULONG offset; /* uncompressed offset within folder */
UBYTE *outpos; /* (high level) start of data to use up */
b|=((ULONG)c)<<k;k+=8;}}
#define ZIPDUMPBITS(n) {b>>=(n);k-=(n);}
-void Ziphuft_free(struct Ziphuft *t)
+static void Ziphuft_free(struct Ziphuft *t)
{
register struct Ziphuft *p, *q;
}
}
-LONG Ziphuft_build(ULONG *b, ULONG n, ULONG s, UWORD *d, UWORD *e,
+static LONG Ziphuft_build(ULONG *b, ULONG n, ULONG s, UWORD *d, UWORD *e,
struct Ziphuft **t, LONG *m)
{
ULONG a; /* counter for codes of length k */
w += l[h++]; /* add bits already decoded */
/* compute minimum size table less than or equal to *m bits */
- z = (z = g - w) > (ULONG)*m ? *m : z; /* upper limit */
+ z = (z = g - w) > (ULONG)*m ? (ULONG)*m : z; /* upper limit */
if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
{ /* too few codes for k-w bit table */
f -= a + 1; /* deduct codes from patterns left */
return y != 0 && g != 1;
}
-LONG Zipinflate_codes(struct Ziphuft *tl, struct Ziphuft *td,
+static LONG Zipinflate_codes(struct Ziphuft *tl, struct Ziphuft *td,
LONG bl, LONG bd)
{
register ULONG e; /* table entry flag/number of extra bits */
return 0;
}
-LONG Zipinflate_stored(void)
+static LONG Zipinflate_stored(void)
/* "decompress" an inflated type 0 (stored) block. */
{
ULONG n; /* number of bytes in block */
return 0;
}
-LONG Zipinflate_fixed(void)
+static LONG Zipinflate_fixed(void)
{
struct Ziphuft *fixed_tl;
struct Ziphuft *fixed_td;
return i;
}
-LONG Zipinflate_dynamic(void)
+static LONG Zipinflate_dynamic(void)
/* decompress an inflated type 2 (dynamic Huffman codes) block. */
{
LONG i; /* temporary variables */
return 0;
}
-LONG Zipinflate_block(LONG *e) /* e == last block flag */
+static LONG Zipinflate_block(LONG *e) /* e == last block flag */
{ /* decompress an inflated block */
ULONG t; /* block type */
register ULONG b; /* bit buffer */
return 2;
}
-int ZIPdecompress(int inlen, int outlen)
+static int ZIPdecompress(int inlen, int outlen)
{
LONG e; /* last block flag */
static ULONG q_position_base[42];
/* Initialise a model which decodes symbols from [s] to [s]+[n]-1 */
-void QTMinitmodel(struct QTMmodel *m, struct QTMmodelsym *sym, int n, int s) {
+static void QTMinitmodel(struct QTMmodel *m, struct QTMmodelsym *sym, int n, int s) {
int i;
m->shiftsleft = 4;
m->entries = n;
m->syms[n].cumfreq = 0;
}
-int QTMinit(int window, int level) {
+static int QTMinit(int window, int level) {
int wndsize = 1 << window, msz = window * 2, i;
ULONG j;
/* QTM supports window sizes of 2^10 (1Kb) through 2^21 (2Mb) */
/* if a previously allocated window is big enough, keep it */
if (window < 10 || window > 21) return DECR_DATAFORMAT;
- if (QTM(actual_size) < wndsize) {
+ if (QTM(actual_size) < (ULONG)wndsize) {
if (QTM(window)) free(QTM(window));
QTM(window) = NULL;
}
}
-void QTMupdatemodel(struct QTMmodel *model, int sym) {
+static void QTMupdatemodel(struct QTMmodel *model, int sym) {
struct QTMmodelsym temp;
int i, j;
#define Q_INIT_BITSTREAM do { bitsleft = 0; bitbuf = 0; } while (0)
#define Q_FILL_BUFFER do { \
- if (bitsleft <= (ULONG_BITS - 16)) { \
+ if (bitsleft <= (int)(ULONG_BITS - 16)) { \
bitbuf |= ((inpos[0]<<8)|inpos[1]) << (ULONG_BITS-16 - bitsleft); \
bitsleft += 16; inpos += 2; \
} \
} while (0)
-int QTMdecompress(int inlen, int outlen) {
+static int QTMdecompress(int inlen, int outlen) {
UBYTE *inpos = CAB(inbuf);
UBYTE *window = QTM(window);
UBYTE *runsrc, *rundest;
UWORD symf;
int i;
- int extra, togo = outlen, match_length, copy_length;
+ int extra, togo = outlen, match_length = 0; /* Prevent: ... might be used uninitialized in this function */
+ int copy_length;
UBYTE selector, sym;
- ULONG match_offset;
+ ULONG match_offset = 0; /* Prevent: ... might be used uninitialized in this function */
UWORD H = 0xFFFF, L = 0, C;
static ULONG lzx_position_base[51];
static UBYTE extra_bits[51];
-int LZXinit(int window) {
+static int LZXinit(int window) {
ULONG wndsize = 1 << window;
int i, j, posn_slots;
* Returns 0 for OK or 1 for error
*/
-int make_decode_table(ULONG nsyms, ULONG nbits, UBYTE *length, UWORD *table) {
+static int make_decode_table(ULONG nsyms, ULONG nbits, UBYTE *length, UWORD *table) {
register UWORD sym;
register ULONG leaf;
register UBYTE bit_num = 1;
UBYTE *ip;
};
-int lzx_read_lens(UBYTE *lens, ULONG first, ULONG last, struct lzx_bits *lb) {
+static int lzx_read_lens(UBYTE *lens, ULONG first, ULONG last, struct lzx_bits *lb) {
ULONG i,j, x,y;
int z;
return 0;
}
-int LZXdecompress(int inlen, int outlen) {
+static int LZXdecompress(int inlen, int outlen) {
UBYTE *inpos = CAB(inbuf);
UBYTE *endinp = inpos + inlen;
UBYTE *window = LZX(window);
+#if 0 /* CAPTIVE */
/* all the file IO is abstracted into these routines:
* cabinet_(open|close|read|seek|skip|getoffset)
int ok = 0;
if (!(name = malloc(strlen(fi->filename) + (dir ? strlen(dir) : 0) + 2))) {
- fprintf(stderr, "out of memory!\n");
+ g_warning(_("out of memory!"));
return 0;
}
return ok;
}
+
/* closes a completed file, updates protections and timestamp */
void file_close(struct file *fi) {
struct utimbuf utb;
return 1;
}
-
void cabinet_close(struct cabinet *cab) {
if (cab->fh) {
fclose(cab->fh);
cab->fh = NULL;
}
-void cabinet_seek(struct cabinet *cab, off_t offset) {
- if (fseek(cab->fh, offset, SEEK_SET) < 0) {
- perror(cab->filename);
- }
+#endif /* CAPTIVE */
+
+static void cabinet_seek(struct cabinet *cab, off_t offset) {
+ acquire_cabinet_seek(cab->acquire_cabinet,offset);
}
-void cabinet_skip(struct cabinet *cab, off_t distance) {
- if (fseek(cab->fh, distance, SEEK_CUR) < 0) {
- perror(cab->filename);
- }
+static void cabinet_skip(struct cabinet *cab, off_t distance) {
+ acquire_cabinet_seek_skip(cab->acquire_cabinet,distance);
}
-off_t cabinet_getoffset(struct cabinet *cab) {
- return ftell(cab->fh);
+static off_t cabinet_getoffset(struct cabinet *cab) {
+ return acquire_cabinet_tell(cab->acquire_cabinet);
}
/* read data from a cabinet, returns success */
-int cabinet_read(struct cabinet *cab, UBYTE *buf, size_t length) {
- size_t avail = (size_t) (cab->filelen - cabinet_getoffset(cab));
- if (length > avail) {
- fprintf(stderr, "%s: WARNING; cabinet is truncated\n", cab->filename);
- length = avail;
- }
- if (fread((void *)buf, 1, length, cab->fh) != length) {
- perror(cab->filename);
+static int cabinet_read(struct cabinet *cab, UBYTE *buf, size_t length) {
+ GnomeVFSResult errvfsresult;
+ GnomeVFSFileSize bytes_read;
+
+ errvfsresult=acquire_cabinet_read(cab->acquire_cabinet,buf,length,&bytes_read);
+ if (errvfsresult!=GNOME_VFS_OK) {
+ g_warning(_("%s: cabinet read error: %s"), cab->filename, gnome_vfs_result_to_string(errvfsresult));
return 0;
}
+ if (bytes_read!=length)
+ g_warning(_("%s: WARNING; cabinet is truncated"), cab->filename);
return 1;
}
+#if 0 /* CAPTIVE */
+
/* try to open a cabinet file, returns success */
int cabinet_open(struct cabinet *cab) {
char *name = cab->filename;
return 1;
}
+#endif /* CAPTIVE */
+
/* allocate and read an aribitrarily long string from the cabinet */
-char *cabinet_read_string(struct cabinet *cab) {
+static char *cabinet_read_string(struct cabinet *cab) {
off_t len=256, base = cabinet_getoffset(cab), maxlen = cab->filelen - base;
int ok = 0, i;
UBYTE *buf = NULL;
if (!ok) {
if (len == maxlen) {
- fprintf(stderr, "%s: WARNING; cabinet is truncated\n", cab->filename);
+ g_warning(_("%s: WARNING; cabinet is truncated"), cab->filename);
break;
}
len += 256;
} while (!ok);
if (!ok) {
- if (buf) free(buf); else fprintf(stderr, "out of memory!\n");
+ if (buf) free(buf); else g_warning(_("out of memory!"));
return NULL;
}
}
/* reads the header and all folder and file entries in this cabinet */
-int cabinet_read_entries(struct cabinet *cab) {
+static int cabinet_read_entries(struct cabinet *cab) {
int num_folders, num_files, header_resv, folder_resv = 0, i;
struct folder *fol, *linkfol = NULL;
struct file *file, *linkfile = NULL;
/* check basic MSCF signature */
if (EndGetI32(buf+cfhead_Signature) != 0x4643534d) {
- fprintf(stderr, "%s: not a Microsoft cabinet file\n", cab->filename);
+ g_warning(_("%s: not a Microsoft cabinet file"), cab->filename);
return 0;
}
/* get the number of folders */
num_folders = EndGetI16(buf+cfhead_NumFolders);
if (num_folders == 0) {
- fprintf(stderr, "%s: no folders in cabinet\n", cab->filename);
+ g_warning(_("%s: no folders in cabinet"), cab->filename);
return 0;
}
/* get the number of files */
num_files = EndGetI16(buf+cfhead_NumFiles);
if (num_files == 0) {
- fprintf(stderr, "%s: no files in cabinet\n", cab->filename);
+ g_warning(_("%s: no files in cabinet"), cab->filename);
return 0;
}
if ((buf[cfhead_MajorVersion] > 1) ||
(buf[cfhead_MajorVersion] == 1 && buf[cfhead_MinorVersion] > 3))
{
- fprintf(stderr, "%s: WARNING; cabinet format version > 1.3\n",
+ g_warning(_("%s: WARNING; cabinet format version > 1.3"),
cab->filename);
}
cab->block_resv = buf[cfheadext_DataReserved];
if (header_resv > 60000) {
- fprintf(stderr, "%s: WARNING; header reserved space > 60000\n",
+ g_warning(_("%s: WARNING; header reserved space > 60000"),
cab->filename);
}
/* skip the reserved header */
- if (header_resv) fseek(cab->fh, (off_t) header_resv, SEEK_CUR);
+ if (header_resv) cabinet_skip(cab, (off_t) header_resv);
}
if (cab->flags & cfheadPREV_CABINET) {
cab->prevname = cabinet_read_string(cab);
if (!cab->prevname) return 0;
cab->previnfo = cabinet_read_string(cab);
+ if (!cab->previnfo) return 0;
}
if (cab->flags & cfheadNEXT_CABINET) {
cab->nextname = cabinet_read_string(cab);
if (!cab->nextname) return 0;
cab->nextinfo = cabinet_read_string(cab);
+ if (!cab->nextinfo) return 0;
}
/* read folders */
if (folder_resv) cabinet_skip(cab, folder_resv);
fol = (struct folder *) calloc(1, sizeof(struct folder));
- if (!fol) { fprintf(stderr, "out of memory!\n"); return 0; }
+ if (!fol) { g_warning(_("out of memory!")); return 0; }
fol->cab[0] = cab;
fol->offset[0] = base_offset + (off_t) EndGetI32(buf+cffold_DataOffset);
for (i = 0; i < num_files; i++) {
if (!cabinet_read(cab, buf, cffile_SIZEOF)) return 0;
file = (struct file *) calloc(1, sizeof(struct file));
- if (!file) { fprintf(stderr, "out of memory!\n"); return 0; }
+ if (!file) { g_warning(_("out of memory!")); return 0; }
file->length = EndGetI32(buf+cffile_UncompressedSize);
file->offset = EndGetI32(buf+cffile_FolderOffset);
/* increase the number of splits */
if ((i = ++(predfol->num_splits)) > CAB_SPLITMAX) {
mergeok = 0;
- fprintf(stderr, "%s: internal error, increase CAB_SPLITMAX\n",
+ g_warning(_("%s: internal error, increase CAB_SPLITMAX"),
basecab->filename);
}
else {
* file [name]. Returns a cabinet structure if successful, or NULL
* otherwise.
*/
-struct cabinet *load_cab_offset(char *name, off_t offset) {
+static struct cabinet *load_cab_offset(struct acquire_cabinet *acquire_cabinet, off_t offset) {
struct cabinet *cab = (struct cabinet *) calloc(1, sizeof(struct cabinet));
int ok;
if (!cab) return NULL;
- cab->filename = name;
- if ((ok = cabinet_open(cab))) {
- cabinet_seek(cab, offset);
- ok = cabinet_read_entries(cab);
- cabinet_close(cab);
- }
+ cab->acquire_cabinet = acquire_cabinet;
+ cab->filename = cab->acquire_cabinet->filename;
+ /* if ((ok = cabinet_open(cab))) * CAPTIVE */
+ cab->filelen = acquire_cabinet->size;
+ cabinet_seek(cab, offset);
+ ok = cabinet_read_entries(cab);
+ /* cabinet_close(cab); * CAPTIVE */
if (ok) return cab;
free(cab);
* member.
*/
#define SEARCH_SIZE (32*1024)
-UBYTE search_buf[SEARCH_SIZE];
+static UBYTE search_buf[SEARCH_SIZE];
-struct cabinet *find_cabs_in_file(char *name) {
+struct cabinet *find_cabs_in_file(struct acquire_cabinet *acquire_cabinet) {
struct cabinet *cab, *cab2, *firstcab = NULL, *linkcab = NULL;
UBYTE *pstart = &search_buf[0], *pend, *p;
- ULONG offset, caboff, cablen, foffset, filelen;
+ ULONG offset, caboff, cablen = 0; /* Prevent: ... might be used uninitialized in this function */
+ ULONG foffset = 0; /* Prevent: ... might be used uninitialized in this function */
+ ULONG filelen;
size_t length;
int state = 0, found = 0, ok = 0;
/* open the file and search for cabinet headers */
if ((cab = (struct cabinet *) calloc(1, sizeof(struct cabinet)))) {
- cab->filename = name;
- if (cabinet_open(cab)) {
+ cab->acquire_cabinet = acquire_cabinet;
+ cab->filename = acquire_cabinet->filename;
+ cab->filelen = acquire_cabinet->size;
+ if (1 /* cabinet_open(cab) * CAPTIVE */) {
filelen = (ULONG) cab->filelen;
for (offset = 0; offset < filelen; offset += length) {
/* search length is either the full length of the search buffer,
{
/* found a potential result - try loading it */
found++;
- cab2 = load_cab_offset(name, (off_t) caboff);
+ cab2 = load_cab_offset(acquire_cabinet, (off_t) caboff);
if (cab2) {
/* success */
ok++;
}
}
}
- cabinet_close(cab);
+ /* cabinet_close(cab); * CAPTIVE */
}
free(cab);
}
/* if there were cabinets that were found but are not ok, point this out */
if (found > ok) {
- fprintf(stderr, "%s: WARNING; found %d bad cabinets\n", name, found-ok);
+ g_warning(_("%s: WARNING; found %d bad cabinets"), acquire_cabinet->filename, found-ok);
}
/* if no cabinets were found, let the user know */
if (!firstcab) {
- fprintf(stderr, "%s: not a Microsoft cabinet file.\n", name);
+ g_warning(_("%s: not a Microsoft cabinet file."), acquire_cabinet->filename);
}
return firstcab;
}
+#if 0 /* CAPTIVE */
+
/* UTF translates two-byte unicode characters into 1, 2 or 3 bytes.
* %000000000xxxxxxx -> %0xxxxxxx
* %00000xxxxxyyyyyy -> %110xxxxx %10yyyyyy
*/
/* translate UTF -> ASCII */
-int convertUTF(UBYTE *in) {
+static int convertUTF(UBYTE *in) {
UBYTE c, *out = in, *end = in + strlen((char *) in) + 1;
ULONG x;
if (fname) free(fname);
}
-int NONEdecompress(int inlen, int outlen) {
+#endif /* CAPTIVE */
+
+static int NONEdecompress(int inlen, int outlen) {
if (inlen != outlen) return DECR_ILLEGALDATA;
memcpy(CAB(outbuf), CAB(inbuf), (size_t) inlen);
return DECR_OK;
}
-ULONG checksum(UBYTE *data, UWORD bytes, ULONG csum) {
+static ULONG checksum(UBYTE *data, UWORD bytes, ULONG csum) {
int len;
ULONG ul = 0;
return csum;
}
-int decompress(struct file *fi, int savemode, int fix) {
+int file_write(struct file *fi, UBYTE *buf, size_t length);
+
+static int decompress(struct file *fi, int savemode, int fix) {
ULONG bytes = savemode ? fi->length : fi->offset - CAB(offset);
struct cabinet *cab = CAB(current)->cab[CAB(split)];
UBYTE buf[cfdata_SIZEOF], *data;
inlen = outlen = 0;
while (outlen == 0) {
/* read the block header, skip the reserved part */
- if (!cabinet_read(cab, buf, cfdata_SIZEOF)) return DECR_INPUT;
+ if ((NONEdecompress==CAB(decompress) && !savemode && bytes>32768)) {
+ cabinet_skip(cab, cfdata_SIZEOF);
+ memset(buf + cfdata_CheckSum, 0, 4); /* no CheckSum */
+ /* FIXME: Is it safe to assume 'NONEdecompress' block size 32768?
+ * Probably not but we need to prevent scattering block headers through the file.
+ */
+ buf[cfdata_CompressedSize + 0]=(32768>>0)&0xFF;
+ buf[cfdata_CompressedSize + 1]=(32768>>8)&0xFF;
+ buf[cfdata_UncompressedSize + 0]=(32768>>0)&0xFF;
+ buf[cfdata_UncompressedSize + 1]=(32768>>8)&0xFF;
+ } else {
+ if (!cabinet_read(cab, buf, cfdata_SIZEOF)) return DECR_INPUT;
+ }
cabinet_skip(cab, cab->block_resv);
/* we shouldn't get blocks over CAB_INPUTMAX in size */
len = EndGetI16(buf+cfdata_CompressedSize);
inlen += len;
if (inlen > CAB_INPUTMAX) return DECR_INPUT;
- if (!cabinet_read(cab, data, len)) return DECR_INPUT;
+ if ((NONEdecompress==CAB(decompress) && !savemode && bytes>32768)) {
+ cabinet_skip(cab, len);
+ } else {
+ if (!cabinet_read(cab, data, len)) return DECR_INPUT;
+ }
/* clear two bytes after read-in data */
data[len+1] = data[len+2] = 0;
/* perform checksum test on the block (if one is stored) */
cksum = EndGetI32(buf+cfdata_CheckSum);
- if (cksum && cksum != checksum(buf+4, 4, checksum(data, len, 0))) {
- /* checksum is wrong */
- if (fix && ((fi->folder->comp_type & cffoldCOMPTYPE_MASK)
- == cffoldCOMPTYPE_MSZIP))
- {
- fprintf(stderr, "%s: WARNING; checksum failed\n", fi->filename);
- }
- else {
- return DECR_CHECKSUM;
+ if (!(NONEdecompress==CAB(decompress) && !savemode && bytes>32768)) {
+ if (cksum && cksum != checksum(buf+4, 4, checksum(data, len, 0))) {
+ /* checksum is wrong */
+ if (fix && ((fi->folder->comp_type & cffoldCOMPTYPE_MASK)
+ == cffoldCOMPTYPE_MSZIP))
+ {
+ g_warning(_("%s: WARNING; checksum failed"), fi->filename);
+ }
+ else {
+ return DECR_CHECKSUM;
+ }
}
}
/* outlen=0 means this block was part of a split block */
outlen = EndGetI16(buf+cfdata_UncompressedSize);
if (outlen == 0) {
+#if 0 /* CAPTIVE */
cabinet_close(cab);
cab = CAB(current)->cab[++CAB(split)];
if (!cabinet_open(cab)) return DECR_INPUT;
cabinet_seek(cab, CAB(current)->offset[CAB(split)]);
+#else
+ return DECR_INPUT;
+#endif
}
}
- /* decompress block */
- if ((err = CAB(decompress)(inlen, outlen))) {
- if (fix && ((fi->folder->comp_type & cffoldCOMPTYPE_MASK)
- == cffoldCOMPTYPE_MSZIP))
- {
- fprintf(stderr, "%s: WARNING; failed decrunching block\n",
- fi->filename);
- }
- else {
- return err;
+ if (!(NONEdecompress==CAB(decompress) && !savemode && bytes>32768)) {
+ /* decompress block */
+ if ((err = CAB(decompress)(inlen, outlen))) {
+ if (fix && ((fi->folder->comp_type & cffoldCOMPTYPE_MASK)
+ == cffoldCOMPTYPE_MSZIP))
+ {
+ g_warning(_("%s: WARNING; failed decrunching block"),
+ fi->filename);
+ }
+ else {
+ return err;
+ }
}
}
CAB(outlen) = outlen;
}
-void extract_file(struct file *fi, int lower, int fix, char *dir) {
+int extract_file(struct file *fi, int lower, int fix, char *dir) {
struct folder *fol = fi->folder, *oldfol = CAB(current);
LONG err = DECR_OK;
if (err) goto exit_handler;
/* initialisation OK, set current folder and reset offset */
+#if 0 /* CAPTIVE */
if (oldfol) cabinet_close(oldfol->cab[CAB(split)]);
- if (!cabinet_open(fol->cab[0])) goto exit_handler;
+ if (!cabinet_open(fol->cab[0])) {
+ err = DECR_ILLEGALDATA;
+ goto exit_handler;
+ }
+#endif /* CAPTIVE */
cabinet_seek(fol->cab[0], fol->offset[0]);
CAB(current) = fol;
CAB(offset) = 0;
if ((err = decompress(fi, 0, fix))) goto exit_handler;
CAB(offset) = fi->offset;
}
- if (!file_open(fi, lower, dir)) return;
+#if 0 /* CAPTIVE */
+ if (!file_open(fi, lower, dir)) return 0;
+#endif /* CAPTIVE */
err = decompress(fi, 1, fix);
if (err) CAB(current) = NULL; else CAB(offset) += fi->length;
+#if 0 /* CAPTIVE */
file_close(fi);
+#endif /* CAPTIVE */
exit_handler:
if (err) {
- char *errmsg, *cabname;
+ const char *errmsg, *cabname;
switch (err) {
case DECR_NOMEMORY:
- errmsg = "out of memory!\n"; break;
+ errmsg = _("out of memory!"); break;
case DECR_ILLEGALDATA:
- errmsg = "%s: illegal or corrupt data\n"; break;
+ errmsg = _("%s: illegal or corrupt data"); break;
case DECR_DATAFORMAT:
- errmsg = "%s: unsupported data format\n"; break;
+ errmsg = _("%s: unsupported data format"); break;
case DECR_CHECKSUM:
- errmsg = "%s: checksum error\n"; break;
+ errmsg = _("%s: checksum error"); break;
case DECR_INPUT:
- errmsg = "%s: input error\n"; break;
+ errmsg = _("%s: input error"); break;
case DECR_OUTPUT:
- errmsg = "%s: output error\n"; break;
+ errmsg = _("%s: output error"); break;
default:
- errmsg = "%s: unknown error (BUG)\n";
+ errmsg = _("%s: unknown error (BUG)");
}
if (CAB(current)) {
cabname = fi->folder->cab[0]->filename;
}
- fprintf(stderr, errmsg, cabname);
+ g_warning(errmsg, cabname);
+ return 0;
}
+ return 1;
}
+#if 0 /* CAPTIVE */
+
/* tries to find *cabname, from the directory path of origcab, correcting the
* case of *cabname if necessary, If found, writes back to *cabname.
*/
}
}
+
/* process_cabinet() is called by main() for every file listed on the
* command line. It will find every cabinet file in that file, and will
* search for every chained cabinet attached to those cabinets, then it
cab1->prevname, cab1->previnfo);
find_cabinet_file(&(cab1->prevname), cabname);
if (!(cab1->prevcab = load_cab_offset(cab1->prevname, 0))) {
- fprintf(stderr, "%s: can't read previous cabinet %s\n",
+ g_warning(_("%s: can't read previous cabinet %s"),
cabname, cab1->prevname);
break;
}
cab2->nextname, cab2->nextinfo);
find_cabinet_file(&(cab2->nextname), cabname);
if (!(cab2->nextcab = load_cab_offset(cab2->nextname, 0))) {
- fprintf(stderr, "%s: can't read next cabinet %s\n",
+ g_warning(_("%s: can't read next cabinet %s"),
cabname, cab2->nextname);
break;
}
return err;
}
+
+#endif /* CAPTIVE */