clamav/libclammspack/examples/cabrip.c
2023-02-12 11:24:44 -08:00

85 lines
2.1 KiB
C

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <mspack.h>
#include "mspack/macros.h"
#if HAVE_FSEEKO
# define fseek fseeko
#endif
#define BUF_SIZE (1024*4096)
char buf[BUF_SIZE];
void rip(char *fname, off_t offset, unsigned int length) {
static unsigned int counter = 1;
struct stat st_buf;
char outname[13];
FILE *in = NULL, *out = NULL;
/* find an unused output filename */
do {
snprintf(outname, 13, "%08u.cab", counter++);
} while (stat(outname, &st_buf) == 0);
printf("ripping %s offset %" LD " length %u to %s\n",
fname, offset, length, outname);
if (!(in = fopen(fname, "rb"))) {
perror(fname);
goto cleanup;
}
if (!(out = fopen(outname, "wb"))) {
perror(outname);
goto cleanup;
}
if (fseek(in, offset, SEEK_SET)) {
fprintf(stderr, "%s: can't seek to cab offset %"LD"\n", fname, offset);
goto cleanup;
}
while (length) {
size_t run = (length > BUF_SIZE) ? BUF_SIZE : length;
size_t actual = fread(&buf[0], 1, run, in);
if (actual < run) {
fprintf(stderr, "%s: file %u bytes shorter than expected\n",
fname, length - (unsigned int)(run - actual));
length = run = actual;
}
if (fwrite(&buf[0], 1, run, out) != run) {
perror(outname);
break;
}
length -= run;
}
cleanup:
if (in) fclose(in);
if (out) fclose(out);
}
int main(int argc, char *argv[]) {
struct mscab_decompressor *cabd;
struct mscabd_cabinet *cab, *c;
int err;
MSPACK_SYS_SELFTEST(err);
if (err) return 0;
if ((cabd = mspack_create_cab_decompressor(NULL))) {
cabd->set_param(cabd, MSCABD_PARAM_SALVAGE, 1);
for (argv++; *argv; argv++) {
if ((cab = cabd->search(cabd, *argv))) {
for (c = cab; c; c = c->next) {
rip(*argv, c->base_offset, c->length);
}
cabd->close(cabd, cab);
}
}
mspack_destroy_cab_decompressor(cabd);
}
return 0;
}