Continue development of bfile system.
authorGuillermo S. Romero <gsr.b3d@infernal-iceberg.com>
Mon, 19 Oct 2009 18:44:09 +0000 (18:44 +0000)
committerGuillermo S. Romero <gsr.b3d@infernal-iceberg.com>
Mon, 19 Oct 2009 18:44:09 +0000 (18:44 +0000)
Still not usable, but some parts could be made more portable already.
Help welcome for MacOSX and MSWindows calls and paths.

release/environment-macosx [new file with mode: 0644]
release/environment-mswindows [new file with mode: 0644]
release/environment-unix [new file with mode: 0644]
source/blender/blenlib/BLI_bfile.h
source/blender/blenlib/BLI_util.h
source/blender/blenlib/intern/BLI_bfile.c
source/blender/blenlib/intern/util.c

diff --git a/release/environment-macosx b/release/environment-macosx
new file mode 100644 (file)
index 0000000..d41d5ec
--- /dev/null
@@ -0,0 +1,18 @@
+# This is a Blender Environment Variable config file.
+#
+# Comment lines start with "#", other lines will be split at the "="
+# and the part before will be used as env var name and the part after
+# as env var value. The value can make reference to previous or
+# prelaunch variables with "${}" and the content will be replaced.
+# Once set, values of variables will not be overwritten.
+#
+# BLENDER_SHARE should be /Library/Application Support/Blender for typical installs.
+# BLENDER_VERSION will be set by the program before processing this file.
+BLENDER_USER_BASE=${HOME}/Library/Application Support/Blender/${BLENDER_VERSION}
+BLENDER_SYSTEM_BASE=${BLENDER_SHARE}/${BLENDER_VERSION}
+BLENDER_USER_DATAFILES=${HOME}/Library/Application Support/Blender/${BLENDER_VERSION}/datafiles
+BLENDER_SYSTEM_DATAFILES=${BLENDER_SHARE}/${BLENDER_VERSION}/datafiles
+BLENDER_USER_PY=${HOME}/Library/Application Support/Blender/${BLENDER_VERSION}/py
+BLENDER_SYSTEM_PY=${BLENDER_SHARE}/${BLENDER_VERSION}/py
+BLENDER_USER_PLUGINS=${HOME}/Library/Application Support/Blender/${BLENDER_VERSION}/plugins
+BLENDER_SYSTEM_PLUGINS=${BLENDER_SHARE}/${BLENDER_VERSION}/plugins
diff --git a/release/environment-mswindows b/release/environment-mswindows
new file mode 100644 (file)
index 0000000..f8890f8
--- /dev/null
@@ -0,0 +1,18 @@
+# This is a Blender Environment Variable config file.\r
+#\r
+# Comment lines start with "#", other lines will be split at the "="\r
+# and the part before will be used as env var name and the part after\r
+# as env var value. The value can make reference to previous or\r
+# prelaunch variables with "%%" and the content will be replaced.\r
+# Once set, values of variables will not be overwritten.\r
+#\r
+# BLENDER_SHARE should be COMMON_APPDATA\\Blender Foundation\\Blender for typical installs.\r
+# BLENDER_VERSION will be set by the program before processing this file.\r
+BLENDER_USER_BASE=%USERPROFILE%\\Blender Foundation\\Blender\\%BLENDER_VERSION%\r
+BLENDER_SYSTEM_BASE=%BLENDER_SHARE%\\%BLENDER_VERSION%\r
+BLENDER_USER_DATAFILES=%USERPROFILE%\\Blender Foundation\\%BLENDER_VERSION%\\datafiles\r
+BLENDER_SYSTEM_DATAFILES=%BLENDER_SHARE%\\%BLENDER_VERSION%\\datafiles\r
+BLENDER_USER_PY=%USERPROFILE%\\Blender Foundation\\%BLENDER_VERSION%\\py\r
+BLENDER_SYSTEM_PY=%BLENDER_SHARE%\\%BLENDER_VERSION%\\py\r
+BLENDER_USER_PLUGINS=%USERPROFILE%\\Blender Foundation\\%BLENDER_VERSION%\\plugins\r
+BLENDER_SYSTEM_PLUGINS=%BLENDER_SHARE%\\%BLENDER_VERSION%\\plugins\r
diff --git a/release/environment-unix b/release/environment-unix
new file mode 100644 (file)
index 0000000..8a13c28
--- /dev/null
@@ -0,0 +1,18 @@
+# This is a Blender Environment Variable config file.
+#
+# Comment lines start with "#", other lines will be split at the "="
+# and the part before will be used as env var name and the part after
+# as env var value. The value can make reference to previous or
+# prelaunch variables with "${}" and the content will be replaced.
+# Once set, values of variables will not be overwritten.
+#
+# BLENDER_SHARE should be /usr/share/blender for typical distro installs.
+# BLENDER_VERSION will be set by the program before processing this file.
+BLENDER_USER_BASE=${HOME}/.blender/${BLENDER_VERSION}
+BLENDER_SYSTEM_BASE=${BLENDER_SHARE}/${BLENDER_VERSION}
+BLENDER_USER_DATAFILES=${HOME}/.blender/${BLENDER_VERSION}/datafiles
+BLENDER_SYSTEM_DATAFILES=${BLENDER_SHARE}/${BLENDER_VERSION}/datafiles
+BLENDER_USER_PY=${HOME}/.blender/${BLENDER_VERSION}/py
+BLENDER_SYSTEM_PY=${BLENDER_SHARE}/${BLENDER_VERSION}/py
+BLENDER_USER_PLUGINS=${HOME}/.blender/${BLENDER_VERSION}/plugins
+BLENDER_SYSTEM_PLUGINS=${BLENDER_SHARE}/${BLENDER_VERSION}/plugins
index 92543558a19e559672412775af0f228516a3c853..15374b4d44563e4eac26d0c00ebf1c070d1cb2ec 100644 (file)
@@ -38,9 +38,9 @@
 #define BFILE_NORMAL (0)
 /* No supervision, just translate // if needed, RISKY */
 #define BFILE_RAW    (1<<0)
-/* Path is relative to config dirs */
+/* Path is based in env vars specified by "envvars" */
 #define BFILE_CONFIG (1<<1)
-/* Path is for current session temp file */
+/* Path is for current session temp files */
 #define BFILE_TEMP   (1<<2)
 
 /* Config handling, special cases: */
 /* Compression to apply on close: */
 #define BFILE_GZIP (1<<5)
 
+/**
+ For the envvars param.
+ */
+typedef enum BEnvVarFamilies {
+       BENV_NONE,
+       BENV_BASE,
+       BENV_DATAFILES,
+       BENV_PYTHON,
+       BENV_PLUGINS
+} BEnvVarFam;
+
 /**
  File descriptor for Blender abstracted file access.
  */
@@ -58,22 +69,23 @@ typedef struct {
        int fd;
 
        /* Anything below should not be touched directly */
-       int uflags;  /* Special options requested by upper level, copy of bflags */
-       char *fpath; /* Final/requested path name */
-       char *tpath; /* Temp path name if applicable */
-       int type;    /* Own flags, common classification of open and fopen */
-       int error;   /* An op caused an error, unsafe to replace older files */
+       int uflags;       /* Special options requested by upper level, copy of bflags */
+       BEnvVarFam evars; /* What kind of file, describe the env vars to use */
+       char *fpath;      /* Final/requested path name */
+       char *tpath;      /* Temp path name if applicable */
+       int classf;       /* Own flags, common classification of open and fopen */
+       int error;        /* An op caused an error, unsafe to replace older files */
 } BFILE;
 
 /**
  Open a BFILE* with fopen()-like syntax.
  */
-BFILE *BLI_bfile_fopen(const char *path, const char *mode, int bflags);
+BFILE *BLI_bfile_fopen(const char *path, const char *mode, int bflags, BEnvVarFam envvars);
 
 /**
  Open a BFILE* with open()-like syntax.
  */
-BFILE *BLI_bfile_open(const char *pathname, int flags, int bflags);
+BFILE *BLI_bfile_open(const char *pathname, int flags, int bflags, BEnvVarFam envvars);
 
 /**
  Get the FILE* associated with the BFILE*.
index 1ce7a8cdb772c0818bad7fce6f4aefb3093a6008..7642b71eea08a242448cf5c42193c3aac082a038 100644 (file)
@@ -51,6 +51,7 @@ char *BLI_gethome_folder(char *folder_name, int flag);
 #define BLI_GETHOME_ALL                        (BLI_GETHOME_SYSTEM|BLI_GETHOME_LOCAL|BLI_GETHOME_USER)
 
 void BLI_setenv(const char *env, const char *val);
+void BLI_setenv_if_new(const char *env, const char* val);
 
 void BLI_make_file_string(const char *relabase, char *string,  const char *dir, const char *file);
 void BLI_make_exist(char *dir);
index a7ce1df5712f99bcd34f4738932a9096f8d8322b..4de1e6ce4a1996ffdc3650e01e9458c583f31874 100644 (file)
  */
 
 #include <string.h>
-
+#include <stdlib.h>
 #ifndef WIN32
   #include <unistd.h>
 #else
   #include <io.h>
   #include "BLI_winstuff.h"
 #endif
-
+#include <sys/param.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <libgen.h>
 
 #include "MEM_guardedalloc.h"
-
+#include "BKE_utildefines.h"
+#include "BKE_blender.h"
+#include "BLI_util.h"
+#include "BLI_fileops.h"
+#include "BLI_storage.h"
 #include "BLI_bfile.h"
 
-// This would provide config paths and their oldest viable version
-// so if there is an uncompatible change, user's old versions are not loaded
-//#include "bfile_tables.h"
-
-/* Internal bfile type flags */
-#define BTF_OPEN     (0)
-#define BTF_FOPEN    (1<<0)
-#define BTF_READ     (1<<1)
-#define BTF_WRITE    (1<<2)
-#define BTF_AT_END   (1<<3)
-#define BTF_DISCARD  (1<<4)
-
-
-void fill_paths(BFILE *bfile, const char *path) {
-       char* source_path = NULL;
-       int bflags = bfile->uflags;
-
-       if(bflags & BFILE_NORMAL || bflags & BFILE_RAW) {
-//             bfile->fpath is path with // replaced
-       }
-       if(bflags & BFILE_TEMP) {
-//             bfile->fpath is tempdir+path
-       }
-       if(bflags & BFILE_CONFIG) {
-//             bfile->fpath is userdir+version+path
-//             source_path is first hit in (if using fallback to older versions)
-//                 userdir+curversion+path (... userdir+limitversion+path) sysdir+path
-//             (limitversion is based in path, using some kind of regex or "tables")
-       }
-
-       if(bfile->type & BTF_WRITE && !(bflags & BFILE_RAW)) {
-               /* Generate temp path */
-               // bfile->tpath is fpath+randstring
-               if(!(bfile->type & BTF_DISCARD)) {
-                       /* Copy data to tpath */
-                       if(source_path) {
-                               // copy it from older version or sys version
-                       }
-               }
-       } else {
-               bfile->tpath = bfile->fpath;
-       }
-}
-
-BFILE *BLI_bfile_fopen(const char *path, const char *mode, int bflags) {
+/* Internal bfile classification flags */
+#define BCF_OPEN     (0)
+#define BCF_FOPEN    (1<<0)
+#define BCF_READ     (1<<1)
+#define BCF_WRITE    (1<<2)
+#define BCF_AT_END   (1<<3)
+#define BCF_DISCARD  (1<<4)
+
+/* Declaration of internal functions */
+void chomp(char* line);
+void expand_envvars(char* src, char* dst);
+void fill_paths(BFILE *bfile, const char *path);
+char* find_in_pathlist(char* filename, char* pathlist);
+void init_vars_from_file(const char* path);
+void setup_temp();
+
+/*** Exported functions ***/
+
+BFILE *BLI_bfile_fopen(const char *path, const char *mode, int bflags,
+                       BEnvVarFam envvars)
+{
        BFILE *bfile;
 
        bfile = MEM_mallocN(sizeof(BFILE), "bfile-fopen");
-       bfile->type = BTF_FOPEN;
+       bfile->classf = BCF_FOPEN;
        bfile->uflags = bflags;
 
        /* From fopen() doc, we can guess some logic:
-       r  BTF_READ
-       r+ BTF_READ | BTF_WRITE
-       w  BTF_DISCARD | BTF_WRITE
-       w+ BTF_DISCARD | BTF_WRITE | BTF_READ
-       a  BTF_AT_END | BTF_WRITE
-       a+ BTF_AT_END | BTF_WRITE | BTF_READ
+       r  BCF_READ
+       r+ BCF_READ | BCF_WRITE
+       w  BCF_DISCARD | BCF_WRITE
+       w+ BCF_DISCARD | BCF_WRITE | BCF_READ
+       a  BCF_AT_END | BCF_WRITE
+       a+ BCF_AT_END | BCF_WRITE | BCF_READ
        */
        if(strchr(mode, 'r'))
-               bfile->type |= BTF_READ;
+               bfile->classf |= BCF_READ;
        if(strchr(mode, 'w'))
-               bfile->type |= (BTF_DISCARD | BTF_WRITE);
+               bfile->classf |= (BCF_DISCARD | BCF_WRITE);
        if(strchr(mode, 'a'))
-               bfile->type |= (BTF_AT_END | BTF_WRITE);
+               bfile->classf |= (BCF_AT_END | BCF_WRITE);
        if(strchr(mode, '+'))
-               bfile->type |= (BTF_READ | BTF_WRITE);
+               bfile->classf |= (BCF_READ | BCF_WRITE);
 
        fill_paths(bfile, path);
 
@@ -118,24 +99,26 @@ BFILE *BLI_bfile_fopen(const char *path, const char *mode, int bflags) {
 }
 
 
-BFILE *BLI_bfile_open(const char *pathname, int flags, int bflags) {
+BFILE *BLI_bfile_open(const char *pathname, int flags, int bflags,
+                      BEnvVarFam envvars)
+{
        BFILE *bfile;
 
        bfile = MEM_mallocN(sizeof(BFILE), "bfile-open");
-       bfile->type = BTF_OPEN;
+       bfile->classf = BCF_OPEN;
        bfile->uflags = bflags;
 
        /* Easy mapping for open() */
        if(flags & O_RDONLY)
-               bfile->type |= BTF_READ;
+               bfile->classf |= BCF_READ;
        if(flags & O_WRONLY)
-               bfile->type |= BTF_WRITE;
+               bfile->classf |= BCF_WRITE;
        if(flags & O_RDWR)
-               bfile->type |= (BTF_READ | BTF_WRITE);
+               bfile->classf |= (BCF_READ | BCF_WRITE);
        if(flags & O_APPEND)
-               bfile->type |= BTF_AT_END;
+               bfile->classf |= BCF_AT_END;
        if(flags & O_TRUNC)
-               bfile->type |= BTF_DISCARD;
+               bfile->classf |= BCF_DISCARD;
 
        fill_paths(bfile, pathname);
 
@@ -180,7 +163,9 @@ ssize_t BLI_bfile_read(BFILE *f, void *buf, size_t count) {
 }
 
 
-size_t BLI_bfile_fwrite(const void *ptr, size_t size, size_t nmemb, BFILE *f) {
+size_t BLI_bfile_fwrite(const void *ptr, size_t size, size_t nmemb,
+                        BFILE *f)
+{
        size_t ret;
 
        ret = fwrite(ptr, size, nmemb, f->stream);
@@ -205,7 +190,7 @@ size_t BLI_bfile_fread(void *ptr, size_t size, size_t nmemb, BFILE *f) {
 
 
 void BLI_bfile_close(BFILE *bfile) {
-       if((bfile->type | BTF_WRITE) &&
+       if((bfile->classf | BCF_WRITE) &&
           !(bfile->uflags | BFILE_RAW)) {
                /* Make sure data is on disk */
                /* Move to final name if no errors */
@@ -234,3 +219,296 @@ void BLI_bfile_set_error(BFILE *bfile, int error) {
                bfile->error = error;
        }
 }
+
+
+#if defined(WIN32)
+ #define LAST_SESSION_FILE "%HOME%\\Blender\\last-session FIXME FIXME FIXME"
+ #define ENVIRONMENT_FILE "FIXME"
+ #define SHARED_DIRECTORY "FIXME TOO"
+#elif defined(OSX)
+ #define LAST_SESSION_FILE "${HOME}/Library/Application Support/Blender/last-session"
+ #define ENVIRONMENT_FILE "${HOME}/Library/Application Support/Blender/${BLENDER_VERSION}/environment"
+ #define SHARED_DIRECTORY "/Library/Application Support/Blender"
+#else
+ #define LAST_SESSION_FILE "${HOME}/.blender/last-session"
+ #define ENVIRONMENT_FILE "${HOME}/.blender/${BLENDER_VERSION}/environment"
+ #define SHARED_DIRECTORY "/usr/share/blender"
+#endif
+void BLI_bfile_init_vars() {
+       char file[MAXPATHLEN];
+       char temp[MAXPATHLEN];
+       extern char bprogname[];
+       FILE* fp;
+
+       /* This one is unconditional */
+       sprintf(temp, "%d", BLENDER_VERSION);
+       BLI_setenv("BLENDER_VERSION", temp);
+
+       /* Is this unpack&run? */
+       sprintf(temp, "%s/%d/environment", dirname(bprogname), BLENDER_VERSION);
+       if(BLI_exist(temp)) {
+               BLI_setenv_if_new("BLENDER_SHARE", dirname(bprogname));
+       } else {
+               BLI_setenv_if_new("BLENDER_SHARE", SHARED_DIRECTORY);
+       }
+
+       expand_envvars(LAST_SESSION_FILE, file);
+       fp = fopen(file, "r");
+       /* 1st line, read previous version */
+       if (fp && (fscanf(fp, "%3c\n", temp) == 1)) {
+               temp[3] = '\0';
+               BLI_setenv("BLENDER_VERSION_PREV", temp);
+               /* 2nd line, read previous session path if needed */
+               if(!getenv("BLENDER_TEMP")) {
+                       if ((fgets(temp, MAXPATHLEN, fp) != NULL)) {
+                               /* Clean any \n */
+                               chomp(temp);
+                               /* Check the dir is still there or generate new one */
+                               if(!BLI_exist(temp)) {
+                                       setup_temp();
+                               }
+                       } else {
+                               /* We have to generate it for sure */
+                               setup_temp();
+                       }
+               }
+       } else {
+               /* Probably new user, or only <=249 before */
+               BLI_setenv("BLENDER_VERSION_PREV", "0");
+               setup_temp();
+       }
+
+       if(fp) {
+               fclose(fp);
+       }
+
+       /* Load vars from user and system files */
+       expand_envvars(ENVIRONMENT_FILE, file);
+       init_vars_from_file(file);
+       sprintf(temp, "/%d/environment", BLENDER_VERSION);
+       BLI_make_file_string("/", file, getenv("BLENDER_SHARE"), temp);
+       init_vars_from_file(file);
+}
+
+
+/*** Internal functions ***/
+
+/**
+ Eliminate trailing EOL by writing a \0 over it.
+ Name taken from Perl.
+ */
+void chomp(char* line) {
+       int len = strlen(line);
+#ifndef WIN32
+       if (line[len - 1] == '\n') {
+               line[len - 1] = '\0';
+       }
+#else
+       if ((line[len - 2] == '\r' ) && ((line[len - 1] == '\n'))) {
+               line[len - 2] = '\0';
+       }
+#endif /* WIN32 */
+}
+
+
+/**
+ Parse a file with lines like FOO=bar (comment lines have # as first
+ character) assigning to envvar FOO the value bar if FOO does not
+ exist yet.
+ Any white space before FOO, around the = or trailing will be used,
+ so beware.
+ */
+#define MAX_LINE 4096
+#define ENV_VAR 256
+#define VAR_LEN 8192
+void init_vars_from_file(const char* path) {
+       char line[MAX_LINE];
+       char name[ENV_VAR];
+       FILE *fp;
+       char* separator;
+       char expanded[VAR_LEN];
+
+       fp = fopen(path, "r");
+       if (!fp) return;
+
+       while (fgets(line, MAX_LINE, fp) != NULL) {
+               /* Ignore comment lines */
+               if (line[0] == '#')
+                       continue;
+
+               /* Split into envvar name and contents */
+               separator = strchr(line, '=');
+               if(separator && ((separator - line) < ENV_VAR)) {
+                       /* First remove EOL */
+                       chomp(line);
+                       strncpy(name, line, separator - line);
+                       name[separator - line] = '\0';
+                       expand_envvars(separator + 1, expanded);
+                       BLI_setenv_if_new(name, expanded);
+               }
+       }
+       fclose(fp);
+}
+
+
+/**
+ Look for ${} (or %%) env vars in src and expand if the var
+ exists (even if empty value). If not exist, the name is left as is.
+ The process is done all over src, and nested ${${}} is not supported.
+ src must be \0 terminated, and dst must be big enough.
+*/
+#ifndef WIN32
+ #define ENVVAR_PREFFIX "${"
+ #define ENVVAR_P_SIZE 2
+ #define ENVVAR_SUFFIX "}"
+ #define ENVVAR_S_SIZE 1
+#else
+ #define ENVVAR_PREFFIX "%"
+ #define ENVVAR_P_SIZE 1
+ #define ENVVAR_SUFFIX "%"
+ #define ENVVAR_S_SIZE 1
+#endif /* WIN32 */
+void expand_envvars(char* src, char* dst) {
+       char* hit1;
+       char* hit2;
+       char name[ENV_VAR];
+       char* value;
+       int prevlen;
+       int done = 0;
+       char* source = src;
+
+       dst[0] = '\0';
+       while (!done) {
+               hit1 = strstr(source, ENVVAR_PREFFIX);
+               if (hit1) {
+                       hit2 = strstr(hit1 + ENVVAR_P_SIZE, ENVVAR_SUFFIX);
+                       if (hit2) {
+                               /* "Copy" the leading part, if any */
+                               if (hit1 != source) {
+                                       prevlen = strlen(dst);
+                                       strncat(dst, source, hit1 - source);
+                                       dst[prevlen + (hit1 - source)] = '\0';
+                               }
+                               /* Figure the name of the env var we just found  */
+                               strncpy(name, hit1 + ENVVAR_P_SIZE,
+                                       hit2 - (hit1 + ENVVAR_P_SIZE));
+                               name[hit2 - (hit1 + ENVVAR_P_SIZE)] = '\0';
+                               /* See if we can get something with that name */
+                               value = getenv(name);
+                               if (value) {
+                                       /* Push the var value */
+                                       strcat(dst, value);
+                               } else {
+                                       /* Leave the var name, so it is clear that it failed */
+                                       strcat(dst, ENVVAR_PREFFIX);
+                                       strcat(dst, name);
+                                       strcat(dst, ENVVAR_SUFFIX);
+                               }
+                               /* Continue after closing mark, like a new string */
+                               source = hit2 + ENVVAR_S_SIZE;
+                       } else {
+                               /* Non terminated var so "copy as is" and finish */
+                               strcat(dst, source);
+                               done = 1;
+                       }
+               } else {
+                       /* "Copy" whatever is left */
+                       strcat(dst, source);
+                       done = 1;
+               }
+       }
+}
+
+
+/**
+ Return a full path if the filename exists when combined
+ with any item from pathlist. Or NULL otherwise.
+ */
+#ifdef WIN32
+ #define SEPARATOR ';'
+#else
+ #define SEPARATOR ':'
+#endif
+char* find_in_pathlist(char* filename, char* pathlist) {
+       char first[FILE_MAX + 10];
+       char* rest = NULL;
+
+       /* Separate first path from rest, use typical separator for current OS */
+       rest = strchr(pathlist, SEPARATOR);
+       if (rest) {
+               strncpy(first, pathlist, rest - pathlist);
+               first[rest - pathlist] = '\0';
+               /* Skip the separator so it becomes a valid new pathlist */
+               rest++;
+       } else {
+               strcpy(first, pathlist);
+       }
+
+       /* Check if combination exists */
+       BLI_add_slash(first);
+       strcat(first, filename);
+       if(BLI_exist(first)) {
+               return strdup(first);
+       }
+
+       /* First path failed, try with rest of paths if possible */
+       if(rest) {
+               return find_in_pathlist(filename, rest);
+       } else {
+               return NULL;
+       }
+}
+
+
+/**
+ Setup fpath and tpath based in the needs of the bfile.
+ */
+void fill_paths(BFILE *bfile, const char *path) {
+       char* source_path = NULL;
+       int bflags = bfile->uflags;
+
+       if(bflags & BFILE_NORMAL || bflags & BFILE_RAW) {
+//             bfile->fpath is path with // replaced
+       }
+       if(bflags & BFILE_TEMP) {
+//             bfile->fpath is tempdir+path
+       }
+       if(bflags & BFILE_CONFIG) {
+//             bfile->fpath is userdir+version+path
+//             source_path is first hit in (if using fallback to older versions)
+//                 userdir+curversion+path (... userdir+limitversion+path) sysdir+path
+//             (limitversion is based in path, using some kind of regex or "tables")
+       }
+
+       if(bfile->classf & BCF_WRITE && !(bflags & BFILE_RAW)) {
+               /* Generate temp path */
+               // bfile->tpath is fpath+randstring
+               if(!(bfile->classf & BCF_DISCARD)) {
+                       /* Copy data to tpath */
+                       if(source_path) {
+                               // copy it from older version or sys version
+                       }
+               }
+       } else {
+               bfile->tpath = bfile->fpath;
+       }
+}
+
+
+/**
+ Create a temp directory in safe and multiuser way.
+ */
+void setup_temp() {
+       char template[MAXPATHLEN];
+       char* tempdir;
+
+       if(getenv("TMPDIR")) {
+               sprintf(template, "%s/blender-XXXXXX", getenv("TMPDIR"));
+       } else {
+               sprintf(template, "/tmp/blender-XXXXXX");
+// MacOSX NSTemporaryDirectory and WIN32 ???
+       }
+       tempdir = mkdtemp(template);
+       BLI_setenv("BLENDER_TEMP", tempdir);
+}
+
index 387d1881d3cf9eeaaf1e612952d8310d51a5743e..e2acbf21624427c607d71aa4b42dcf8c12b102d9 100644 (file)
@@ -992,6 +992,18 @@ void BLI_setenv(const char *env, const char*val)
 #endif
 }
 
+
+/**
+ Only set an env var if already not there.
+ Like Unix setenv(env, val, 0);
+ */
+void BLI_setenv_if_new(const char *env, const char* val)
+{
+       if(getenv(env) == NULL)
+               BLI_setenv(env, val);
+}
+
+
 void BLI_clean(char *path)
 {
        if(path==0) return;
@@ -1374,10 +1386,10 @@ void BLI_where_am_i(char *fullname, const char *name)
        char *path = NULL, *temp;
        
 #ifdef _WIN32
-       char *seperator = ";";
+       char *separator = ";";
        char slash = '\\';
 #else
-       char *seperator = ":";
+       char *separator = ":";
        char slash = '/';
 #endif
 
@@ -1415,7 +1427,7 @@ void BLI_where_am_i(char *fullname, const char *name)
                        path = getenv("PATH");
                        if (path) {
                                do {
-                                       temp = strstr(path, seperator);
+                                       temp = strstr(path, separator);
                                        if (temp) {
                                                strncpy(filename, path, temp - path);
                                                filename[temp - path] = 0;