Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

261 lines
4.7 KiB

  1. //========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include <dirent.h>
  8. #include "tier1/strtools.h"
  9. #include "tier0/memdbgoff.h"
  10. #include "linux_support.h"
  11. #ifdef OSX
  12. #include <AvailabilityMacros.h>
  13. #endif
  14. char selectBuf[PATH_MAX];
  15. #if defined(OSX) && !defined(MAC_OS_X_VERSION_10_9)
  16. int FileSelect(struct dirent *ent)
  17. #else
  18. int FileSelect(const struct dirent *ent)
  19. #endif
  20. {
  21. const char *mask=selectBuf;
  22. const char *name=ent->d_name;
  23. //printf("Test:%s %s\n",mask,name);
  24. if(!strcmp(name,".") || !strcmp(name,"..") ) return 0;
  25. if(!strcmp(selectBuf,"*.*")) return 1;
  26. while( *mask && *name )
  27. {
  28. if(*mask=='*')
  29. {
  30. mask++; // move to the next char in the mask
  31. if(!*mask) // if this is the end of the mask its a match
  32. {
  33. return 1;
  34. }
  35. while(*name && toupper(*name)!=toupper(*mask))
  36. { // while the two don't meet up again
  37. name++;
  38. }
  39. if(!*name)
  40. { // end of the name
  41. break;
  42. }
  43. }
  44. else if (*mask!='?')
  45. {
  46. if( toupper(*mask) != toupper(*name) )
  47. { // mismatched!
  48. return 0;
  49. }
  50. else
  51. {
  52. mask++;
  53. name++;
  54. if( !*mask && !*name)
  55. { // if its at the end of the buffer
  56. return 1;
  57. }
  58. }
  59. }
  60. else /* mask is "?", we don't care*/
  61. {
  62. mask++;
  63. name++;
  64. }
  65. }
  66. return( !*mask && !*name ); // both of the strings are at the end
  67. }
  68. int FillDataStruct(FIND_DATA *dat)
  69. {
  70. struct stat fileStat;
  71. if(dat->numMatches<0)
  72. return -1;
  73. char szFullPath[MAX_PATH];
  74. Q_snprintf( szFullPath, sizeof(szFullPath), "%s/%s", dat->cBaseDir, dat->namelist[dat->numMatches]->d_name );
  75. if(!stat(szFullPath,&fileStat))
  76. {
  77. dat->dwFileAttributes=fileStat.st_mode;
  78. }
  79. else
  80. {
  81. dat->dwFileAttributes=0;
  82. }
  83. // now just put the filename in the output data
  84. Q_snprintf( dat->cFileName, sizeof(dat->cFileName), "%s", dat->namelist[dat->numMatches]->d_name );
  85. //printf("%s\n", dat->namelist[dat->numMatches]->d_name);
  86. free(dat->namelist[dat->numMatches]);
  87. dat->numMatches--;
  88. return 1;
  89. }
  90. HANDLE FindFirstFile( const char *fileName, FIND_DATA *dat)
  91. {
  92. char nameStore[PATH_MAX];
  93. char *dir=NULL;
  94. int n,iret=-1;
  95. Q_strncpy(nameStore,fileName, sizeof( nameStore ) );
  96. if(strrchr(nameStore,'/') )
  97. {
  98. dir=nameStore;
  99. while(strrchr(dir,'/') )
  100. {
  101. struct stat dirChk;
  102. // zero this with the dir name
  103. dir=strrchr(nameStore,'/');
  104. *dir='\0';
  105. dir=nameStore;
  106. stat(dir,&dirChk);
  107. if( S_ISDIR( dirChk.st_mode ) )
  108. {
  109. break;
  110. }
  111. }
  112. }
  113. else
  114. {
  115. // couldn't find a dir seperator...
  116. return (HANDLE)-1;
  117. }
  118. if( strlen(dir)>0 )
  119. {
  120. Q_strncpy(selectBuf,fileName+strlen(dir)+1, sizeof( selectBuf ) );
  121. Q_strncpy(dat->cBaseDir,dir, sizeof( dat->cBaseDir ) );
  122. dat->namelist = NULL;
  123. n = scandir(dir, &dat->namelist, FileSelect, alphasort);
  124. if (n < 0)
  125. {
  126. // silently return, nothing interesting
  127. dat->namelist = NULL;
  128. }
  129. else
  130. {
  131. dat->numMatches=n-1; // n is the number of matches
  132. iret=FillDataStruct(dat);
  133. if ( ( iret<0 ) && dat->namelist )
  134. {
  135. free(dat->namelist);
  136. dat->namelist = NULL;
  137. }
  138. }
  139. }
  140. // printf("Returning: %i \n",iret);
  141. return (HANDLE)(intp)iret;
  142. }
  143. bool FindNextFile(HANDLE handle, FIND_DATA *dat)
  144. {
  145. if(dat->numMatches<0)
  146. {
  147. if ( dat->namelist != NULL )
  148. {
  149. free( dat->namelist );
  150. dat->namelist = NULL;
  151. }
  152. return false; // no matches left
  153. }
  154. FillDataStruct(dat);
  155. return true;
  156. }
  157. bool FindClose(HANDLE handle)
  158. {
  159. return true;
  160. }
  161. static char fileName[MAX_PATH];
  162. #if defined(OSX) && !defined(MAC_OS_X_VERSION_10_9)
  163. int CheckName(struct dirent *dir)
  164. #else
  165. int CheckName(const struct dirent *dir)
  166. #endif
  167. {
  168. return !strcasecmp( dir->d_name, fileName );
  169. }
  170. const char *findFileInDirCaseInsensitive(const char *file, char *pFileNameOut)
  171. {
  172. const char *dirSep = strrchr(file,'/');
  173. if( !dirSep )
  174. {
  175. dirSep=strrchr(file,'\\');
  176. if( !dirSep )
  177. {
  178. return NULL;
  179. }
  180. }
  181. char *dirName = static_cast<char *>( alloca( ( dirSep - file ) +1 ) );
  182. if( !dirName )
  183. return NULL;
  184. strncpy( dirName , file, dirSep - file );
  185. dirName[ dirSep - file ] = '\0';
  186. struct dirent **namelist = NULL;
  187. strncpy( fileName, dirSep + 1, MAX_PATH );
  188. int n = scandir( dirName , &namelist, CheckName, alphasort );
  189. // Free all entries beyond the first one, we don't care about them
  190. while ( n > 1 )
  191. {
  192. -- n;
  193. free( namelist[n] );
  194. }
  195. if ( n > 0 )
  196. {
  197. Q_snprintf( pFileNameOut, sizeof( fileName ), "%s/%s", dirName, namelist[0]->d_name );
  198. free( namelist[0] );
  199. n = 0;
  200. }
  201. else
  202. {
  203. Q_strncpy( pFileNameOut, file, MAX_PATH );
  204. Q_strlower( pFileNameOut );
  205. }
  206. if ( ( n >= 0 ) && namelist )
  207. {
  208. free( namelist );
  209. }
  210. return pFileNameOut;
  211. }