Skip to content

Commit

Permalink
Catch up on some Unicode stuff that I've discovered while yanking ar…
Browse files Browse the repository at this point in the history
…ound

  with canon names.  Mostly cleanups and NT vs. 9x fixups, plus some more
  useful canon types I'm playing with.  Hope to close this tommorow.


git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@60651 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
wrowe committed Nov 8, 2000
1 parent 0bb9a15 commit 6022fea
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 105 deletions.
7 changes: 2 additions & 5 deletions file_io/unix/fileacc.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,6 @@
#else
#include "fileio.h"
#endif
#if APR_HAS_UNICODE_FS
#include "i18n.h"
#endif

/* A file to put ALL of the accessor functions for apr_file_t types. */

Expand All @@ -92,9 +89,9 @@ apr_status_t apr_get_filename(char **fname, apr_file_t *thefile)
return APR_ENAMETOOLONG;
}
else
#else /* !APR_HAS_UNICODE_FS */
#endif /* !APR_HAS_UNICODE_FS */
*fname = apr_pstrdup(thefile->cntxt, thefile->n.fname);
#endif

#else /* !def Win32 */
*fname = apr_pstrdup(thefile->cntxt, thefile->fname);
#endif
Expand Down
12 changes: 5 additions & 7 deletions file_io/win32/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,6 @@
#include "apr_file_io.h"
#include "apr_strings.h"
#include "apr_portable.h"
#if APR_HAS_UNICODE_FS
#include "i18n.h"
#endif
#include "atime.h"

#if APR_HAVE_ERRNO_H
Expand Down Expand Up @@ -94,16 +91,17 @@ apr_status_t apr_opendir(apr_dir_t **new, const char *dirname, apr_pool_t *cont)
{
apr_status_t rv;
int lremains = len;
int dremains = (len + 3) * 2;
int dremains = len;
(*new) = apr_pcalloc(cont, sizeof(apr_dir_t));
(*new)->w.entry = apr_pcalloc(cont, sizeof(WIN32_FIND_DATAW));
(*new)->w.dirname = apr_palloc(cont, dremains);
(*new)->w.dirname = apr_palloc(cont, dremains + 7);
wcscpy((*new)->w.dirname, L"//?/");
if ((rv = conv_utf8_to_ucs2(dirname, &lremains,
(*new)->w.dirname, &dremains)))
(*new)->w.dirname + 4, &dremains)))
return rv;
if (lremains)
return APR_ENAMETOOLONG;
len = (len + 3) * 2 - dremains;
len = len + 4 - dremains;
if (len && (*new)->w.dirname[len - 1] != '/') {
(*new)->w.dirname[len++] = '/';
}
Expand Down
4 changes: 0 additions & 4 deletions file_io/win32/filedup.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,6 @@
#include "apr_general.h"
#include "apr_strings.h"
#include <string.h>
#if APR_HAS_UNICODE_FS
#include "i18n.h"
#include <wchar.h>
#endif

apr_status_t apr_dupfile(apr_file_t **new_file, apr_file_t *old_file, apr_pool_t *p)
{
Expand Down
14 changes: 14 additions & 0 deletions file_io/win32/fileio.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,27 @@

#define APR_FILE_BUFSIZE 4096

#if APR_HAS_UNICODE_FS
#include "i18n.h"
#include <wchar.h>

typedef apr_int16_t apr_wchar_t;

apr_wchar_t *utf8_to_unicode_path(const char* srcstr, apr_pool_t *p);
#endif

typedef enum apr_canon_case_e {
APR_CANON_CASE_GIVEN,
APR_CANON_CASE_LOWER,
APR_CANON_CASE_TRUE
} apr_canon_case_e;

typedef enum apr_canon_path_e {
APR_CANON_PATH_VIRUTAL,
APR_CANON_PATH_ABSOLUTE,
APR_CANON_PATH_RELATIVE
} apr_canon_path_e;

/*
* Internal canonical filename elements for the apr_canon_t elems
* ccase tracks the mechanism used to resolve this element
Expand All @@ -117,6 +130,7 @@ typedef struct apr_canon_elem_t {
struct apr_canon_t {
apr_pool_t *cntxt;
apr_array_header_t *elems;
apr_canon_path_e type;
};

/* quick run-down of fields in windows' apr_file_t structure that may have
Expand Down
39 changes: 11 additions & 28 deletions file_io/win32/filestat.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,31 +58,10 @@
#include "apr_general.h"
#include "apr_errno.h"
#include "apr_time.h"
#if APR_HAS_UNICODE_FS
#include "i18n.h"
#endif
#include <sys/stat.h>
#include "atime.h"
#include "misc.h"

/* XXX: this is wrong for W2K */
#define S_ISLNK(m) (0)
#define S_ISREG(m) (((m) & (S_IFMT)) == S_IFREG)
#define S_ISDIR(m) (((m) & (S_IFDIR)) == S_IFDIR)

static apr_filetype_e filetype_from_mode(int mode)
{
apr_filetype_e type = APR_NOFILE;

if (S_ISREG(mode))
type = APR_REG;
if (S_ISDIR(mode))
type = APR_DIR;
if (S_ISLNK(mode))
type = APR_LNK;

return type;
}

BOOLEAN is_exe(const char* fname, apr_pool_t *cont) {
/*
Expand Down Expand Up @@ -125,20 +104,22 @@ apr_status_t apr_getfileinfo(apr_finfo_t *finfo, apr_file_t *thefile)

/* If my rudimentary knowledge of posix serves... inode is the absolute
* id of the file (uniquifier) that is returned by NT as follows:
* user and group could be related as SID's, although this would ensure
* it's own unique set of issues. All three fields are significantly
* longer than the posix compatible kernals would ever require.
* TODO: Someday solve this, and fix the executable flag below the
* right way with a security permission test (as well as r/w flags.)
*
* dwVolumeSerialNumber
* nFileIndexHigh
* nFileIndexLow
*
* user and group could be returned as SID's, although this creates
* it's own unique set of issues. All three fields are significantly
* longer than the posix compatible kernals would ever require.
* TODO: Someday solve this, and fix the executable flag below the
* right way with a security permission test (as well as r/w flags.)
*/
finfo->user = 0;
finfo->group = 0;
finfo->inode = 0;
finfo->device = 0; /* ### use drive letter - 'A' ? */
finfo->inode = (apr_ino_t) FileInformation.nFileIndexHigh << 16
| FileInformation.nFileIndexLow;
finfo->device = FileInformation.dwVolumeSerialNumber;

/* Filetype - Directory or file: this case _will_ never happen */
if (FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
Expand All @@ -160,6 +141,7 @@ apr_status_t apr_getfileinfo(apr_finfo_t *finfo, apr_file_t *thefile)
#else
finfo->protection = S_IFIFO;
#endif
finfo->filetype = APR_PIPE;
}
else {
finfo->protection = 0;
Expand Down Expand Up @@ -212,6 +194,7 @@ apr_status_t apr_stat(apr_finfo_t *finfo, const char *fname, apr_pool_t *cont)
#if APR_HAS_UNICODE_FS
if (!apr_get_oslevel(cont, &os_level) && os_level >= APR_WIN_NT)
{

apr_wchar_t wname[MAX_PATH];
int len = MAX_PATH;
int lremains = strlen(fname) + 1;
Expand Down
127 changes: 66 additions & 61 deletions file_io/win32/open.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,23 @@
#include <string.h>
#include <sys/stat.h>
#include "misc.h"
#if APR_HAS_UNICODE_FS
#include "i18n.h"
#endif

apr_wchar_t *utf8_to_unicode_path(const char* srcstr, apr_pool_t *p)
{
/* TODO: The computations could preconvert the string to determine
* the true size of the retstr, but that's a memory over speed
* tradeoff that isn't appropriate this early in development.
*/
int srcremains = strlen(srcstr) + 1;
int retremains = srcremains + 4;
apr_wchar_t *retstr = apr_palloc(p, retremains * 2);
wcscpy (retstr, L"//?/");
if (conv_utf8_to_ucs2(srcstr, &srcremains,
retstr + 4, &retremains) || srcremains)
return NULL;
else
return retstr;
}

apr_status_t file_cleanup(void *thefile)
{
Expand All @@ -85,12 +99,8 @@ apr_status_t apr_open(apr_file_t **new, const char *fname,
DWORD createflags = 0;
DWORD attributes = 0;
DWORD sharemode = FILE_SHARE_READ | FILE_SHARE_WRITE;
apr_oslevel_e level;
apr_oslevel_e os_level;
apr_status_t rv;
#if APR_HAS_UNICODE_FS
int lremains = strlen(fname) + 1;
int dremains = (lremains) * 2;
#endif

(*new) = (apr_file_t *)apr_pcalloc(cont, sizeof(apr_file_t));
(*new)->cntxt = cont;
Expand All @@ -115,20 +125,23 @@ apr_status_t apr_open(apr_file_t **new, const char *fname,
if (rv)
return rv;
}
#if APR_HAS_UNICODE_FS
(*new)->w.fname = apr_palloc(cont, dremains);
if ((rv = conv_utf8_to_ucs2(fname, &lremains,
(*new)->w.fname, &dremains)))
return rv;
if (lremains)
return APR_ENAMETOOLONG;
#else
(*new)->n.fname = apr_pstrdup(cont, fname);
#endif

if (apr_get_oslevel(cont, &level) == APR_SUCCESS && level >= APR_WIN_NT) {
if (!apr_get_oslevel(cont, &os_level) && os_level >= APR_WIN_NT)
sharemode |= FILE_SHARE_DELETE;
else
os_level = 0;

#if APR_HAS_UNICODE_FS
if (os_level >= APR_WIN_NT)
{
(*new)->w.fname = utf8_to_unicode_path(fname, cont);
if (!(*new)->w.fname)
/* XXX: really bad file name */
return APR_ENAMETOOLONG;
}
else
#endif
(*new)->n.fname = apr_pstrdup(cont, fname);

if (flag & APR_CREATE) {
if (flag & APR_EXCL) {
Expand Down Expand Up @@ -167,12 +180,13 @@ apr_status_t apr_open(apr_file_t **new, const char *fname,
}

#if APR_HAS_UNICODE_FS
(*new)->filehand = CreateFileW((*new)->w.fname, oflags, sharemode,
NULL, createflags, attributes, 0);
#else
(*new)->filehand = CreateFile((*new)->n.fname, oflags, sharemode,
NULL, createflags, attributes, 0);
if (os_level >= APR_WIN_NT)
(*new)->filehand = CreateFileW((*new)->w.fname, oflags, sharemode,
NULL, createflags, attributes, 0);
else
#endif
(*new)->filehand = CreateFile((*new)->n.fname, oflags, sharemode,
NULL, createflags, attributes, 0);
if ((*new)->filehand == INVALID_HANDLE_VALUE) {
return apr_get_os_error();
}
Expand Down Expand Up @@ -213,51 +227,42 @@ apr_status_t apr_close(apr_file_t *file)
apr_status_t apr_remove_file(const char *path, apr_pool_t *cont)
{
#if APR_HAS_UNICODE_FS
apr_wchar_t wpath[MAX_PATH];
int lremains = strlen(path) + 1;
int dremains = MAX_PATH;
apr_status_t rv;
if ((rv = conv_utf8_to_ucs2(path, &lremains,
wpath, &dremains)))
return rv;
if (lremains)
return APR_ENAMETOOLONG;
if (DeleteFileW(wpath))
#else
if (DeleteFile(path))
apr_oslevel_e os_level;
if (!apr_get_oslevel(cont, &os_level) && os_level >= APR_WIN_NT)
{
apr_wchar_t *wpath = utf8_to_unicode_path(path, cont);
if (!wpath)
return APR_ENAMETOOLONG;
if (DeleteFileW(wpath))
return APR_SUCCESS;
}
else
#endif
return APR_SUCCESS;
if (DeleteFile(path))
return APR_SUCCESS;
return apr_get_os_error();
}

apr_status_t apr_rename_file(const char *from_path, const char *to_path,
apr_pool_t *p)
apr_pool_t *cont)
{
#if APR_HAS_UNICODE_FS
apr_wchar_t wfrompath[MAX_PATH];
apr_wchar_t wtopath[MAX_PATH];
int lremains = strlen(from_path) + 1;
int dremains = MAX_PATH;
apr_status_t rv;
if ((rv = conv_utf8_to_ucs2(from_path, &lremains,
wfrompath, &dremains)))
return rv;
if (lremains)
return APR_ENAMETOOLONG;
lremains = strlen(to_path) + 1;
dremains = MAX_PATH;
if ((rv = conv_utf8_to_ucs2(to_path, &lremains,
wtopath, &dremains)))
return rv;
if (lremains)
return APR_ENAMETOOLONG;
if (MoveFileExW(wfrompath, wtopath, MOVEFILE_REPLACE_EXISTING |
MOVEFILE_COPY_ALLOWED))
#else
if (MoveFileEx(from_path, to_path, MOVEFILE_REPLACE_EXISTING |
MOVEFILE_COPY_ALLOWED))
apr_oslevel_e os_level;
if (!apr_get_oslevel(cont, &os_level) && os_level >= APR_WIN_NT)
{
apr_wchar_t *wfrompath = utf8_to_unicode_path(from_path, cont);
apr_wchar_t *wtopath = utf8_to_unicode_path(to_path, cont);
if (!wfrompath || !wtopath)
return APR_ENAMETOOLONG;
if (MoveFileExW(wfrompath, wtopath, MOVEFILE_REPLACE_EXISTING |
MOVEFILE_COPY_ALLOWED))
return APR_SUCCESS;
}
else
#endif
return APR_SUCCESS;
if (MoveFileEx(from_path, to_path, MOVEFILE_REPLACE_EXISTING |
MOVEFILE_COPY_ALLOWED))
return APR_SUCCESS;
return apr_get_os_error();
}

Expand Down
5 changes: 5 additions & 0 deletions include/apr_file_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,13 @@ typedef struct apr_canon_t apr_canon_t;
typedef apr_int32_t apr_fileperms_t;
typedef uid_t apr_uid_t;
typedef gid_t apr_gid_t;
#ifdef WIN32
typedef apr_uint64_t apr_ino_t;
typedef apr_uint32_t apr_dev_t;
#else
typedef ino_t apr_ino_t;
typedef dev_t apr_dev_t;
#endif

/**
* The file information structure. This is analogous to the POSIX
Expand Down
Loading

0 comments on commit 6022fea

Please sign in to comment.