44
44
#include <sys/stat.h>
46
#if defined (__sun__) || defined (__sun) || defined (__NetBSD__)
46
#if defined(__sun__) || defined(__sun) || defined(__NetBSD__)
47
47
#include <sys/statvfs.h> /* Other modern unix os's should probably use this also */
48
48
#elif !defined(__FreeBSD__) && !defined(linux) && (defined(__sparc) || defined(__sparc__))
49
49
#include <sys/statfs.h>
52
#if defined (__FreeBSD__) || defined (__OpenBSD__)
52
#if defined(__FreeBSD__) || defined(__OpenBSD__)
53
53
#include <sys/param.h>
54
54
#include <sys/mount.h>
87
87
#include "BLI_listbase.h"
88
88
#include "BLI_linklist.h"
89
#include "BLI_string.h"
89
90
#include "BLI_fileops.h"
91
91
#include "BLI_fileops_types.h"
92
#include "BLI_string.h"
93
#include "BLI_fileops.h"
95
#include "BKE_utildefines.h"
92
#include "BLI_path_util.h"
98
static int totnum,actnum;
95
static int totnum, actnum;
99
96
static struct direntry *files;
101
static struct ListBase dirbase_={NULL, NULL};
98
static struct ListBase dirbase_ = {NULL, NULL};
102
99
static struct ListBase *dirbase = &dirbase_;
104
101
/* can return NULL when the size is not big enough */
105
char *BLI_current_working_dir(char *dir, const int maxncpy)
102
char *BLI_current_working_dir(char *dir, const size_t maxncpy)
107
const char *pwd= getenv("PWD");
104
const char *pwd = getenv("PWD");
109
106
BLI_strncpy(dir, pwd, maxncpy);
119
116
/* type is equal to stat.st_mode */
121
118
if (S_ISDIR(entry1->type)) {
122
if (S_ISDIR(entry2->type)==0) return (-1);
119
if (S_ISDIR(entry2->type) == 0) return (-1);
125
122
if (S_ISDIR(entry2->type)) return (1);
127
124
if (S_ISREG(entry1->type)) {
128
if (S_ISREG(entry2->type)==0) return (-1);
125
if (S_ISREG(entry2->type) == 0) return (-1);
131
128
if (S_ISREG(entry2->type)) return (1);
134
131
if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1);
136
133
/* make sure "." and ".." are always first */
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);
134
if (strcmp(entry1->relname, ".") == 0) return (-1);
135
if (strcmp(entry2->relname, ".") == 0) return (1);
136
if (strcmp(entry1->relname, "..") == 0) return (-1);
137
if (strcmp(entry2->relname, "..") == 0) return (1);
142
return (BLI_natstrcmp(entry1->relname,entry2->relname));
139
return (BLI_natstrcmp(entry1->relname, entry2->relname));
149
146
DWORD sectorspc, bytesps, freec, clusters;
152
tmp[0]='\\'; tmp[1]=0; /* Just a failsafe */
153
if (dir[0]=='/' || dir[0]=='\\') {
157
else if (dir[1]==':') {
164
GetDiskFreeSpace(tmp,§orspc, &bytesps, &freec, &clusters);
166
return (double) (freec*bytesps*sectorspc);
149
tmp[0] = '\\'; tmp[1] = 0; /* Just a failsafe */
150
if (dir[0] == '/' || dir[0] == '\\') {
154
else if (dir[1] == ':') {
161
GetDiskFreeSpace(tmp, §orspc, &bytesps, &freec, &clusters);
163
return (double) (freec * bytesps * sectorspc);
169
#if defined (__sun__) || defined (__sun) || defined (__NetBSD__)
166
#if defined(__sun__) || defined(__sun) || defined(__NetBSD__)
170
167
struct statvfs disk;
172
169
struct statfs disk;
174
char name[FILE_MAXDIR],*slash;
171
char name[FILE_MAXDIR], *slash;
175
172
int len = strlen(dir);
177
174
if (len >= FILE_MAXDIR) /* path too long */
183
slash = strrchr(name,'/');
180
slash = strrchr(name, '/');
184
181
if (slash) slash[1] = 0;
186
else strcpy(name,"/");
183
else strcpy(name, "/");
188
#if defined (__FreeBSD__) || defined (linux) || defined (__OpenBSD__) || defined (__APPLE__) || defined(__GNU__) || defined(__GLIBC__)
185
#if defined(__FreeBSD__) || defined(linux) || defined(__OpenBSD__) || defined(__APPLE__) || defined(__GNU__) || defined(__GLIBC__)
189
186
if (statfs(name, &disk)) return(-1);
192
#if defined (__sun__) || defined (__sun) || defined (__NetBSD__)
193
if (statvfs(name, &disk)) return(-1);
189
#if defined(__sun__) || defined(__sun) || defined(__NetBSD__)
190
if (statvfs(name, &disk)) return(-1);
194
191
#elif !defined(__FreeBSD__) && !defined(linux) && (defined(__sparc) || defined(__sparc__))
195
192
/* WARNING - This may not be supported by geeneric unix os's - Campbell */
196
193
if (statfs(name, &disk, sizeof(struct statfs), 0)) return(-1);
233
230
if ((dir = (DIR *)opendir("."))) {
234
while ((fname = (struct dirent*) readdir(dir)) != NULL) {
231
while ((fname = (struct dirent *) readdir(dir)) != NULL) {
235
232
dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
237
BLI_strncpy(buf + rellen ,fname->d_name, sizeof(buf) - rellen);
234
BLI_strncpy(buf + rellen, fname->d_name, sizeof(buf) - rellen);
238
235
dlink->name = BLI_strdup(buf);
239
BLI_addhead(dirbase,dlink);
236
BLI_addhead(dirbase, dlink);
258
files=(struct direntry *)malloc(newnum * sizeof(struct direntry));
255
files = (struct direntry *)malloc(newnum * sizeof(struct direntry));
261
258
dlink = (struct dirlink *) dirbase->first;
263
memset(&files[actnum], 0 , sizeof(struct direntry));
260
memset(&files[actnum], 0, sizeof(struct direntry));
264
261
files[actnum].relname = dlink->name;
265
262
files[actnum].path = BLI_strdupcat(dirname, dlink->name);
266
263
// use 64 bit file size, only needed for WIN32 and WIN64.
267
264
// Excluding other than current MSVC compiler until able to test
269
{wchar_t * name_16 = alloc_utf16_from_8(dlink->name,0);
270
#if (defined(WIN32) || defined(WIN64)) && (_MSC_VER>=1500)
271
_wstat64(name_16,&files[actnum].s);
267
wchar_t *name_16 = alloc_utf16_from_8(dlink->name, 0);
268
#if (defined(WIN32) || defined(WIN64)) && (_MSC_VER >= 1500)
269
_wstat64(name_16, &files[actnum].s);
272
270
#elif defined(__MINGW32__)
273
_stati64(dlink->name,&files[actnum].s);
271
_stati64(dlink->name, &files[actnum].s);
278
stat(dlink->name,&files[actnum].s);
277
stat(dlink->name, &files[actnum].s);
280
files[actnum].type=files[actnum].s.st_mode;
279
files[actnum].type = files[actnum].s.st_mode;
281
280
files[actnum].flags = 0;
292
291
BLI_freelist(dirbase);
293
if (files) qsort(files, actnum, sizeof(struct direntry), (int (*)(const void *,const void*))bli_compare);
292
if (files) qsort(files, actnum, sizeof(struct direntry), (int (*)(const void *, const void *))bli_compare);
296
printf("%s empty directory\n",dirname);
295
printf("%s empty directory\n", dirname);
302
printf("%s non-existant directory\n",dirname);
301
printf("%s non-existant directory\n", dirname);
311
static const char * types[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"};
310
static const char *types[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"};
319
struct direntry * file;
318
struct direntry *file;
323
for (num=0, file= files; num<actnum; num++, file++) {
322
for (num = 0, file = files; num < actnum; num++, file++) {
326
325
BLI_strncpy(file->mode1, types[0], sizeof(file->mode1));
333
332
BLI_strncpy(file->mode2, types[(mode & 0070) >> 3], sizeof(file->mode2));
334
333
BLI_strncpy(file->mode3, types[(mode & 0007)], sizeof(file->mode3));
336
if (((mode & S_ISGID) == S_ISGID) && (file->mode2[2]=='-'))file->mode2[2]='l';
335
if (((mode & S_ISGID) == S_ISGID) && (file->mode2[2] == '-')) file->mode2[2] = 'l';
338
337
if (mode & (S_ISUID | S_ISGID)) {
339
if (file->mode1[2]=='x') file->mode1[2]='s';
340
else file->mode1[2]='S';
338
if (file->mode1[2] == 'x') file->mode1[2] = 's';
339
else file->mode1[2] = 'S';
342
if (file->mode2[2]=='x')file->mode2[2]='s';
341
if (file->mode2[2] == 'x') file->mode2[2] = 's';
345
344
if (mode & S_ISVTX) {
352
strcpy(file->owner,"user");
351
strcpy(file->owner, "user");
355
354
struct passwd *pwuser;
356
355
pwuser = getpwuid(file->s.st_uid);
358
357
BLI_strncpy(file->owner, pwuser->pw_name, sizeof(file->owner));
366
tm= localtime(&file->s.st_mtime);
365
tm = localtime(&file->s.st_mtime);
367
366
// prevent impossible dates in windows
368
if (tm==NULL) tm= localtime(&zero);
367
if (tm == NULL) tm = localtime(&zero);
369
368
strftime(file->time, sizeof(file->time), "%H:%M", tm);
370
369
strftime(file->date, sizeof(file->date), "%d-%b-%y", tm);
374
373
* will buy us some time until files get bigger than 4GB or until
375
374
* everyone starts using __USE_FILE_OFFSET64 or equivalent.
377
st_size= file->s.st_size;
376
st_size = file->s.st_size;
379
if (st_size > 1024*1024*1024) {
380
BLI_snprintf(file->size, sizeof(file->size), "%.2f GB", ((double)st_size)/(1024*1024*1024));
378
if (st_size > 1024 * 1024 * 1024) {
379
BLI_snprintf(file->size, sizeof(file->size), "%.2f GB", ((double)st_size) / (1024 * 1024 * 1024));
382
else if (st_size > 1024*1024) {
383
BLI_snprintf(file->size, sizeof(file->size), "%.1f MB", ((double)st_size)/(1024*1024));
381
else if (st_size > 1024 * 1024) {
382
BLI_snprintf(file->size, sizeof(file->size), "%.1f MB", ((double)st_size) / (1024 * 1024));
385
384
else if (st_size > 1024) {
386
BLI_snprintf(file->size, sizeof(file->size), "%d KB", (int)(st_size/1024));
385
BLI_snprintf(file->size, sizeof(file->size), "%d KB", (int)(st_size / 1024));
389
388
BLI_snprintf(file->size, sizeof(file->size), "%d B", (int)st_size);
402
401
else if (st_size < 100 * 1000 * 1000) {
403
402
BLI_snprintf(size, sizeof(size), "%2d %03d %03d",
404
(int) (st_size / (1000 * 1000)), (int) ((st_size / 1000) % 1000), (int) ( st_size % 1000));
403
(int) (st_size / (1000 * 1000)), (int) ((st_size / 1000) % 1000), (int) (st_size % 1000));
407
406
/* XXX, whats going on here?. 2x calls - campbell */
420
419
unsigned int BLI_dir_contents(const char *dirname, struct direntry **filelist)
422
// reset global variables
423
// memory stored in files is free()'d in
424
// filesel.c:freefilelist()
421
/* reset global variables
422
* memory stored in files is free()'d in
423
* filesel.c:freefilelist() */
426
425
actnum = totnum = 0;
429
bli_builddir(dirname,"");
428
bli_builddir(dirname, "");
430
429
bli_adddirstrings();
449
448
if (file <= 0) return (-1);
450
fstat(file, &buf);//CHANGE
449
fstat(file, &buf); /* CHANGE */
451
450
return (buf.st_size);
454
453
size_t BLI_file_size(const char *path)
456
int size, file = BLI_open(path, O_BINARY|O_RDONLY, 0);
455
int size, file = BLI_open(path, O_BINARY | O_RDONLY, 0);
475
474
/* in Windows stat doesn't recognize dir ending on a slash
476
475
* To not break code where the ending slash is expected we
477
476
* don't mess with the argument name directly here - elubie */
478
wchar_t * tmp_16 = alloc_utf16_from_8(name, 0);
477
wchar_t *tmp_16 = alloc_utf16_from_8(name, 0);
480
479
len = wcslen(tmp_16);
481
if (len > 3 && ( tmp_16[len-1]==L'\\' || tmp_16[len-1]==L'/') ) tmp_16[len-1] = '\0';
480
if (len > 3 && (tmp_16[len - 1] == L'\\' || tmp_16[len - 1] == L'/') ) tmp_16[len - 1] = '\0';
482
481
#ifndef __MINGW32__
483
482
res = _wstat(tmp_16, &st);
519
518
int BLI_is_file(const char *path)
521
int mode= BLI_exists(path);
520
int mode = BLI_exists(path);
522
521
return (mode && !S_ISDIR(mode));
525
524
LinkNode *BLI_file_read_as_lines(const char *name)
527
FILE *fp= BLI_fopen(name, "r");
528
LinkNode *lines= NULL;
526
FILE *fp = BLI_fopen(name, "r");
527
LinkNode *lines = NULL;
532
531
if (!fp) return NULL;
534
533
fseek(fp, 0, SEEK_END);
535
size= (size_t)ftell(fp);
534
size = (size_t)ftell(fp);
536
535
fseek(fp, 0, SEEK_SET);
538
buf= MEM_mallocN(size, "file_as_lines");
537
buf = MEM_mallocN(size, "file_as_lines");
543
* size = because on win32 reading
544
* all the bytes in the file will return
545
* less bytes because of crnl changes.
547
size= fread(buf, 1, size, fp);
548
for (i=0; i<=size; i++) {
549
if (i==size || buf[i]=='\n') {
550
char *line= BLI_strdupn(&buf[last], i-last);
542
* size = because on win32 reading
543
* all the bytes in the file will return
544
* less bytes because of crnl changes.
546
size = fread(buf, 1, size, fp);
547
for (i = 0; i <= size; i++) {
548
if (i == size || buf[i] == '\n') {
549
char *line = BLI_strdupn(&buf[last], i - last);
552
551
BLI_linklist_prepend(&lines, line);
566
565
void BLI_file_free_lines(LinkNode *lines)
568
BLI_linklist_free(lines, (void(*)(void*)) MEM_freeN);
567
BLI_linklist_free(lines, (void (*)(void *))MEM_freeN);
571
570
/** is file1 older then file2 */