2 Copyright (c) 2001, Loki software, inc.
5 Redistribution and use in source and binary forms, with or without modification,
6 are permitted provided that the following conditions are met:
8 Redistributions of source code must retain the above copyright notice, this list
9 of conditions and the following disclaimer.
11 Redistributions in binary form must reproduce the above copyright notice, this
12 list of conditions and the following disclaimer in the documentation and/or
13 other materials provided with the distribution.
15 Neither the name of Loki software nor the names of its contributors may be used
16 to endorse or promote products derived from this software without specific prior
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
23 DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 // Leonardo Zide (leo@lokigames.com)
38 #include "qsysprintf.h"
41 #if defined ( __linux__ ) || defined ( __APPLE__ )
46 #include <sys/types.h>
51 bool radCopyFile( const char *lpExistingFileName, const char *lpNewFileName, bool fatal_on_error ){
56 char realsrc[PATH_MAX], realdest[PATH_MAX];
58 realpath( lpExistingFileName, realsrc );
59 realpath( lpNewFileName, realdest );
61 src = fopen( realsrc, "rb" );
63 if ( fatal_on_error ) {
64 Error( "Failed to open source for copy: %s\n", realsrc );
66 Sys_Printf( "Failed to open source for copy: %s\n", realsrc );
69 dst = fopen( realdest, "wb" );
71 if ( fatal_on_error ) {
72 Error( "Failed to open destination for copy: %s\n", realdest );
74 Sys_Printf( "Failed to open destination for copy: %s\n", realdest );
79 fseek( src, 0, SEEK_END );
85 if ( fread( buf, l, 1, src ) == 1 ) {
86 if ( fwrite( buf, l, 1, dst ) == 1 ) {
92 if ( fatal_on_error ) {
93 Error( "short read or short write while copying %s to %s\n", realsrc, realdest );
95 Sys_Printf( "short read or short write while copying %s to %s\n", realsrc, realdest );
105 bool radCreateDirectory( const char *directory, bool fatal_on_error ) {
106 if ( mkdir( directory, 0777 ) >= 0 ) {
109 if ( fatal_on_error ) {
110 Error( "mkdir %s failed - check your permissions", directory );
112 Sys_Printf( "mkdir %s failed - check your permissions\n", directory );
116 int GetFullPathName( const char *lpFileName, int nBufferLength, char *lpBuffer, char **lpFilePart ){
117 if ( lpFileName[0] == '/' ) {
118 strcpy( lpBuffer, lpFileName );
119 *lpFilePart = strrchr( lpBuffer, '/' );
120 return strlen( lpBuffer );
123 if ( getcwd( lpBuffer, nBufferLength ) == NULL ) {
127 strcat( lpBuffer, "/" );
128 *lpFilePart = lpBuffer + strlen( lpBuffer );
129 strcat( lpBuffer, lpFileName );
131 char *scr = lpBuffer, *dst = lpBuffer;
132 for ( int i = 0; ( i < nBufferLength ) && ( *scr != 0 ); i++ )
134 if ( *scr == '/' && *( scr + 1 ) == '.' && *( scr + 2 ) == '.' ) {
136 while ( dst != lpBuffer && *dst != '/' )
149 return strlen( lpBuffer );
152 EPathCheck CheckFile( const char *path ) {
154 if ( stat( path, &sbuf ) == -1 ) {
157 if ( S_ISDIR( sbuf.st_mode ) ) {
158 return PATH_DIRECTORY;
163 FindFiles::FindFiles( const char *_directory ) {
164 findHandle = opendir( _directory );
167 FindFiles::~FindFiles() {
168 if ( findHandle != NULL ) {
169 closedir( findHandle );
174 const char* FindFiles::NextFile() {
177 if ( findHandle == NULL ) {
181 d = readdir( findHandle );
190 FindFiles::FindFiles( const char *_directory ) {
192 directory = _directory;
193 if ( directory.GetLength() > 0 ) {
194 endChar = directory.GetAt( directory.GetLength() - 1 );
195 if ( !( endChar == '/' || endChar == '\\' ) ) {
196 // We're only using '/' as the path separator throughout this code, not '\'.
197 // However, I'd hate to see the code silently fail due to a trailing '\', so
198 // I added the check for it.
203 findHandle = INVALID_HANDLE_VALUE;
206 FindFiles::~FindFiles() {
207 if ( findHandle != INVALID_HANDLE_VALUE ) {
208 FindClose( findHandle );
209 findHandle = INVALID_HANDLE_VALUE;
213 const char* FindFiles::NextFile() {
214 if ( findHandle == INVALID_HANDLE_VALUE ) {
215 findHandle = FindFirstFile( directory.GetBuffer(), &findFileData );
216 if ( findHandle == INVALID_HANDLE_VALUE ) {
219 return findFileData.cFileName;
221 if ( FindNextFile( findHandle, &findFileData ) == 0 ) {
222 FindClose( findHandle );
223 findHandle = INVALID_HANDLE_VALUE;
226 return findFileData.cFileName;
229 EPathCheck CheckFile( const char *path ) {
231 if ( _stat( path, &sbuf ) == -1 ) {
234 if ( ( sbuf.st_mode & _S_IFDIR ) != 0 ) {
235 return PATH_DIRECTORY;
240 bool radCreateDirectory( const char *directory, bool fatal_on_error ) {
241 if ( CreateDirectory( directory, NULL ) ) {
244 if ( fatal_on_error ) {
245 Error( "mkdir %s failed - check your permissions", directory );
247 Sys_Printf( "mkdir %s failed - check your permissions\n", directory );
251 bool radCopyFile( const char *lpExistingFileName, const char *lpNewFileName, bool fatal_on_error ) {
252 if ( CopyFile( lpExistingFileName, lpNewFileName, FALSE ) ) {
255 if ( fatal_on_error ) {
256 Error( "copy %s %s failed - check your permissions", lpExistingFileName, lpNewFileName );
258 Sys_Printf( "copy %s %s failed - check your permissions\n", lpExistingFileName, lpNewFileName );
264 bool radCopyTree( const char *source, const char *dest, bool fatal_on_error ) {
268 FindFiles fileScan( source );
270 while ( ( dirname = fileScan.NextFile() ) != NULL ) {
271 if ( strcmp( dirname, "." ) == 0 || strcmp( dirname, ".." ) == 0 ) {
274 if ( strcmp( dirname, ".svn" ) == 0 ) {
283 switch ( CheckFile( srcEntry.GetBuffer() ) ) {
285 if ( fatal_on_error ) {
286 Error( "%s does not exist. check your permissions", srcEntry.GetBuffer() );
289 case PATH_DIRECTORY: {
290 if ( CheckFile( dstEntry.GetBuffer() ) == PATH_FAIL ) {
291 Sys_Printf( "Create directory %s\n", dstEntry.GetBuffer() );
292 if ( !radCreateDirectory( dstEntry.GetBuffer(), fatal_on_error ) ) {
297 ret = radCopyTree( srcEntry.GetBuffer(), dstEntry.GetBuffer(), fatal_on_error );
304 Sys_Printf( "Copy %s -> %s\n", srcEntry.GetBuffer(), dstEntry.GetBuffer() );
305 bool ret = radCopyFile( srcEntry.GetBuffer(), dstEntry.GetBuffer(), fatal_on_error );