Sindbad~EG File Manager
#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) {
found = 1;
}
else {
/* cabinet was not found, look for it in the current dir */
cab[len] = '\0';
if ((dir = opendir(cab))) {
while ((entry = readdir(dir))) {
if (strcasecmp(cabname, entry->d_name) == 0) {
strcat(cab, entry->d_name);
found = (stat(cab, &st_buf) == 0);
break;
}
}
closedir(dir);
}
}
if (!found || !S_ISREG(st_buf.st_mode)) {
/* cabinet not found, or not a regular file */
free(cab);
cab = NULL;
}
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))) {
fprintf(stderr, "can't make decompressor\n");
return 1;
}
for (argv++; (cabname = *argv); argv++) {
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);
}
mspack_destroy_cab_decompressor(cabd);
return 0;
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists