Errors in saving runtime, and fileops in file window; files were copied
[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
42 #ifdef HAVE_CONFIG_H
43 #include <config.h>
44 #endif
45
46 #ifdef WIN32
47 #include "BLI_winstuff.h"
48 #else
49 #include <sys/param.h>
50 #endif
51
52 #include "BLI_blenlib.h"
53 #include "BLI_storage.h"
54 #include "BLI_fileops.h"
55 #include "BLI_callbacks.h"
56
57 /* implementations: */
58 char *first_slash(char *string) {
59         char *ffslash, *fbslash;
60         
61         ffslash= strchr(string, '/');   
62         fbslash= strchr(string, '\\');
63         
64         if (!ffslash) return fbslash;
65         else if (!fbslash) return ffslash;
66         
67         if ((int)ffslash < (int)fbslash) return ffslash;
68         else return fbslash;
69 }
70
71 char *BLI_last_slash(char *string) {
72         char *lfslash, *lbslash;
73         
74         lfslash= strrchr(string, '/');  
75         lbslash= strrchr(string, '\\');
76
77         if (!lfslash) return lbslash; 
78         else if (!lbslash) return lfslash;
79         
80         if ((int)lfslash < (int)lbslash) return lbslash;
81         else return lfslash;
82 }
83
84 #ifdef WIN32
85
86 static char str[MAXPATHLEN+12];
87
88 int BLI_delete(char *file, int dir, int recursive) {
89         int err;
90
91         if (recursive) {
92                 callLocalErrorCallBack("Recursive delete is unsupported on Windows");
93                 err= 1;
94         } else if (dir) {
95                 err= !RemoveDirectory(file);
96                 if (err) printf ("Unable to remove directory");
97         } else {
98                 err= !DeleteFile(file);
99                 if (err) callLocalErrorCallBack("Unable to delete file");
100         }
101
102         return err;
103 }
104
105 int BLI_touch(char *file) {
106         callLocalErrorCallBack("Touching files is unsupported on Windows");
107         
108         return 1;
109 }
110
111 int BLI_move(char *file, char *to) {
112         int err;
113
114         // windows doesn't support moveing to a directory
115         // it has to be 'mv filename filename' and not
116         // 'mv filename destdir'
117
118         strcpy(str, to);
119         // points 'to' to a directory ?
120         if (BLI_last_slash(str) == (str + strlen(str) - 1)) {
121                 if (BLI_last_slash(file) != NULL) {
122                         strcat(str, BLI_last_slash(file) + 1);
123                 }
124         }
125
126         err= !MoveFile(file, str);
127         if (err) {
128                 callLocalErrorCallBack("Unable to move file");
129                 printf(" Move from '%s' to '%s' failed\n", file, str);
130         }
131
132         return err;
133 }
134
135
136 int BLI_copy_fileops(char *file, char *to) {
137         int err;
138
139         // windows doesn't support copying to a directory
140         // it has to be 'cp filename filename' and not
141         // 'cp filename destdir'
142
143         strcpy(str, to);
144         // points 'to' to a directory ?
145         if (BLI_last_slash(str) == (str + strlen(str) - 1)) {
146                 if (BLI_last_slash(file) != NULL) {
147                         strcat(str, BLI_last_slash(file) + 1);
148                 }
149         }
150
151         err= !CopyFile(file,str,FALSE);
152         
153         if (err) {
154                 callLocalErrorCallBack("Unable to copy file!");
155                 printf(" Copy from '%s' to '%s' failed\n", file, str);
156         }
157
158         return err;
159 }
160
161 int BLI_link(char *file, char *to) {
162         callLocalErrorCallBack("Linking files is unsupported on Windows");
163         
164         return 1;
165 }
166
167 int BLI_backup(char *file, char *from, char *to) {
168         callLocalErrorCallBack("Backing up files is unsupported on Windows");
169         
170         return 1;
171 }
172
173 int BLI_exists(char *file) {
174         return (GetFileAttributes(file) != 0xFFFFFFFF);
175 }
176
177 void BLI_recurdir_fileops(char *dirname) {
178         char *lslash;
179         char tmp[MAXPATHLEN];
180         
181         // First remove possible slash at the end of the dirname.
182         // This routine otherwise tries to create
183         // blah1/blah2/ (with slash) after creating
184         // blah1/blah2 (without slash)
185
186         strcpy(tmp, dirname);
187         lslash= BLI_last_slash(tmp);
188
189         if (lslash == tmp + strlen(tmp) - 1) {
190                 *lslash = 0;
191         }
192         
193         if (BLI_exists(tmp)) return;
194                 
195         lslash= BLI_last_slash(tmp);
196         if (lslash) {
197                         /* Split about the last slash and recurse */    
198                 *lslash = 0;
199                 BLI_recurdir_fileops(tmp);
200         }
201         
202         if(dirname[0]) /* patch, this recursive loop tries to create a nameless directory */
203                 if (!CreateDirectory(dirname, NULL))
204                         callLocalErrorCallBack("Unable to create directory\n");
205 }
206
207 int BLI_rename(char *from, char *to) {
208         if (!BLI_exists(from)) return 0;
209
210         if (BLI_exists(to))
211                 if(BLI_delete(to, 0, 0)) return 1;
212                 
213         return rename(from, to);
214 }
215
216 #else /* The sane UNIX world */
217
218 /*
219  * but the sane UNIX world is tied to the interface, and the system
220  * timer, and... We implement a callback mechanism. The system will
221  * have to initialise the callback before the functions will work!
222  * */
223 static char str[MAXPATHLEN+12];
224
225 int BLI_delete(char *file, int dir, int recursive) 
226 {
227         if(strchr(file, '"')) {
228                 printf("Error: not deleted file %s because of quote!\n", file);
229         }
230         else {
231                 if (recursive) sprintf(str, "/bin/rm -rf \"%s\"", file);
232                 else if (dir) sprintf(str, "/bin/rmdir \"%s\"", file);
233                 else sprintf(str, "/bin/rm -f \"%s\"", file);
234
235                 return system(str);
236         }
237         return -1;
238 }
239
240 int BLI_touch(char *file) 
241 {
242         
243         if( BLI_exists("/bin/touch") )
244                 sprintf(str, "/bin/touch %s", file);
245         else
246                 sprintf(str, "/usr/bin/touch %s", file);
247         
248         return system(str);
249 }
250
251 int BLI_move(char *file, char *to) {
252         sprintf(str, "/bin/mv -f \"%s\" \"%s\"", file, to);
253
254         return system(str);
255 }
256
257 int BLI_copy_fileops(char *file, char *to) {
258         sprintf(str, "/bin/cp -rf \"%s\" \"%s\"", file, to);
259
260         return system(str);
261 }
262
263 int BLI_link(char *file, char *to) {
264         sprintf(str, "/bin/ln -f \"%s\" \"%s\"", file, to);
265         
266         return system(str);
267 }
268
269 int BLI_backup(char *file, char *from, char *to) {
270         sprintf(str, "/bin/su root -c 'cd %s; /bin/tar cf - \"%s\" | (/bin/cd %s; /bin/tar xf -)'", from, file, to);
271         
272         return system(str);
273 }
274
275 int BLI_exists(char *file) {
276         return BLI_exist(file);
277 }
278
279 void BLI_recurdir_fileops(char *dirname) {
280         char *lslash;
281         char tmp[MAXPATHLEN];
282                 
283         if (BLI_exists(dirname)) return;
284
285         strcpy(tmp, dirname);
286                 
287         lslash= BLI_last_slash(tmp);
288         if (lslash) {
289                         /* Split about the last slash and recurse */    
290                 *lslash = 0;
291                 BLI_recurdir_fileops(tmp);
292         }
293
294         mkdir(dirname, 0777);
295 }
296
297 int BLI_rename(char *from, char *to) {
298         if (!BLI_exists(from)) return 0;
299         
300         if (BLI_exists(to))     if(BLI_delete(to, 0, 0)) return 1;
301                 
302         return rename(from, to);
303 }
304
305 #endif