wrowe 01/06/27 12:44:28
Modified: file_io/unix filepath.c
file_io/win32 filepath.c
include apr_file_info.h
Log:
Add the flags argument to apr_filepath_root, to allow finer control of
canonicalization and os-native formatting. Renamed a bunch of local
functions in the win32 implementation so it's clear they are not external.
Revision Changes Path
1.4 +1 -0 apr/file_io/unix/filepath.c
Index: filepath.c
===================================================================
RCS file: /home/cvs/apr/file_io/unix/filepath.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- filepath.c 2001/04/02 22:01:11 1.3
+++ filepath.c 2001/06/27 19:44:21 1.4
@@ -94,6 +94,7 @@
APR_DECLARE(apr_status_t) apr_filepath_root(const char **rootpath,
const char **inpath,
+ apr_int32_t flags,
apr_pool_t *p)
{
if (**inpath == '/')
1.7 +58 -41 apr/file_io/win32/filepath.c
Index: filepath.c
===================================================================
RCS file: /home/cvs/apr/file_io/win32/filepath.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- filepath.c 2001/06/18 05:08:44 1.6
+++ filepath.c 2001/06/27 19:44:23 1.7
@@ -93,8 +93,8 @@
}
-static apr_status_t apr_filepath_root_test(char *path,
- apr_pool_t *p)
+static apr_status_t filepath_root_test(char *path,
+ apr_pool_t *p)
{
apr_status_t rv;
#if APR_HAS_UNICODE_FS
@@ -150,9 +150,9 @@
}
-static apr_status_t apr_filepath_drive_get(char **rootpath,
- char drive,
- apr_pool_t *p)
+static apr_status_t filepath_drive_get(char **rootpath,
+ char drive,
+ apr_pool_t *p)
{
char path[APR_PATH_MAX];
#if APR_HAS_UNICODE_FS
@@ -197,7 +197,7 @@
}
-static apr_status_t apr_filepath_root_case(char **rootpath,
+static apr_status_t filepath_root_case(char **rootpath,
char *root,
apr_pool_t *p)
{
@@ -273,7 +273,9 @@
*/
APR_DECLARE(apr_status_t) apr_filepath_root(const char **rootpath,
- const char **inpath, apr_pool_t
*p)
+ const char **inpath,
+ apr_int32_t flags,
+ apr_pool_t *p)
{
const char *testpath = *inpath;
const char *delim1;
@@ -292,7 +294,7 @@
/* given '//?/C: or //./C: let us try this
* all over again from the drive designator
*/
- rv = apr_filepath_root(rootpath, &testpath, p);
+ rv = apr_filepath_root(rootpath, &testpath, flags, p);
if (!rv || rv == APR_EINCOMPLETE)
*inpath = testpath;
return rv;
@@ -341,6 +343,9 @@
else
newpath = apr_pstrndup(p, testpath, delim2 - testpath);
+ /* Win32 will argue about slashed in UNC paths, so use
+ * backslashes till we finish testing
+ */
newpath[0] = '\\';
newpath[1] = '\\';
newpath[delim1 - testpath] = '\\';
@@ -357,13 +362,14 @@
* root this designation!
*/
newpath[delim2 - testpath] = '\\';
- rv = apr_filepath_root_test(newpath, p);
- if (rv)
- return rv;
- rv = apr_filepath_root_case(&newpath, newpath, p);
- if (rv)
- return rv;
-
+ if (flags & APR_FILEPATH_TRUENAME) {
+ rv = filepath_root_test(newpath, p);
+ if (rv)
+ return rv;
+ rv = filepath_root_case(&newpath, newpath, p);
+ if (rv)
+ return rv;
+ }
/* If this root included the trailing / or \ designation
* then lop off multiple trailing slashes
*/
@@ -401,10 +407,13 @@
}
/* Left with a path of '/', what drive are we asking about?
- * The guess is left to the caller.
*/
- *rootpath = apr_pstrndup(p, testpath, 1);
+ // ?? if (flags & APR_FILEPATH_TRUENAME)
*inpath = ++testpath;
+ newpath = apr_palloc(p, 2);
+ newpath[0] = ((flags & APR_FILEPATH_NATIVE) ? '\\' : '/');
+ newpath[1] = '\0';
+ *rootpath = newpath;
return APR_EINCOMPLETE;
}
@@ -414,37 +423,37 @@
apr_status_t rv;
/* Validate that D:\ drive exists, test must be rooted
* Note that posix/win32 insists a drive letter is upper case,
- * so who are we to argue with a 'feature' we might exploit.
+ * so who are we to argue with a 'feature'.
* It is a safe fold, since only A-Z is legal, and has no
* side effects of legal mis-mapped non-us-ascii codes.
*/
- newpath = apr_palloc(p, 3);
- newpath[0] = toupper(testpath[0]);
+ newpath = apr_palloc(p, 4);
+ newpath[0] = testpath[0];
newpath[1] = ':';
- newpath[2] = '\\';
+ newpath[2] = ((flags & APR_FILEPATH_NATIVE) ? '\\' : '/');
newpath[3] = '\0';
- rv = apr_filepath_root_test(newpath, p);
- if (rv)
- return rv;
-
- /* Have full 'd:/' so replace our \ with the given root char
+ if (flags & APR_FILEPATH_TRUENAME) {
+ newpath[0] = toupper(newpath[0]);
+ rv = filepath_root_test(newpath, p);
+ if (rv)
+ return rv;
+ }
+ /* Just give back the root the user handed to us.
*/
- if (testpath[2] == '/' || testpath[2] == '\\') {
- newpath[2] = testpath[2];
+ if (testpath[2] != '/' && testpath[2] != '\\') {
+ newpath[2] = '\0';
*rootpath = newpath;
- *inpath = testpath + 3;
- while (**inpath == '/' || **inpath == '\\')
- ++*inpath;
- return APR_SUCCESS;
+ *inpath = testpath + 2;
+ return APR_EINCOMPLETE;
}
- /* Left with path of 'd:' from the cwd of this drive letter
- * so truncate the root \ we added above;
+ /* strip off remaining slashes that designate the root.
*/
- newpath[2] = '\0';
+ *inpath = testpath + 3;
+ while (**inpath == '/' || **inpath == '\\')
+ ++*inpath;
*rootpath = newpath;
- *inpath = testpath + 2;
- return APR_EINCOMPLETE;
+ return APR_SUCCESS;
}
/* Nothing interesting */
@@ -479,7 +488,10 @@
addtype = APR_ERELATIVE;
}
else {
- addtype = apr_filepath_root(&addroot, &addpath, p);
+ /* This call _should_ test the path
+ */
+ addtype = apr_filepath_root(&addroot, &addpath,
+ APR_FILEPATH_TRUENAME, p);
if (addtype == APR_SUCCESS) {
addtype = APR_EABSOLUTE;
}
@@ -538,7 +550,7 @@
*/
char *getpath;
if (addtype == APR_EINCOMPLETE && addroot[1] == ':')
- rv = apr_filepath_drive_get(&getpath, addroot[0], p);
+ rv = filepath_drive_get(&getpath, addroot[0], p);
else
rv = apr_filepath_get(&getpath, p);
if (rv != APR_SUCCESS)
@@ -547,7 +559,9 @@
}
if (!baseroot) {
- basetype = apr_filepath_root(&baseroot, &basepath, p);
+ /* This call should _not_ test the path
+ */
+ basetype = apr_filepath_root(&baseroot, &basepath, 0, p);
if (basetype == APR_SUCCESS) {
basetype = APR_EABSOLUTE;
}
@@ -836,7 +850,10 @@
* and replace our path with the canonical UNC root path
*/
path[pathlen] = '\0';
- testtype = apr_filepath_root(&testroot, &testpath, p);
+ /* This call _should_ test the path
+ */
+ testtype = apr_filepath_root(&testroot, &testpath,
+ APR_FILEPATH_TRUENAME, p);
if (testtype == APR_SUCCESS) {
rootlen = pathlen = (testpath - path);
memcpy(path, testroot, pathlen);
1.19 +17 -7 apr/include/apr_file_info.h
Index: apr_file_info.h
===================================================================
RCS file: /home/cvs/apr/include/apr_file_info.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- apr_file_info.h 2001/05/23 17:43:59 1.18
+++ apr_file_info.h 2001/06/27 19:44:26 1.19
@@ -262,7 +262,7 @@
*/
APR_DECLARE(apr_status_t) apr_dir_rewind(apr_dir_t *thedir);
-/* apr_filepath flags
+/* apr_filepath optional flags
*/
/* Cause apr_filepath_merge to fail if addpath is above rootpath */
@@ -287,7 +287,8 @@
#define APR_FILEPATH_NATIVE 0x10
/* Resolve the true case of existing directories and file elements
- * of addpath, and append a proper trailing slash if a directory
+ * of addpath, (resolving any aliases on Win32) and append a proper
+ * trailing slash if a directory
*/
#define APR_FILEPATH_TRUENAME 0x20
@@ -295,13 +296,21 @@
* Extract the rootpath from the given filepath
* @param rootpath the root file path returned with APR_SUCCESS or
APR_EINCOMPLETE
* @param filepath the pathname to parse for it's root component
+ * @param flags the desired rules to apply, from
+ * <PRE>
+ * APR_FILEPATH_NATIVE Use native path seperators (e.g. '\' on Win32)
+ * APR_FILEPATH_TRUENAME Tests that the root exists, and makes it
proper
+ * </PRE>
* @param p the pool to allocate the new path string from
* @deffunc apr_status_t apr_filepath_root(const char **rootpath, const char
**inpath, apr_pool_t *p)
- * @tip on return, filepath now points to the character following the root.
- * In the simplest example, given a filepath of "/foo", returns the rootpath
- * of "/" and filepath points at "foo". This is far more complex on other
- * platforms, which even changes alternate format of rootpath to canonical
- * form. The function returns APR_ERELATIVE if filepath isn't rooted (an
+ * @tip on return, filepath points to the first non-root character in the
+ * given filepath. In the simplest example, given a filepath of "/foo",
+ * returns the rootpath of "/" and filepath points at "foo". This is far
+ * more complex on other platforms, which will canonicalize the root form
+ * to a consistant format, given the APR_FILEPATH_TRUENAME flag, and also
+ * test for the validity of that root (e.g., that a drive d:/ or network
+ * share //machine/foovol/).
+ * The function returns APR_ERELATIVE if filepath isn't rooted (an
* error), APR_EINCOMPLETE if the root path is ambigious (but potentially
* legitimate, e.g. "/" on Windows is incomplete because it doesn't specify
* the drive letter), or APR_EBADPATH if the root is simply invalid.
@@ -309,6 +318,7 @@
*/
APR_DECLARE(apr_status_t) apr_filepath_root(const char **rootpath,
const char **filepath,
+ apr_int32_t flags,
apr_pool_t *p);
/**