95
87
#include "BLI_listbase.h"
96
88
#include "BLI_linklist.h"
97
#include "BLI_storage_types.h"
89
#include "BLI_fileops.h"
91
#include "BLI_fileops_types.h"
98
92
#include "BLI_string.h"
93
#include "BLI_fileops.h"
99
95
#include "BKE_utildefines.h"
102
98
static int totnum,actnum;
103
99
static struct direntry *files;
105
static struct ListBase dirbase_={
101
static struct ListBase dirbase_={NULL, NULL};
107
102
static struct ListBase *dirbase = &dirbase_;
110
char *BLI_getwdN(char *dir)
104
/* can return NULL when the size is not big enough */
105
char *BLI_current_working_dir(char *dir, const int maxncpy)
120
/* 160 is FILE_MAXDIR in filesel.c */
121
return( getcwd(dir, 160) );
107
const char *pwd= getenv("PWD");
109
BLI_strncpy(dir, pwd, maxncpy);
113
return getcwd(dir, maxncpy);
127
int BLI_compare(struct direntry *entry1, struct direntry *entry2)
117
static int bli_compare(struct direntry *entry1, struct direntry *entry2)
129
119
/* type is equal to stat.st_mode */
131
if (S_ISDIR(entry1->type)){
121
if (S_ISDIR(entry1->type)) {
132
122
if (S_ISDIR(entry2->type)==0) return (-1);
134
125
if (S_ISDIR(entry2->type)) return (1);
136
if (S_ISREG(entry1->type)){
127
if (S_ISREG(entry1->type)) {
137
128
if (S_ISREG(entry2->type)==0) return (-1);
139
131
if (S_ISREG(entry2->type)) return (1);
141
133
if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1);
142
134
if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1);
144
136
/* make sure "." and ".." are always first */
145
if( strcmp(entry1->relname, ".")==0 ) return (-1);
146
if( strcmp(entry2->relname, ".")==0 ) return (1);
147
if( strcmp(entry1->relname, "..")==0 ) return (-1);
148
if( strcmp(entry2->relname, "..")==0 ) return (1);
137
if ( strcmp(entry1->relname, ".")==0 ) return (-1);
138
if ( strcmp(entry2->relname, ".")==0 ) return (1);
139
if ( strcmp(entry1->relname, "..")==0 ) return (-1);
140
if ( strcmp(entry2->relname, "..")==0 ) return (1);
150
142
return (BLI_natstrcmp(entry1->relname,entry2->relname));
154
double BLI_diskfree(char *dir)
146
double BLI_dir_free_space(const char *dir)
157
149
DWORD sectorspc, bytesps, freec, clusters;
209
void BLI_builddir(char *dirname, char *relname)
203
static void bli_builddir(const char *dirname, const char *relname)
211
205
struct dirent *fname;
212
206
struct dirlink *dlink;
213
int rellen, newnum = 0, len;
207
int rellen, newnum = 0;
211
BLI_strncpy(buf, relname, sizeof(buf));
218
212
rellen=strlen(relname);
225
if (chdir(dirname) == -1){
230
if ( (dir = (DIR *)opendir(".")) ){
219
if (chdir(dirname) == -1) {
224
UTF16_ENCODE(dirname);
225
if (!SetCurrentDirectoryW(dirname_16)) {
230
UTF16_UN_ENCODE(dirname);
233
if ((dir = (DIR *)opendir("."))) {
231
234
while ((fname = (struct dirent*) readdir(dir)) != NULL) {
232
len= strlen(fname->d_name);
234
235
dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
236
strcpy(buf+rellen,fname->d_name);
237
BLI_strncpy(buf + rellen ,fname->d_name, sizeof(buf) - rellen);
237
238
dlink->name = BLI_strdup(buf);
238
239
BLI_addhead(dirbase,dlink);
245
if (files) files=(struct direntry *)realloc(files,(totnum+newnum) * sizeof(struct direntry));
246
else files=(struct direntry *)malloc(newnum * sizeof(struct direntry));
247
void *tmp = realloc(files, (totnum+newnum) * sizeof(struct direntry));
249
files = (struct direntry *)tmp;
251
else { /* realloc fail */
258
files=(struct direntry *)malloc(newnum * sizeof(struct direntry));
249
261
dlink = (struct dirlink *) dirbase->first;
251
263
memset(&files[actnum], 0 , sizeof(struct direntry));
252
264
files[actnum].relname = dlink->name;
253
265
files[actnum].path = BLI_strdupcat(dirname, dlink->name);
254
266
// use 64 bit file size, only needed for WIN32 and WIN64.
255
// Excluding other than current MSVC compiler until able to test.
267
// Excluding other than current MSVC compiler until able to test
269
{wchar_t * name_16 = alloc_utf16_from_8(dlink->name,0);
256
270
#if (defined(WIN32) || defined(WIN64)) && (_MSC_VER>=1500)
257
_stat64(dlink->name,&files[actnum].s);
271
_wstat64(name_16,&files[actnum].s);
272
#elif defined(__MINGW32__)
273
_stati64(dlink->name,&files[actnum].s);
259
278
stat(dlink->name,&files[actnum].s);
265
284
dlink = dlink->next;
268
288
printf("Couldn't get memory for dir\n");
272
292
BLI_freelist(dirbase);
273
if (files) qsort(files, actnum, sizeof(struct direntry), (int (*)(const void *,const void*))BLI_compare);
293
if (files) qsort(files, actnum, sizeof(struct direntry), (int (*)(const void *,const void*))bli_compare);
275
296
printf("%s empty directory\n",dirname);
280
302
printf("%s non-existant directory\n",dirname);
284
void BLI_adddirstrings()
306
static void bli_adddirstrings(void)
289
static char * types[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"};
311
static const char * types[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"};
301
for(num=0, file= files; num<actnum; num++, file++){
323
for (num=0, file= files; num<actnum; num++, file++) {
304
strcpy(file->mode1, types[0]);
305
strcpy(file->mode2, types[0]);
306
strcpy(file->mode3, types[0]);
326
BLI_strncpy(file->mode1, types[0], sizeof(file->mode1));
327
BLI_strncpy(file->mode2, types[0], sizeof(file->mode2));
328
BLI_strncpy(file->mode3, types[0], sizeof(file->mode3));
308
330
mode = file->s.st_mode;
310
strcpy(file->mode1, types[(mode & 0700) >> 6]);
311
strcpy(file->mode2, types[(mode & 0070) >> 3]);
312
strcpy(file->mode3, types[(mode & 0007)]);
332
BLI_strncpy(file->mode1, types[(mode & 0700) >> 6], sizeof(file->mode1));
333
BLI_strncpy(file->mode2, types[(mode & 0070) >> 3], sizeof(file->mode2));
334
BLI_strncpy(file->mode3, types[(mode & 0007)], sizeof(file->mode3));
314
336
if (((mode & S_ISGID) == S_ISGID) && (file->mode2[2]=='-'))file->mode2[2]='l';
316
if (mode & (S_ISUID | S_ISGID)){
338
if (mode & (S_ISUID | S_ISGID)) {
317
339
if (file->mode1[2]=='x') file->mode1[2]='s';
318
340
else file->mode1[2]='S';
320
342
if (file->mode2[2]=='x')file->mode2[2]='s';
345
if (mode & S_ISVTX) {
324
346
if (file->mode3[2] == 'x') file->mode3[2] = 't';
325
347
else file->mode3[2] = 'T';
334
356
pwuser = getpwuid(file->s.st_uid);
336
358
BLI_strncpy(file->owner, pwuser->pw_name, sizeof(file->owner));
338
snprintf(file->owner, sizeof(file->owner), "%d", file->s.st_uid);
361
BLI_snprintf(file->owner, sizeof(file->owner), "%d", file->s.st_uid);
343
366
tm= localtime(&file->s.st_mtime);
344
367
// prevent impossible dates in windows
345
if(tm==NULL) tm= localtime(&zero);
346
strftime(file->time, 8, "%H:%M", tm);
347
strftime(file->date, 16, "%d-%b-%y", tm);
368
if (tm==NULL) tm= localtime(&zero);
369
strftime(file->time, sizeof(file->time), "%H:%M", tm);
370
strftime(file->date, sizeof(file->date), "%d-%b-%y", tm);
350
373
* Seems st_size is signed 32-bit value in *nix and Windows. This
354
377
st_size= file->s.st_size;
356
379
if (st_size > 1024*1024*1024) {
357
sprintf(file->size, "%.2f GB", ((double)st_size)/(1024*1024*1024));
380
BLI_snprintf(file->size, sizeof(file->size), "%.2f GB", ((double)st_size)/(1024*1024*1024));
359
382
else if (st_size > 1024*1024) {
360
sprintf(file->size, "%.1f MB", ((double)st_size)/(1024*1024));
383
BLI_snprintf(file->size, sizeof(file->size), "%.1f MB", ((double)st_size)/(1024*1024));
362
385
else if (st_size > 1024) {
363
sprintf(file->size, "%d KB", (int)(st_size/1024));
386
BLI_snprintf(file->size, sizeof(file->size), "%d KB", (int)(st_size/1024));
366
sprintf(file->size, "%d B", (int)st_size);
389
BLI_snprintf(file->size, sizeof(file->size), "%d B", (int)st_size);
369
strftime(datum, 32, "%d-%b-%y %H:%M", tm);
392
strftime(datum, 32, "%d-%b-%y %H:%M", tm); /* XXX, is this used? - campbell */
371
394
if (st_size < 1000) {
372
sprintf(size, "%10d", (int) st_size);
373
} else if (st_size < 1000 * 1000) {
374
sprintf(size, "%6d %03d", (int) (st_size / 1000), (int) (st_size % 1000));
375
} else if (st_size < 100 * 1000 * 1000) {
376
sprintf(size, "%2d %03d %03d", (int) (st_size / (1000 * 1000)), (int) ((st_size / 1000) % 1000), (int) ( st_size % 1000));
378
sprintf(size, "> %4.1f M", (double) (st_size / (1024.0 * 1024.0)));
379
sprintf(size, "%10d", (int) st_size);
382
sprintf(buf,"%s %s %s %7s %s %s %10s %s", file->mode1, file->mode2, file->mode3, file->owner, file->date, file->time, size,
385
file->string=MEM_mallocN(strlen(buf)+1, "filestring");
387
strcpy(file->string,buf);
395
BLI_snprintf(size, sizeof(size), "%10d",
398
else if (st_size < 1000 * 1000) {
399
BLI_snprintf(size, sizeof(size), "%6d %03d",
400
(int) (st_size / 1000), (int) (st_size % 1000));
402
else if (st_size < 100 * 1000 * 1000) {
403
BLI_snprintf(size, sizeof(size), "%2d %03d %03d",
404
(int) (st_size / (1000 * 1000)), (int) ((st_size / 1000) % 1000), (int) ( st_size % 1000));
407
/* XXX, whats going on here?. 2x calls - campbell */
408
BLI_snprintf(size, sizeof(size), "> %4.1f M", (double) (st_size / (1024.0 * 1024.0)));
409
BLI_snprintf(size, sizeof(size), "%10d", (int) st_size);
412
BLI_snprintf(buf, sizeof(buf), "%s %s %s %7s %s %s %10s %s",
413
file->mode1, file->mode2, file->mode3, file->owner,
414
file->date, file->time, size, file->relname);
416
file->string = BLI_strdup(buf);
392
unsigned int BLI_getdir(char *dirname, struct direntry **filelist)
420
unsigned int BLI_dir_contents(const char *dirname, struct direntry **filelist)
394
422
// reset global variables
395
423
// memory stored in files is free()'d in
396
424
// filesel.c:freefilelist()
398
426
actnum = totnum = 0;
401
BLI_builddir(dirname,"");
429
bli_builddir(dirname,"");
405
433
*(filelist) = files;
407
436
// keep blender happy. Blender stores this in a variable
408
437
// where 0 has special meaning.....
409
438
*(filelist) = files = malloc(sizeof(struct direntry));
416
int BLI_filesize(int file)
445
size_t BLI_file_descriptor_size(int file)
420
449
if (file <= 0) return (-1);
450
fstat(file, &buf);//CHANGE
422
451
return (buf.st_size);
425
int BLI_filepathsize(const char *path)
454
size_t BLI_file_size(const char *path)
427
int size, file = open(path, O_BINARY|O_RDONLY);
456
int size, file = BLI_open(path, O_BINARY|O_RDONLY, 0);
432
size = BLI_filesize(file);
461
size = BLI_file_descriptor_size(file);
438
int BLI_exist(char *name)
467
int BLI_exists(const char *name)
440
#if defined(WIN32) && !defined(__MINGW32__)
441
471
struct _stat64i32 st;
442
/* in Windows stat doesn't recognize dir ending on a slash
443
To not break code where the ending slash is expected we
444
don't mess with the argument name directly here - elubie */
445
char tmp[FILE_MAXDIR+FILE_MAXFILE];
475
/* in Windows stat doesn't recognize dir ending on a slash
476
* To not break code where the ending slash is expected we
477
* don't mess with the argument name directly here - elubie */
478
wchar_t * tmp_16 = alloc_utf16_from_8(name, 0);
447
BLI_strncpy(tmp, name, FILE_MAXDIR+FILE_MAXFILE);
449
if (len > 3 && ( tmp[len-1]=='\\' || tmp[len-1]=='/') ) tmp[len-1] = '\0';
450
res = _stat(tmp, &st);
480
len = wcslen(tmp_16);
481
if (len > 3 && ( tmp_16[len-1]==L'\\' || tmp_16[len-1]==L'/') ) tmp_16[len-1] = '\0';
483
res = _wstat(tmp_16, &st);
485
res = _wstati64(tmp_16, &st);
451
488
if (res == -1) return(0);
452
#elif defined(WIN32) && defined(__MINGW32__)
454
char tmp[FILE_MAXDIR+FILE_MAXFILE];
456
BLI_strncpy(tmp, name, FILE_MAXDIR+FILE_MAXFILE);
458
if (len > 3 && ( tmp[len-1]=='\\' || tmp[len-1]=='/') ) tmp[len-1] = '\0';
459
res = stat(tmp, &st);
463
491
if (stat(name,&st)) return(0);
465
493
return(st.st_mode);
498
int BLI_stat(const char *path, struct stat *buffer)
502
r=_wstat(path_16,buffer);
503
UTF16_UN_ENCODE(path);
507
int BLI_stat(const char *path, struct stat *buffer)
509
return stat(path, buffer);
468
513
/* would be better in fileops.c except that it needs stat.h so add here */
469
int BLI_is_dir(char *file) {
470
return S_ISDIR(BLI_exist(file));
473
LinkNode *BLI_read_file_as_lines(char *name)
475
FILE *fp= fopen(name, "r");
514
int BLI_is_dir(const char *file)
516
return S_ISDIR(BLI_exists(file));
519
int BLI_is_file(const char *path)
521
int mode= BLI_exists(path);
522
return (mode && !S_ISDIR(mode));
525
LinkNode *BLI_file_read_as_lines(const char *name)
527
FILE *fp= BLI_fopen(name, "r");
476
528
LinkNode *lines= NULL;
480
532
if (!fp) return NULL;
482
534
fseek(fp, 0, SEEK_END);
535
size= (size_t)ftell(fp);
484
536
fseek(fp, 0, SEEK_SET);
486
538
buf= MEM_mallocN(size, "file_as_lines");
491
543
* size = because on win32 reading
514
void BLI_free_file_lines(LinkNode *lines)
566
void BLI_file_free_lines(LinkNode *lines)
516
568
BLI_linklist_free(lines, (void(*)(void*)) MEM_freeN);
571
/** is file1 older then file2 */
519
572
int BLI_file_older(const char *file1, const char *file2)
575
struct _stat st1, st2;
580
if (_wstat(file1_16, &st1)) return 0;
581
if (_wstat(file2_16, &st2)) return 0;
583
UTF16_UN_ENCODE(file2);
584
UTF16_UN_ENCODE(file1);
521
586
struct stat st1, st2;
523
if(stat(file1, &st1)) return 0;
524
if(stat(file2, &st2)) return 0;
588
if (stat(file1, &st1)) return 0;
589
if (stat(file2, &st2)) return 0;
526
591
return (st1.st_mtime < st2.st_mtime);