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