path.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  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. #ifdef HAVE_CONFIG_H
  39. # include <config.h>
  40. #endif
  41. /***********************************************************
  42. * Path functions - removing ../ from path
  43. **********************************************************/
  44. #include <windows.h>
  45. #include <stdio.h>
  46. #include <sys/types.h>
  47. #include <sys/stat.h>
  48. #include <io.h> /* For _findfirst */
  49. #include <direct.h> /* For _rmdir */
  50. #include <errno.h>
  51. #include "nt/ntos.h"
  52. DWORD NS_WINAPI
  53. PATH_RemoveRelative ( char * path )
  54. {
  55. char * src;
  56. char * dst;
  57. src = path;
  58. dst = path;
  59. while ( *src ) {
  60. if ( *src == '.' ) {
  61. if ( *(src+1) == '.' ) {
  62. /* strip off the "../" */
  63. src += 2;
  64. /* back off least significant directory */
  65. dst--;
  66. if ( ( *dst == '\\' ) || ( *dst == '/' ) )
  67. *dst--;
  68. while ( dst > path ) {
  69. if ( ( *dst == '\\' ) || ( *dst == '/' ) )
  70. break;
  71. dst--;
  72. }
  73. } else {
  74. // remove single "."
  75. }
  76. } else
  77. *dst++ = *src++;
  78. }
  79. *dst = '\0';
  80. return TRUE;
  81. }
  82. DWORD NS_WINAPI
  83. PATH_ConvertNtSlashesToUnix( LPCTSTR lpszNtPath, LPSTR lpszUnixPath )
  84. {
  85. if ( lpszNtPath == NULL )
  86. return 0;
  87. /* create reverse slashes and escape them */
  88. while ( *lpszNtPath ) {
  89. if ( *lpszNtPath == '\\' )
  90. *lpszUnixPath = '/';
  91. else
  92. *lpszUnixPath = *lpszNtPath;
  93. lpszNtPath++;
  94. lpszUnixPath++;
  95. }
  96. *lpszUnixPath = '\0';
  97. return 0;
  98. }
  99. static DWORD
  100. PATH_DeleteRecursivelyFoundFile ( char * fullFileName, char * path, char * fileName )
  101. {
  102. if ( strcmp ( fileName, "." ) == 0)
  103. return TRUE;
  104. if ( strcmp ( fileName, ".." ) == 0)
  105. return TRUE;
  106. strcpy ( fullFileName, path );
  107. strcat ( fullFileName, "\\" );
  108. strcat ( fullFileName, fileName );
  109. return PATH_DeleteRecursively ( fullFileName );
  110. }
  111. /* if the path specified is a file name, the file is deleted
  112. * If the path specifies a directory, the directory is deleted
  113. */
  114. DWORD NS_WINAPI
  115. PATH_DeleteRecursively ( char * path )
  116. {
  117. int result;
  118. unsigned short fileStatus;
  119. struct _stat buf;
  120. struct _finddata_t fileFound;
  121. long hFile;
  122. DWORD retStatus = TRUE;
  123. char fullFileName[_MAX_PATH];
  124. int error;
  125. /* Check if statistics are valid: */
  126. result = _stat( path, &buf );
  127. if( result != 0 )
  128. return TRUE; // file or directory does not exist
  129. fileStatus = buf.st_mode & _S_IFMT;
  130. /* check if regular file */
  131. if ( fileStatus & _S_IFREG ) {
  132. if ( remove ( path ) == -1 ) {
  133. error = errno;
  134. switch ( error ) {
  135. case ENOENT:
  136. break;
  137. case EACCES:
  138. break;
  139. default:
  140. break;
  141. }
  142. return FALSE;
  143. }
  144. return TRUE;
  145. }
  146. if ( (fileStatus & _S_IFDIR) == 0 )
  147. return FALSE;
  148. /* path contains a directory, delete all files recursively */
  149. /* Find first .c file in current directory */
  150. strcpy ( fullFileName, path );
  151. strcat ( fullFileName, "\\*.*");
  152. if( (hFile = _findfirst( fullFileName, &fileFound )) != -1L ) { /* directory contain files? */
  153. if ( !PATH_DeleteRecursivelyFoundFile ( fullFileName, path, fileFound.name ) )
  154. retStatus = FALSE;
  155. /* Find the rest of the .c files */
  156. while( _findnext( hFile, &fileFound ) == 0 ) {
  157. if ( !PATH_DeleteRecursivelyFoundFile ( fullFileName, path, fileFound.name ) )
  158. retStatus = FALSE;
  159. }
  160. _findclose( hFile );
  161. }
  162. /* remove the directory, now that it is empty */
  163. if ( _rmdir( path ) == -1 )
  164. retStatus = FALSE;
  165. return retStatus;
  166. }
  167. /* GetNextFileInDirectory - gets next file in the directory
  168. * Set hFile to zero, when you call it. The routine returns the
  169. * next value for hFile. When the routine returns NULL, there is
  170. * no more files
  171. *
  172. */
  173. DWORD NS_WINAPI
  174. PATH_GetNextFileInDirectory ( long hFile, char * path, char * lpFileName )
  175. {
  176. int result;
  177. unsigned short fileStatus;
  178. struct _stat buf;
  179. struct _finddata_t fileFound;
  180. DWORD retStatus = TRUE;
  181. char fullFileName[_MAX_PATH];
  182. if ( hFile == 0 ) {
  183. /* Check if statistics are valid: */
  184. result = _stat( path, &buf );
  185. if( result != 0 )
  186. return 0; // file or directory does not exist
  187. fileStatus = buf.st_mode & _S_IFMT;
  188. if ( (fileStatus & _S_IFDIR) == 0 )
  189. return 0;
  190. /* path contains a directory, delete all files recursively */
  191. /* Find first .c file in current directory */
  192. strcpy ( fullFileName, path );
  193. strcat ( fullFileName, "\\*.*");
  194. if( (hFile = _findfirst( fullFileName, &fileFound )) == -1L )
  195. return 0;
  196. if ( ( strcmp ( fileFound.name , "." ) != 0)
  197. && ( strcmp ( fileFound.name , ".." ) != 0) ) {
  198. strcpy ( lpFileName, fileFound.name );
  199. return hFile;
  200. }
  201. }
  202. /* Find the rest of the .c files */
  203. while( _findnext( hFile, &fileFound ) == 0 ) {
  204. if ( ( strcmp ( fileFound.name , "." ) != 0)
  205. && ( strcmp ( fileFound.name , ".." ) != 0) ) {
  206. strcpy ( lpFileName, fileFound.name );
  207. return hFile;
  208. }
  209. }
  210. _findclose( hFile );
  211. return 0;
  212. }
  213. /*---------------------------------------------------------------------------*\
  214. *
  215. * Function: PATH_GetNextSubDirectory
  216. *
  217. * Purpose: Gets next sub directory in the path
  218. *
  219. * Input:
  220. * hFile: set to zero first time called; use return value for subsequent calls
  221. * path: directory containing sub directories
  222. * lpSubDirectoryName: buffer to store sub directorie name
  223. * lpSubDirectoryPrefix: chars to exactly match begining of directory name
  224. *
  225. * Returns:
  226. * hFile to be used on subsequent call (0, if no more directories)
  227. *
  228. * Comments:
  229. \*---------------------------------------------------------------------------*/
  230. DWORD NS_WINAPI
  231. PATH_GetNextSubDirectory( long hFile, char * path, char * lpSubDirectoryName, char * lpSubDirectoryPrefix )
  232. {
  233. int result;
  234. unsigned short fileStatus;
  235. struct _stat buf;
  236. char * subDirectoryPrefix;
  237. char * p;
  238. char fullFileName[_MAX_PATH];
  239. BOOL bSubDirectoryFound;
  240. do {
  241. hFile = PATH_GetNextFileInDirectory ( hFile, path, lpSubDirectoryName );
  242. if ( hFile == 0 )
  243. return 0;
  244. /* Check if file is a directory */
  245. strcpy ( fullFileName, path );
  246. strcat ( fullFileName, "\\" );
  247. strcat ( fullFileName, lpSubDirectoryName );
  248. result = _stat( fullFileName, &buf );
  249. if( result == 0 ) {
  250. fileStatus = buf.st_mode & _S_IFMT;
  251. if ( (fileStatus & _S_IFDIR) == _S_IFDIR ) {
  252. /* check if sub directory matches prefix */
  253. bSubDirectoryFound = TRUE;
  254. if ( lpSubDirectoryPrefix ) {
  255. p = lpSubDirectoryName;
  256. subDirectoryPrefix = lpSubDirectoryPrefix;
  257. while ( *subDirectoryPrefix ) {
  258. if ( *subDirectoryPrefix++ != *p++ ) {
  259. bSubDirectoryFound = FALSE;
  260. break;
  261. }
  262. }
  263. }
  264. if ( bSubDirectoryFound )
  265. return hFile;
  266. }
  267. }
  268. } while ( hFile );
  269. return 0; // no more sub directories
  270. }