11 #define _CFILE_INTERNAL  
   92 #define CFILE_STACK_MAX 8 
   95 static int Cfile_stack_pos = 0;
 
  102 static const char *Cfile_cdrom_dir = NULL;
 
  107 static int cfget_cfile_block();
 
  108 static CFILE *cf_open_fill_cfblock(
const char* 
source, 
int line, FILE * 
fp, 
int type);
 
  113 #elif defined SCP_UNIX 
  114 static CFILE *cf_open_mapped_fill_cfblock(
const char* 
source, 
int line, FILE *
fp, 
int type);
 
  117 static void cf_chksum_long_init();
 
  119 static void dump_opened_files()
 
  122                 auto cb = &Cfile_block_list[
i];
 
  124                         mprintf((
"    %s:%d\n", cb->source_file, cb->line_num));
 
  129 static void cfile_close()
 
  131         mprintf((
"Still opened files:\n"));
 
  138         #define MIN_NUM_PATH_COMPONENTS 2      
  140         #define MIN_NUM_PATH_COMPONENTS 3      
  150 static bool cfile_in_root_dir(
const char *exe_path)
 
  154         const char *
p = exe_path;
 
  168                 token_count += new_token;
 
  169         } 
while (*p != 
'\0');
 
  200         if (cfile_in_root_dir(buf)) {
 
  202                            "FreeSpace2/Fred2 cannot be run from a drive root directory!",
 
  235         cf_chksum_long_init();
 
  237         Cfile_cdrom_dir = cdrom_dir;
 
  259 int cfile_chdrive( 
int DriveNum, 
int flag )
 
  268         _chdrive( DriveNum );
 
  275         if ( (!flag) && (n != org) )
 
  293 static int _cfile_chdir(
const char *new_dir, 
const char *cur_dir 
__UNUSED)
 
  296         const char *
path = NULL;
 
  297         const char no_dir[] = 
"\\.";
 
  300         const char *colon = strchr(new_dir, 
':');
 
  303                 if (!cfile_chdrive(tolower(*(colon - 1)) - 
'a' + 1, 1))
 
  321                 cfile_chdrive(tolower(cur_dir[0]) - 
'a' + 1, 1);
 
  355         strncpy(Cfile_stack[Cfile_stack_pos++], OriginalDirectory,
 
  360         return _cfile_chdir(dir, OriginalDirectory);
 
  378         return _cfile_chdir(dir, OriginalDirectory);
 
  385         if ( !Cfile_stack_pos )
 
  410         find_handle = _findfirst( 
"*", &find );
 
  411         if (find_handle != -1) {
 
  413                         if (!(find.attrib & _A_SUBDIR) && !(find.attrib & _A_RDONLY)) {
 
  420                 } 
while (!_findnext(find_handle, &find));
 
  421                 _findclose( find_handle );
 
  423 #elif defined SCP_UNIX 
  425         memset(&globinfo, 0, 
sizeof(globinfo));
 
  426         int status = glob(
"*", 0, NULL, &globinfo);
 
  428                 for (
unsigned int i = 0;  
i < globinfo.gl_pathc;  
i++) {
 
  432                         stat(globinfo.gl_pathv[
i], &statbuf);
 
  433                         if (S_ISREG(statbuf.st_mode)) {
 
  463         flen = strlen(filename);
 
  467         if ((flen < 4) || 
stricmp(path + flen - elen, ext)) {
 
  490                                       path_type, filename);
 
  492         return (
_unlink(longname) != -1);
 
  505         return access(longname,mode);
 
  518         if ( (filename == NULL) || !strlen(filename) )
 
  529         if ( (filename == NULL) || !strlen(filename) )
 
  538         if ( (filename == NULL) || !strlen(filename) )
 
  541         if ( (num_ext <= 0) || (ext_list == NULL) )
 
  556         FILE *
fp = fopen(longname, 
"rb");
 
  560                 DWORD z = GetFileAttributes(longname);
 
  561                 SetFileAttributes(longname, z | set & ~clear);
 
  578         ret_code = rename(old_longname, new_longname );         
 
  609                 dir_tree[num_dirs++] = current_dir;
 
  617         for (i=num_dirs-1; i>=0; i-- )  {
 
  620                 if ( 
_mkdir(longname)==0 )      {
 
  621                         mprintf(( 
"CFILE: Created new directory '%s'\n", longname ));
 
  662         Assert(file_path && strlen(file_path));
 
  675         if ( strchr(mode,
'w') || strchr(mode,
'+') || strchr(mode,
'a') ) {
 
  678                 if ( strpbrk(file_path, 
"/") ) {
 
  680                 if ( strpbrk(file_path,
"/\\:")  ) {
 
  693                 Assert( !(type & CFILE_MEMORY_MAPPED) );
 
  702                 if(strcspn(mode, 
"ra+") != strlen(mode) && (strchr(mode, 
't') || !strchr(mode, 
'b')))
 
  706                         unsigned int max = 
sizeof(happy_mode) - 2;      
 
  709                         for( i = 0; i < strlen(mode); i++)
 
  715                                         happy_mode[
i] = mode[
i];
 
  720                         happy_mode[
i] = 
'\0';
 
  730                 FILE *fp = fopen(longname, happy_mode);
 
  732                         return cf_open_fill_cfblock(source, line, fp, dir_type);
 
  743         strcpy_s(copy_file_path, file_path);
 
  746         if ( 
cf_find_file_location( copy_file_path, dir_type, 
sizeof(longname) - 1, longname, &size, &offset, localize ) )      {
 
  749                 nprintf((
"CFileDebug", 
"Requested file %s found at: %s\n", file_path, longname));
 
  751                 if ( type & CFILE_MEMORY_MAPPED ) {
 
  758                                 hFile = CreateFile(longname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 
  760                                 if (hFile != INVALID_HANDLE_VALUE)      {
 
  761                                         return cf_open_mapped_fill_cfblock(source, line, hFile, dir_type);
 
  763 #elif defined SCP_UNIX 
  764                                 FILE *fp = fopen( longname, 
"rb" );
 
  766                                         return cf_open_mapped_fill_cfblock(source, line, fp, dir_type);
 
  773                         FILE *fp = fopen( longname, 
"rb" );
 
  778                                         return cf_open_packed_cfblock(source, line, fp, dir_type, offset, size );
 
  781                                         return cf_open_fill_cfblock(source, line, fp, dir_type);
 
  809         Assert( file_path && strlen(file_path) );
 
  814         if ( strchr(mode, 
'w') ) {
 
  820         FILE *fp = fopen( file_path, 
"rb" );
 
  827                 return cf_open_packed_cfblock(source, line, fp, dir_type, offset, size);
 
  830                 return cf_open_fill_cfblock(source, line, fp, dir_type);
 
  849                 return cf_open_fill_cfblock(
LOCATION, fp, 0);
 
  862 static int cfget_cfile_block()
 
  868                 cb = &Cfile_block_list[
i];
 
  878         nprintf((
"Warning",
"A free Cfile_block could not be found.\n"));
 
  881         mprintf((
"Out of cfile blocks! Currently opened files:\n"));
 
  884         Assertion(
false, 
"There are no more free cfile blocks. This means that there are too many files opened by FSO.\n" 
  885                 "This is probably caused by a programming or scripting error where a file does not get closed."); 
 
  901         Assert(cfile->
id >= 0 && cfile->
id < MAX_CFILE_BLOCKS);
 
  902         cb = &Cfile_block_list[cfile->
id];      
 
  908                 result = UnmapViewOfFile((
void*)cb->
data);
 
  910                 result = CloseHandle(cb->hInFile);              
 
  912                 result = CloseHandle(cb->hMapFile);             
 
  915 #elif defined SCP_UNIX 
  921                         result = fclose(cb->
fp);
 
  924         } 
else if ( cb->
fp != NULL )    {
 
  926                 result = fclose(cb->
fp);
 
  942         if(cfile->
id < 0 || cfile->
id >= MAX_CFILE_BLOCKS)
 
  963 static CFILE *cf_open_fill_cfblock(
const char* source, 
int line, FILE *fp, 
int type)
 
  967         cfile_block_index = cfget_cfile_block();
 
  968         if ( cfile_block_index == -1 ) {
 
 1002 static CFILE *cf_open_packed_cfblock(
const char* source, 
int line, FILE *fp, 
int type, 
int offset, 
int size)
 
 1007         cfile_block_index = cfget_cfile_block();
 
 1008         if ( cfile_block_index == -1 ) {
 
 1042 static CFILE *cf_open_mapped_fill_cfblock(
const char* source, 
int line, 
HANDLE hFile, 
int type)
 
 1043 #elif defined SCP_UNIX 
 1044 static CFILE *cf_open_mapped_fill_cfblock(
const char* source, 
int line, FILE *fp, 
int type)
 
 1049         cfile_block_index = cfget_cfile_block();
 
 1050         if ( cfile_block_index == -1 ) {
 
 1067                 cfbp->hInFile = hFile;
 
 1076                 cfbp->hMapFile = CreateFileMapping(cfbp->hInFile, NULL, PAGE_READONLY, 0, 0, NULL);
 
 1077                 if (cfbp->hMapFile == NULL) { 
 
 1078                         nprintf((
"Error", 
"Could not create file-mapping object.\n")); 
 
 1082                 cfbp->
data = (
ubyte*)MapViewOfFile(cfbp->hMapFile, FILE_MAP_READ, 0, 0, 0);
 
 1084 #elif defined SCP_UNIX 
 1087                 cfbp->
data = mmap(NULL,                                         
 
 1114         Assert(cfile->
id >= 0 && cfile->
id < MAX_CFILE_BLOCKS);
 
 1115         cb = &Cfile_block_list[cfile->
id];      
 
 1136         Assert( (cfile->
id >= 0) && (cfile->
id < MAX_CFILE_BLOCKS) );
 
 1157         if (
cfread( &f, 
sizeof(f), 1, file) != 1)
 
 1171         if (
cfread( &i, 
sizeof(i), 1, file) != 1)
 
 1185         if (
cfread( &i, 
sizeof(i), 1, file) != 1)
 
 1199         if (
cfread( &s, 
sizeof(s), 1, file) != 1)
 
 1213         if (
cfread( &s, 
sizeof(s), 1, file) != 1)
 
 1227         if (
cfread( &b, 
sizeof(b), 1, file) != 1)
 
 1239                         vec->
xyz.x = vec->
xyz.y = vec->
xyz.z = 0.0f;
 
 1255                         ang->
p = ang->
b = ang->
h = 0.0f;
 
 1272         if (
cfread( &b, 
sizeof(b), 1, file) != 1)
 
 1295         Assertion( (len < n), 
"len: %i, n: %i", len, n );
 
 1297                 cfread(buf, len, 1, file);
 
 1307         return cfwrite(&f, 
sizeof(f), 1, file);
 
 1313         return cfwrite(&i, 
sizeof(i), 1, file);
 
 1319         return cfwrite(&i, 
sizeof(i), 1, file);
 
 1325         return cfwrite(&s, 
sizeof(s), 1, file);
 
 1331         return cfwrite(&s, 
sizeof(s), 1, file);
 
 1336         return cfwrite(&b, 
sizeof(b), 1, file);
 
 1363         return cfwrite( &b, 
sizeof(b), 1, file);
 
 1368         if ( (!buf) || (buf && !buf[0]) ) {
 
 1371         int len = strlen(buf);
 
 1372         if(!
cfwrite(buf, len, 1, file)){
 
 1380         int len = strlen(buf);
 
 1386                 return cfwrite(buf,len,1,file);
 
 1397         Assert(cfile->
id >= 0 && cfile->
id < MAX_CFILE_BLOCKS);
 
 1398         cb = &Cfile_block_list[cfile->
id];      
 
 1419         if(buf == NULL || elsize == 0 || nelem == 0)
 
 1426                 Error(
LOCATION, 
"Attempt to write to a VP file (unsupported)");
 
 1430         if(cb->
data != NULL)
 
 1436         size_t bytes_written = 0;
 
 1437         size_t size = elsize * nelem;
 
 1439         bytes_written = fwrite(buf, 1, size, cb->
fp);
 
 1442         if (bytes_written > 0) {
 
 1443                 cb->
size += bytes_written;
 
 1447 #if defined(CHECK_SIZE) && !defined(NDEBUG) 
 1451         return ((
int)bytes_written / elsize);
 
 1469                 Error(
LOCATION, 
"Attempt to write character to a VP file (unsupported)");
 
 1473         if(cb->
data != NULL)
 
 1491 #if defined(CHECK_SIZE) && !defined(NDEBUG) 
 1516                 Error(
LOCATION, 
"Attempt to write character to a VP file (unsupported)");
 
 1520         if(cb->
data != NULL)
 
 1531                 cb->
size += strlen(str);
 
 1535 #if defined(CHECK_SIZE) && !defined(NDEBUG) 
 1553         if ( result == 1 )      {
 
 1580         for (i=0; i<n-1; i++ )  {
 
 1584                         int ret = 
cfread( &tmp_c, 1, 1, cfile );
 
 1594                 } 
while ( c == 13 );
 
 1596                 if ( c==
'\n' ) 
break;
 
 1608 #define CRC32_POLYNOMIAL                                        0xEDB88320 
 1609 static uint CRCTable[256];
 
 1611 #define CF_CHKSUM_SAMPLE_SIZE                           512 
 1619         sum1 = sum2 = (
int)(seed);
 
 1623                 if (sum1 >= 255 ) sum1 -= 255;
 
 1628         return (
ushort)((sum1 << 8) + sum2);
 
 1641                 crc = (crc >> 8) ^ CRCTable[(crc ^ *p++) & 0xff];
 
 1646 static void cf_chksum_long_init()
 
 1651         for (i = 0; i < 256; i++) {
 
 1654                 for (j = 8; j > 0; j--) {
 
 1688                 cfseek(cfile, 0, SEEK_SET);
 
 1698                         read_size = max_size - cf_total;
 
 1702                 cf_len = 
cfread(cf_buffer, 1, read_size, cfile);
 
 1716         } 
while((cf_len > 0) && (cf_total < max_size));
 
 1724         const int safe_size = 2097152; 
 
 1725         const int header_offset = 32;  
 
 1733         if (chk_long == NULL) {
 
 1738         FILE *fp = fopen(filename, 
"rb");
 
 1748         fseek(fp, 0, SEEK_END);
 
 1749         max_size = ftell(fp);
 
 1753                 fseek(fp, 0, SEEK_SET);
 
 1757                 CLAMP(max_size, 0, safe_size);
 
 1760                         "max_size (%d) > header_offset in packfile %s", max_size, filename);
 
 1761                 max_size -= header_offset;
 
 1763                 fseek(fp, -(max_size), SEEK_END);
 
 1773                         read_size = max_size - cf_total;
 
 1776                 cf_len = fread(cf_buffer, 1, read_size, fp);
 
 1784         } 
while ( (cf_len > 0) && (cf_total < max_size) );
 
 1794         CFILE *cfile = NULL;            
 
 1806         ret_val = cf_chksum_do(cfile, chksum, NULL, max_size);
 
 1824         start_pos = 
cftell(file);
 
 1825         if(start_pos == -1){
 
 1833         ret_code = cf_chksum_do(file, chksum, NULL, max_size);
 
 1844         CFILE *cfile = NULL;            
 
 1856         ret_val = cf_chksum_do(cfile, NULL, chksum, max_size);
 
 1874         start_pos = 
cftell(file);
 
 1875         if(start_pos == -1){
 
 1883         ret_code = cf_chksum_do(file, NULL, chksum, max_size);
 
 1899         Assert(cfile->
id >= 0 && cfile->
id < MAX_CFILE_BLOCKS);
 
 1900         cb = &Cfile_block_list[cfile->
id];      
 
void cfread_angles(angles *ang, CFILE *file, int ver, angles *deflt)
 
int cf_is_valid(CFILE *cfile)
 
int cfwrite_ushort(ushort s, CFILE *file)
 
#define CF_TYPE_SINGLE_PLAYERS
 
int cf_get_dir_type(CFILE *cfile)
 
int cf_delete(const char *filename, int path_type)
Delete the specified file. 
 
#define CF_TYPE_VOICE_DEBRIEFINGS
 
void cf_set_max_read_len(CFILE *cfile, size_t len)
 
#define CF_RENAME_FAIL_ACCESS
 
int cfread(void *buf, int elsize, int nelem, CFILE *fp)
 
void cf_attrib(const char *name, int set, int clear, int type)
 
int cfwrite_ubyte(ubyte b, CFILE *file)
 
CFILE * _cfopen_special(const char *source, int line, const char *file_path, const char *mode, const int size, const int offset, int dir_type)
 
int cfwrite_uint(uint i, CFILE *file)
 
void _cdecl void void _cdecl void _cdecl Warning(char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
 
#define DIR_SEPARATOR_CHAR
 
#define CF_TYPE_VOICE_SPECIAL
 
#define CFILE_MEMORY_MAPPED
 
struct vec3d::@225::@227 xyz
 
const char * Osreg_user_dir
 
void cf_free_secondary_filelist()
 
#define Assertion(expr, msg,...)                                                                        
 
void cfread_string(char *buf, int n, CFILE *file)
 
int cfwrite_angles(angles *ang, CFILE *file)
 
int cf_find_file_location_ext(const char *filename, const int ext_num, const char **ext_list, int pathtype, int max_out=0, char *pack_filename=NULL, int *size=NULL, int *offset=NULL, bool localize=false)
 
#define CF_TYPE_PLAYER_IMAGES
 
#define CF_TYPE_SQUAD_IMAGES
 
int cf_create_default_path_string(char *path, uint path_max, int pathtype, const char *filename, bool localize)
 
const char * detect_home(void)
 
GLenum GLuint GLenum GLsizei const GLchar * buf
 
#define CF_TYPE_MULTI_CACHE
 
int cf_chksum_pack(const char *filename, uint *chk_long, bool full)
 
#define CLAMP(x, min, max)
 
int _getcwd(char *buffer, unsigned int len)
 
int cfwrite_char(char b, CFILE *file)
 
int cfile_push_chdir(int type)
Push current directory onto a 'stack' and change to a new directory. 
 
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
 
int cf_find_file_location(const char *filespec, int pathtype, int max_out, char *pack_filename, int *size, int *offset, bool localize=false)
 
#define CF_CHKSUM_SAMPLE_SIZE
 
int _mkdir(const char *path)
 
char * cfgets(char *buf, int n, CFILE *cfile)
 
int cfwrite_float(float f, CFILE *file)
 
cf_pathtype Pathtypes[CF_MAX_PATH_TYPES]
 
#define CF_TYPE_MULTI_PLAYERS
 
#define DIR_SEPARATOR_STR
 
int cf_exists_full(const char *filename, int dir_type)
 
#define CF_TYPE_VOICE_CMD_BRIEF
 
int _chdir(const char *path)
 
int cfile_flush_dir(int dir_type)
 
int cfwrite_string(const char *buf, CFILE *file)
 
#define CF_RENAME_FAIL_EXIST
 
Cfile_block Cfile_block_list[MAX_CFILE_BLOCKS]
 
uint cf_add_chksum_long(uint seed, ubyte *buffer, int size)
 
#define CF_TYPE_VOICE_BRIEFINGS
 
int cfwrite_string_len(const char *buf, CFILE *file)
Write a fixed length string (not including its null terminator), with the length stored in file...
 
int cfputc(int c, CFILE *cfile)
 
int cf_rename(const char *old_name, const char *name, int dir_type)
 
int cfwrite(const void *buf, int elsize, int nelem, CFILE *cfile)
 
#define CF_TYPE_INTEL_ANIMS
 
short cfread_short(CFILE *file, int ver, short deflt)
 
#define CF_TYPE_INTERFACE
 
int cfile_chdir(const char *dir)
Change to the specified directory. 
 
int cfwrite_int(int i, CFILE *file)
 
void cf_set_version(CFILE *cfile, int version)
 
int cf_chksum_short(const char *filename, ushort *chksum, int max_size, int cf_type)
 
void _cdecl void void _cdecl Error(const char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
 
int cf_chksum_long(const char *filename, uint *chksum, int max_size, int cf_type)
 
ubyte cfread_ubyte(CFILE *file, int ver, ubyte deflt)
 
GLuint const GLchar * name
 
void cfread_vector(vec3d *vec, CFILE *file, int ver, vec3d *deflt)
 
char * cf_add_ext(const char *filename, const char *ext)
 
void cf_build_secondary_filelist(const char *cdrom_dir)
 
GLboolean GLboolean GLboolean b
 
int cfputs(const char *str, CFILE *cfile)
 
char cfread_char(CFILE *file, int ver, char deflt)
 
char Cfile_root_dir[CFILE_ROOT_DIRECTORY_LEN]
 
cf_init_lowlevel_read_code(cfp, 0, 0, 0)
 
int cfwrite_short(short s, CFILE *file)
 
#define MIN_NUM_PATH_COMPONENTS
 
#define CF_TYPE_SPECIFIED(path_type)
 
#define CFILE_ROOT_DIRECTORY_LEN
 
GLsizei const GLchar ** path
 
int MessageBox(HWND h, const char *s1, const char *s2, int i)
 
#define CFILE_BLOCK_UNUSED
 
ushort cfread_ushort(CFILE *file, int ver, ushort deflt)
 
void cf_create_directory(int dir_type)
 
#define CF_TYPE_SOUNDS_8B22K
 
int cfread_int(CFILE *file, int ver, int deflt)
 
#define CF_TYPE_SOUNDS_16B11K
 
float cfread_float(CFILE *file, int ver, float deflt)
 
GLsizei GLsizei GLchar * source
 
#define CF_MAX_PATH_TYPES
 
void * cf_returndata(CFILE *cfile)
 
int cfwrite_vector(vec3d *vec, CFILE *file)
 
int cfclose(CFILE *cfile)
 
#define CF_TYPE_VOICE_PERSONAS
 
#define CF_TYPE_VOICE_TRAINING
 
int cfilelength(CFILE *cfile)
 
#define CF_RENAME_SUCCESS
 
int cf_exists(const char *filename, int dir_type)
 
int cf_access(const char *filename, int dir_type, int mode)
 
uint cfread_uint(CFILE *file, int ver, uint deflt)
 
int cfile_init(const char *exe_dir, const char *cdrom_dir)
Initialize the cfile system. Called once at application start. 
 
int cf_exists_full_ext(const char *filename, int dir_type, const int num_ext, const char **ext_list)
 
CFILE * _cfopen(const char *source, int line, const char *file_path, const char *mode, int type, int dir_type, bool localize)
 
ushort cf_add_chksum_short(ushort seed, ubyte *buffer, int size)
 
void cfread_string_len(char *buf, int n, CFILE *file)
Read a fixed length string that is not null-terminated, with the length stored in file...
 
int cfseek(CFILE *fp, int offset, int where)