fcea30982bd9e5fc271d945d9e38171b06f25543
[blender.git] / source / blender / blenlib / intern / fileops.c
1 /*
2  * blenlib/fileops.h 
3  *
4  * cleaned up (a bit) mar-01 nzc
5  *
6  * More low-level file things.
7  *
8  * $Id$
9  *
10  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version. The Blender
16  * Foundation also sells licenses for use in proprietary software under
17  * the Blender License.  See http://www.blender.org/BL/ for information
18  * about this.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software Foundation,
27  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
28  *
29  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
30  * All rights reserved.
31  *
32  * The Original Code is: all of this file.
33  *
34  * Contributor(s): none yet.
35  *
36  * ***** END GPL/BL DUAL LICENSE BLOCK *****
37  */
38
39 #include <string.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42
43 #ifdef HAVE_CONFIG_H
44 #include <config.h>
45 #endif
46
47 #include "zlib.h"
48
49 #ifdef WIN32
50 #include "BLI_winstuff.h"
51 #include <io.h>
52 #else
53 #include <sys/param.h>
54 #endif
55
56 #include "BLI_blenlib.h"
57 #include "BLI_storage.h"
58 #include "BLI_fileops.h"
59 #include "BLI_callbacks.h"
60
61 #include <sys/types.h>
62 #include <sys/stat.h>
63 #include <fcntl.h>
64
65 #include "BKE_utildefines.h"
66 #include <errno.h>
67
68 /* implementations: */
69 char *first_slash(char *string) {
70         char *ffslash, *fbslash;
71         
72         ffslash= strchr(string, '/');   
73         fbslash= strchr(string, '\\');
74         
75         if (!ffslash) return fbslash;
76         else if (!fbslash) return ffslash;
77         
78         if ((long)ffslash < (long)fbslash) return ffslash;
79         else return fbslash;
80 }
81
82 char *BLI_last_slash(char *string) {
83         char *lfslash, *lbslash;
84         
85         lfslash= strrchr(string, '/');  
86         lbslash= strrchr(string, '\\');
87
88         if (!lfslash) return lbslash; 
89         else if (!lbslash) return lfslash;
90         
91         if ((long)lfslash < (long)lbslash) return lbslash;
92         else return lfslash;
93 }
94
95 /* gzip the file in from and write it to "to". 
96  return -1 if zlib fails, -2 if the originating file does not exist
97  note: will remove the "from" file
98   */
99 int BLI_gzip(char *from, char *to) {
100         char buffer[10240];
101         int file;
102         int readsize = 0;
103         
104         gzFile gzfile = gzopen(to,"wb"); 
105         if (NULL == gzfile) return -1;
106         
107         file = open(from,O_BINARY|O_RDONLY);
108         
109         if ( -1 == file )       return -2;
110
111         while ( 1 )
112         {
113                 readsize = read(file, buffer, 10240);
114                 
115                 if (readsize <= 0) break;
116                 
117                 gzwrite(gzfile,buffer,readsize);
118         }
119         
120         gzclose(gzfile);
121         close(file);
122         
123         remove(from);
124
125         return 0;
126 }
127
128 /* return 1 when file can be written */
129 int BLI_is_writable(char *filename)
130 {
131         int file;
132         
133         file = open(filename, O_BINARY | O_RDWR | O_CREAT | O_TRUNC, 0666);
134         
135         if (file < 0)
136                 return 0;
137         else {
138                 close(file);
139                 return 1;
140         }
141 }
142
143 #ifdef WIN32
144
145 static char str[MAXPATHLEN+12];
146
147 int BLI_delete(char *file, int dir, int recursive) {
148         int err;
149
150         if (recursive) {
151                 callLocalErrorCallBack("Recursive delete is unsupported on Windows");
152                 err= 1;
153         } else if (dir) {
154                 err= !RemoveDirectory(file);
155                 if (err) printf ("Unable to remove directory");
156         } else {
157                 err= !DeleteFile(file);
158                 if (err) callLocalErrorCallBack("Unable to delete file");
159         }
160
161         return err;
162 }
163
164 int BLI_touch(char *file) {
165         callLocalErrorCallBack("Touching files is unsupported on Windows");
166         
167         return 1;
168 }
169
170 int BLI_move(char *file, char *to) {
171         int err;
172
173         // windows doesn't support moveing to a directory
174         // it has to be 'mv filename filename' and not
175         // 'mv filename destdir'
176
177         strcpy(str, to);
178         // points 'to' to a directory ?
179         if (BLI_last_slash(str) == (str + strlen(str) - 1)) {
180                 if (BLI_last_slash(file) != NULL) {
181                         strcat(str, BLI_last_slash(file) + 1);
182                 }
183         }
184
185         err= !MoveFile(file, str);
186         if (err) {
187                 callLocalErrorCallBack("Unable to move file");
188                 printf(" Move from '%s' to '%s' failed\n", file, str);
189         }
190
191         return err;
192 }
193
194
195 int BLI_copy_fileops(char *file, char *to) {
196         int err;
197
198         // windows doesn't support copying to a directory
199         // it has to be 'cp filename filename' and not
200         // 'cp filename destdir'
201
202         strcpy(str, to);
203         // points 'to' to a directory ?
204         if (BLI_last_slash(str) == (str + strlen(str) - 1)) {
205                 if (BLI_last_slash(file) != NULL) {
206                         strcat(str, BLI_last_slash(file) + 1);
207                 }
208         }
209
210         err= !CopyFile(file,str,FALSE);
211         
212         if (err) {
213                 callLocalErrorCallBack("Unable to copy file!");
214                 printf(" Copy from '%s' to '%s' failed\n", file, str);
215         }
216
217         return err;
218 }
219
220 int BLI_link(char *file, char *to) {
221         callLocalErrorCallBack("Linking files is unsupported on Windows");
222         
223         return 1;
224 }
225
226 int BLI_backup(char *file, char *from, char *to) {
227         callLocalErrorCallBack("Backing up files is unsupported on Windows");
228         
229         return 1;
230 }
231
232 int BLI_exists(char *file) {
233         return (GetFileAttributes(file) != 0xFFFFFFFF);
234 }
235
236 void BLI_recurdir_fileops(char *dirname) {
237         char *lslash;
238         char tmp[MAXPATHLEN];
239         
240         // First remove possible slash at the end of the dirname.
241         // This routine otherwise tries to create
242         // blah1/blah2/ (with slash) after creating
243         // blah1/blah2 (without slash)
244
245         strcpy(tmp, dirname);
246         lslash= BLI_last_slash(tmp);
247
248         if (lslash == tmp + strlen(tmp) - 1) {
249                 *lslash = 0;
250         }
251         
252         if (BLI_exists(tmp)) return;
253                 
254         lslash= BLI_last_slash(tmp);
255         if (lslash) {
256                         /* Split about the last slash and recurse */    
257                 *lslash = 0;
258                 BLI_recurdir_fileops(tmp);
259         }
260         
261         if(dirname[0]) /* patch, this recursive loop tries to create a nameless directory */
262                 if (!CreateDirectory(dirname, NULL))
263                         callLocalErrorCallBack("Unable to create directory\n");
264 }
265
266 int BLI_rename(char *from, char *to) {
267         if (!BLI_exists(from)) return 0;
268
269         if (BLI_exists(to))
270                 if(BLI_delete(to, 0, 0)) return 1;
271                 
272         return rename(from, to);
273 }
274
275 #else /* The sane UNIX world */
276
277 /*
278  * but the sane UNIX world is tied to the interface, and the system
279  * timer, and... We implement a callback mechanism. The system will
280  * have to initialise the callback before the functions will work!
281  * */
282 static char str[MAXPATHLEN+12];
283
284 int BLI_delete(char *file, int dir, int recursive) 
285 {
286         if(strchr(file, '"')) {
287                 printf("Error: not deleted file %s because of quote!\n", file);
288         }
289         else {
290                 if (recursive) sprintf(str, "/bin/rm -rf \"%s\"", file);
291                 else if (dir) sprintf(str, "/bin/rmdir \"%s\"", file);
292                 else sprintf(str, "/bin/rm -f \"%s\"", file);
293
294                 return system(str);
295         }
296         return -1;
297 }
298
299 int BLI_touch(char *file) 
300 {
301         
302         if( BLI_exists("/bin/touch") )
303                 sprintf(str, "/bin/touch %s", file);
304         else
305                 sprintf(str, "/usr/bin/touch %s", file);
306         
307         return system(str);
308 }
309
310 int BLI_move(char *file, char *to) {
311         sprintf(str, "/bin/mv -f \"%s\" \"%s\"", file, to);
312
313         return system(str);
314 }
315
316 int BLI_copy_fileops(char *file, char *to) {
317         sprintf(str, "/bin/cp -rf \"%s\" \"%s\"", file, to);
318
319         return system(str);
320 }
321
322 int BLI_link(char *file, char *to) {
323         sprintf(str, "/bin/ln -f \"%s\" \"%s\"", file, to);
324         
325         return system(str);
326 }
327
328 int BLI_backup(char *file, char *from, char *to) {
329         sprintf(str, "/bin/su root -c 'cd %s; /bin/tar cf - \"%s\" | (/bin/cd %s; /bin/tar xf -)'", from, file, to);
330         
331         return system(str);
332 }
333
334 int BLI_exists(char *file) {
335         return BLI_exist(file);
336 }
337
338 void BLI_recurdir_fileops(char *dirname) {
339         char *lslash;
340         char tmp[MAXPATHLEN];
341                 
342         if (BLI_exists(dirname)) return;
343
344         strcpy(tmp, dirname);
345                 
346         lslash= BLI_last_slash(tmp);
347         if (lslash) {
348                         /* Split about the last slash and recurse */    
349                 *lslash = 0;
350                 BLI_recurdir_fileops(tmp);
351         }
352
353         mkdir(dirname, 0777);
354 }
355
356 int BLI_rename(char *from, char *to) {
357         if (!BLI_exists(from)) return 0;
358         
359         if (BLI_exists(to))     if(BLI_delete(to, 0, 0)) return 1;
360                 
361         return rename(from, to);
362 }
363
364 #endif