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