Back to index

php5  5.3.10
Classes | Defines | Typedefs | Functions | Variables
tsrm_virtual_cwd.h File Reference
#include "TSRM.h"
#include "tsrm_config_common.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <unistd.h>
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _cwd_state
struct  _realpath_cache_bucket
struct  _virtual_cwd_globals

Defines

#define DEFAULT_SLASH   '/'
#define DEFAULT_DIR_SEPARATOR   ':'
#define IS_SLASH(c)   ((c) == '/')
#define IS_SLASH_P(c)   (*(c) == '/')
#define COPY_WHEN_ABSOLUTE(path)   0
#define IS_ABSOLUTE_PATH(path, len)   (IS_SLASH(path[0]))
#define CWD_API
#define php_sys_stat   stat
#define php_sys_lstat   lstat
#define CWD_EXPAND   0 /* expand "." and ".." but dont resolve symlinks */
#define CWD_FILEPATH   1 /* resolve symlinks if file is exist otherwise expand */
#define CWD_REALPATH   2 /* call realpath(), resolve symlinks. File must exist */
#define REALPATH_CACHE_TTL   (2*60) /* 2 minutes */
#define REALPATH_CACHE_SIZE   0 /* disabled while php.ini isn't loaded */
#define CWDG(v)   (cwd_globals.v)
#define VCWD_GETCWD(buff, size)   getcwd(buff, size)
#define VCWD_FOPEN(path, mode)   fopen(path, mode)
#define VCWD_OPEN(path, flags)   open(path, flags)
#define VCWD_OPEN_MODE(path, flags, mode)   open(path, flags, mode)
#define VCWD_CREAT(path, mode)   creat(path, mode)
#define VCWD_RENAME(oldname, newname)   rename(oldname, newname)
#define VCWD_CHDIR(path)   chdir(path)
#define VCWD_CHDIR_FILE(path)   virtual_chdir_file(path, chdir)
#define VCWD_GETWD(buf)   getwd(buf)
#define VCWD_STAT(path, buff)   php_sys_stat(path, buff)
#define VCWD_LSTAT(path, buff)   lstat(path, buff)
#define VCWD_UNLINK(path)   unlink(path)
#define VCWD_MKDIR(pathname, mode)   mkdir(pathname, mode)
#define VCWD_RMDIR(pathname)   rmdir(pathname)
#define VCWD_OPENDIR(pathname)   opendir(pathname)
#define VCWD_POPEN(command, type)   popen(command, type)
#define VCWD_ACCESS(pathname, mode)   access(pathname, mode)
#define VCWD_REALPATH(path, real_path)   tsrm_realpath(path, real_path TSRMLS_CC)
#define VCWD_CHMOD(path, mode)   chmod(path, mode)
#define VCWD_CHOWN(path, owner, group)   chown(path, owner, group)

Typedefs

typedef struct _cwd_state cwd_state
typedef int(* verify_path_func )(const cwd_state *)
typedef struct
_realpath_cache_bucket 
realpath_cache_bucket
typedef struct _virtual_cwd_globals virtual_cwd_globals

Functions

CWD_API void virtual_cwd_startup (void)
CWD_API void virtual_cwd_shutdown (void)
CWD_API char * virtual_getcwd_ex (size_t *length TSRMLS_DC)
CWD_API char * virtual_getcwd (char *buf, size_t size TSRMLS_DC)
CWD_API int virtual_chdir (const char *path TSRMLS_DC)
CWD_API int virtual_chdir_file (const char *path, int(*p_chdir)(const char *path TSRMLS_DC) TSRMLS_DC)
CWD_API int virtual_filepath (const char *path, char **filepath TSRMLS_DC)
CWD_API int virtual_filepath_ex (const char *path, char **filepath, verify_path_func verify_path TSRMLS_DC)
CWD_API char * virtual_realpath (const char *path, char *real_path TSRMLS_DC)
CWD_API FILE * virtual_fopen (const char *path, const char *mode TSRMLS_DC)
CWD_API int virtual_open (const char *path TSRMLS_DC, int flags,...)
CWD_API int virtual_creat (const char *path, mode_t mode TSRMLS_DC)
CWD_API int virtual_rename (char *oldname, char *newname TSRMLS_DC)
CWD_API int virtual_stat (const char *path, struct stat *buf TSRMLS_DC)
CWD_API int virtual_lstat (const char *path, struct stat *buf TSRMLS_DC)
CWD_API int virtual_unlink (const char *path TSRMLS_DC)
CWD_API int virtual_mkdir (const char *pathname, mode_t mode TSRMLS_DC)
CWD_API int virtual_rmdir (const char *pathname TSRMLS_DC)
CWD_API DIRvirtual_opendir (const char *pathname TSRMLS_DC)
CWD_API FILE * virtual_popen (const char *command, const char *type TSRMLS_DC)
CWD_API int virtual_access (const char *pathname, int mode TSRMLS_DC)
CWD_API int virtual_chmod (const char *filename, mode_t mode TSRMLS_DC)
CWD_API int virtual_chown (const char *filename, uid_t owner, gid_t group, int link TSRMLS_DC)
CWD_API int virtual_file_ex (cwd_state *state, const char *path, verify_path_func verify_path, int use_realpath)
CWD_API char * tsrm_realpath (const char *path, char *real_path TSRMLS_DC)
CWD_API void realpath_cache_clean (TSRMLS_D)
CWD_API void realpath_cache_del (const char *path, int path_len TSRMLS_DC)
CWD_API realpath_cache_bucketrealpath_cache_lookup (const char *path, int path_len, time_t t TSRMLS_DC)
CWD_API int realpath_cache_size (TSRMLS_D)
CWD_API int realpath_cache_max_buckets (TSRMLS_D)
CWD_API realpath_cache_bucket ** realpath_cache_get_buckets (TSRMLS_D)

Variables

virtual_cwd_globals cwd_globals

Class Documentation

struct _cwd_state

Definition at line 145 of file tsrm_virtual_cwd.h.

Class Members
char * cwd
int cwd_length
struct _realpath_cache_bucket

Definition at line 211 of file tsrm_virtual_cwd.h.

Collaboration diagram for _realpath_cache_bucket:
Class Members
time_t expires
int is_dir
unsigned long key
struct _realpath_cache_bucket * next
char * path
int path_len
char * realpath
int realpath_len
struct _virtual_cwd_globals

Definition at line 228 of file tsrm_virtual_cwd.h.

Collaboration diagram for _virtual_cwd_globals:
Class Members
cwd_state cwd
realpath_cache_bucket * realpath_cache
long realpath_cache_size
long realpath_cache_size_limit
long realpath_cache_ttl

Define Documentation

#define COPY_WHEN_ABSOLUTE (   path)    0

Definition at line 108 of file tsrm_virtual_cwd.h.

#define CWD_API

Definition at line 129 of file tsrm_virtual_cwd.h.

#define CWD_EXPAND   0 /* expand "." and ".." but dont resolve symlinks */

Definition at line 200 of file tsrm_virtual_cwd.h.

#define CWD_FILEPATH   1 /* resolve symlinks if file is exist otherwise expand */

Definition at line 201 of file tsrm_virtual_cwd.h.

#define CWD_REALPATH   2 /* call realpath(), resolve symlinks. File must exist */

Definition at line 202 of file tsrm_virtual_cwd.h.

#define CWDG (   v)    (cwd_globals.v)

Definition at line 241 of file tsrm_virtual_cwd.h.

#define DEFAULT_DIR_SEPARATOR   ':'

Definition at line 98 of file tsrm_virtual_cwd.h.

#define DEFAULT_SLASH   '/'

Definition at line 93 of file tsrm_virtual_cwd.h.

#define IS_ABSOLUTE_PATH (   path,
  len 
)    (IS_SLASH(path[0]))

Definition at line 112 of file tsrm_virtual_cwd.h.

#define IS_SLASH (   c)    ((c) == '/')

Definition at line 101 of file tsrm_virtual_cwd.h.

#define IS_SLASH_P (   c)    (*(c) == '/')

Definition at line 102 of file tsrm_virtual_cwd.h.

#define php_sys_lstat   lstat

Definition at line 139 of file tsrm_virtual_cwd.h.

#define php_sys_stat   stat

Definition at line 138 of file tsrm_virtual_cwd.h.

#define REALPATH_CACHE_SIZE   0 /* disabled while php.ini isn't loaded */

Definition at line 209 of file tsrm_virtual_cwd.h.

#define REALPATH_CACHE_TTL   (2*60) /* 2 minutes */

Definition at line 208 of file tsrm_virtual_cwd.h.

#define VCWD_ACCESS (   pathname,
  mode 
)    access(pathname, mode)

Definition at line 315 of file tsrm_virtual_cwd.h.

#define VCWD_CHDIR (   path)    chdir(path)

Definition at line 302 of file tsrm_virtual_cwd.h.

#define VCWD_CHDIR_FILE (   path)    virtual_chdir_file(path, chdir)

Definition at line 303 of file tsrm_virtual_cwd.h.

#define VCWD_CHMOD (   path,
  mode 
)    chmod(path, mode)

Definition at line 328 of file tsrm_virtual_cwd.h.

#define VCWD_CHOWN (   path,
  owner,
  group 
)    chown(path, owner, group)

Definition at line 330 of file tsrm_virtual_cwd.h.

#define VCWD_CREAT (   path,
  mode 
)    creat(path, mode)

Definition at line 294 of file tsrm_virtual_cwd.h.

#define VCWD_FOPEN (   path,
  mode 
)    fopen(path, mode)

Definition at line 291 of file tsrm_virtual_cwd.h.

#define VCWD_GETCWD (   buff,
  size 
)    getcwd(buff, size)

Definition at line 290 of file tsrm_virtual_cwd.h.

#define VCWD_GETWD (   buf)    getwd(buf)

Definition at line 304 of file tsrm_virtual_cwd.h.

#define VCWD_LSTAT (   path,
  buff 
)    lstat(path, buff)

Definition at line 306 of file tsrm_virtual_cwd.h.

#define VCWD_MKDIR (   pathname,
  mode 
)    mkdir(pathname, mode)

Definition at line 308 of file tsrm_virtual_cwd.h.

#define VCWD_OPEN (   path,
  flags 
)    open(path, flags)

Definition at line 292 of file tsrm_virtual_cwd.h.

#define VCWD_OPEN_MODE (   path,
  flags,
  mode 
)    open(path, flags, mode)

Definition at line 293 of file tsrm_virtual_cwd.h.

#define VCWD_OPENDIR (   pathname)    opendir(pathname)

Definition at line 310 of file tsrm_virtual_cwd.h.

#define VCWD_POPEN (   command,
  type 
)    popen(command, type)

Definition at line 311 of file tsrm_virtual_cwd.h.

#define VCWD_REALPATH (   path,
  real_path 
)    tsrm_realpath(path, real_path TSRMLS_CC)

Definition at line 318 of file tsrm_virtual_cwd.h.

#define VCWD_RENAME (   oldname,
  newname 
)    rename(oldname, newname)

Definition at line 300 of file tsrm_virtual_cwd.h.

#define VCWD_RMDIR (   pathname)    rmdir(pathname)

Definition at line 309 of file tsrm_virtual_cwd.h.

#define VCWD_STAT (   path,
  buff 
)    php_sys_stat(path, buff)

Definition at line 305 of file tsrm_virtual_cwd.h.

#define VCWD_UNLINK (   path)    unlink(path)

Definition at line 307 of file tsrm_virtual_cwd.h.


Typedef Documentation

typedef struct _cwd_state cwd_state
typedef int(* verify_path_func)(const cwd_state *)

Definition at line 150 of file tsrm_virtual_cwd.h.


Function Documentation

Definition at line 600 of file tsrm_virtual_cwd.c.

{
       int i;

       for (i = 0; i < sizeof(CWDG(realpath_cache))/sizeof(CWDG(realpath_cache)[0]); i++) {
              realpath_cache_bucket *p = CWDG(realpath_cache)[i];
              while (p != NULL) {
                     realpath_cache_bucket *r = p;
                     p = p->next;
                     free(r);
              }
              CWDG(realpath_cache)[i] = NULL;
       }
       CWDG(realpath_cache_size) = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

CWD_API void realpath_cache_del ( const char *  path,
int path_len  TSRMLS_DC 
)

Definition at line 617 of file tsrm_virtual_cwd.c.

{
#ifdef PHP_WIN32
       unsigned long key = realpath_cache_key(path, path_len TSRMLS_CC);
#else
       unsigned long key = realpath_cache_key(path, path_len);
#endif
       unsigned long n = key % (sizeof(CWDG(realpath_cache)) / sizeof(CWDG(realpath_cache)[0]));
       realpath_cache_bucket **bucket = &CWDG(realpath_cache)[n];

       while (*bucket != NULL) {
              if (key == (*bucket)->key && path_len == (*bucket)->path_len &&
                                   memcmp(path, (*bucket)->path, path_len) == 0) {
                     realpath_cache_bucket *r = *bucket;
                     *bucket = (*bucket)->next;
                 
                     /* if the pointers match then only subtract the length of the path */
                     if(r->path == r->realpath) {
                            CWDG(realpath_cache_size) -= sizeof(realpath_cache_bucket) + r->path_len + 1;
                     } else {
                            CWDG(realpath_cache_size) -= sizeof(realpath_cache_bucket) + r->path_len + 1 + r->realpath_len + 1;
                     }
                 
                     free(r);
                     return;
              } else {
                     bucket = &(*bucket)->next;
              }
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 750 of file tsrm_virtual_cwd.c.

{
       return CWDG(realpath_cache);
}

Here is the caller graph for this function:

CWD_API realpath_cache_bucket* realpath_cache_lookup ( const char *  path,
int  path_len,
time_t t  TSRMLS_DC 
)

Definition at line 734 of file tsrm_virtual_cwd.c.

{
       return realpath_cache_find(path, path_len, t TSRMLS_CC);
}

Here is the call graph for this function:

Definition at line 745 of file tsrm_virtual_cwd.c.

{
       return (sizeof(CWDG(realpath_cache)) / sizeof(CWDG(realpath_cache)[0]));
}

Here is the caller graph for this function:

Definition at line 740 of file tsrm_virtual_cwd.c.

Here is the call graph for this function:

Here is the caller graph for this function:

CWD_API char* tsrm_realpath ( const char *  path,
char *real_path  TSRMLS_DC 
)

Definition at line 1918 of file tsrm_virtual_cwd.c.

{
       cwd_state new_state;
       char cwd[MAXPATHLEN];

       /* realpath("") returns CWD */
       if (!*path) {
              new_state.cwd = (char*)malloc(1);
              if (new_state.cwd == NULL) {
                     return NULL;
              }
              new_state.cwd[0] = '\0';
              new_state.cwd_length = 0;
              if (VCWD_GETCWD(cwd, MAXPATHLEN)) {
                     path = cwd;
              }
       } else if (!IS_ABSOLUTE_PATH(path, strlen(path)) &&
                                   VCWD_GETCWD(cwd, MAXPATHLEN)) {
              new_state.cwd = strdup(cwd);
              new_state.cwd_length = strlen(cwd);
       } else {
              new_state.cwd = (char*)malloc(1);
              if (new_state.cwd == NULL) {
                     return NULL;
              }
              new_state.cwd[0] = '\0';
              new_state.cwd_length = 0;
       }

       if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH)) {
              free(new_state.cwd);
              return NULL;
       }

       if (real_path) {
              int copy_len = new_state.cwd_length>MAXPATHLEN-1 ? MAXPATHLEN-1 : new_state.cwd_length;
              memcpy(real_path, new_state.cwd, copy_len);
              real_path[copy_len] = '\0';
              free(new_state.cwd);
              return real_path;
       } else {
              return new_state.cwd;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

CWD_API int virtual_access ( const char *  pathname,
int mode  TSRMLS_DC 
)

Definition at line 1481 of file tsrm_virtual_cwd.c.

{
       cwd_state new_state;
       int ret;

       CWD_STATE_COPY(&new_state, &CWDG(cwd));
       if (virtual_file_ex(&new_state, pathname, NULL, CWD_REALPATH)) {
              CWD_STATE_FREE(&new_state);
              return -1;
       }

#if defined(TSRM_WIN32)
       ret = tsrm_win32_access(new_state.cwd, mode);
#else
       ret = access(new_state.cwd, mode);
#endif

       CWD_STATE_FREE(&new_state);

       return ret;
}

Here is the call graph for this function:

CWD_API int virtual_chdir ( const char *path  TSRMLS_DC)

Definition at line 1352 of file tsrm_virtual_cwd.c.

{
       return virtual_file_ex(&CWDG(cwd), path, php_is_dir_ok, CWD_REALPATH)?-1:0;
}

Here is the call graph for this function:

CWD_API int virtual_chdir_file ( const char *  path,
int(*)(const char *path TSRMLS_DC) TSRMLS_DC  p_chdir 
)

Definition at line 1358 of file tsrm_virtual_cwd.c.

{
       int length = strlen(path);
       char *temp;
       int retval;
       TSRM_ALLOCA_FLAG(use_heap)

       if (length == 0) {
              return 1; /* Can't cd to empty string */
       }
       while(--length >= 0 && !IS_SLASH(path[length])) {
       }

       if (length == -1) {
              /* No directory only file name */
              errno = ENOENT;
              return -1;
       }

       if (length == COPY_WHEN_ABSOLUTE(path) && IS_ABSOLUTE_PATH(path, length+1)) { /* Also use trailing slash if this is absolute */
              length++;
       }
       temp = (char *) tsrm_do_alloca(length+1, use_heap);
       memcpy(temp, path, length);
       temp[length] = 0;
#if VIRTUAL_CWD_DEBUG
       fprintf (stderr, "Changing directory to %s\n", temp);
#endif
       retval = p_chdir(temp TSRMLS_CC);
       tsrm_free_alloca(temp, use_heap);
       return retval;
}
CWD_API int virtual_chmod ( const char *  filename,
mode_t mode  TSRMLS_DC 
)

Definition at line 1577 of file tsrm_virtual_cwd.c.

{
       cwd_state new_state;
       int ret;

       CWD_STATE_COPY(&new_state, &CWDG(cwd));
       if (virtual_file_ex(&new_state, filename, NULL, CWD_REALPATH)) {
              CWD_STATE_FREE(&new_state);
              return -1;
       }

       ret = chmod(new_state.cwd, mode);

       CWD_STATE_FREE(&new_state);
       return ret;
}

Here is the call graph for this function:

CWD_API int virtual_chown ( const char *  filename,
uid_t  owner,
gid_t  group,
int link  TSRMLS_DC 
)

Definition at line 1596 of file tsrm_virtual_cwd.c.

{
       cwd_state new_state;
       int ret;

       CWD_STATE_COPY(&new_state, &CWDG(cwd));
       if (virtual_file_ex(&new_state, filename, NULL, CWD_REALPATH)) {
              CWD_STATE_FREE(&new_state);
              return -1;
       }

       if (link) {
#if HAVE_LCHOWN
              ret = lchown(new_state.cwd, owner, group);
#else
              ret = -1;
#endif
       } else {
              ret = chown(new_state.cwd, owner, group);
       }

       CWD_STATE_FREE(&new_state);
       return ret;
}

Here is the call graph for this function:

CWD_API int virtual_creat ( const char *  path,
mode_t mode  TSRMLS_DC 
)

Definition at line 1651 of file tsrm_virtual_cwd.c.

{
       cwd_state new_state;
       int f;

       CWD_STATE_COPY(&new_state, &CWDG(cwd));
       if (virtual_file_ex(&new_state, path, NULL, CWD_FILEPATH)) {
              CWD_STATE_FREE(&new_state);
              return -1;
       }

       f = creat(new_state.cwd,  mode);

       CWD_STATE_FREE(&new_state);
       return f;
}

Here is the call graph for this function:

CWD_API void virtual_cwd_shutdown ( void  )

Definition at line 488 of file tsrm_virtual_cwd.c.

{
#ifndef ZTS
       cwd_globals_dtor(&cwd_globals TSRMLS_CC);
#endif
#if (defined(TSRM_WIN32) || defined(NETWARE)) && defined(ZTS)
       tsrm_mutex_free(cwd_mutex);
#endif

       free(main_cwd_state.cwd); /* Don't use CWD_STATE_FREE because the non global states will probably use emalloc()/efree() */
}

Here is the call graph for this function:

Here is the caller graph for this function:

CWD_API void virtual_cwd_startup ( void  )

Definition at line 445 of file tsrm_virtual_cwd.c.

{
       char cwd[MAXPATHLEN];
       char *result;

#ifdef NETWARE
       result = getcwdpath(cwd, NULL, 1);
       if(result)
       {
              char *c=cwd;
              while(c = strchr(c, '\\'))
              {
                     *c='/';
                     ++c;
              }
       }
#else
       result = getcwd(cwd, sizeof(cwd));
#endif
       if (!result) {
              cwd[0] = '\0';
       }

       main_cwd_state.cwd_length = strlen(cwd);
#ifdef TSRM_WIN32
       if (main_cwd_state.cwd_length >= 2 && cwd[1] == ':') {
              cwd[0] = toupper(cwd[0]);
       }
#endif
       main_cwd_state.cwd = strdup(cwd);

#ifdef ZTS
       ts_allocate_id(&cwd_globals_id, sizeof(virtual_cwd_globals), (ts_allocate_ctor) cwd_globals_ctor, (ts_allocate_dtor) cwd_globals_dtor);
#else
       cwd_globals_ctor(&cwd_globals TSRMLS_CC);
#endif

#if (defined(TSRM_WIN32) || defined(NETWARE)) && defined(ZTS)
       cwd_mutex = tsrm_mutex_alloc();
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

CWD_API int virtual_file_ex ( cwd_state state,
const char *  path,
verify_path_func  verify_path,
int  use_realpath 
)

Definition at line 1148 of file tsrm_virtual_cwd.c.

{
       int path_length = strlen(path);
       char resolved_path[MAXPATHLEN];
       int start = 1;
       int ll = 0;
       time_t t;
       int ret;
       int add_slash;
       void *tmp;
       TSRMLS_FETCH();

       if (path_length == 0 || path_length >= MAXPATHLEN-1) {
#ifdef TSRM_WIN32
# if _MSC_VER < 1300
              errno = EINVAL;
# else
              _set_errno(EINVAL);
# endif
#else
              errno = EINVAL;
#endif
              return 1;
       }

#if VIRTUAL_CWD_DEBUG
       fprintf(stderr,"cwd = %s path = %s\n", state->cwd, path);
#endif

       /* cwd_length can be 0 when getcwd() fails.
        * This can happen under solaris when a dir does not have read permissions
        * but *does* have execute permissions */
       if (!IS_ABSOLUTE_PATH(path, path_length)) {
              if (state->cwd_length == 0) {
                     /* resolve relative path */
                     start = 0;
                     memcpy(resolved_path , path, path_length + 1);
              } else {
                     int state_cwd_length = state->cwd_length;

#ifdef TSRM_WIN32
                     if (IS_SLASH(path[0])) {
                            if (state->cwd[1] == ':') {
                                   /* Copy only the drive name */
                                   state_cwd_length = 2;
                            } else if (IS_UNC_PATH(state->cwd, state->cwd_length)) {
                                   /* Copy only the share name */
                                   state_cwd_length = 2;
                                   while (IS_SLASH(state->cwd[state_cwd_length])) {
                                          state_cwd_length++;
                                   }
                                   while (state->cwd[state_cwd_length] &&
                                                 !IS_SLASH(state->cwd[state_cwd_length])) {
                                          state_cwd_length++;
                                   }
                                   while (IS_SLASH(state->cwd[state_cwd_length])) {
                                          state_cwd_length++;
                                   }
                                   while (state->cwd[state_cwd_length] &&
                                                 !IS_SLASH(state->cwd[state_cwd_length])) {
                                          state_cwd_length++;
                                   }
                            }
                     }
#endif
                     if (path_length + state_cwd_length + 1 >= MAXPATHLEN-1) {
                            return 1;
                     }
                     memcpy(resolved_path, state->cwd, state_cwd_length);
                     resolved_path[state_cwd_length] = DEFAULT_SLASH;
                     memcpy(resolved_path + state_cwd_length + 1, path, path_length + 1);
                     path_length += state_cwd_length + 1;
              }
       } else {
#ifdef TSRM_WIN32
              if (path_length > 2 && path[1] == ':' && !IS_SLASH(path[2])) {
                     resolved_path[0] = path[0];
                     resolved_path[1] = ':';
                     resolved_path[2] = DEFAULT_SLASH;
                     memcpy(resolved_path + 3, path + 2, path_length - 1);
                     path_length++;
              } else
#endif
              memcpy(resolved_path, path, path_length + 1);
       }

#ifdef TSRM_WIN32
       if (memchr(resolved_path, '*', path_length) ||
              memchr(resolved_path, '?', path_length)) {
              return 1;
       }
#endif

#ifdef TSRM_WIN32
       if (IS_UNC_PATH(resolved_path, path_length)) {
              /* skip UNC name */
              resolved_path[0] = DEFAULT_SLASH;
              resolved_path[1] = DEFAULT_SLASH;
              start = 2;
              while (!IS_SLASH(resolved_path[start])) {
                     if (resolved_path[start] == 0) {
                            goto verify;
                     }
                     resolved_path[start] = toupper(resolved_path[start]);
                     start++;
              }
              resolved_path[start++] = DEFAULT_SLASH;
              while (!IS_SLASH(resolved_path[start])) {
                     if (resolved_path[start] == 0) {
                            goto verify;
                     }
                     resolved_path[start] = toupper(resolved_path[start]);
                     start++;
              }
              resolved_path[start++] = DEFAULT_SLASH;
       } else if (IS_ABSOLUTE_PATH(resolved_path, path_length)) {
              /* skip DRIVE name */
              resolved_path[0] = toupper(resolved_path[0]);
              resolved_path[2] = DEFAULT_SLASH;
              start = 3;
       }
#elif defined(NETWARE)
       if (IS_ABSOLUTE_PATH(resolved_path, path_length)) {
              /* skip VOLUME name */
              start = 0;
              while (start != ':') {
                     if (resolved_path[start] == 0) return -1;
                     start++;
              }
              start++;
              if (!IS_SLASH(resolved_path[start])) return -1;
              resolved_path[start++] = DEFAULT_SLASH;
       }
#endif

       add_slash = (use_realpath != CWD_REALPATH) && path_length > 0 && IS_SLASH(resolved_path[path_length-1]);
       t = CWDG(realpath_cache_ttl) ? 0 : -1;
       path_length = tsrm_realpath_r(resolved_path, start, path_length, &ll, &t, use_realpath, 0, NULL TSRMLS_CC);

       if (path_length < 0) {
              errno = ENOENT;
              return 1;
       }

       if (!start && !path_length) {
              resolved_path[path_length++] = '.';
       }
       if (add_slash && path_length && !IS_SLASH(resolved_path[path_length-1])) {
              if (path_length >= MAXPATHLEN-1) {
                     return -1;
              }
              resolved_path[path_length++] = DEFAULT_SLASH;
       }
       resolved_path[path_length] = 0;

#ifdef TSRM_WIN32
verify:
#endif
       if (verify_path) {
              cwd_state old_state;

              CWD_STATE_COPY(&old_state, state);
              state->cwd_length = path_length;

              tmp = realloc(state->cwd, state->cwd_length+1);
              if (tmp == NULL) {
#if VIRTUAL_CWD_DEBUG
                     fprintf (stderr, "Out of memory\n");
#endif
                     return 1;
              }
              state->cwd = (char *) tmp;

              memcpy(state->cwd, resolved_path, state->cwd_length+1);
              if (verify_path(state)) {
                     CWD_STATE_FREE(state);
                     *state = old_state;
                     ret = 1;
              } else {
                     CWD_STATE_FREE(&old_state);
                     ret = 0;
              }
       } else {
              state->cwd_length = path_length;
              tmp = realloc(state->cwd, state->cwd_length+1);
              if (tmp == NULL) {
#if VIRTUAL_CWD_DEBUG
                     fprintf (stderr, "Out of memory\n");
#endif
                     return 1;
              }
              state->cwd = (char *) tmp;

              memcpy(state->cwd, resolved_path, state->cwd_length+1);
              ret = 0;
       }

#if VIRTUAL_CWD_DEBUG
       fprintf (stderr, "virtual_file_ex() = %s\n",state->cwd);
#endif
       return (ret);
}

Here is the call graph for this function:

Here is the caller graph for this function:

CWD_API int virtual_filepath ( const char *  path,
char **filepath  TSRMLS_DC 
)

Definition at line 1453 of file tsrm_virtual_cwd.c.

{
       return virtual_filepath_ex(path, filepath, php_is_file_ok TSRMLS_CC);
}

Here is the call graph for this function:

CWD_API int virtual_filepath_ex ( const char *  path,
char **  filepath,
verify_path_func verify_path  TSRMLS_DC 
)

Definition at line 1438 of file tsrm_virtual_cwd.c.

{
       cwd_state new_state;
       int retval;

       CWD_STATE_COPY(&new_state, &CWDG(cwd));
       retval = virtual_file_ex(&new_state, path, verify_path, CWD_FILEPATH);

       *filepath = new_state.cwd;

       return retval;

}

Here is the call graph for this function:

Here is the caller graph for this function:

CWD_API FILE* virtual_fopen ( const char *  path,
const char *mode  TSRMLS_DC 
)

Definition at line 1459 of file tsrm_virtual_cwd.c.

{
       cwd_state new_state;
       FILE *f;

       if (path[0] == '\0') { /* Fail to open empty path */
              return NULL;
       }

       CWD_STATE_COPY(&new_state, &CWDG(cwd));
       if (virtual_file_ex(&new_state, path, NULL, CWD_FILEPATH)) {
              CWD_STATE_FREE(&new_state);
              return NULL;
       }

       f = fopen(new_state.cwd, mode);

       CWD_STATE_FREE(&new_state);
       return f;
}

Here is the call graph for this function:

CWD_API char* virtual_getcwd ( char *  buf,
size_t size  TSRMLS_DC 
)

Definition at line 543 of file tsrm_virtual_cwd.c.

{
       size_t length;
       char *cwd;

       cwd = virtual_getcwd_ex(&length TSRMLS_CC);

       if (buf == NULL) {
              return cwd;
       }
       if (length > size-1) {
              free(cwd);
              errno = ERANGE; /* Is this OK? */
              return NULL;
       }
       memcpy(buf, cwd, length+1);
       free(cwd);
       return buf;
}

Here is the call graph for this function:

CWD_API char* virtual_getcwd_ex ( size_t *length  TSRMLS_DC)

Definition at line 501 of file tsrm_virtual_cwd.c.

{
       cwd_state *state;

       state = &CWDG(cwd);

       if (state->cwd_length == 0) {
              char *retval;

              *length = 1;
              retval = (char *) malloc(2);
              if (retval == NULL) {
                     return NULL;
              }
              retval[0] = DEFAULT_SLASH;
              retval[1] = '\0';
              return retval;
       }

#ifdef TSRM_WIN32
       /* If we have something like C: */
       if (state->cwd_length == 2 && state->cwd[state->cwd_length-1] == ':') {
              char *retval;

              *length = state->cwd_length+1;
              retval = (char *) malloc(*length+1);
              if (retval == NULL) {
                     return NULL;
              }
              memcpy(retval, state->cwd, *length);
              retval[0] = toupper(retval[0]);
              retval[*length-1] = DEFAULT_SLASH;
              retval[*length] = '\0';
              return retval;
       }
#endif
       *length = state->cwd_length;
       return strdup(state->cwd);
}

Here is the caller graph for this function:

CWD_API int virtual_lstat ( const char *  path,
struct stat *buf  TSRMLS_DC 
)

Definition at line 1724 of file tsrm_virtual_cwd.c.

{
       cwd_state new_state;
       int retval;

       CWD_STATE_COPY(&new_state, &CWDG(cwd));
       if (virtual_file_ex(&new_state, path, NULL, CWD_EXPAND)) {
              CWD_STATE_FREE(&new_state);
              return -1;
       }

       retval = php_sys_lstat(new_state.cwd, buf);

       CWD_STATE_FREE(&new_state);
       return retval;
}

Here is the call graph for this function:

CWD_API int virtual_mkdir ( const char *  pathname,
mode_t mode  TSRMLS_DC 
)

Definition at line 1760 of file tsrm_virtual_cwd.c.

{
       cwd_state new_state;
       int retval;

       CWD_STATE_COPY(&new_state, &CWDG(cwd));
       if (virtual_file_ex(&new_state, pathname, NULL, CWD_FILEPATH)) {
              CWD_STATE_FREE(&new_state);
              return -1;
       }

#ifdef TSRM_WIN32
       retval = mkdir(new_state.cwd);
#else
       retval = mkdir(new_state.cwd, mode);
#endif
       CWD_STATE_FREE(&new_state);
       return retval;
}

Here is the call graph for this function:

CWD_API int virtual_open ( const char *path  TSRMLS_DC,
int  flags,
  ... 
)

Definition at line 1623 of file tsrm_virtual_cwd.c.

{
       cwd_state new_state;
       int f;

       CWD_STATE_COPY(&new_state, &CWDG(cwd));
       if (virtual_file_ex(&new_state, path, NULL, CWD_FILEPATH)) {
              CWD_STATE_FREE(&new_state);
              return -1;
       }

       if (flags & O_CREAT) {
              mode_t mode;
              va_list arg;

              va_start(arg, flags);
              mode = (mode_t) va_arg(arg, int);
              va_end(arg);

              f = open(new_state.cwd, flags, mode);
       } else {
              f = open(new_state.cwd, flags);
       }
       CWD_STATE_FREE(&new_state);
       return f;
}

Here is the call graph for this function:

CWD_API DIR* virtual_opendir ( const char *pathname  TSRMLS_DC)

Definition at line 1803 of file tsrm_virtual_cwd.c.

{
       cwd_state new_state;
       DIR *retval;

       CWD_STATE_COPY(&new_state, &CWDG(cwd));
       if (virtual_file_ex(&new_state, pathname, NULL, CWD_REALPATH)) {
              CWD_STATE_FREE(&new_state);
              return NULL;
       }

       retval = opendir(new_state.cwd);

       CWD_STATE_FREE(&new_state);
       return retval;
}

Here is the call graph for this function:

CWD_API FILE* virtual_popen ( const char *  command,
const char *type  TSRMLS_DC 
)

Definition at line 1858 of file tsrm_virtual_cwd.c.

{
       int command_length;
       int dir_length, extra = 0;
       char *command_line;
       char *ptr, *dir;
       FILE *retval;

       command_length = strlen(command);

       dir_length = CWDG(cwd).cwd_length;
       dir = CWDG(cwd).cwd;
       while (dir_length > 0) {
              if (*dir == '\'') extra+=3;
              dir++;
              dir_length--;
       }
       dir_length = CWDG(cwd).cwd_length;
       dir = CWDG(cwd).cwd;

       ptr = command_line = (char *) malloc(command_length + sizeof("cd '' ; ") + dir_length + extra+1+1);
       if (!command_line) {
              return NULL;
       }
       memcpy(ptr, "cd ", sizeof("cd ")-1);
       ptr += sizeof("cd ")-1;

       if (CWDG(cwd).cwd_length == 0) {
              *ptr++ = DEFAULT_SLASH;
       } else {
              *ptr++ = '\'';
              while (dir_length > 0) {
                     switch (*dir) {
                     case '\'':
                            *ptr++ = '\'';
                            *ptr++ = '\\';
                            *ptr++ = '\'';
                            /* fall-through */
                     default:
                            *ptr++ = *dir;
                     }
                     dir++;
                     dir_length--;
              }
              *ptr++ = '\'';
       }

       *ptr++ = ' ';
       *ptr++ = ';';
       *ptr++ = ' ';

       memcpy(ptr, command, command_length+1);
       retval = popen(command_line, type);

       free(command_line);
       return retval;
}

Here is the call graph for this function:

CWD_API char* virtual_realpath ( const char *  path,
char *real_path  TSRMLS_DC 
)

Definition at line 1392 of file tsrm_virtual_cwd.c.

{
       cwd_state new_state;
       char *retval;
       char cwd[MAXPATHLEN];

       /* realpath("") returns CWD */
       if (!*path) {
              new_state.cwd = (char*)malloc(1);
              if (new_state.cwd == NULL) {
                     retval = NULL;
                     goto end;
              }
              new_state.cwd[0] = '\0';
              new_state.cwd_length = 0;
              if (VCWD_GETCWD(cwd, MAXPATHLEN)) {
                     path = cwd;
              }
       } else if (!IS_ABSOLUTE_PATH(path, strlen(path))) {
              CWD_STATE_COPY(&new_state, &CWDG(cwd));
       } else {
              new_state.cwd = (char*)malloc(1);
              if (new_state.cwd == NULL) {
                     retval = NULL;
                     goto end;
              }
              new_state.cwd[0] = '\0';
              new_state.cwd_length = 0;
       }

       if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH)==0) {
              int len = new_state.cwd_length>MAXPATHLEN-1?MAXPATHLEN-1:new_state.cwd_length;

              memcpy(real_path, new_state.cwd, len);
              real_path[len] = '\0';
              retval = real_path;
       } else {
              retval = NULL;
       }

       CWD_STATE_FREE(&new_state);
end:
       return retval;
}

Here is the call graph for this function:

CWD_API int virtual_rename ( char *  oldname,
char *newname  TSRMLS_DC 
)

Definition at line 1669 of file tsrm_virtual_cwd.c.

{
       cwd_state old_state;
       cwd_state new_state;
       int retval;

       CWD_STATE_COPY(&old_state, &CWDG(cwd));
       if (virtual_file_ex(&old_state, oldname, NULL, CWD_EXPAND)) {
              CWD_STATE_FREE(&old_state);
              return -1;
       }
       oldname = old_state.cwd;

       CWD_STATE_COPY(&new_state, &CWDG(cwd));
       if (virtual_file_ex(&new_state, newname, NULL, CWD_EXPAND)) {
              CWD_STATE_FREE(&old_state);
              CWD_STATE_FREE(&new_state);
              return -1;
       }
       newname = new_state.cwd;

       /* rename on windows will fail if newname already exists.
          MoveFileEx has to be used */
#ifdef TSRM_WIN32
       /* MoveFileEx returns 0 on failure, other way 'round for this function */
       retval = (MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING|MOVEFILE_COPY_ALLOWED) == 0) ? -1 : 0;
#else
       retval = rename(oldname, newname);
#endif

       CWD_STATE_FREE(&old_state);
       CWD_STATE_FREE(&new_state);

       return retval;
}

Here is the call graph for this function:

CWD_API int virtual_rmdir ( const char *pathname  TSRMLS_DC)

Definition at line 1781 of file tsrm_virtual_cwd.c.

{
       cwd_state new_state;
       int retval;

       CWD_STATE_COPY(&new_state, &CWDG(cwd));
       if (virtual_file_ex(&new_state, pathname, NULL, CWD_EXPAND)) {
              CWD_STATE_FREE(&new_state);
              return -1;
       }

       retval = rmdir(new_state.cwd);

       CWD_STATE_FREE(&new_state);
       return retval;
}

Here is the call graph for this function:

CWD_API int virtual_stat ( const char *  path,
struct stat *buf  TSRMLS_DC 
)

Definition at line 1706 of file tsrm_virtual_cwd.c.

{
       cwd_state new_state;
       int retval;

       CWD_STATE_COPY(&new_state, &CWDG(cwd));
       if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH)) {
              CWD_STATE_FREE(&new_state);
              return -1;
       }

       retval = php_sys_stat(new_state.cwd, buf);

       CWD_STATE_FREE(&new_state);
       return retval;
}

Here is the call graph for this function:

CWD_API int virtual_unlink ( const char *path  TSRMLS_DC)

Definition at line 1742 of file tsrm_virtual_cwd.c.

{
       cwd_state new_state;
       int retval;

       CWD_STATE_COPY(&new_state, &CWDG(cwd));
       if (virtual_file_ex(&new_state, path, NULL, CWD_EXPAND)) {
              CWD_STATE_FREE(&new_state);
              return -1;
       }

       retval = unlink(new_state.cwd);

       CWD_STATE_FREE(&new_state);
       return retval;
}

Here is the call graph for this function:


Variable Documentation

Definition at line 76 of file tsrm_virtual_cwd.c.