]> granicus.if.org Git - php/commitdiff
- Try and fix problem with opening wrong file.
authorAndi Gutmans <andi@php.net>
Sun, 27 Aug 2000 18:01:17 +0000 (18:01 +0000)
committerAndi Gutmans <andi@php.net>
Sun, 27 Aug 2000 18:01:17 +0000 (18:01 +0000)
main/main.c
main/php.h
main/php_realpath.c [new file with mode: 0644]
main/php_virtual_cwd.c
main/php_virtual_cwd.h

index b52ae64031267ec311c981fdc09c5720561ca3dc..27330cffb69aad2e6cc8551b77c0cad0c5095a82 100644 (file)
@@ -1146,16 +1146,8 @@ PHPAPI void php_execute_script(zend_file_handle *primary_file CLS_DC ELS_DC PLS_
 
        if (primary_file->type == ZEND_HANDLE_FILENAME 
                        && primary_file->filename) {
-               char *filename;
-
-               filename = strrchr(primary_file->filename, PHP_DIR_SEPARATOR);
-               
-               if (filename) {
-                       filename++;
-                       V_GETCWD(old_cwd, sizeof(old_cwd)-1);
-                       V_CHDIR_FILE(primary_file->filename);
-                       primary_file->filename = filename;
-               }
+               V_GETCWD(old_cwd, sizeof(old_cwd)-1);
+               V_CHDIR_FILE(primary_file->filename);
        }
 
        if (PG(auto_prepend_file) && PG(auto_prepend_file)[0]) {
index 843dc243db7bcf603b20ba545d0c1067b6848ea3..4d5792559757c069eebecebee3fb6ec843d2885a 100644 (file)
@@ -316,7 +316,7 @@ PHPAPI int cfg_get_string(char *varname, char **result);
 #define V_OPEN(open_args) virtual_open open_args
 #define V_CREAT(path, mode) virtual_creat(path, mode)
 #define V_CHDIR(path) virtual_chdir(path)
-#define V_CHDIR_FILE(path) virtual_chdir_file(path)
+#define V_CHDIR_FILE(path) virtual_chdir_file(path, virtual_chdir)
 #define V_GETWD(buf)
 #define V_REALPATH(path,real_path) virtual_realpath(path,real_path)
 #define V_STAT(path, buff) virtual_stat(path, buff)
@@ -344,7 +344,7 @@ PHPAPI int cfg_get_string(char *varname, char **result);
 #define V_OPEN(open_args) open open_args
 #define V_CREAT(path, mode) creat(path, mode)
 #define V_CHDIR(path) chdir(path)
-#define V_CHDIR_FILE(path) virtual_real_chdir_file(path)
+#define V_CHDIR_FILE(path) virtual_real_chdir_file(path, chdir)
 #define V_GETWD(buf) getwd(buf)
 #define V_STAT(path, buff) stat(path, buff)
 #define V_LSTAT(path, buff) lstat(path, buff)
diff --git a/main/php_realpath.c b/main/php_realpath.c
new file mode 100644 (file)
index 0000000..8c7cef5
--- /dev/null
@@ -0,0 +1,283 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP version 4.0                                                      |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group                   |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 2.02 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available at through the world-wide-web at                           |
+   | http://www.php.net/license/2_02.txt.                                 |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Author: Sander Steffann (sander@steffann.nl)                         |
+   +----------------------------------------------------------------------+
+ */
+
+#include "php.h"
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <sys/stat.h>
+
+#ifndef MAXSYMLINKS
+#define MAXSYMLINKS            32
+#endif
+
+#ifndef S_ISDIR
+#define S_ISDIR(mode)   (((mode)&S_IFMT) == S_IFDIR)
+#endif
+
+char *php_realpath(char *path, char resolved_path[]);
+
+#ifdef PHP_WIN32
+#define IS_SLASH(p) ((p) == '/' || (p) == '\\')
+#else
+#define IS_SLASH(p) ((p) == '/')
+#endif
+
+char *php_realpath(char *path, char resolved_path []) {
+       char path_construction[MAXPATHLEN];     /* We build the result in here */
+       char *writepos;                                                 /* Position to write next char */
+
+       char path_copy[MAXPATHLEN];                             /* A work-copy of the path */
+       char *workpos;                                                  /* working position in *path */
+
+#if !defined(PHP_WIN32)
+       char buf[MAXPATHLEN];                                   /* Buffer for readlink */
+       int linklength;                                                 /* The result from readlink */
+#endif
+       int linkcount = 0;                                              /* Count symlinks to avoid loops */
+       
+       struct stat filestat;                                   /* result from stat */
+
+#ifdef PHP_WIN32
+       char *temppos;                                          /* position while counting '.' */
+       int dotcount;                                           /* number of '.' */
+       int t;                                                          /* counter */
+#endif
+
+       /* Set the work-position to the beginning of the given path */
+       strcpy(path_copy, path);
+       workpos = path_copy;
+       
+#ifdef PHP_WIN32
+       /* Find out where we start - Windows version */
+       if (IS_SLASH(*workpos)) {
+               /* We start at the root of the current drive */
+               /* Get the current directory */
+               if (V_GETCWD(path_construction, MAXPATHLEN-1) == NULL) {
+                       /* Unable to get cwd */
+                       resolved_path[0] = 0;
+                       return NULL;
+               }
+               /* We only need the first three chars (for example "C:\") */
+               path_construction[3] = 0;
+               workpos++;
+       } else if (workpos[1] == ':') {
+               /* A drive-letter is specified, copy it */
+               strncpy(path_construction, path, 2);
+               strcat(path_construction, "\\");
+               workpos++;
+               workpos++;
+       } else {
+               /* Use the current directory */
+               if (V_GETCWD(path_construction, MAXPATHLEN-1) == NULL) {
+                       /* Unable to get cwd */
+                       resolved_path[0] = 0;
+                       return NULL;
+               }
+               strcat(path_construction, "\\");
+       }
+#else
+       /* Find out where we start - Unix version */
+       if (*workpos == '/') {
+               /* We start at the root */
+               strcpy(path_construction, "/");
+               workpos++;
+       } else {
+               /* Use the current directory */
+               if (V_GETCWD(path_construction, MAXPATHLEN-1) == NULL) {
+                       /* Unable to get cwd */
+                       resolved_path[0] = 0;
+                       return NULL;
+               }
+               strcat(path_construction, "/");
+       }
+#endif
+
+       /* Set the next-char-position */
+       writepos = &path_construction[strlen(path_construction)];
+
+       /* Go to the end, then stop */
+       while(*workpos != 0) {
+               /* Strip (back)slashes */
+               while(IS_SLASH(*workpos)) workpos++;
+
+#ifdef PHP_WIN32
+               /* reset dotcount */
+               dotcount = 0;
+
+               /* Look for .. */
+               if ((workpos[0] == '.') && (workpos[1] != 0)) {
+                       /* Windows accepts \...\ as \..\..\, \....\ as \..\..\..\, etc */
+                       /* At least Win98 does */
+                       
+                       temppos = workpos;
+                       while(*temppos++ == '.') {
+                               dotcount++;
+                               if (!IS_SLASH(*temppos) && (*temppos != 0) && (*temppos != '.')) {
+                                       /* This is not a /../ component, but a filename that starts with '.' */
+                                       dotcount = 0;
+                               }
+                       }
+                       
+                       /* Go back dotcount-1 times */
+                       for (t=0 ; t<(dotcount-1) ; t++) {
+                               workpos++;              /* move to next '.' */
+                               
+                               /* Can we still go back? */
+                               if ((writepos-3) <= path_construction) return NULL;
+
+                               /* Go back */
+                               writepos--;                                             /* move to '\' */
+                               writepos--;
+                               while(!IS_SLASH(*writepos)) writepos--; /* skip until previous '\\' */
+                       }
+                       workpos++;
+               }
+
+               /* No special case */
+               if (dotcount == 0) {
+                       /* Append */
+                       while(!IS_SLASH(*workpos) && (*workpos != 0)) {
+                               *writepos++ = *workpos++;
+                       }
+               }
+
+               /* Just one '.', go to next element */
+               if (dotcount == 1) {
+                       while(!IS_SLASH(*workpos) && (*workpos != 0)) {
+                               *workpos++;
+                       }
+                       
+                       /* Avoid double \ in the result */
+                       writepos--;
+               }
+               
+               /* If it was a directory, append a slash */
+               if (IS_SLASH(*workpos)) {
+                       *writepos++ = *workpos++;
+               }
+               *writepos = 0;
+#else /* defined(PHP_WIN32) */
+               /* Look for .. */
+               if ((workpos[0] == '.') && (workpos[1] != 0)) {
+                       if ((workpos[1] == '.') && ((workpos[2] == '/') || (workpos[2] == 0))) {
+                               /* One directory back */
+                               /* Set pointers to right position */
+                               workpos++;                                              /* move to second '.' */
+                               workpos++;                                              /* move to '/' */
+                               
+                               /* Only apply .. if not in root */
+                               if ((writepos-1) > path_construction) {
+                                       writepos--;                                             /* move to '/' */
+                                       while(*--writepos != '/') ;             /* skip until previous '/' */
+                               }
+                       } else {
+                               if (workpos[1] == '/') {
+                                       /* Found a /./ skip it */
+                                       workpos++;                                      /* move to '/' */
+
+                                       /* Avoid double / in the result */
+                                       writepos--;
+                               } else {
+                                       /* No special case, the name just started with a . */
+                                       /* Append */
+                                       while((*workpos != '/') && (*workpos != 0)) {
+                                               *writepos++ = *workpos++;
+                                       }
+                               }
+                       }
+               } else {
+                       /* No special case */
+                       /* Append */
+                       while((*workpos != '/') && (*workpos != 0)) {
+                               *writepos++ = *workpos++;
+                       }
+               }
+
+#if HAVE_SYMLINK
+               /* We are going to use path_construction, so close it */
+               *writepos = 0;
+
+               /* Check the current location to see if it is a symlink */
+               if((linklength = readlink(path_construction, buf, MAXPATHLEN)) != -1) {
+                       /* Check linkcount */
+                       if (linkcount > MAXSYMLINKS) return NULL;
+
+                       /* Count this symlink */
+                       linkcount++;
+
+                       /* Set end of buf */
+                       buf[linklength] = 0;
+
+                       /* Check for overflow */
+                       if ((strlen(workpos) + strlen(buf) + 1) >= MAXPATHLEN) return NULL;
+
+                       /* Remove the symlink-component wrom path_construction */
+                       writepos--;                                             /* move to '/' */
+                       while(*--writepos != '/') ;             /* skip until previous '/' */
+                       *++writepos = 0;                                /* end of string after '/' */
+
+                       /* If the symlink starts with a '/', empty path_construction */
+                       if (*buf == '/') {
+                               *path_construction = 0;
+                               writepos = path_construction;
+                       }
+
+                       /* Insert symlink into path_copy */
+                       strcat(buf, workpos);
+                       strcpy(path_copy, buf);
+                       workpos = path_copy;
+               }
+#endif /* HAVE_SYMLINK */
+
+               /* If it was a directory, append a slash */
+               if (*workpos == '/') {
+                       *writepos++ = *workpos++;
+               }
+               *writepos = 0;
+#endif /* defined(PHP_WIN32) */
+       }
+
+       /* Check if the resolved path is a directory */
+       if (V_STAT(path_construction, &filestat) != 0) {
+               if (errno != ENOENT) return NULL;
+       } else {
+               if (S_ISDIR(filestat.st_mode)) {
+                       /* It's a directory, append a / if needed */
+                       if (*(writepos-1) != '/') {
+                               /* Check for overflow */
+                               if ((strlen(workpos) + 2) >= MAXPATHLEN) {
+                                        return NULL;
+                               }
+                               *writepos++ = '/';
+                               *writepos = 0;
+                       }
+               }
+       }
+       
+       strcpy(resolved_path, path_construction);
+       return resolved_path;
+}
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
index c233901b6e83259d66ff43286c6709fae59f372d..054be6d044c27d1006f5505dde82428574131f38 100644 (file)
@@ -31,6 +31,7 @@
 
 #ifdef ZEND_WIN32
 #include "win95nt.h"
+#include <sys/utime.h>
 #endif
 
 #include "php_virtual_cwd.h"
@@ -396,7 +397,7 @@ CWD_API int virtual_chdir(const char *path)
        return virtual_file_ex(&CWDG(cwd), path, php_is_dir_ok)?-1:0;
 }
 
-CWD_API int virtual_chdir_file(const char *path)
+CWD_API int virtual_chdir_file(const char *path, int (*p_chdir)(const char *path))
 {
        int length = strlen(path);
        char *temp;
@@ -421,7 +422,7 @@ CWD_API int virtual_chdir_file(const char *path)
 #if VIRTUAL_CWD_DEBUG
        fprintf (stderr, "Changing directory to %s\n", temp);
 #endif
-       retval = virtual_chdir(temp);
+       retval = p_chdir(temp);
        free(temp);
        return retval;
 }
@@ -732,6 +733,7 @@ CWD_API FILE *virtual_popen(const char *command, const char *type)
 
 #endif
 
+#if 0
 /* taken from Apache 1.3 */
 
 CWD_API void virtual_real_chdir_file(const char *file)
@@ -752,6 +754,8 @@ CWD_API void virtual_real_chdir_file(const char *file)
      * error... ah well. */
 }
 
+#endif
+
 #if 0
 
 main(void)
index 9e7ea9ba66a8c2df3cedaecfa31419e4490023ee..6b6606cc174fc75606c6a42ce177704eff82c090 100644 (file)
@@ -76,8 +76,8 @@ CWD_API void virtual_cwd_shutdown(void);
 CWD_API char *virtual_getcwd_ex(int *length);
 CWD_API char *virtual_getcwd(char *buf, size_t size);
 CWD_API int virtual_chdir(const char *path);
-CWD_API int virtual_chdir_file(const char *path);
-CWD_API void virtual_real_chdir_file(const char *path);
+CWD_API int virtual_chdir_file(const char *path, int (*p_chdir)(const char *path));
+/* CWD_API void virtual_real_chdir_file(const char *path); */
 CWD_API int virtual_filepath(const char *path, char **filepath);
 CWD_API char *virtual_realpath(const char *path, char *real_path);
 CWD_API FILE *virtual_fopen(const char *path, const char *mode);