summaryrefslogtreecommitdiffstats
path: root/sal
diff options
context:
space:
mode:
authorTino Rachui <tra@openoffice.org>2002-12-05 10:31:28 +0000
committerTino Rachui <tra@openoffice.org>2002-12-05 10:31:28 +0000
commit61453b07d53cc8e9d574437e07279cc0cc3291ff (patch)
tree84e4b5a4897951dc3c90f9a96675e143266f9986 /sal
parent#104563#inline header for convenience (diff)
downloadcore-61453b07d53cc8e9d574437e07279cc0cc3291ff.tar.gz
core-61453b07d53cc8e9d574437e07279cc0cc3291ff.zip
#104563#reimplemented osl_searchFileURL
Diffstat (limited to 'sal')
-rw-r--r--sal/osl/unx/file_url.cxx829
1 files changed, 469 insertions, 360 deletions
diff --git a/sal/osl/unx/file_url.cxx b/sal/osl/unx/file_url.cxx
index 34a0c2931f45..15e449539221 100644
--- a/sal/osl/unx/file_url.cxx
+++ b/sal/osl/unx/file_url.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: file_url.cxx,v $
*
- * $Revision: 1.1 $
+ * $Revision: 1.2 $
*
- * last change: $Author: tra $ $Date: 2002-11-29 10:37:46 $
+ * last change: $Author: tra $ $Date: 2002-12-05 11:31:28 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -75,6 +75,16 @@
#include <unistd.h>
#endif
+#if defined (SOLARIS)
+# ifndef _ALLOCA_H
+# include <alloca.h>
+# endif
+#else
+# ifndef _STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+
#ifndef _OSL_FILE_H_
#include <osl/file.h>
#endif
@@ -103,6 +113,10 @@
#include <osl/thread.h>
#endif
+#ifndef _OSL_FILE_HXX_
+#include <osl/file.hxx>
+#endif
+
#ifndef _FILE_ERROR_TRANSL_H_
#include "file_error_transl.h"
#endif
@@ -111,23 +125,47 @@
#include "file_url.h"
#endif
- #ifndef _OSL_FILE_PATH_HELPER_H_
- #include "file_path_helper.h"
- #endif
+#ifndef _OSL_FILE_PATH_HELPER_HXX_
+#include "file_path_helper.hxx"
+#endif
+
+/***************************************************
+
+ General note
+
+ This file contains the part that handles File URLs.
+
+ File URLs as scheme specific notion of URIs
+ (RFC2396) may be handled platform independend, but
+ will not in osl which is considered wrong.
+ Future version of osl should handle File URLs this
+ way. In rtl/uri there is already an URI parser etc.
+ so this code should be consolidated.
+
+ **************************************************/
+
+
/***************************************************
* forward
**************************************************/
extern "C" int UnicodeToText(char *, size_t, const sal_Unicode *, sal_Int32);
+extern "C" int TextToUnicode(const char* text, size_t text_buffer_size, sal_Unicode* unic_text, sal_Int32 unic_text_buffer_size);
+
+/***************************************************
+ * namespace directives
+ **************************************************/
+
+using namespace osl;
/***************************************************
* constants
**************************************************/
-const sal_Unicode OSL_FILE_CHAR_SLASH = ((sal_Unicode)'/');
-const sal_Unicode OSL_FILE_CHAR_COLON = ((sal_Unicode)':');
-const sal_Unicode OSL_FILE_CHAR_DOT = ((sal_Unicode)'.');
+const sal_Unicode UNICHAR_SLASH = ((sal_Unicode)'/');
+const sal_Unicode UNICHAR_COLON = ((sal_Unicode)':');
+const sal_Unicode UNICHAR_DOT = ((sal_Unicode)'.');
/******************************************************************************
*
@@ -137,14 +175,15 @@ const sal_Unicode OSL_FILE_CHAR_DOT = ((sal_Unicode)'.');
/* a slightly modified version of Pchar in rtl/source/uri.c */
const sal_Bool uriCharClass[128] =
-{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Pchar but without encoding slashes */
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Pchar but without encoding slashes */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* !"#$%&'()*+,-./*/
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, /*0123456789:;<=>?*/
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*@ABCDEFGHIJKLMNO*/
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /*PQRSTUVWXYZ[\]^_*/
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*`abcdefghijklmno*/
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0 /*pqrstuvwxyz{|}~ */
+ 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* !"#$%&'()*+,-./ */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, /* 0123456789:;<=>? */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ABCDEFGHIJKLMNO */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* PQRSTUVWXYZ[\]^_ */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* `abcdefghijklmno */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0 /* pqrstuvwxyz{|}~ */
};
@@ -440,7 +479,7 @@ oslFileError osl_getSystemPathFromFileURL_Ex(
if (osl_File_E_None == osl_error)
{
- if (bAllowRelative || (OSL_FILE_CHAR_SLASH == temp->buffer[0]))
+ if (bAllowRelative || (UNICHAR_SLASH == temp->buffer[0]))
{
*pustrSystemPath = temp;
}
@@ -454,194 +493,260 @@ oslFileError osl_getSystemPathFromFileURL_Ex(
return osl_error;
}
-/******************************************************
- * Helper function, return a pinter to the final '\0'
- * of a string
- ******************************************************/
-
-static char* _strtoend(char* pStr)
+namespace /* private */
{
- char* p = pStr;
- while(*p) p++;
- return p;
-}
-/******************************************************
- * Append one character to a string
- ******************************************************/
-
-static char* _strcatchr(char* pStr, char Chr)
-{
- char* p = _strtoend(pStr);
- *p++ = Chr;
- *p = '\0';
- return pStr;
-}
+ /******************************************************
+ * Helper function, return a pinter to the final '\0'
+ * of a string
+ ******************************************************/
-/******************************************************
- *
- ******************************************************/
+ sal_Unicode* ustrtoend(sal_Unicode* pStr)
+ {
+ return (pStr + rtl_ustr_getLength(pStr));
+ }
-static int _islastchr(char* pStr, char Chr)
-{
- char* p = _strtoend(pStr);
- if (p > pStr)
- p--;
- return (*p == Chr);
-}
+ /*********************************************
-/******************************************************
- * Ensure that the given string has the specified last
- * character if necessary append it
- ******************************************************/
+ ********************************************/
+ sal_Unicode* ustrcpy(const sal_Unicode* s, sal_Unicode* d)
+ {
+ const sal_Unicode* sc = s;
+ sal_Unicode* dc = d;
-static char* _strensurelast(char* pStr, char Chr)
-{
- if (!_islastchr(pStr, Chr))
- _strcatchr(pStr, Chr);
- return pStr;
-}
+ while (*dc++ = *sc++)
+ /**/;
-/******************************************************
- * Remove the last part of a path, a path that has
- * only a '/' or no '/' at all will be returned
- * unmodified
- ******************************************************/
+ return d;
+ }
-static char* _rmlastpathtoken(char* aPath)
-{
- /* we always may skip -2 because we
- may at least stand on a '/' but
- either there is no other character
- before this '/' or it's another
- character than the '/'
- */
- char* p = _strtoend(aPath) - 2;
+ /*********************************************
- // move back to the next path separator
- // or to the start of the string
- while (p > aPath && *p != '/')
- p--;
+ ********************************************/
- if (p >= aPath)
+ sal_Unicode* ustrncpy(const sal_Unicode* s, sal_Unicode* d, unsigned int n)
{
- if ('/' == *p)
- {
- p++;
- *p = '\0';
- }
- else
- {
- *p = '\0';
- }
- }
+ const sal_Unicode* sc = s;
+ sal_Unicode* dc = d;
+ unsigned int i = n;
- return aPath;
-}
+ while (i--)
+ *dc++ = *sc++;
-/******************************************************
- *
- ******************************************************/
+ if (n)
+ *dc = 0;
-static oslFileError _osl_resolvepath(
- /*inout*/ char* path,
- /*inout*/ char* current_pos,
- char* sentinel,
- /*inout*/ sal_Bool* failed)
-{
- oslFileError ferr = osl_File_E_None;
+ return d;
+ }
+
+ /*********************************************
+
+ ********************************************/
- if (!*failed)
+ sal_Unicode* ustrchrcat(const sal_Unicode chr, sal_Unicode* d)
{
- char realpath_buffer[PATH_MAX];
+ sal_Unicode* p = ustrtoend(d);
+ *p++ = chr;
+ *p = 0;
+ return d;
+ }
- if (realpath(path, realpath_buffer))
- {
- strcpy(path, realpath_buffer);
- current_pos = _strtoend(path) - 1;
- }
- else
- {
- if (EACCES == errno || ENOTDIR == errno || ENOENT == errno)
- *failed = sal_True;
- else
- ferr = oslTranslateFileError(OSL_FET_ERROR, errno);
- }
+ /*********************************************
+
+ ********************************************/
+
+ sal_Unicode* ustrcat(const sal_Unicode* s, sal_Unicode* d)
+ {
+ sal_Unicode* dc = ustrtoend(d);
+ ustrcpy(s, dc);
+ return d;
}
- return ferr;
-}
+ /******************************************************
+ *
+ ******************************************************/
-/******************************************************
- * Works even with non existing paths. The resulting
- * path must not exceed PATH_MAX else
- * osl_File_E_NAMETOOLONG is the result
- ******************************************************/
+ bool _islastchr(sal_Unicode* pStr, sal_Unicode Chr)
+ {
+ sal_Unicode* p = ustrtoend(pStr);
+ if (p > pStr)
+ p--;
+ return (*p == Chr);
+ }
-static oslFileError osl_realpath_impl_(const char *path_unresolved, char* path_resolved)
-{
- char path_resolved_so_far[PATH_MAX];
- char realpath_buffer[PATH_MAX];
+ /******************************************************
+ * Ensure that the given string has the specified last
+ * character if necessary append it
+ ******************************************************/
- char* punresolved = const_cast<char*>(path_unresolved);
- char* presolvedsf = path_resolved_so_far;
+ sal_Unicode* _strensurelast(sal_Unicode* pStr, sal_Unicode Chr)
+ {
+ if (!_islastchr(pStr, Chr))
+ ustrchrcat(Chr, pStr);
+ return pStr;
+ }
+
+ /******************************************************
+ * Remove the last part of a path, a path that has
+ * only a '/' or no '/' at all will be returned
+ * unmodified
+ ******************************************************/
- /* reserve space for leading '/' and trailing '\0'
- do not exceed this limit */
- char* sentinel = path_resolved_so_far + PATH_MAX - 2;
+ sal_Unicode* _rmlastpathtoken(sal_Unicode* aPath)
+ {
+ /* we always may skip -2 because we
+ may at least stand on a '/' but
+ either there is no other character
+ before this '/' or it's another
+ character than the '/'
+ */
+ sal_Unicode* p = ustrtoend(aPath) - 2;
- /* if realpath fails with error ENOTDIR, EACCES or ENOENT
- we will not call it again, because _osl_realpath should also
- work with non existing directories etc. */
- sal_Bool realpath_failed = sal_False;
- oslFileError ferr;
+ // move back to the next path separator
+ // or to the start of the string
+ while ((p > aPath) && (*p != UNICHAR_SLASH))
+ p--;
- OSL_PRECOND(punresolved && path_resolved, "_osl_realpath: Invalid parameter");
- OSL_PRECOND(punresolved[0] == '/', "_osl_realpath: Bad parameter, not absolute path given");
+ if (p >= aPath)
+ {
+ if (UNICHAR_SLASH == *p)
+ {
+ p++;
+ *p = '\0';
+ }
+ else
+ {
+ *p = '\0';
+ }
+ }
- /* the given unresolved path must not exceed PATH_MAX */
- if (strlen(punresolved) >= PATH_MAX - 2)
- return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
+ return aPath;
+ }
- path_resolved_so_far[0] = '\0';
+ /******************************************************
+ *
+ ******************************************************/
- while (*punresolved != '\0')
+ oslFileError _osl_resolvepath(
+ /*inout*/ sal_Unicode* path,
+ /*inout*/ sal_Unicode* current_pos,
+ /*in */ sal_Unicode* sentinel,
+ /*inout*/ bool* failed)
{
- /* ignore '/.' , skip one part back when '/..' */
+ oslFileError ferr = osl_File_E_None;
- if ('.' == *punresolved && *presolvedsf == '/' )
+ if (!*failed)
{
- if ('\0' == *(punresolved + 1))
+ char unresolved_path[PATH_MAX];
+ if (!UnicodeToText(unresolved_path, sizeof(unresolved_path), path, rtl_ustr_getLength(path)))
+ return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
+
+ char resolved_path[PATH_MAX];
+ if (realpath(unresolved_path, resolved_path))
{
- punresolved++;
- continue;
+ if (!TextToUnicode(resolved_path, strlen(resolved_path), path, PATH_MAX))
+ return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
+
+ current_pos = ustrtoend(path) - 1;
}
- else if ('/' == *(punresolved + 1))
+ else
{
- punresolved += 2;
- continue;
+ if (EACCES == errno || ENOTDIR == errno || ENOENT == errno)
+ *failed = true;
+ else
+ ferr = oslTranslateFileError(OSL_FET_ERROR, errno);
}
- else if ('.' == *(punresolved + 1) && ('\0' == *(punresolved + 2) || '/' == *(punresolved + 2)))
- {
- _rmlastpathtoken(path_resolved_so_far);
+ }
- presolvedsf = _strtoend(path_resolved_so_far) - 1;
+ return ferr;
+ }
- if ('/' == *(punresolved + 2))
- punresolved += 3;
- else
+ /******************************************************
+ * Works even with non existing paths. The resulting
+ * path must not exceed PATH_MAX else
+ * osl_File_E_NAMETOOLONG is the result
+ ******************************************************/
+
+ oslFileError osl_getAbsoluteFileURL_impl_(const rtl::OUString& unresolved_path, rtl::OUString& resolved_path)
+ {
+ // the given unresolved path must not exceed PATH_MAX
+ if (unresolved_path.getLength() >= (PATH_MAX - 2))
+ return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
+
+ sal_Unicode path_resolved_so_far[PATH_MAX];
+ sal_Unicode realpath_buffer[PATH_MAX];
+ const sal_Unicode* punresolved = unresolved_path.getStr();
+ sal_Unicode* presolvedsf = path_resolved_so_far;
+
+ // reserve space for leading '/' and trailing '\0'
+ // do not exceed this limit
+ sal_Unicode* sentinel = path_resolved_so_far + PATH_MAX - 2;
+
+ // if realpath fails with error ENOTDIR, EACCES or ENOENT
+ // we will not call it again, because _osl_realpath should also
+ // work with non existing directories etc.
+ bool realpath_failed = false;
+ oslFileError ferr;
+
+ path_resolved_so_far[0] = '\0';
+
+ while (*punresolved != '\0')
+ {
+ // ignore '/.' , skip one part back when '/..'
+
+ if ((UNICHAR_DOT == *punresolved) && (UNICHAR_SLASH == *presolvedsf))
+ {
+ if ('\0' == *(punresolved + 1))
+ {
+ punresolved++;
+ continue;
+ }
+ else if (UNICHAR_SLASH == *(punresolved + 1))
+ {
punresolved += 2;
+ continue;
+ }
+ else if ((UNICHAR_DOT == *(punresolved + 1)) && ('\0' == *(punresolved + 2) || (UNICHAR_SLASH == *(punresolved + 2))))
+ {
+ _rmlastpathtoken(path_resolved_so_far);
+
+ presolvedsf = ustrtoend(path_resolved_so_far) - 1;
+
+ if (UNICHAR_SLASH == *(punresolved + 2))
+ punresolved += 3;
+ else
+ punresolved += 2;
- continue;
+ continue;
+ }
+ else // a file or directory name may start with '.'
+ {
+ if ((presolvedsf = ustrtoend(path_resolved_so_far)) > sentinel)
+ return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
+
+ ustrchrcat(*punresolved++, path_resolved_so_far);
+
+ if ('\0' == *punresolved && !realpath_failed)
+ {
+ ferr = _osl_resolvepath(
+ path_resolved_so_far,
+ presolvedsf,
+ sentinel,
+ &realpath_failed);
+
+ if (osl_File_E_None != ferr)
+ return ferr;
+ }
+ }
}
- else /* a file or directory name may start with '.' */
+ else if (UNICHAR_SLASH == *punresolved)
{
- if ((presolvedsf = _strtoend(path_resolved_so_far)) > sentinel)
+ if ((presolvedsf = ustrtoend(path_resolved_so_far)) > sentinel)
return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
- _strcatchr(path_resolved_so_far, *punresolved++);
+ ustrchrcat(*punresolved++, path_resolved_so_far);
- if ('\0' == *punresolved && !realpath_failed)
+ if (!realpath_failed)
{
ferr = _osl_resolvepath(
path_resolved_so_far,
@@ -651,292 +756,296 @@ static oslFileError osl_realpath_impl_(const char *path_unresolved, char* path_r
if (osl_File_E_None != ferr)
return ferr;
- }
- }
- }
- else if ('/' == *punresolved)
- {
- if ((presolvedsf = _strtoend(path_resolved_so_far)) > sentinel)
- return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
- _strcatchr(path_resolved_so_far, *punresolved++);
+ if (!_islastchr(path_resolved_so_far, UNICHAR_SLASH))
+ {
+ if ((presolvedsf = ustrtoend(path_resolved_so_far)) > sentinel)
+ return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
- if (!realpath_failed)
+ ustrchrcat(UNICHAR_SLASH, path_resolved_so_far);
+ }
+ }
+ }
+ else // any other character
{
- ferr = _osl_resolvepath(
- path_resolved_so_far,
- presolvedsf,
- sentinel,
- &realpath_failed);
+ if ((presolvedsf = ustrtoend(path_resolved_so_far)) > sentinel)
+ return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
- if (osl_File_E_None != ferr)
- return ferr;
+ ustrchrcat(*punresolved++, path_resolved_so_far);
- if (!_islastchr(path_resolved_so_far, '/'))
+ if ('\0' == *punresolved && !realpath_failed)
{
- if ((presolvedsf = _strtoend(path_resolved_so_far)) > sentinel)
- return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
+ ferr = _osl_resolvepath(
+ path_resolved_so_far,
+ presolvedsf,
+ sentinel,
+ &realpath_failed);
- _strcatchr(path_resolved_so_far, '/');
+ if (osl_File_E_None != ferr)
+ return ferr;
}
}
}
- else // any other character
- {
- if ((presolvedsf = _strtoend(path_resolved_so_far)) > sentinel)
- return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
- _strcatchr(path_resolved_so_far, *punresolved++);
+ sal_Int32 len = rtl_ustr_getLength(path_resolved_so_far);
- if ('\0' == *punresolved && !realpath_failed)
- {
- ferr = _osl_resolvepath(
- path_resolved_so_far,
- presolvedsf,
- sentinel,
- &realpath_failed);
-
- if (osl_File_E_None != ferr)
- return ferr;
- }
- }
- }
+ OSL_ASSERT(len < PATH_MAX);
- OSL_ASSERT(strlen(path_resolved_so_far) < PATH_MAX);
+ resolved_path = rtl::OUString(path_resolved_so_far, len);
- strcpy(path_resolved, path_resolved_so_far);
+ return osl_File_E_None;
+ }
+
+} // end namespace private
- return osl_File_E_None;
-}
/******************************************************
- * Helper function, check if the path starts with a '/'
- * then its absolute
- *
- * @precond aPath must not be 0
+ * osl_getAbsoluteFileURL
******************************************************/
-static int osl_is_relative_path_impl_(const rtl_uString* aPath)
+oslFileError osl_getAbsoluteFileURL(rtl_uString* ustrBaseDirURL, rtl_uString* ustrRelativeURL, rtl_uString** pustrAbsoluteURL)
{
- OSL_PRECOND(aPath, "Invalid parameter");
- return ((sal_Unicode)'/' != aPath->buffer[0]);
-}
+ FileBase::RC rc;
+ rtl::OUString unresolved_path;
-/******************************************************
- * Helper function, concatenate two paths base + rel
- * -> base/rel
- ******************************************************/
+ rc = FileBase::getSystemPathFromFileURL(rtl::OUString(ustrRelativeURL), unresolved_path);
-static void _pathcat(
- const rtl_uString* ustrBasePath, const rtl_uString* ustrRelativePath, rtl_uString** pustrConcatedPath)
-{
- sal_Int32 needed_capacity = ustrBasePath->length + ustrRelativePath->length + 1;
+ if(FileBase::E_None != rc)
+ return oslFileError(rc);
- OSL_PRECOND(ustrBasePath && ustrRelativePath, "Invalid parameter");
- OSL_PRECOND(pustrConcatedPath && !*pustrConcatedPath, "Invalid parameter");
+ if (systemPathIsRelativePath(unresolved_path))
+ {
+ rtl::OUString base_path;
+ rc = (FileBase::RC) osl_getSystemPathFromFileURL_Ex(ustrBaseDirURL, &base_path.pData, sal_False);
- rtl_uString_new_WithLength(pustrConcatedPath, needed_capacity);
+ if (FileBase::E_None != rc)
+ return oslFileError(rc);
- rtl_uStringbuffer_insert(pustrConcatedPath, &needed_capacity, 0, ustrBasePath->buffer, ustrBasePath->length);
+ rtl::OUString abs_path;
+ systemPathMakeAbsolutePath(base_path, unresolved_path, abs_path);
- OSL_ASSERT(((rtl_uString*)*pustrConcatedPath)->length);
+ unresolved_path = abs_path;
+ }
- if (ustrBasePath->buffer[ustrBasePath->length - 1] != (sal_Unicode)'/')
- rtl_uStringbuffer_insert_ascii(pustrConcatedPath, &needed_capacity, ((rtl_uString*)*pustrConcatedPath)->length, "/", 1);
+ rtl::OUString resolved_path;
+ rc = (FileBase::RC) osl_getAbsoluteFileURL_impl_(unresolved_path, resolved_path);
- rtl_uStringbuffer_insert(
- pustrConcatedPath,
- &needed_capacity,
- ((rtl_uString*)*pustrConcatedPath)->length,
- ustrRelativePath->buffer,
- ustrRelativePath->length);
+ if (FileBase::E_None == rc)
+ {
+ rc = (FileBase::RC) osl_getFileURLFromSystemPath(resolved_path.pData, pustrAbsoluteURL);
+ OSL_ASSERT(FileBase::E_None == rc);
+ }
+
+ return oslFileError(rc);
}
-/******************************************************
- *
- ******************************************************/
-oslFileError osl_getAbsoluteFileURL(
- rtl_uString* ustrBaseDirURL, rtl_uString* ustrRelativeURL, rtl_uString** pustrAbsoluteURL)
+namespace /* private */
{
- oslFileError ferr = osl_File_E_INVAL;
- rtl_uString* ustrPath = NULL;
- char asciiPath[PATH_MAX];
- ferr = osl_getSystemPathFromFileURL(ustrRelativeURL, &ustrPath);
+ /****************************************************************************
+ * osl_access_impl_
+ ***************************************************************************/
- if(osl_File_E_None != ferr)
- return ferr;
+ int osl_access_impl_(const sal_Unicode* path, int mode)
+ {
+ int nRet = -1;
+ char p[PATH_MAX];
+ if (UnicodeToText(p, sizeof(p), path, rtl_ustr_getLength(path)))
+ nRet = access(p, mode);
- if(osl_is_relative_path_impl_(ustrPath))
+ return nRet;
+ }
+
+ /*********************************************
+
+ ********************************************/
+
+ struct Path
{
- rtl_uString* ustrBasePath = NULL;
- rtl_uString* ustrConcatedPath = NULL;
+ const sal_Unicode* begin_;
+ const sal_Unicode* end_;
- /* concatinate base and relative path */
- ferr = osl_getSystemPathFromFileURL(ustrBaseDirURL, &ustrBasePath);
+ Path() : begin_(0), end_(0) {}
- if (osl_File_E_None != ferr)
+ operator void* ()
{
- rtl_uString_release(ustrPath);
- return ferr;
+ unsigned int l = get_length();
+ return reinterpret_cast<void*>(l);
}
- _pathcat(ustrBasePath, ustrPath, &ustrConcatedPath);
-
- rtl_uString_release(ustrBasePath);
- rtl_uString_release(ustrPath);
+ unsigned int get_length()
+ {
+ OSL_ENSURE(end_ > begin_, "end_ must be greater than begin_");
+ return static_cast<unsigned int>(end_ - begin_);
+ }
+ };
- ustrPath = ustrConcatedPath;
- }
+ /**************************************************
+ Path tokens are under Unix are ':' separated
+ *************************************************/
- /* convert unicode path to text */
- if (UnicodeToText(asciiPath, PATH_MAX, ustrPath->buffer, ustrPath->length))
+ Path pathlist_get_next(const sal_Unicode* pathlist)
{
- char realPath[PATH_MAX];
+ OSL_ASSERT(pathlist);
- /* use realpath to determine absolute path */
- ferr = osl_realpath_impl_(asciiPath, realPath);
+ const sal_Unicode* p = pathlist;
+ Path path;
- if (osl_File_E_None == ferr)
+ if (*p)
{
- rtl_uString* ustrRealPath = NULL;
-
- /* convert file name to unicode */
- rtl_string2UString(
- &ustrRealPath,
- realPath,
- strlen(realPath),
- osl_getThreadTextEncoding(),
- OSTRING_TO_OUSTRING_CVTFLAGS);
-
- /* file urls must be encoded */
- ferr = osl_getFileURLFromSystemPath(ustrRealPath, pustrAbsoluteURL);
+ path.begin_ = path.end_ = p;
- OSL_ASSERT(osl_File_E_None == ferr);
-
- rtl_uString_release(ustrRealPath);
+ while (*path.end_ && (*path.end_ != UNICHAR_COLON))
+ ++path.end_;
}
- }
- else
- {
- ferr = osl_File_E_INVAL;
+ return path;
}
- rtl_uString_release(ustrPath);
+ /****************************************************************************
+ search_path_impl_
- return ferr;
-}
+ @param path
+ The file or path the should be searched for.
-/****************************************************************************
- * ImplSearchPath
- ***************************************************************************/
+ @param search_paths
+ A list of search paths, ':' separated.
-static char * ImplSearchPath( char * buffer, size_t buflen, const char * filePath, const char * searchPath, char separator )
-{
- char *pPathItem;
- char *pc;
- size_t nFilePathLen;
+ @param result
+ On success receives the path found, buffer must be at least
+ PATH_MAX long.
- pPathItem = const_cast<char*>(searchPath);
- nFilePathLen = strlen(filePath);
+ ***************************************************************************/
- do
+ bool search_path_impl_(const sal_Unicode* file_path, const sal_Unicode* search_paths, sal_Unicode* result)
{
- char path[PATH_MAX];
- size_t len;
+ bool bRet = false;
+ const sal_Unicode* sp = search_paths;
+ sal_Unicode buff[PATH_MAX];
+ sal_Unicode* b = buff;
- /* extract path item */
- pc = strchr( pPathItem, separator );
- len = pc ? pc - pPathItem : strlen( pPathItem );
-
- /* copy path entry to buffer and append file Path */
- if( PATH_MAX > len + nFilePathLen + 1 )
+ while (*sp)
{
- strncpy( path, pPathItem, len );
- path[len++] = '/';
- strcpy( path + len, filePath );
+ Path path = pathlist_get_next(sp);
+
+ if (path)
+ {
+ ustrncpy(path.begin_, b, path.get_length());
- if( 0 <= access( path, F_OK ) )
- return realpath( path, buffer );
+ if (b[rtl_ustr_getLength(b) - 1] != UNICHAR_SLASH)
+ ustrchrcat(UNICHAR_SLASH, b);
+
+ ustrcat(file_path, b);
+
+ if (osl_access_impl_(buff, F_OK) > -1)
+ {
+ bRet = true;
+ break;
+ }
+ }
+ sp = path.end_ + 1;
}
+ if (bRet)
+ ustrcpy(buff, result);
- pPathItem = pc + 1;
+ return bRet;
}
- while( NULL != pc );
- return NULL;
-}
+ /*********************************************
+ No separate error code if unicode to text
+ conversion or getenv fails because for the
+ caller there is no difference why a file
+ could not be found in $PATH
+ ********************************************/
-/****************************************************************************
- * osl_searchFileURL
- ***************************************************************************/
+ bool find_in_PATH(const rtl::OUString& file_path, sal_Unicode* result)
+ {
+ bool bfound = false;
+ char* env_path = getenv("PATH");
-oslFileError osl_searchFileURL( rtl_uString* ustrFilePath, rtl_uString* ustrSearchPath, rtl_uString** pustrURL )
-{
- rtl_uString* ustrPath = NULL;
- oslFileError eRet;
+ if (env_path)
+ {
+ // approximated unicode buffer size may be a little bigger
+ // than necessary if there are 3 byte MBCS character
- char searchPath[PATH_MAX];
- char filePath[PATH_MAX];
- char path[PATH_MAX] = "";
+ int lp = strlen(env_path) + 1; // include final '\0'
+ sal_Unicode* env_path_unic = reinterpret_cast<sal_Unicode*>(
+ alloca(sizeof(sal_Unicode) * lp));
- OSL_ASSERT( ustrFilePath );
- OSL_ASSERT( ustrSearchPath );
- OSL_ASSERT( pustrURL );
+ if (TextToUnicode(env_path, lp, env_path_unic, lp))
+ bfound = search_path_impl_(file_path.pData->buffer, env_path_unic, result);
+ }
+ return bfound;
+ }
- /* file path may also be an URL */
- eRet = FileURLToPath( filePath, PATH_MAX, ustrFilePath );
+ /*********************************************
+ No separate error code if unicode to text
+ conversion or getcwd fails because for the
+ caller there is no difference why a file
+ could not be found in CDW
+ ********************************************/
- if( eRet != osl_File_E_None )
+ bool find_in_CWD(const rtl::OUString& file_path, sal_Unicode* result)
{
- if( eRet == osl_File_E_INVAL )
+ bool bfound = false;
+ char CWD[PATH_MAX];
+
+ if (getcwd(CWD, PATH_MAX))
{
- /* seems not to be an URL, so expect it to be a system patrh */
- if( ! UnicodeToText( filePath, PATH_MAX, ustrFilePath->buffer, ustrFilePath->length ) )
- return osl_File_E_INVAL;
+ sal_Unicode CWD_unic[PATH_MAX];
+ if (TextToUnicode(CWD, strlen(CWD) + 1, CWD_unic, PATH_MAX))
+ bfound = search_path_impl_(file_path.pData->buffer, CWD_unic, result);
}
- else
- return eRet;
+ return bfound;
}
- /* if a search path is specified, it is no file URL */
- if( ustrSearchPath->length && UnicodeToText( searchPath, PATH_MAX, ustrSearchPath->buffer, ustrSearchPath->length ) )
+ /*********************************************
+
+ ********************************************/
+
+ bool find_in_searchPath(const rtl::OUString& file_path, rtl_uString* search_path, sal_Unicode* result)
{
- if( NULL == ImplSearchPath( path, PATH_MAX, filePath, searchPath, ';' ) )
- *path = '\0';
+ return (search_path && search_path_impl_(file_path.pData->buffer, search_path->buffer, result));
}
- /* did we already find something ? */
- if( '\0' == *path )
- {
- char * pEnvPath = getenv("PATH");
+} // end namespace private
- /* fallback to PATH env var */
- if( ( NULL == pEnvPath ) || ( NULL == ImplSearchPath( path, PATH_MAX, filePath, pEnvPath , ':' ) ) )
- {
- char workdir[PATH_MAX];
- /* last try: current working dir */
- if( ( NULL == getcwd( workdir, PATH_MAX ) ) || ( NULL == ImplSearchPath( path, PATH_MAX, filePath, workdir , ':' ) ) )
- return osl_File_E_NOENT;
- }
- }
+/****************************************************************************
+ * osl_searchFileURL
+ ***************************************************************************/
+
+oslFileError osl_searchFileURL(rtl_uString* ustrFilePath, rtl_uString* ustrSearchPath, rtl_uString** pustrURL)
+{
+ OSL_PRECOND(ustrFilePath && pustrURL, "osl_searchFileURL: invalid parameter");
- /* did we find something, then convert it */
- if( *path )
+ FileBase::RC rc;
+ rtl::OUString file_path;
+
+ // try to interpret search path as file url else assume it's a system path list
+ rc = FileBase::getSystemPathFromFileURL(rtl::OUString(ustrFilePath), file_path);
+ if ((FileBase::E_None != rc) && (FileBase::E_INVAL == rc))
+ file_path = ustrFilePath;
+ else if (FileBase::E_None != rc)
+ return oslFileError(rc);
+
+ bool bfound = false;
+ sal_Unicode result[PATH_MAX];
+
+ if (find_in_searchPath(file_path, ustrSearchPath, result) ||
+ find_in_PATH(file_path, result) ||
+ find_in_CWD(file_path, result))
{
- /* convert file name to unicode */
- rtl_string2UString( &ustrPath, path, strlen( path ), osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS );
+ rtl::OUString fpf(result, rtl_ustr_getLength(result));
+ oslFileError osl_error = osl_getFileURLFromSystemPath(fpf.pData, pustrURL);
+ OSL_ASSERT(osl_File_E_None == osl_error);
- /* file urls must be encoded */
- osl_getFileURLFromSystemPath( ustrPath, pustrURL );
- rtl_uString_release( ustrPath );
+ bfound = true;
}
-
- return osl_File_E_None;
+ return bfound ? osl_File_E_None : osl_File_E_NOENT;
}
+
/****************************************************************************
* FileURLToPath
***************************************************************************/