This is a patch from the FreeBSD people:
[blender-staging.git] / source / blender / blenlib / intern / storage.c
index a71a470777c5893c71c6bfe1b82def1e2f1e26b8..f288dde5815c304537868be1959471844ddde725 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>    
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 #ifdef WIN32
-
-#include <windows.h>
 #include "BLI_winstuff.h"
 #include <sys/types.h>
 #include <io.h>
@@ -56,7 +50,9 @@
 #include <time.h>
 #include <sys/stat.h>
 
-#if defined(__sgi) || defined(__sun__) || defined(__sun) || defined(__sparc) || defined(__sparc__)
+#if defined (__sun__) || defined (__sun)
+#include <sys/statvfs.h> /* Other modern unix os's should probably use this also */
+#elif !defined(__FreeBSD__) && !defined(linux) && (defined(__sgi) || defined(__sparc) || defined(__sparc__))
 #include <sys/statfs.h>
 #endif
 
@@ -65,7 +61,7 @@
 #include <sys/mount.h>
 #endif
 
-#if defined(linux) || defined(__CYGWIN32__)
+#if defined(linux) || defined(__CYGWIN32__) || defined(__hpux)
 #include <sys/vfs.h>
 #endif
 
@@ -110,11 +106,8 @@ struct statfs {
 #include "BLI_util.h"
 #include "BLI_linklist.h"
 
-/* functions */
-void  BLI_buildpwtable(struct passwd **pwtable);
-void  BLI_freepwtable(struct passwd *pwtable);
-char *BLI_findpwtable(struct passwd *pwtable, unsigned short user);
+#include "BKE_utildefines.h"
+
 /* vars: */
 static int totnum,actnum;
 static struct direntry *files;
@@ -157,7 +150,13 @@ int BLI_compare(struct direntry *entry1, struct direntry *entry2)
        }
        if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1);
        if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1);
-       return (strcasecmp(entry1->relname,entry2->relname));
+       
+       /* make sure "." and ".." are always first */
+       if( strcmp(entry1->relname, ".")==0 ) return (-1);
+       if( strcmp(entry2->relname, ".")==0 ) return (1);
+       if( strcmp(entry1->relname, "..")==0 ) return (-1);
+       
+       return (BLI_strcasecmp(entry1->relname,entry2->relname));
 }
 
 
@@ -182,29 +181,37 @@ double BLI_diskfree(char *dir)
 
        return (double) (freec*bytesps*sectorspc);
 #else
-       struct statfs disk;
-       char name[100],*slash;
-
 
+#if defined (__sun__) || defined (__sun)
+       struct statvfs disk;
+#else
+       struct statfs disk;
+#endif
+       char name[FILE_MAXDIR],*slash;
+       int len = strlen(dir);
+       
+       if (len >= FILE_MAXDIR) /* path too long */
+               return -1;
+       
        strcpy(name,dir);
 
-       if(strlen(name)){
+       if(len){
                slash = strrchr(name,'/');
                if (slash) slash[1] = 0;
        } else strcpy(name,"/");
 
-#if defined (__FreeBSD__) || defined (linux) || defined (__OpenBSD__) 
+#if defined (__FreeBSD__) || defined (linux) || defined (__OpenBSD__) || defined (__APPLE__) 
        if (statfs(name, &disk)) return(-1);
 #endif
 #ifdef __BeOS
        return -1;
 #endif
-#if defined (__sgi) || defined (__sun__) || defined (__sun) || defined(__sparc) || defined(__sparc__)
 
-       if (statfs(name, &disk, sizeof(struct statfs), 0)){
-               /* printf("diskfree: Couldn't get information about %s.\n",dir); */
-               return(-1);
-       }
+#if defined (__sun__) || defined (__sun)
+       if (statvfs(name, &disk)) return(-1);   
+#elif !defined(__FreeBSD__) && !defined(linux) && (defined (__sgi) || defined(__sparc) || defined(__sparc__))
+       /* WARNING - This may not be supported by geeneric unix os's - Campbell */
+       if (statfs(name, &disk, sizeof(struct statfs), 0)) return(-1);
 #endif
 
        return ( ((double) disk.f_bsize) * ((double) disk.f_bfree));
@@ -240,7 +247,7 @@ void BLI_builddir(char *dirname, char *relname)
                return;
        }
 
-       if (dir = (DIR *)opendir(".")){
+       if ( (dir = (DIR *)opendir(".")) ){
                while ((fname = (struct dirent*) readdir(dir)) != NULL) {
                        
                        if(hide_dot && fname->d_name[0]=='.' && fname->d_name[1]!='.' && fname->d_name[1]!=0);
@@ -250,7 +257,7 @@ void BLI_builddir(char *dirname, char *relname)
                                if (dlink){
                                        strcpy(buf+rellen,fname->d_name);
        
-                                       dlink->name = strdup(buf);
+                                       dlink->name = BLI_strdup(buf);
        
                                        if (dlink->name[0] == '.') {
                                                if (dlink->name[1] == 0) seen_ = 1;
@@ -269,14 +276,22 @@ void BLI_builddir(char *dirname, char *relname)
                        if (seen_ == 0) {       /* Cachefs PATCH */
                                dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
                                strcpy(buf+rellen,"./.");
-                               dlink->name = strdup(buf);
+                               dlink->name = BLI_strdup(buf);
                                BLI_addhead(dirbase,dlink);
                                newnum++;
                        }
                        if (seen__ == 0) {      /* MAC PATCH */
                                dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
                                strcpy(buf+rellen,"./..");
-                               dlink->name = strdup(buf);
+                               dlink->name = BLI_strdup(buf);
+                               BLI_addhead(dirbase,dlink);
+                               newnum++;
+                       }
+#else // WIN32
+                       if (seen_ == 0) {       /* should only happen for root paths like "C:\" */
+                               dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
+                               strcpy(buf+rellen,".");
+                               dlink->name = BLI_strdup(buf);
                                BLI_addhead(dirbase,dlink);
                                newnum++;
                        }
@@ -314,68 +329,6 @@ void BLI_builddir(char *dirname, char *relname)
        }
 }
 
-#ifndef WIN32
-void BLI_buildpwtable(struct passwd **pwtable)
-{
-       int count=0,slen;
-       struct passwd *pw,*pwtab;
-
-       do{
-               pw=getpwent();
-               if (pw){
-                       count++;
-               }
-       }while(pw);
-       endpwent();
-
-       pwtab = (struct passwd *)calloc(count+1,sizeof(struct passwd));
-       count=0;
-       do{
-               pw=getpwent();
-               if (pw){
-                       pwtab[count] = *pw;
-                       slen = strlen(pw->pw_name);
-                       pwtab[count].pw_name = malloc(slen+1);
-                       strcpy(pwtab[count].pw_name,pw->pw_name);
-                       count ++;
-               }
-       }while(pw);
-       pwtab[count].pw_name = 0;
-       endpwent();
-
-       *(pwtable) = pwtab;
-}
-
-void BLI_freepwtable(struct passwd *pwtable)
-{
-       int count=0;
-
-       do{
-               if (pwtable[count].pw_name) free(pwtable[count].pw_name);
-               else break;
-               count++;
-       }while (1);
-
-       free(pwtable);
-}
-
-
-char *BLI_findpwtable(struct passwd *pwtable, ushort user)
-{
-       static char string[32];
-       
-       while (pwtable->pw_name){
-               if (pwtable->pw_uid == user){
-                       return (pwtable->pw_name);
-               }
-               pwtable++;
-       }
-       sprintf(string, "%d", user);
-       return (string);
-}
-#endif
-
-
 void BLI_adddirstrings()
 {
        char datum[100];
@@ -383,16 +336,16 @@ void BLI_adddirstrings()
        char size[250];
        static char * types[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"};
        int num, mode;
-       int num1, num2, num3, num4, st_size;
-#ifndef WIN32  
-       struct passwd *pwtable;
+       off_t num1, num2, num3, num4, num5;
+#ifdef WIN32
+       __int64 st_size;
+#else
+       off_t st_size;
 #endif
+       
        struct direntry * file;
        struct tm *tm;
-       
-#ifndef WIN32
-       BLI_buildpwtable(&pwtable);
-#endif
+       time_t zero= 0;
 
        file = &files[0];
        
@@ -427,14 +380,29 @@ void BLI_adddirstrings()
 #ifdef WIN32
                strcpy(files[num].owner,"user");
 #else
-               strcpy(files[num].owner, BLI_findpwtable(pwtable,files[num].s.st_uid));
+               {
+                       struct passwd *pwuser;
+                       pwuser = getpwuid(files[num].s.st_uid);
+                       if ( pwuser ) {
+                       strcpy(files[num].owner, pwuser->pw_name);
+                       } else {
+                               sprintf(files[num].owner, "%d", files[num].s.st_uid);
+            }
+               }
 #endif
 
                tm= localtime(&files[num].s.st_mtime);
+               // prevent impossible dates in windows
+               if(tm==NULL) tm= localtime(&zero);
                strftime(files[num].time, 8, "%H:%M", tm);
                strftime(files[num].date, 16, "%d-%b-%y", tm);
-               
-               st_size= (int)files[num].s.st_size;
+
+               /*
+                * Seems st_size is signed 32-bit value in *nix and Windows.  This
+                * will buy us some time until files get bigger than 4GB or until
+                * everyone starts using __USE_FILE_OFFSET64 or equivalent.
+                */
+               st_size= (off_t)files[num].s.st_size;
                
                num1= st_size % 1000;
                num2= st_size/1000;
@@ -443,24 +411,28 @@ void BLI_adddirstrings()
                num3= num3 % 1000;
                num4= st_size/(1000*1000*1000);
                num4= num4 % 1000;
+               num5= st_size/(1000000000000LL);
+               num5= num5 % 1000;
 
-               if(num4) sprintf(files[num].size, "%3d %03d %03d %03d", num4, num3, num2, num1);
-               else if(num3) sprintf(files[num].size, "%7d %03d %03d", num3, num2, num1);
-               else if(num2) sprintf(files[num].size, "%11d %03d", num2, num1);
-               else if(num1) sprintf(files[num].size, "%15d", num1);
-               else sprintf(files[num].size, "");
+               if(num5)
+                       sprintf(files[num].size, "%1d %03d %03d %03d K", (int)num5, (int)num4, (int)num3, (int)num2);
+               else if(num4) sprintf(files[num].size, "%3d %03d %03d %03d", (int)num4, (int)num3, (int)num2, (int)num1);
+               else if(num3) sprintf(files[num].size, "%7d %03d %03d", (int)num3, (int)num2, (int)num1);
+               else if(num2) sprintf(files[num].size, "%11d %03d", (int)num2, (int)num1);
+               else if(num1) sprintf(files[num].size, "%15d", (int)num1);
+               else sprintf(files[num].size, "0");
 
-               strftime(datum, 32, "%d-%b-%y %R", tm);
+               strftime(datum, 32, "%d-%b-%y %H:%M", tm);
 
                if (st_size < 1000) {
-                       sprintf(size, "%10d", st_size);
+                       sprintf(size, "%10d", (int) st_size);
                } else if (st_size < 1000 * 1000) {
-                       sprintf(size, "%6d %03d", st_size / 1000, st_size % 1000);
+                       sprintf(size, "%6d %03d", (int) (st_size / 1000), (int) (st_size % 1000));
                } else if (st_size < 100 * 1000 * 1000) {
-                       sprintf(size, "%2d %03d %03d", st_size / (1000 * 1000), (st_size / 1000) % 1000, st_size % 1000);
+                       sprintf(size, "%2d %03d %03d", (int) (st_size / (1000 * 1000)), (int) ((st_size / 1000) % 1000), (int) ( st_size % 1000));
                } else {
-                       sprintf(size, "> %4.1f M", st_size / (1024.0 * 1024.0));
-                       sprintf(size, "%10d", st_size);
+                       sprintf(size, "> %4.1f M", (double) (st_size / (1024.0 * 1024.0)));
+                       sprintf(size, "%10d", (int) st_size);
                }
 
                sprintf(buf,"%s %s %10s %s", files[num].date, files[num].time, size,
@@ -469,16 +441,13 @@ void BLI_adddirstrings()
                sprintf(buf,"%s %s %s %7s %s %s %10s %s", file->mode1, file->mode2, file->mode3, files[num].owner, files[num].date, files[num].time, size,
                        files[num].relname);
 
-               files[num].string=malloc(strlen(buf)+1);
+               files[num].string=MEM_mallocN(strlen(buf)+1, "filestring");
                if (files[num].string){
                        strcpy(files[num].string,buf);
                }
 
                file++;
        }
-#ifndef WIN32
-       BLI_freepwtable(pwtable);
-#endif
 }
 
 unsigned int BLI_getdir(char *dirname,  struct direntry **filelist)
@@ -514,13 +483,35 @@ int BLI_filesize(int file)
        return (buf.st_size);
 }
 
+int BLI_filepathsize(const char *path)
+{
+       int size, file = open(path, O_BINARY|O_RDONLY);
+       
+       if (file <= 0)
+               return -1;
+       
+       size = BLI_filesize(file);
+       close(file);
+       return size;
+}
 
 
 int BLI_exist(char *name)
 {
        struct stat st;
-
-       if (stat(name,&st)) return(0);
+#ifdef WIN32
+       /*  in Windows stat doesn't recognize dir ending on a slash 
+               To not break code where the ending slash is expected we
+               don't mess with the argument name directly here - elubie */
+       char tmp[FILE_MAXDIR+FILE_MAXFILE];
+       int len;
+       BLI_strncpy(tmp, name, FILE_MAXDIR+FILE_MAXFILE);
+       len = strlen(tmp);
+       if (len > 3 && ( tmp[len-1]=='\\' || tmp[len-1]=='/') ) tmp[len-1] = '\0';
+       if (stat(tmp,&st)) return(0);
+#else
+       if (stat(name,&st)) return(0);  
+#endif
        return(st.st_mode);
 }