|
Blender
V2.59
|
00001 /* 00002 * $Id: fileops.c 36276 2011-04-21 15:53:30Z campbellbarton $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00021 * All rights reserved. 00022 * 00023 * The Original Code is: all of this file. 00024 * 00025 * Contributor(s): none yet. 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 */ 00029 00035 #include <string.h> 00036 #include <stdio.h> 00037 00038 #include <sys/types.h> 00039 #include <sys/stat.h> 00040 #include <fcntl.h> 00041 00042 #include <errno.h> 00043 00044 #include "zlib.h" 00045 00046 #ifdef WIN32 00047 #include <io.h> 00048 #include "BLI_winstuff.h" 00049 #include "BLI_callbacks.h" 00050 #else 00051 #include <unistd.h> // for read close 00052 #include <sys/param.h> 00053 #endif 00054 00055 #include "BLI_blenlib.h" 00056 00057 #include "BKE_utildefines.h" 00058 00059 #include "BLO_sys_types.h" // for intptr_t support 00060 00061 00062 /* gzip the file in from and write it to "to". 00063 return -1 if zlib fails, -2 if the originating file does not exist 00064 note: will remove the "from" file 00065 */ 00066 int BLI_gzip(const char *from, const char *to) { 00067 char buffer[10240]; 00068 int file; 00069 int readsize = 0; 00070 int rval= 0, err; 00071 gzFile gzfile; 00072 00073 gzfile = gzopen(to, "wb"); 00074 if(gzfile == NULL) 00075 return -1; 00076 00077 file = open(from, O_BINARY|O_RDONLY); 00078 if(file < 0) 00079 return -2; 00080 00081 while(1) { 00082 readsize = read(file, buffer, 10240); 00083 00084 if(readsize < 0) { 00085 rval= -2; /* error happened in reading */ 00086 fprintf(stderr, "Error reading file %s: %s.\n", from, strerror(errno)); 00087 break; 00088 } 00089 else if(readsize == 0) 00090 break; /* done reading */ 00091 00092 if(gzwrite(gzfile, buffer, readsize) <= 0) { 00093 rval= -1; /* error happened in writing */ 00094 fprintf(stderr, "Error writing gz file %s: %s.\n", to, gzerror(gzfile, &err)); 00095 break; 00096 } 00097 } 00098 00099 gzclose(gzfile); 00100 close(file); 00101 00102 return rval; 00103 } 00104 00105 /* return 1 when file can be written */ 00106 int BLI_is_writable(const char *filename) 00107 { 00108 int file; 00109 00110 /* first try to open without creating */ 00111 file = open(filename, O_BINARY | O_RDWR, 0666); 00112 00113 if (file < 0) { 00114 /* now try to open and create. a test without actually 00115 * creating a file would be nice, but how? */ 00116 file = open(filename, O_BINARY | O_RDWR | O_CREAT, 0666); 00117 00118 if(file < 0) { 00119 return 0; 00120 } 00121 else { 00122 /* success, delete the file we create */ 00123 close(file); 00124 BLI_delete(filename, 0, 0); 00125 return 1; 00126 } 00127 } 00128 else { 00129 close(file); 00130 return 1; 00131 } 00132 } 00133 00134 int BLI_touch(const char *file) 00135 { 00136 FILE *f = fopen(file,"r+b"); 00137 if (f != NULL) { 00138 char c = getc(f); 00139 rewind(f); 00140 putc(c,f); 00141 } else { 00142 f = fopen(file,"wb"); 00143 } 00144 if (f) { 00145 fclose(f); 00146 return 1; 00147 } 00148 return 0; 00149 } 00150 00151 int BLI_exists(const char *file) { 00152 return BLI_exist(file); 00153 } 00154 00155 #ifdef WIN32 00156 00157 static char str[MAXPATHLEN+12]; 00158 00159 int BLI_delete(const char *file, int dir, int recursive) { 00160 int err; 00161 00162 if (recursive) { 00163 callLocalErrorCallBack("Recursive delete is unsupported on Windows"); 00164 err= 1; 00165 } else if (dir) { 00166 err= !RemoveDirectory(file); 00167 if (err) printf ("Unable to remove directory"); 00168 } else { 00169 err= !DeleteFile(file); 00170 if (err) callLocalErrorCallBack("Unable to delete file"); 00171 } 00172 00173 return err; 00174 } 00175 00176 int BLI_move(const char *file, const char *to) { 00177 int err; 00178 00179 // windows doesn't support moveing to a directory 00180 // it has to be 'mv filename filename' and not 00181 // 'mv filename destdir' 00182 00183 strcpy(str, to); 00184 // points 'to' to a directory ? 00185 if (BLI_last_slash(str) == (str + strlen(str) - 1)) { 00186 if (BLI_last_slash(file) != NULL) { 00187 strcat(str, BLI_last_slash(file) + 1); 00188 } 00189 } 00190 00191 err= !MoveFile(file, str); 00192 if (err) { 00193 callLocalErrorCallBack("Unable to move file"); 00194 printf(" Move from '%s' to '%s' failed\n", file, str); 00195 } 00196 00197 return err; 00198 } 00199 00200 00201 int BLI_copy_fileops(const char *file, const char *to) { 00202 int err; 00203 00204 // windows doesn't support copying to a directory 00205 // it has to be 'cp filename filename' and not 00206 // 'cp filename destdir' 00207 00208 strcpy(str, to); 00209 // points 'to' to a directory ? 00210 if (BLI_last_slash(str) == (str + strlen(str) - 1)) { 00211 if (BLI_last_slash(file) != NULL) { 00212 strcat(str, BLI_last_slash(file) + 1); 00213 } 00214 } 00215 00216 err= !CopyFile(file,str,FALSE); 00217 00218 if (err) { 00219 callLocalErrorCallBack("Unable to copy file!"); 00220 printf(" Copy from '%s' to '%s' failed\n", file, str); 00221 } 00222 00223 return err; 00224 } 00225 00226 int BLI_link(const char *file, const char *to) { 00227 callLocalErrorCallBack("Linking files is unsupported on Windows"); 00228 (void)file; 00229 (void)to; 00230 return 1; 00231 } 00232 00233 void BLI_recurdir_fileops(const char *dirname) { 00234 char *lslash; 00235 char tmp[MAXPATHLEN]; 00236 00237 // First remove possible slash at the end of the dirname. 00238 // This routine otherwise tries to create 00239 // blah1/blah2/ (with slash) after creating 00240 // blah1/blah2 (without slash) 00241 00242 strcpy(tmp, dirname); 00243 lslash= BLI_last_slash(tmp); 00244 00245 if (lslash == tmp + strlen(tmp) - 1) { 00246 *lslash = 0; 00247 } 00248 00249 if (BLI_exists(tmp)) return; 00250 00251 lslash= BLI_last_slash(tmp); 00252 if (lslash) { 00253 /* Split about the last slash and recurse */ 00254 *lslash = 0; 00255 BLI_recurdir_fileops(tmp); 00256 } 00257 00258 if(dirname[0]) /* patch, this recursive loop tries to create a nameless directory */ 00259 if (!CreateDirectory(dirname, NULL)) 00260 callLocalErrorCallBack("Unable to create directory\n"); 00261 } 00262 00263 int BLI_rename(const char *from, const char *to) { 00264 if (!BLI_exists(from)) return 0; 00265 00266 /* make sure the filenames are different (case insensitive) before removing */ 00267 if (BLI_exists(to) && BLI_strcasecmp(from, to)) 00268 if(BLI_delete(to, 0, 0)) return 1; 00269 00270 return rename(from, to); 00271 } 00272 00273 #else /* The UNIX world */ 00274 00275 /* 00276 * but the UNIX world is tied to the interface, and the system 00277 * timer, and... We implement a callback mechanism. The system will 00278 * have to initialise the callback before the functions will work! 00279 * */ 00280 static char str[12 + (MAXPATHLEN * 2)]; 00281 00282 int BLI_delete(const char *file, int dir, int recursive) 00283 { 00284 if(strchr(file, '"')) { 00285 printf("Error: not deleted file %s because of quote!\n", file); 00286 } 00287 else { 00288 if (recursive) { 00289 BLI_snprintf(str, sizeof(str), "/bin/rm -rf \"%s\"", file); 00290 return system(str); 00291 } 00292 else if (dir) { 00293 BLI_snprintf(str, sizeof(str), "/bin/rmdir \"%s\"", file); 00294 return system(str); 00295 } 00296 else { 00297 return remove(file); //BLI_snprintf(str, sizeof(str), "/bin/rm -f \"%s\"", file); 00298 } 00299 } 00300 return -1; 00301 } 00302 00303 int BLI_move(const char *file, const char *to) { 00304 BLI_snprintf(str, sizeof(str), "/bin/mv -f \"%s\" \"%s\"", file, to); 00305 00306 return system(str); 00307 } 00308 00309 int BLI_copy_fileops(const char *file, const char *to) { 00310 BLI_snprintf(str, sizeof(str), "/bin/cp -rf \"%s\" \"%s\"", file, to); 00311 00312 return system(str); 00313 } 00314 00315 int BLI_link(const char *file, const char *to) { 00316 BLI_snprintf(str, sizeof(str), "/bin/ln -f \"%s\" \"%s\"", file, to); 00317 00318 return system(str); 00319 } 00320 00321 void BLI_recurdir_fileops(const char *dirname) { 00322 char *lslash; 00323 char tmp[MAXPATHLEN]; 00324 00325 if (BLI_exists(dirname)) return; 00326 00327 strcpy(tmp, dirname); 00328 00329 lslash= BLI_last_slash(tmp); 00330 if (lslash) { 00331 /* Split about the last slash and recurse */ 00332 *lslash = 0; 00333 BLI_recurdir_fileops(tmp); 00334 } 00335 00336 mkdir(dirname, 0777); 00337 } 00338 00339 int BLI_rename(const char *from, const char *to) { 00340 if (!BLI_exists(from)) return 0; 00341 00342 if (BLI_exists(to)) if(BLI_delete(to, 0, 0)) return 1; 00343 00344 return rename(from, to); 00345 } 00346 00347 #endif