d3699d57 |
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mspack.h>
#include <sys/stat.h>
#include <dirent.h>
#include <md5_fh.h>
#include <error.h>
/**
* Matches a cabinet's filename case-insensitively in the filesystem and
* returns the case-correct form.
*
* @param origcab if this is non-NULL, the pathname part of this filename
* will be extracted, and the search will be conducted in
* that directory.
* @param cabname the internal CAB filename to search for.
* @return a copy of the full, case-correct filename of the given cabinet
* filename, or NULL if the specified filename does not exist on disk.
*/
static char *find_cabinet_file(char *origcab, char *cabname) {
struct dirent *entry;
struct stat st_buf;
int found = 0, len;
char *tail, *cab;
DIR *dir;
/* ensure we have a cabinet name at all */
if (!cabname || !cabname[0]) return NULL;
/* find if there's a directory path in the origcab */
tail = origcab ? strrchr(origcab, '/') : NULL;
len = (tail - origcab) + 1;
/* allocate memory for our copy */
if (!(cab = (char *) malloc((tail ? len : 2) + strlen(cabname) + 1))) return NULL;
/* add the directory path from the original cabinet name, or "." */
if (tail) memcpy(cab, origcab, (size_t) len);
else cab[0]='.', cab[1]='/', len=2;
cab[len] = '\0';
/* try accessing the cabinet with its current name (case-sensitive) */
strcpy(&cab[len], cabname);
if (stat(cab, &st_buf) == 0) { |
d3699d57 |
}
return cab;
}
int main(int argc, char *argv[]) {
struct mscab_decompressor *cabd;
struct mscabd_cabinet *cab, *c, *c2;
struct mscabd_file *file;
char *cabname, *newname;
int err;
setbuf(stdout, NULL);
setbuf(stderr, NULL);
/* if self-test reveals an error */
MSPACK_SYS_SELFTEST(err);
if (err) return 1;
if (!(cabd = mspack_create_cab_decompressor(&read_files_write_md5))) { |
cafa0bf3 |
printf("*** %s\n", cabname);
if (!(cab = cabd->open(cabd, cabname))) {
fprintf(stderr, "cab open error: %s\n", ERROR(cabd));
continue;
}
/* prepend any spanning cabinets */
for (c = cab; c && (c->flags & MSCAB_HDR_PREVCAB); c = c->prevcab) {
if (!(newname = find_cabinet_file(cabname, c->prevname))) {
fprintf(stderr, "%s: can't find \"%s\" to prepend\n",
cabname, c->prevname);
break;
}
if (!(c2 = cabd->open(cabd, newname))) {
fprintf(stderr, "%s: error opening \"%s\" for prepend: %s\n",
cabname, newname, ERROR(cabd));
break;
}
if (cabd->prepend(cabd, c, c2) != MSPACK_ERR_OK) {
fprintf(stderr, "%s: error prepending \"%s\": %s\n",
cabname, newname, ERROR(cabd));
break;
}
}
/* append any spanning cabinets */
for (c = cab; c && (c->flags & MSCAB_HDR_NEXTCAB); c = c->nextcab) {
if (!(newname = find_cabinet_file(cabname, c->nextname))) {
fprintf(stderr, "%s: can't find \"%s\" to append\n",
cabname, c->nextname);
break;
}
if (!(c2 = cabd->open(cabd, newname))) {
fprintf(stderr, "%s: error opening \"%s\" for append: %s\n",
cabname, newname, ERROR(cabd));
break;
}
if (cabd->append(cabd, c, c2) != MSPACK_ERR_OK) {
fprintf(stderr, "%s: error appending \"%s\": %s\n",
cabname, newname, ERROR(cabd));
break;
}
}
/* extract files */
for (file = cab->files; file; file = file->next ) {
if (cabd->extract(cabd, file, NULL) == MSPACK_ERR_OK) {
printf("%s %s\n", md5_string, file->filename);
}
else {
fprintf(stderr, "%s: error extracting \"%s\": %s\n",
cabname, file->filename, ERROR(cabd));
}
}
/* free all resources */
for (c2 = cab->prevcab; c2; c2 = c2->prevcab) free((void*)c2->filename);
for (c2 = cab->nextcab; c2; c2 = c2->nextcab) free((void*)c2->filename);
cabd->close(cabd, cab); |