path.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. /** BEGIN COPYRIGHT BLOCK
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  35. * Copyright (C) 2005 Red Hat, Inc.
  36. * All rights reserved.
  37. * END COPYRIGHT BLOCK **/
  38. /***********************************************************
  39. * Path functions - removing ../ from path
  40. **********************************************************/
  41. #include <windows.h>
  42. #include <stdio.h>
  43. #include <sys/types.h>
  44. #include <sys/stat.h>
  45. #include <io.h> /* For _findfirst */
  46. #include <direct.h> /* For _rmdir */
  47. #include <errno.h>
  48. #include "nt/ntos.h"
  49. DWORD NS_WINAPI
  50. PATH_RemoveRelative ( char * path )
  51. {
  52. char * src;
  53. char * dst;
  54. src = path;
  55. dst = path;
  56. while ( *src ) {
  57. if ( *src == '.' ) {
  58. if ( *(src+1) == '.' ) {
  59. /* strip off the "../" */
  60. src += 2;
  61. /* back off least significant directory */
  62. dst--;
  63. if ( ( *dst == '\\' ) || ( *dst == '/' ) )
  64. *dst--;
  65. while ( dst > path ) {
  66. if ( ( *dst == '\\' ) || ( *dst == '/' ) )
  67. break;
  68. dst--;
  69. }
  70. } else {
  71. // remove single "."
  72. }
  73. } else
  74. *dst++ = *src++;
  75. }
  76. *dst = '\0';
  77. return TRUE;
  78. }
  79. DWORD NS_WINAPI
  80. PATH_ConvertNtSlashesToUnix( LPCTSTR lpszNtPath, LPSTR lpszUnixPath )
  81. {
  82. if ( lpszNtPath == NULL )
  83. return 0;
  84. /* create reverse slashes and escape them */
  85. while ( *lpszNtPath ) {
  86. if ( *lpszNtPath == '\\' )
  87. *lpszUnixPath = '/';
  88. else
  89. *lpszUnixPath = *lpszNtPath;
  90. lpszNtPath++;
  91. lpszUnixPath++;
  92. }
  93. *lpszUnixPath = '\0';
  94. return 0;
  95. }
  96. static DWORD
  97. PATH_DeleteRecursivelyFoundFile ( char * fullFileName, char * path, char * fileName )
  98. {
  99. if ( strcmp ( fileName, "." ) == 0)
  100. return TRUE;
  101. if ( strcmp ( fileName, ".." ) == 0)
  102. return TRUE;
  103. strcpy ( fullFileName, path );
  104. strcat ( fullFileName, "\\" );
  105. strcat ( fullFileName, fileName );
  106. return PATH_DeleteRecursively ( fullFileName );
  107. }
  108. /* if the path specified is a file name, the file is deleted
  109. * If the path specifies a directory, the directory is deleted
  110. */
  111. DWORD NS_WINAPI
  112. PATH_DeleteRecursively ( char * path )
  113. {
  114. int result;
  115. unsigned short fileStatus;
  116. struct _stat buf;
  117. struct _finddata_t fileFound;
  118. long hFile;
  119. DWORD retStatus = TRUE;
  120. char fullFileName[_MAX_PATH];
  121. int error;
  122. /* Check if statistics are valid: */
  123. result = _stat( path, &buf );
  124. if( result != 0 )
  125. return TRUE; // file or directory does not exist
  126. fileStatus = buf.st_mode & _S_IFMT;
  127. /* check if regular file */
  128. if ( fileStatus & _S_IFREG ) {
  129. if ( remove ( path ) == -1 ) {
  130. error = errno;
  131. switch ( error ) {
  132. case ENOENT:
  133. break;
  134. case EACCES:
  135. break;
  136. default:
  137. break;
  138. }
  139. return FALSE;
  140. }
  141. return TRUE;
  142. }
  143. if ( (fileStatus & _S_IFDIR) == 0 )
  144. return FALSE;
  145. /* path contains a directory, delete all files recursively */
  146. /* Find first .c file in current directory */
  147. strcpy ( fullFileName, path );
  148. strcat ( fullFileName, "\\*.*");
  149. if( (hFile = _findfirst( fullFileName, &fileFound )) != -1L ) { /* directory contain files? */
  150. if ( !PATH_DeleteRecursivelyFoundFile ( fullFileName, path, fileFound.name ) )
  151. retStatus = FALSE;
  152. /* Find the rest of the .c files */
  153. while( _findnext( hFile, &fileFound ) == 0 ) {
  154. if ( !PATH_DeleteRecursivelyFoundFile ( fullFileName, path, fileFound.name ) )
  155. retStatus = FALSE;
  156. }
  157. _findclose( hFile );
  158. }
  159. /* remove the directory, now that it is empty */
  160. if ( _rmdir( path ) == -1 )
  161. retStatus = FALSE;
  162. return retStatus;
  163. }
  164. /* GetNextFileInDirectory - gets next file in the directory
  165. * Set hFile to zero, when you call it. The routine returns the
  166. * next value for hFile. When the routine returns NULL, there is
  167. * no more files
  168. *
  169. */
  170. DWORD NS_WINAPI
  171. PATH_GetNextFileInDirectory ( long hFile, char * path, char * lpFileName )
  172. {
  173. int result;
  174. unsigned short fileStatus;
  175. struct _stat buf;
  176. struct _finddata_t fileFound;
  177. DWORD retStatus = TRUE;
  178. char fullFileName[_MAX_PATH];
  179. if ( hFile == 0 ) {
  180. /* Check if statistics are valid: */
  181. result = _stat( path, &buf );
  182. if( result != 0 )
  183. return 0; // file or directory does not exist
  184. fileStatus = buf.st_mode & _S_IFMT;
  185. if ( (fileStatus & _S_IFDIR) == 0 )
  186. return 0;
  187. /* path contains a directory, delete all files recursively */
  188. /* Find first .c file in current directory */
  189. strcpy ( fullFileName, path );
  190. strcat ( fullFileName, "\\*.*");
  191. if( (hFile = _findfirst( fullFileName, &fileFound )) == -1L )
  192. return 0;
  193. if ( ( strcmp ( fileFound.name , "." ) != 0)
  194. && ( strcmp ( fileFound.name , ".." ) != 0) ) {
  195. strcpy ( lpFileName, fileFound.name );
  196. return hFile;
  197. }
  198. }
  199. /* Find the rest of the .c files */
  200. while( _findnext( hFile, &fileFound ) == 0 ) {
  201. if ( ( strcmp ( fileFound.name , "." ) != 0)
  202. && ( strcmp ( fileFound.name , ".." ) != 0) ) {
  203. strcpy ( lpFileName, fileFound.name );
  204. return hFile;
  205. }
  206. }
  207. _findclose( hFile );
  208. return 0;
  209. }
  210. /*---------------------------------------------------------------------------*\
  211. *
  212. * Function: PATH_GetNextSubDirectory
  213. *
  214. * Purpose: Gets next sub directory in the path
  215. *
  216. * Input:
  217. * hFile: set to zero first time called; use return value for subsequent calls
  218. * path: directory containing sub directories
  219. * lpSubDirectoryName: buffer to store sub directorie name
  220. * lpSubDirectoryPrefix: chars to exactly match begining of directory name
  221. *
  222. * Returns:
  223. * hFile to be used on subsequent call (0, if no more directories)
  224. *
  225. * Comments:
  226. \*---------------------------------------------------------------------------*/
  227. DWORD NS_WINAPI
  228. PATH_GetNextSubDirectory( long hFile, char * path, char * lpSubDirectoryName, char * lpSubDirectoryPrefix )
  229. {
  230. int result;
  231. unsigned short fileStatus;
  232. struct _stat buf;
  233. char * subDirectoryPrefix;
  234. char * p;
  235. char fullFileName[_MAX_PATH];
  236. BOOL bSubDirectoryFound;
  237. do {
  238. hFile = PATH_GetNextFileInDirectory ( hFile, path, lpSubDirectoryName );
  239. if ( hFile == 0 )
  240. return 0;
  241. /* Check if file is a directory */
  242. strcpy ( fullFileName, path );
  243. strcat ( fullFileName, "\\" );
  244. strcat ( fullFileName, lpSubDirectoryName );
  245. result = _stat( fullFileName, &buf );
  246. if( result == 0 ) {
  247. fileStatus = buf.st_mode & _S_IFMT;
  248. if ( (fileStatus & _S_IFDIR) == _S_IFDIR ) {
  249. /* check if sub directory matches prefix */
  250. bSubDirectoryFound = TRUE;
  251. if ( lpSubDirectoryPrefix ) {
  252. p = lpSubDirectoryName;
  253. subDirectoryPrefix = lpSubDirectoryPrefix;
  254. while ( *subDirectoryPrefix ) {
  255. if ( *subDirectoryPrefix++ != *p++ ) {
  256. bSubDirectoryFound = FALSE;
  257. break;
  258. }
  259. }
  260. }
  261. if ( bSubDirectoryFound )
  262. return hFile;
  263. }
  264. }
  265. } while ( hFile );
  266. return 0; // no more sub directories
  267. }