CFILE * CFOpen (char *filename, char *folder, char *mode, int bUseD1Hog) { int length = -1; FILE *fp; CFILE *cfile = NULL; char *pszHogExt, *pszFileExt; if (! (filename && *filename)) return NULL; if ((*filename != '\x01') /*&& !bUseD1Hog*/) { fp = cfile_get_filehandle (filename, folder, mode); // Check for non-hog file first... if (!fp && ((pszFileExt = strstr (filename, ".rdl")) || (pszFileExt = strstr (filename, ".rl2"))) && (pszHogExt = strchr (gameHogFiles.szAltHogFile, '.')) && !stricmp (pszFileExt, pszHogExt)) fp = cfile_get_filehandle (gameHogFiles.szAltHogFile, folder, mode); // Check for non-hog file first... } else { fp = NULL; //don't look in dir, only in hogfile if (*filename == '\x01') filename++; } if (!fp) { if (fp = CFFindLibFile (filename, &length, bUseD1Hog)) if (stricmp (mode, "rb")) { Error ("Cannot read hog file\n(wrong file io mode).\n"); return NULL; } } if (fp) { if (!(cfile = d_malloc (sizeof (CFILE)))) fclose (fp); else { cfile->file = fp; cfile->raw_position = 0; cfile->size = (length < 0) ? ffilelength (fp) : length; cfile->lib_offset = (length < 0) ? 0 : ftell (fp); } } //if (!cfile) LogErr ("CFOpen(): error opening %s\n", filename); return cfile; }
CFILE * cfopen(char * filename, char * mode ) { int length; FILE * fp; CFILE *cfile; if (stricmp( mode, "rb")) { printf( "CFILES CAN ONLY BE OPENED WITH RB\n" ); exit(1); } fp = cfile_get_filehandle( filename, mode ); // Check for non-hog file first... if ( !fp ) { fp = cfile_find_libfile(filename, &length ); if ( !fp ) return NULL; // No file found cfile = malloc ( sizeof(CFILE) ); if ( cfile == NULL ) { fclose(fp); return NULL; } cfile->file = fp; cfile->size = length; cfile->lib_offset = ftell( fp ); cfile->raw_position = 0; return cfile; } else { cfile = malloc ( sizeof(CFILE) ); if ( cfile == NULL ) { fclose(fp); return NULL; } cfile->file = fp; cfile->size = ffilelength(fp); cfile->lib_offset = 0; cfile->raw_position = 0; return cfile; } }
int CFile::Open (const char *filename, const char *folder, const char *mode, int bUseD1Hog) { int length = -1; FILE *fp = NULL; const char *pszHogExt, *pszFileExt; m_cf.file = NULL; if (!(filename && *filename)) return 0; if ((*filename != '\x01') /*&& !bUseD1Hog*/) { fp = GetFileHandle (filename, folder, mode); // Check for non-hogP file first... if (!fp && ((pszFileExt = strstr (filename, ".rdl")) || (pszFileExt = strstr (filename, ".rl2"))) && (pszHogExt = strchr (hogFileManager.AltHogFile (), '.')) && !stricmp (pszFileExt, pszHogExt)) fp = GetFileHandle (hogFileManager.AltHogFile (), folder, mode); // Check for non-hogP file first... } else { fp = NULL; //don't look in dir, only in tHogFile filename++; } if (!fp) { if ((fp = hogFileManager.Find (filename, &length, bUseD1Hog))) if (stricmp (mode, "rb")) { ::Error ("Cannot read hogP file\n (wrong file io mode).\n"); return 0; } } if (!fp) return 0; m_cf.file = fp; m_cf.rawPosition = 0; m_cf.size = (length < 0) ? ffilelength (fp) : length; m_cf.libOffset = (length < 0) ? 0 : ftell (fp); m_cf.filename = const_cast<char*> (filename); return 1; }
int CFOpen (CFILE *cfP, const char *filename, const char *folder, const char *mode, int bUseD1Hog) { int length = -1; FILE *fp = NULL; const char *pszHogExt, *pszFileExt; cfP->file = NULL; if (! (filename && *filename)) return 0; if ((*filename != '\x01') /*&& !bUseD1Hog*/) { fp = CFGetFileHandle (filename, folder, mode); // Check for non-hogP file first... if (!fp && ((pszFileExt = strstr (filename, ".rdl")) || (pszFileExt = strstr (filename, ".rl2"))) && (pszHogExt = strchr (gameHogFiles.szAltHogFile, '.')) && !stricmp (pszFileExt, pszHogExt)) fp = CFGetFileHandle (gameHogFiles.szAltHogFile, folder, mode); // Check for non-hogP file first... } else { fp = NULL; //don't look in dir, only in tHogFile filename++; } if (!fp) { if ((fp = CFFindLibFile (filename, &length, bUseD1Hog))) if (stricmp (mode, "rb")) { Error ("Cannot read hogP file\n (wrong file io mode).\n"); return 0; } } if (!fp) return 0; cfP->file = fp; cfP->raw_position = 0; cfP->size = (length < 0) ? ffilelength (fp) : length; cfP->lib_offset = (length < 0) ? 0 : ftell (fp); cfP->filename = (char *) filename; return 1; }
int main(int argc,char *argv[]) { char **files; // Actual file list to work on (stored by findfile loop) unsigned short filesnum=0; // Number of strings stored in files array unsigned short filesmax=-1; // Max number of files allowed in files array unsigned long filelen; // Storage for length of BSP file unsigned long year=1970+(time(0)/31536000); // Current year struct _finddata_t fd; // Used for findfile struct param *param; // Parameter list char *arg; // Argument char *entbuf; // Entity script storage char drive[_MAX_DRIVE]; // Used for building full path name for files char dir[_MAX_DIR]; // Used for building full path name for files char path[_MAX_PATH]; // Used for building full path name for files int index; // Index, multiple uses int handle; // Handle for findfile int changes; // Number of changes to BSP file that was made int filesmodified; // Number of files modified int filestotal; // Total files processed int fileserrors; // Files with problems int fileschanges; // Total changes in all flies BSPHEADER hdr; // Header of BSP file FILE *hin=0; // BSP file stream if(year<2005) // For dodgy clocks :-) year=2005; printf("EntWiz/%u.%02u (%u-Bit) by MS-Design, Compiled %s\n" // Show info "\n",vermaj,vermin,addrlen*8,verdate,year); fileschanges=fileserrors=filesmodified=filestotal=0; // Zero stuff if(argc==1) // Nothing specified so show help return showhelp(*argv); for(index=1;index<argc;index++) // Process each command line parameter { arg=argv[index]; // Set alias if(*arg=='/') // Is command switch { *arg++; // Remove forwardslash param=params; // Alias the allowable commands structure while(param->name) // Walk through the allowable commands list { if(strcmp(param->name,arg)) // Compare { param++; continue; } if(index+param->num+1>argc) // Check if we have enough parameters { changes=param->num-(argc-(index+param->num-1)); printf("Need %u more paramete%s for '%s' option\n",changes,changes==1?"r":"rs",arg); return 1; } if(commandsnum==commandsmax) // Make sure we dont go over the limit { printf("Commands limit of %u reached\n",commandsmax); return 1; } // (Re)allocate address space for commands structure array if(!(commands=commandsnum?realloc(commands,(commandsnum+1)*addrlen):malloc(addrlen))) { printf("Can't (re)alloc %u bytes of address space for commands structure\n",(commandsnum+1)*addrlen); return 1; } if(!(commands[commandsnum]=malloc(sizeof(SCOMMAND)))) // Alloc structure { printf("Can't allocate %u bytes of memory for command strucutre\n",sizeof(SCOMMAND)); return 1; } if(param->num>=1&&verifypattern(index+1,argv[index+1])) return 1; if(param->num>=2&&verifypattern(index+2,argv[index+2])) return 1; if(param->num>=3&&verifypattern(index+3,argv[index+3])) return 1; command=commands[commandsnum++]; // Set alias for structure in array command->id=param->id; // Set command and inc num commands command->x=command->y=command->z=0; // Nullify X, Y and Z if(param->num>=1) // Set X (No need to alloc just alias from argv) command->x=argv[index+1]; if(param->num>=2) // Set Y command->y=argv[index+2]; if(param->num>=3) // Set Z command->z=argv[index+3]; index+=param->num; // Increment index so we dont parse the same stuff param++; // Goto the next item in commands structure array; *arg=0; // We got a match so make sure to goto the next parameter break; } if(!*arg) // Matched a parameter continue; printf("%s: Unknown parameter\n",arg); return 1; } else { // It's a filespec so add it to the fspecs array if(fspecsnum==fspecsmax) // Make sure we don't go over the limit { printf("Limit of %u for file specifications exceeded\n",fspecsmax); return 1; } // Allocate address space for fpsec array if(!(fspecs=fspecsnum?realloc(fspecs,(fspecsnum+1)*addrlen):malloc(addrlen))) { printf("Can't (re)alloc %u bytes of address space for fspec array\n",(fspecsnum+1)*addrlen); return 1; } // Alias it (again, don't need to alloc, just use argv) fspecs[fspecsnum++]=arg; } } if(!commandsnum&&!fspecsnum) // This shouldnt happen but just incase return showhelp(*argv); if(!commandsnum) // No commands were specified { printf("Nothing to do!\n"); return 1; } if(!fspecsnum) // No filespecs specified { printf("No filenames specified to perform commands on\n"); return 1; } for(index=0;index<fspecsnum;index++) // Process filespecs { if((handle=_findfirst(fspecs[index],&fd))==-1) // Find file/files with wildcards { printf("%s: No matching files, %s\n",fspecs[index],_sys_errlist[errno]); continue; } _splitpath(fspecs[index],drive,dir,0,0); // Want drive & directory from filespec do // Process each file { if(fd.attrib&_A_SUBDIR) // Ignore directories continue; *path=0; // Make zero length string for building relative path strcpy(path,drive); // Copy drive from fspec strcat(path,dir); // Copy directory from fspec strcat(path,fd.name); // Copy matching filename // Ignore read only files if(fd.attrib&_A_RDONLY||fd.attrib&_A_SYSTEM||fd.attrib&_A_HIDDEN) { printf("%s: File is read-only, skipping\n",path); continue; } if(filesnum==filesmax) // Check we dont go over the limit { printf("Limit of %u for files count exceeded\n",filesmax); return 1; } // (Re)alloc files array if(!(files=filesnum?realloc(files,(filesnum+1)*addrlen):malloc(addrlen))) { printf("Can't (re)alloc %u bytes of address space for files array\n",(filesnum+1)*addrlen); return 1; } // Duplicate string (need to alloc this time) if(!(files[filesnum++]=strdup(path))) { printf("Can't alloc %u bytes of memory for filename string\n",strlen(files[filesnum-1])+1); return 1; } } while(!_findnext(handle,&fd)); } if(!filesnum) // Stop if we found no valid files { printf("\nNo matching files\n"); return 1; } for(index=0;index<filesnum;index++) // Time to walk through each file now { entbuf=0; // Holds entity script if(hin) // If any existing input handle is open (due to error), close it fclose(hin); if(entbuf) // Free storage buffer if it hasnt been deallocated (due to error) free(entbuf); filestotal++; // Increment total number of files processed fileserrors++; // Increment errors, (decremented on success) arg=files[index]; // Alias current filename printf("Processing %s... ",arg); // Tell user whats going on if(!(hin=fopen(arg,"rb"))) // Open input file { printf("Open failure, %s!\n",_sys_errlist[errno]); continue; } if((filelen=ffilelength(hin))<sizeof(BSPHEADER)) // Get file length { printf("Not a BSP file (filelen[%u]<%u)\n",filelen,sizeof(BSPHEADER)); continue; } if(fread(&hdr,sizeof(BSPHEADER),1,hin)<1) // Read BSP header info { printf("Header read failure, %s!\n",_sys_errlist[errno]); continue; } if(hdr.magic!=BSP_MAGIC) // Check that its a BSP file { printf("Not a BSP file (%08x!=%08x)!\n",hdr.magic,BSP_MAGIC); continue; } // Make sure location of entity isnt greater then file length if(hdr.entloc>filelen) { printf("BSP corrupted (entloc[%u]>filelen[%u])\n",hdr.entloc,filelen); continue; } // Make sure end location of entity script isnt greater then file length if(hdr.entend>filelen) { printf("BSP corrupted (entloc[%u]+entsiz[%u][=%u]<filelen[%u])\n",hdr.entloc,hdr.entsiz,hdr.entloc+hdr.entsiz,filelen); continue; } if(fseek(hin,hdr.entloc,SEEK_SET)) // Seek to entity data in input file { printf("Seek to position %u failed, %s!\n",hdr.entloc,_sys_errlist[errno]); continue; } if(!(entbuf=malloc(hdr.entsiz+1))) // Allocate storage for entity script { printf("Can't alloc %u bytes for ent storage\n",hdr.entsiz+1); continue; } if(fread(entbuf,hdr.entsiz,1,hin)<1) // Read entity script { printf("Entity data read failure for %u bytes, %s!\n",hdr.entsiz,_sys_errlist[errno]); continue; } entbuf[hdr.entsiz]=0; // Null terminate at end of storage (for str* funcs) if(!processcommands(arg,hin,entbuf,&hdr,filelen,&changes)) // Parse script { if(changes) // BSP was modified { filesmodified++; // Increment modified counter fileschanges+=changes; // Increment total changes } printf("OK! (%u chang%s)\n",changes,changes==1?"e":"es"); // Tell user fileserrors--; // Decrement file errors (incremented at beginning of loop) } if(entbuf) // Free storage buffer and nullify it so it doesnt get freed again { free(entbuf); entbuf=0; } if(hin) // Close input file buffer and nullify it so it doesnt get closed again { fclose(hin); hin=0; } // Goto next file } printf("\n" // Print summary "Result: %u fil%s, %u modificatio%s, %u chang%s and %u erro%s\n" "\n" "Operation completed!\n", filestotal, filestotal==1?"e":"es", // Pluralise filesmodified, filesmodified==1?"n":"ns", // Pluralise fileschanges, fileschanges==1?"e":"es", // Pluralise fileserrors, fileserrors==1?"r":"rs"); // Pluralise return 0; }