]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - radiant/missing.cpp
fix
[xonotic/netradiant.git] / radiant / missing.cpp
1 /*
2 Copyright (c) 2001, Loki software, inc.
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without modification,
6 are permitted provided that the following conditions are met:
7
8 Redistributions of source code must retain the above copyright notice, this list
9 of conditions and the following disclaimer.
10
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.
14
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
17 written permission.
18
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.
29 */
30
31 //
32 // Missing functions
33 //
34 // Leonardo Zide (leo@lokigames.com)
35 //
36
37 #include "missing.h"
38 #include "qsysprintf.h"
39
40 #if defined (__linux__) || defined (__APPLE__)
41
42 #include <stdio.h>
43 #include <unistd.h>
44 #include <sys/time.h>
45 #include <sys/types.h>
46 #include <sys/stat.h>
47 #include <stdlib.h>
48 #include <dirent.h>
49
50 bool radCopyFile(const char *lpExistingFileName, const char *lpNewFileName)
51 {
52   FILE *src, *dst;
53   void* buf;
54   int l;
55   bool ret = false;
56   char realsrc[PATH_MAX], realdest[PATH_MAX];
57
58   realpath (lpExistingFileName, realsrc);
59   realpath (lpNewFileName, realdest);
60
61   src = fopen (realsrc, "rb");
62   if ( !src ) {
63     return false;
64   }
65   dst = fopen (realdest, "wb");
66   if (!dst) {
67     fclose (src);
68     return false;
69   }
70
71   fseek (src, 0, SEEK_END);
72   l = ftell (src);
73   rewind (src);
74   buf = g_malloc (l);
75
76   if (buf != NULL)
77     if (fread (buf, l, 1, src) == 1)
78       if (fwrite (buf, l, 1, dst) == 1)
79         ret = true;
80
81   g_free (buf);
82   fclose (src);
83   fclose (dst);
84
85   return ret;
86 }
87
88 bool radCreateDirectory( const char *directory ) {
89         if ( mkdir( directory, 0777 ) == -1 ) {
90                 Sys_Printf( "mkdir %s failed\n", directory );
91                 return false;
92         }
93         return true;
94 }
95
96 int GetFullPathName(const char *lpFileName, int nBufferLength, char *lpBuffer, char **lpFilePart)
97 {
98   if (lpFileName[0] == '/')
99   {
100     strcpy (lpBuffer, lpFileName);
101     *lpFilePart = strrchr (lpBuffer, '/');
102     return strlen (lpBuffer);
103   }
104
105   if (getcwd (lpBuffer, nBufferLength) == NULL)
106     return 0;
107
108   strcat (lpBuffer, "/");
109   *lpFilePart = lpBuffer + strlen (lpBuffer);
110   strcat (lpBuffer, lpFileName);
111
112   char *scr = lpBuffer, *dst = lpBuffer;
113   for (int i = 0; (i < nBufferLength) && (*scr != 0); i++)
114   {
115     if (*scr == '/' && *(scr+1) == '.' && *(scr+2) == '.')
116     {
117       scr += 4;
118       while (dst != lpBuffer && *dst != '/')
119       {
120         dst--;
121         i--;
122       }
123     }
124
125     *dst = *scr;
126
127     scr++; dst++;
128   }
129   *dst = 0;
130
131   return strlen (lpBuffer);
132 }
133
134 EPathCheck CheckFile( const char *path ) {
135         struct stat             sbuf;
136         if ( stat( path, &sbuf ) == -1 ) {
137                 return PATH_FAIL;
138         }
139         if ( S_ISDIR( sbuf.st_mode ) ) {
140                 return PATH_DIRECTORY;
141         }
142         return PATH_FILE;
143 }
144
145 FindFiles::FindFiles( const char *_directory ) {
146         findHandle = opendir( _directory );
147 }
148
149 FindFiles::~FindFiles() {
150         if ( findHandle != NULL ) {
151                 closedir( findHandle );
152         }
153 }
154
155 const char* FindFiles::NextFile() {
156         struct dirent *d;
157
158         if ( findHandle == NULL )
159                 return NULL;
160
161         d = readdir( findHandle );
162         if ( d )
163                 return d->d_name;
164         return NULL;
165 }
166
167 #else
168
169 FindFiles::FindFiles( const char *_directory ) {
170         directory = _directory;
171         directory += '*';
172         findHandle = INVALID_HANDLE_VALUE;
173 }
174
175 FindFiles::~FindFiles() {
176         if ( findHandle != NULL ) {
177                 FindClose( findHandle );
178         }
179 }
180
181 const char* FindFiles::NextFile() {
182         if ( findHandle == INVALID_HANDLE_VALUE ) {
183                 findHandle = FindFirstFile( directory.GetBuffer(), &findFileData );
184                 if ( findHandle == INVALID_HANDLE_VALUE ) {
185                         return NULL;
186                 }
187                 return findFileData.cFileName;
188         }
189         if ( FindNextFile( findHandle, &findFileData ) == 0 ) {
190                 FindClose( findHandle );
191                 return NULL;
192         }
193         return findFileData.cFileName;
194 }
195
196 EPathCheck CheckFile( const char *path ) {
197         struct _stat sbuf;
198         if ( _stat( path, &sbuf ) == -1 ) {
199                 return PATH_FAIL;
200         }
201         if ( ( sbuf.st_mode & _S_IFDIR ) != 0 ) {
202                 return PATH_DIRECTORY;
203         }
204         return PATH_FILE;
205 }
206
207 bool radCreateDirectory( const char *directory ) {
208         return CreateDirectory( directory, NULL );
209 }
210
211 bool radCopyFile( const char *lpExistingFileName, const char *lpNewFileName ) {
212         return CopyFile( lpExistingFileName, lpNewFileName, FALSE );
213 }
214
215 #endif
216
217 bool CopyTree( const char *source, const char *dest ) {
218         Str                             srcEntry;
219         Str                             dstEntry;
220         const char              *dirname;
221         FindFiles               fileScan( source );
222
223         while ( ( dirname = fileScan.NextFile() ) != NULL ) {
224                 if ( strcmp( dirname, "." ) == 0 || strcmp( dirname, ".." ) == 0 ) {
225                         continue;
226                 }
227                 if ( strcmp( dirname, ".svn" ) == 0 ) {
228                         continue;
229                 }
230                 srcEntry = source;
231                 srcEntry += "/";
232                 srcEntry += dirname;
233                 dstEntry = dest;
234                 dstEntry += "/";
235                 dstEntry += dirname;
236                 switch ( CheckFile( srcEntry.GetBuffer() ) ) {
237                         case PATH_DIRECTORY: {
238                                 if ( CheckFile( dstEntry.GetBuffer() ) == PATH_FAIL ) {
239                                         radCreateDirectory( dstEntry.GetBuffer() );
240                                 }
241                                 bool ret;
242                                 ret = CopyTree( srcEntry.GetBuffer(), dstEntry.GetBuffer() );
243                                 if ( !ret ) {
244                                         return false;
245                                 }
246                                 break;
247                         }
248                         case PATH_FILE: {
249                                 Sys_Printf( "copy %s -> %s\n", srcEntry.GetBuffer(), dstEntry.GetBuffer() );
250                                 bool ret = radCopyFile( srcEntry.GetBuffer(), dstEntry.GetBuffer() );
251                                 if ( !ret ) {
252                                         return false;
253                                 }
254                                 break;
255                         }
256                 }
257         }
258         return true;
259 }