void packScanDir( const char* path, list_t* dirList ) { struct dirent *pent; struct stat st; char* buf=malloc(sizeof(char)*2048); DIR *pdir= opendir( path ); if(pdir) { while( (pent=readdir(pdir)) ) { //We're not going to read hidden files or . / .. if(pent->d_name[0] != '.') { sprintf(buf, "%s/%s",path,pent->d_name); if(stat(buf, &st)==0) { if( (st.st_mode&S_IFDIR)==S_IFDIR ) { //Ignore the "wizznic" directory since it's allready added. if(strcmp( buf, "packs/000_wizznic" ) != 0) { char* pdstr = malloc( sizeof(char)*strlen(buf)+1 ); strcpy( pdstr, buf ); listAppendData( dirList, (void*)pdstr ); } } else if( (st.st_mode&S_IFREG) ) { //It's a file, let's try and see if it's a bundle. int l = strlen(buf); if( l > 4 && strcasecmp( &buf[l-4] ,".wiz" )==0 ) { l = debundle( buf, getUsrPackDir() ); if( l == BUNDLE_SUCCESS ) { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Installed bundle '%s'.\n", buf); char* pdstr = malloc( sizeof(char)*strlen(buf)+1 ); strcpy( pdstr, bundlePath() ); listAppendData( dirList, (void*)pdstr ); unlink( buf ); } else if( l == BUNDLE_FAIL_CORRUPT ) { SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "The bundle file '%s' is corrupt, deleting it.\n", buf); unlink( buf ); } else if( l == BUNDLE_FAIL_UNSUPPORTED_VERSION ) { SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "The bundle file '%s' is not supported by this version of Wizznic, please try and update Wizznic.\n", buf); } else if( l == BUNDLE_FAIL_DIR_EXISTS ) { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "The bundle file '%s' has already been installed.\n", buf); } bundlePathReset(); } } } else { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "packScanDir(); Error: stat('%s') failed!\n", buf); } } } closedir(pdir); } free(buf); }
int debundle( const char* file, const char* outDir ) { int i; int ret=BUNDLE_FAIL_NOT_BUNDLEFILE; FILE* f=NULL; char* name=NULL; char buf[2048]; printf("Trying to debundle %s into %s\n", file,outDir); bundlePathReset(); bundleHeader_t header; bundleFileEntry* fe=NULL; //Open file f = fopen( file, "rb"); if(f) { //Read header if( fread( &header, sizeof(bundleHeader_t), 1, f ) == 1 ) { //Verify it's a bundle if( strcmp(header.ident, bundleFileIdentString) == 0 ) { //This code reads version 0x10 bundles. if( header.version == 0x10 ) { //Create output directory (We ignore this return value because it may exist and that is okay too). //mkdir(outDir, S_IRWXU); fe = malloc( sizeof(bundleFileEntry)* header.numEntries ); // Read all the entries into an array if( fread( fe, sizeof(bundleFileEntry), header.numEntries, f ) == header.numEntries ) { //Create directories and files for( i=0; i < header.numEntries; i++ ) { //Verify that type is sane if( fe[i].type == TYPE_DIR || fe[i].type == TYPE_FILE ) { name = malloc( fe[i].nameLen+1 ); memset(name,0,fe[i].nameLen+1); //Read name if( fread(name, fe[i].nameLen, 1, f) == 1 ) { //Prepend the output directory name to the filename. sprintf(buf, "%s/%s", outDir, name ); free(name); //Create entry in the filesystem ret = debundleCreateEntry( &fe[i], buf, f ); if( ret != BUNDLE_SUCCESS ) { break; } else { //Hack: We assume that the first entry to be debundled is the topdirectory. if( lastExtractedBundle == NULL ) { lastExtractedBundle = malloc( strlen(buf)+1 ); sprintf(lastExtractedBundle, "%s", buf ); } } //Entry was created } else { //Read name printf(" ERROR: Could not read a filename from bundlefile.\n"); ret = BUNDLE_FAIL_CORRUPT; } //Could not read name } //Type check } //Loop through entries //Check for the end marker if( ret == BUNDLE_SUCCESS ) { memset( buf, 0, strlen(bundleFileEndMarkString)+1 ); if( fread(buf, strlen(bundleFileEndMarkString), 1, f) != 1 ) { printf("ERROR: Could not read end of file marker.\n"); ret = BUNDLE_FAIL_CORRUPT; } else if( strcmp(buf, bundleFileEndMarkString) != 0 ) { printf("ERROR: Expected to read '%s' but got '%s'.\n", bundleFileEndMarkString, buf); ret = BUNDLE_FAIL_CORRUPT; } } } else { printf("ERROR: Could not read %i entries from file.\n", header.numEntries); ret = BUNDLE_FAIL_CORRUPT; } // Read all the entries into an array } else { //Version 0x10 printf("Error: Bundle File version %i is unsupported by this version of Wizznic.\n", header.version ); ret = BUNDLE_FAIL_UNSUPPORTED_VERSION; } //Unknown version } else { // Read ident string printf("ERROR: File %s is not a Wizznic Bundle file.\n", file); ret = BUNDLE_FAIL_NOT_BUNDLEFILE; } } else { // < Read header printf("ERROR: File %s is not a Wizznic Bundle file.\n", file); ret = BUNDLE_FAIL_NOT_BUNDLEFILE; } } else { ret = BUNDLE_FAIL_COULD_NOT_OPEN; printf("Could not open file '%s' for input.\n", file); } //Free resources if( fe ) { free(fe); } if( f ) { fclose(f); } lastError=ret; return(ret); }