remove unused includes for blenlib, left ifdef's for non linux os's alone.
[blender.git] / source / blender / blenlib / intern / fileops.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include <string.h>
31 #include <stdio.h>
32
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36
37 #include <errno.h>
38
39 #include "zlib.h"
40
41 #ifdef WIN32
42 #include <io.h>
43 #include "BLI_winstuff.h"
44 #else
45 #include <unistd.h> // for read close
46 #include <sys/param.h>
47 #endif
48
49
50 #include "BLI_blenlib.h"
51
52 #include "BKE_utildefines.h"
53
54 #include "BLO_sys_types.h" // for intptr_t support
55
56 /* implementations: */
57 char *first_slash(char *string) {
58         char *ffslash, *fbslash;
59         
60         ffslash= strchr(string, '/');   
61         fbslash= strchr(string, '\\');
62         
63         if (!ffslash) return fbslash;
64         else if (!fbslash) return ffslash;
65         
66         if ((intptr_t)ffslash < (intptr_t)fbslash) return ffslash;
67         else return fbslash;
68 }
69
70 char *BLI_last_slash(const char *string) {
71         char *lfslash, *lbslash;
72         
73         lfslash= strrchr(string, '/');  
74         lbslash= strrchr(string, '\\');
75
76         if (!lfslash) return lbslash; 
77         else if (!lbslash) return lfslash;
78         
79         if ((intptr_t)lfslash < (intptr_t)lbslash) return lbslash;
80         else return lfslash;
81 }
82
83 static const char *last_slash_len(const char *string, int len) {
84         int a;
85
86         for(a=len-1; a>=0; a--)
87                 if(string[a] == '/' || string[a] == '\\')
88                         return &string[a];
89         
90         return NULL;
91 }
92
93 const char *BLI_short_filename(const char *string) {
94         const char *ls, *lls;
95         
96         ls= last_slash_len(string, strlen(string));
97         if(!ls)
98                 return string;
99         
100         lls= last_slash_len(string, ls-string);
101
102         if(lls)
103                 return lls+1;
104         else
105                 return ls+1;
106 }
107
108 /* adds a slash if there isnt one there alredy */
109 int BLI_add_slash(char *string) {
110         int len = strlen(string);
111 #ifdef WIN32
112         if (len==0 || string[len-1]!='\\') {
113                 string[len] = '\\';
114                 string[len+1] = '\0';
115                 return len+1;
116         }
117 #else
118         if (len==0 || string[len-1]!='/') {
119                 string[len] = '/';
120                 string[len+1] = '\0';
121                 return len+1;
122         }
123 #endif
124         return len;
125 }
126
127 /* removes a slash if there is one */
128 void BLI_del_slash(char *string) {
129         int len = strlen(string);
130         while (len) {
131 #ifdef WIN32
132                 if (string[len-1]=='\\') {
133 #else
134                 if (string[len-1]=='/') {
135 #endif
136                         string[len-1] = '\0';
137                         len--;
138                 } else {
139                         break;
140                 }
141         }
142 }
143
144 /* gzip the file in from and write it to "to". 
145  return -1 if zlib fails, -2 if the originating file does not exist
146  note: will remove the "from" file
147   */
148 int BLI_gzip(char *from, char *to) {
149         char buffer[10240];
150         int file;
151         int readsize = 0;
152         int rval= 0, err;
153         gzFile gzfile;
154         
155         gzfile = gzopen(to, "wb"); 
156         if(gzfile == NULL)
157                 return -1;
158         
159         file = open(from, O_BINARY|O_RDONLY);
160         if(file < 0)
161                 return -2;
162
163         while(1) {
164                 readsize = read(file, buffer, 10240);
165
166                 if(readsize < 0) {
167                         rval= -2; /* error happened in reading */
168                         fprintf(stderr, "Error reading file %s: %s.\n", from, strerror(errno));
169                         break;
170                 }
171                 else if(readsize == 0)
172                         break; /* done reading */
173                 
174                 if(gzwrite(gzfile, buffer, readsize) <= 0) {
175                         rval= -1; /* error happened in writing */
176                         fprintf(stderr, "Error writing gz file %s: %s.\n", to, gzerror(gzfile, &err));
177                         break;
178                 }
179         }
180         
181         gzclose(gzfile);
182         close(file);
183
184         return rval;
185 }
186
187 /* return 1 when file can be written */
188 int BLI_is_writable(char *filename)
189 {
190         int file;
191         
192         /* first try to open without creating */
193         file = open(filename, O_BINARY | O_RDWR, 0666);
194         
195         if (file < 0) {
196                 /* now try to open and create. a test without actually
197                  * creating a file would be nice, but how? */
198                 file = open(filename, O_BINARY | O_RDWR | O_CREAT, 0666);
199                 
200                 if(file < 0) {
201                         return 0;
202                 }
203                 else {
204                         /* success, delete the file we create */
205                         close(file);
206                         BLI_delete(filename, 0, 0);
207                         return 1;
208                 }
209         }
210         else {
211                 close(file);
212                 return 1;
213         }
214 }
215
216 int BLI_touch(const char *file)
217 {
218    FILE *f = fopen(file,"r+b");
219    if (f != NULL) {
220                 char c = getc(f);
221                 rewind(f);
222                 putc(c,f);
223         } else {
224            f = fopen(file,"wb");
225         }
226         if (f) {
227                 fclose(f);
228                 return 1;
229         }
230         return 0;
231 }
232
233 #ifdef WIN32
234
235 static char str[MAXPATHLEN+12];
236
237 int BLI_delete(char *file, int dir, int recursive) {
238         int err;
239
240         if (recursive) {
241                 callLocalErrorCallBack("Recursive delete is unsupported on Windows");
242                 err= 1;
243         } else if (dir) {
244                 err= !RemoveDirectory(file);
245                 if (err) printf ("Unable to remove directory");
246         } else {
247                 err= !DeleteFile(file);
248                 if (err) callLocalErrorCallBack("Unable to delete file");
249         }
250
251         return err;
252 }
253
254 int BLI_move(char *file, char *to) {
255         int err;
256
257         // windows doesn't support moveing to a directory
258         // it has to be 'mv filename filename' and not
259         // 'mv filename destdir'
260
261         strcpy(str, to);
262         // points 'to' to a directory ?
263         if (BLI_last_slash(str) == (str + strlen(str) - 1)) {
264                 if (BLI_last_slash(file) != NULL) {
265                         strcat(str, BLI_last_slash(file) + 1);
266                 }
267         }
268
269         err= !MoveFile(file, str);
270         if (err) {
271                 callLocalErrorCallBack("Unable to move file");
272                 printf(" Move from '%s' to '%s' failed\n", file, str);
273         }
274
275         return err;
276 }
277
278
279 int BLI_copy_fileops(char *file, char *to) {
280         int err;
281
282         // windows doesn't support copying to a directory
283         // it has to be 'cp filename filename' and not
284         // 'cp filename destdir'
285
286         strcpy(str, to);
287         // points 'to' to a directory ?
288         if (BLI_last_slash(str) == (str + strlen(str) - 1)) {
289                 if (BLI_last_slash(file) != NULL) {
290                         strcat(str, BLI_last_slash(file) + 1);
291                 }
292         }
293
294         err= !CopyFile(file,str,FALSE);
295         
296         if (err) {
297                 callLocalErrorCallBack("Unable to copy file!");
298                 printf(" Copy from '%s' to '%s' failed\n", file, str);
299         }
300
301         return err;
302 }
303
304 int BLI_link(char *file, char *to) {
305         callLocalErrorCallBack("Linking files is unsupported on Windows");
306         
307         return 1;
308 }
309
310 int BLI_exists(char *file) {
311         return (GetFileAttributes(file) != 0xFFFFFFFF);
312 }
313
314 void BLI_recurdir_fileops(char *dirname) {
315         char *lslash;
316         char tmp[MAXPATHLEN];
317         
318         // First remove possible slash at the end of the dirname.
319         // This routine otherwise tries to create
320         // blah1/blah2/ (with slash) after creating
321         // blah1/blah2 (without slash)
322
323         strcpy(tmp, dirname);
324         lslash= BLI_last_slash(tmp);
325
326         if (lslash == tmp + strlen(tmp) - 1) {
327                 *lslash = 0;
328         }
329         
330         if (BLI_exists(tmp)) return;
331                 
332         lslash= BLI_last_slash(tmp);
333         if (lslash) {
334                         /* Split about the last slash and recurse */    
335                 *lslash = 0;
336                 BLI_recurdir_fileops(tmp);
337         }
338         
339         if(dirname[0]) /* patch, this recursive loop tries to create a nameless directory */
340                 if (!CreateDirectory(dirname, NULL))
341                         callLocalErrorCallBack("Unable to create directory\n");
342 }
343
344 int BLI_rename(char *from, char *to) {
345         if (!BLI_exists(from)) return 0;
346
347         /* make sure the filenames are different (case insensitive) before removing */
348         if (BLI_exists(to) && BLI_strcasecmp(from, to))
349                 if(BLI_delete(to, 0, 0)) return 1;
350
351         return rename(from, to);
352 }
353
354 #else /* The sane UNIX world */
355
356 /*
357  * but the sane UNIX world is tied to the interface, and the system
358  * timer, and... We implement a callback mechanism. The system will
359  * have to initialise the callback before the functions will work!
360  * */
361 static char str[MAXPATHLEN+12];
362
363 int BLI_delete(char *file, int dir, int recursive) 
364 {
365         if(strchr(file, '"')) {
366                 printf("Error: not deleted file %s because of quote!\n", file);
367         }
368         else {
369                 if (recursive) {
370                         sprintf(str, "/bin/rm -rf \"%s\"", file);
371                         return system(str);
372                 }
373                 else if (dir) {
374                         sprintf(str, "/bin/rmdir \"%s\"", file);
375                         return system(str);
376                 }
377                 else {
378                         return remove(file); //sprintf(str, "/bin/rm -f \"%s\"", file);
379                 }
380         }
381         return -1;
382 }
383
384 int BLI_move(char *file, char *to) {
385         sprintf(str, "/bin/mv -f \"%s\" \"%s\"", file, to);
386
387         return system(str);
388 }
389
390 int BLI_copy_fileops(char *file, char *to) {
391         sprintf(str, "/bin/cp -rf \"%s\" \"%s\"", file, to);
392
393         return system(str);
394 }
395
396 int BLI_link(char *file, char *to) {
397         sprintf(str, "/bin/ln -f \"%s\" \"%s\"", file, to);
398         
399         return system(str);
400 }
401
402 int BLI_exists(char *file) {
403         return BLI_exist(file);
404 }
405
406 void BLI_recurdir_fileops(char *dirname) {
407         char *lslash;
408         char tmp[MAXPATHLEN];
409                 
410         if (BLI_exists(dirname)) return;
411
412         strcpy(tmp, dirname);
413                 
414         lslash= BLI_last_slash(tmp);
415         if (lslash) {
416                         /* Split about the last slash and recurse */    
417                 *lslash = 0;
418                 BLI_recurdir_fileops(tmp);
419         }
420
421         mkdir(dirname, 0777);
422 }
423
424 int BLI_rename(char *from, char *to) {
425         if (!BLI_exists(from)) return 0;
426         
427         if (BLI_exists(to))     if(BLI_delete(to, 0, 0)) return 1;
428
429         return rename(from, to);
430 }
431
432 #endif