I just don't get this. It seems trivial.
Why aren't we porting apr_strftime, Mladen?
FWIW... I tossed my 15 minutes at this today and I have no extra time
remaining this week. I won't commit the file code till I have time to
thoroughly digest it, and deadlines loom. I'll try to commit it over the
weekend. If there is anything else I missed outside of file_io (and fileio.h)
let us know.
For those interested, the remaining file_io I need to review is also attached.
Bill
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
#include "win32/atime.h"
#include "apr_portable.h"
#include "apr_strings.h"
APR_DECLARE_DATA const char apr_month_snames[12][4] =
{
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct",
"Nov", "Dec"
};
APR_DECLARE_DATA const char apr_day_snames[7][4] =
{
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
APR_DECLARE(apr_status_t) apr_rfc822_date(char *date_str, apr_time_t t)
{
apr_time_exp_t xt;
const char *s;
int real_year;
apr_time_exp_gmt(&xt, t);
/* example: "Sat, 08 Jan 2000 18:31:41 GMT" */
/* 12345678901234567890123456789 */
s = &apr_day_snames[xt.tm_wday][0];
*date_str++ = *s++;
*date_str++ = *s++;
*date_str++ = *s++;
*date_str++ = ',';
*date_str++ = ' ';
*date_str++ = xt.tm_mday / 10 + '0';
*date_str++ = xt.tm_mday % 10 + '0';
*date_str++ = ' ';
s = &apr_month_snames[xt.tm_mon][0];
*date_str++ = *s++;
*date_str++ = *s++;
*date_str++ = *s++;
*date_str++ = ' ';
real_year = 1900 + xt.tm_year;
/* This routine isn't y10k ready. */
*date_str++ = real_year / 1000 + '0';
*date_str++ = real_year % 1000 / 100 + '0';
*date_str++ = real_year % 100 / 10 + '0';
*date_str++ = real_year % 10 + '0';
*date_str++ = ' ';
*date_str++ = xt.tm_hour / 10 + '0';
*date_str++ = xt.tm_hour % 10 + '0';
*date_str++ = ':';
*date_str++ = xt.tm_min / 10 + '0';
*date_str++ = xt.tm_min % 10 + '0';
*date_str++ = ':';
*date_str++ = xt.tm_sec / 10 + '0';
*date_str++ = xt.tm_sec % 10 + '0';
*date_str++ = ' ';
*date_str++ = 'G';
*date_str++ = 'M';
*date_str++ = 'T';
*date_str++ = 0;
return APR_SUCCESS;
}
APR_DECLARE(apr_status_t) apr_ctime(char *date_str, apr_time_t t)
{
apr_time_exp_t xt;
const char *s;
int real_year;
/* example: "Wed Jun 30 21:49:08 1993" */
/* 123456789012345678901234 */
apr_time_exp_lt(&xt, t);
s = &apr_day_snames[xt.tm_wday][0];
*date_str++ = *s++;
*date_str++ = *s++;
*date_str++ = *s++;
*date_str++ = ' ';
s = &apr_month_snames[xt.tm_mon][0];
*date_str++ = *s++;
*date_str++ = *s++;
*date_str++ = *s++;
*date_str++ = ' ';
*date_str++ = xt.tm_mday / 10 + '0';
*date_str++ = xt.tm_mday % 10 + '0';
*date_str++ = ' ';
*date_str++ = xt.tm_hour / 10 + '0';
*date_str++ = xt.tm_hour % 10 + '0';
*date_str++ = ':';
*date_str++ = xt.tm_min / 10 + '0';
*date_str++ = xt.tm_min % 10 + '0';
*date_str++ = ':';
*date_str++ = xt.tm_sec / 10 + '0';
*date_str++ = xt.tm_sec % 10 + '0';
*date_str++ = ' ';
real_year = 1900 + xt.tm_year;
*date_str++ = real_year / 1000 + '0';
*date_str++ = real_year % 1000 / 100 + '0';
*date_str++ = real_year % 100 / 10 + '0';
*date_str++ = real_year % 10 + '0';
*date_str++ = 0;
return APR_SUCCESS;
}
#ifndef _WIN32_WCE
int win32_strftime_extra(char *s, size_t max, const char *format,
const struct tm *tm) {
/* If the new format string is bigger than max, the result string won't fit
* anyway. If format strings are added, made sure the padding below is
* enough */
char *new_format = (char *) malloc(max + 11);
size_t i, j, format_length = strlen(format);
int return_value;
int length_written;
for (i = 0, j = 0; (i < format_length && j < max);) {
if (format[i] != '%') {
new_format[j++] = format[i++];
continue;
}
switch (format[i+1]) {
case 'C':
length_written = apr_snprintf(new_format + j, max - j, "%2d",
(tm->tm_year + 1970)/100);
j = (length_written == -1) ? max : (j + length_written);
i += 2;
break;
case 'D':
/* Is this locale dependent? Shouldn't be...
Also note the year 2000 exposure here */
memcpy(new_format + j, "%m/%d/%y", 8);
i += 2;
j += 8;
break;
case 'r':
memcpy(new_format + j, "%I:%M:%S %p", 11);
i += 2;
j += 11;
break;
case 'T':
memcpy(new_format + j, "%H:%M:%S", 8);
i += 2;
j += 8;
break;
case 'e':
length_written = apr_snprintf(new_format + j, max - j, "%2d",
tm->tm_mday);
j = (length_written == -1) ? max : (j + length_written);
i += 2;
break;
default:
/* We know we can advance two characters forward here. Also
* makes sure that %% is preserved. */
new_format[j++] = format[i++];
new_format[j++] = format[i++];
}
}
if (j >= max) {
*s = '\0'; /* Defensive programming, okay since output is undefined*/
return_value = 0;
} else {
new_format[j] = '\0';
return_value = strftime(s, max, new_format, tm);
}
free(new_format);
return return_value;
}
#endif
APR_DECLARE(apr_status_t) apr_strftime(char *s, apr_size_t *retsize,
apr_size_t max, const char *format,
apr_time_exp_t *xt)
{
#ifdef _WIN32_WCE
*retsize = 0;
#else
struct tm tm;
memset(&tm, 0, sizeof tm);
tm.tm_sec = xt->tm_sec;
tm.tm_min = xt->tm_min;
tm.tm_hour = xt->tm_hour;
tm.tm_mday = xt->tm_mday;
tm.tm_mon = xt->tm_mon;
tm.tm_year = xt->tm_year;
tm.tm_wday = xt->tm_wday;
tm.tm_yday = xt->tm_yday;
tm.tm_isdst = xt->tm_isdst;
(*retsize) = win32_strftime_extra(s, max, format, &tm);
#endif
return APR_SUCCESS;
}
Index: file_io/win32/filestat.c
===================================================================
RCS file: /home/cvs/apr/file_io/win32/filestat.c,v
retrieving revision 1.68
diff -u -r1.68 filestat.c
--- file_io/win32/filestat.c 24 Apr 2002 04:17:44 -0000 1.68
+++ file_io/win32/filestat.c 4 Jun 2002 04:59:43 -0000
@@ -53,15 +53,19 @@
*/
#include <windows.h>
-#include <aclapi.h>
#include "apr_private.h"
+#if HAVE_ACLAPI
+#include <aclapi.h>
+#endif
#include "win32/fileio.h"
#include "apr_file_io.h"
#include "apr_general.h"
#include "apr_strings.h"
#include "apr_errno.h"
#include "apr_time.h"
+#if APR_HAVE_SYS_STAT_H
#include <sys/stat.h>
+#endif
#include "atime.h"
#include "misc.h"
@@ -75,7 +79,9 @@
static void free_world(void)
{
if (worldid) {
+#if HAVE_ACLAPI
FreeSid(worldid);
+#endif
worldid = NULL;
}
}
@@ -103,6 +109,7 @@
return (prot << scope);
}
+#if HAVE_ACLAPI
static void resolve_prot(apr_finfo_t *finfo, apr_int32_t wanted, PACL dacl)
{
TRUSTEE_W ident = {NULL, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_SID};
@@ -221,16 +228,17 @@
finfo->valid |= APR_FINFO_UPROT | APR_FINFO_GPROT | APR_FINFO_WPROT;
}
+#endif /* HAVE_ACLAPI */
apr_status_t more_finfo(apr_finfo_t *finfo, const void *ufile,
apr_int32_t wanted, int whatfile)
{
PSID user = NULL, grp = NULL;
PACL dacl = NULL;
- apr_status_t rv;
if (apr_os_level < APR_WIN_NT)
guess_protection_bits(finfo);
+#if HAVE_ACLAPI
else if (wanted & (APR_FINFO_PROT | APR_FINFO_OWNER))
{
/* On NT this request is incredibly expensive, but accurate.
@@ -239,6 +247,7 @@
* tests, but remember GetNamedSecurityInfo & GetSecurityInfo
* are not supported on 9x.
*/
+ apr_status_t rv;
SECURITY_INFORMATION sinf = 0;
PSECURITY_DESCRIPTOR pdesc = NULL;
if (wanted & (APR_FINFO_USER | APR_FINFO_UPROT))
@@ -303,7 +312,7 @@
else if (wanted & APR_FINFO_PROT)
guess_protection_bits(finfo);
}
-
+#endif
return ((wanted & ~finfo->valid) ? APR_INCOMPLETE : APR_SUCCESS);
}
@@ -394,6 +403,8 @@
fillin_fileinfo(finfo, (WIN32_FILE_ATTRIBUTE_DATA *) &FileInfo, 1, wanted);
+/* WCE has only regular files */
+#ifndef _WIN32_WCE
if (finfo->filetype == APR_REG)
{
/* Go the extra mile to be -certain- that we have a real, regular
@@ -413,6 +424,7 @@
*/
}
}
+#endif
finfo->pool = thefile->pool;
@@ -465,10 +477,12 @@
if (strlen(fname) >= APR_PATH_MAX) {
return APR_ENAMETOOLONG;
}
+#endif
#if APR_HAS_UNICODE_FS
IF_WIN_OS_IS_UNICODE
{
+#ifndef _WIN32_WCE
if ((wanted & (APR_FINFO_IDENT | APR_FINFO_NLINK))
|| (~wanted & APR_FINFO_LINK)) {
/* FindFirstFile and GetFileAttributesEx can't figure the inode,
@@ -488,6 +502,7 @@
else if (ident_rv == APR_INCOMPLETE)
wanted &= ~finfo->valid;
}
+#endif
if (rv = utf8_to_unicode_path(wfname, sizeof(wfname)
/ sizeof(apr_wchar_t), fname))
@@ -517,7 +532,6 @@
filename = apr_pstrdup(pool, tmpname);
}
}
-#endif
#if APR_HAS_ANSI_FS
ELSE_WIN_OS_IS_ANSI
if ((apr_os_level >= APR_WIN_98) && (!(wanted & APR_FINFO_NAME) ||
isroot))
@@ -576,6 +590,7 @@
IF_WIN_OS_IS_UNICODE
{
#if APR_HAS_UNICODE_FS
+#ifndef _WIN32_WCE
apr_wchar_t tmpname[APR_FILE_MAX];
apr_wchar_t *tmpoff;
if (GetFullPathNameW(wfname, sizeof(tmpname) /
sizeof(apr_wchar_t),
@@ -585,6 +600,9 @@
&& !wcsncmp(tmpname, L"\\\\.\\", 4))
finfo->filetype = APR_CHR;
}
+#else /* !defined(_WIN32_WCE) */
+ /* WCE lacks GetFullPathName */
+#endif
#else
char tmpname[APR_FILE_MAX];
char *tmpoff;
Index: file_io/win32/filesys.c
===================================================================
RCS file: /home/cvs/apr/file_io/win32/filesys.c,v
retrieving revision 1.8
diff -u -r1.8 filesys.c
--- file_io/win32/filesys.c 22 Mar 2002 06:06:26 -0000 1.8
+++ file_io/win32/filesys.c 4 Jun 2002 04:59:43 -0000
@@ -103,9 +103,13 @@
apr_status_t filepath_root_test(char *path, apr_pool_t *p)
{
+/* WCE has no drives */
+#ifdef _WIN32_WCE
+ return APR_SUCCESS;
+#else
apr_status_t rv;
#if APR_HAS_UNICODE_FS
- if (apr_os_level >= APR_WIN_NT)
+ IF_WIN_OS_IS_UNICODE
{
apr_wchar_t wpath[APR_PATH_MAX];
if (rv = utf8_to_unicode_path(wpath, sizeof(wpath)
@@ -113,13 +117,15 @@
return rv;
rv = GetDriveTypeW(wpath);
}
- else
#endif
+#if APR_HAS_ANSI_FS
+ ELSE_WIN_OS_IS_ANSI
rv = GetDriveType(path);
-
+#endif
if (rv == DRIVE_UNKNOWN || rv == DRIVE_NO_ROOT_DIR)
return APR_EBADPATH;
return APR_SUCCESS;
+#endif
}
@@ -130,10 +136,11 @@
#if APR_HAS_UNICODE_FS
IF_WIN_OS_IS_UNICODE
{
- apr_wchar_t *ignored;
- apr_wchar_t wdrive[8];
apr_wchar_t wpath[APR_PATH_MAX];
apr_status_t rv;
+#ifndef _WIN32_WCE
+ apr_wchar_t *ignored;
+ apr_wchar_t wdrive[8];
/* ???: This needs review, apparently "\\?\d:." returns "\\?\d:"
* as if that is useful for anything.
*/
@@ -141,6 +148,9 @@
wdrive[0] = (apr_wchar_t)(unsigned char)drive;
if (!GetFullPathNameW(wdrive, sizeof(wpath) / sizeof(apr_wchar_t),
wpath, &ignored))
return apr_get_os_error();
+#else
+ wcscpy(wpath, L"\\\\");
+#endif
if ((rv = unicode_to_utf8_path(path, sizeof(path), wpath)))
return rv;
}
@@ -184,9 +194,14 @@
if (rv = utf8_to_unicode_path(wroot, sizeof(wroot)
/ sizeof(apr_wchar_t), root))
return rv;
+#ifndef _WIN32_WCE
if (!GetFullPathNameW(wroot, sizeof(wpath) / sizeof(apr_wchar_t),
wpath, &ignored))
return apr_get_os_error();
-
+#else
+ /* XXX: WCE lacks GetFullPathName
+ *
+ */
+#endif
/* Borrow wroot as a char buffer (twice as big as necessary)
*/
if ((rv = unicode_to_utf8_path((char*)wroot, sizeof(wroot), wpath)))
@@ -207,6 +222,9 @@
return APR_SUCCESS;
}
+#if defined(_WIN32_WCE)
+static apr_wchar_t wce_curr_wpath[APR_PATH_MAX] = {0};
+#endif
APR_DECLARE(apr_status_t) apr_filepath_get(char **rootpath, apr_int32_t flags,
apr_pool_t *p)
@@ -215,11 +233,17 @@
#if APR_HAS_UNICODE_FS
IF_WIN_OS_IS_UNICODE
{
- apr_wchar_t wpath[APR_PATH_MAX];
apr_status_t rv;
+#ifndef _WIN32_WCE
+ apr_wchar_t wpath[APR_PATH_MAX];
if (!GetCurrentDirectoryW(sizeof(wpath) / sizeof(apr_wchar_t), wpath))
return apr_get_os_error();
if ((rv = unicode_to_utf8_path(path, sizeof(path), wpath)))
+#else
+ if (!wcslen(wce_curr_wpath))
+ wcscpy(wce_curr_wpath, L"\\\\");
+ if ((rv = unicode_to_utf8_path(path, sizeof(path), wce_curr_wpath)))
+#endif
return rv;
}
#endif
@@ -252,8 +276,12 @@
if (rv = utf8_to_unicode_path(wpath, sizeof(wpath)
/ sizeof(apr_wchar_t), rootpath))
return rv;
+#ifndef _WIN32_WCE
if (!SetCurrentDirectoryW(wpath))
return apr_get_os_error();
+#else
+ wcscpy(wce_curr_wpath, wpath);
+#endif
}
#endif
#if APR_HAS_ANSI_FS
Index: file_io/win32/readwrite.c
===================================================================
RCS file: /home/cvs/apr/file_io/win32/readwrite.c,v
retrieving revision 1.67
diff -u -r1.67 readwrite.c
--- file_io/win32/readwrite.c 20 Mar 2002 08:54:43 -0000 1.67
+++ file_io/win32/readwrite.c 4 Jun 2002 04:59:43 -0000
@@ -76,6 +76,7 @@
/* Peek at the pipe. If there is no data available, return APR_EAGAIN.
* If data is available, go ahead and read it.
*/
+#ifndef _WIN32_WCE
if (file->pipe) {
char tmpbuf[5];
DWORD dwBytesRead;
@@ -103,6 +104,7 @@
* timeout file i/o (which means setting file i/o non-blocking)
*/
}
+#endif
}
if (file->pOverlapped && !file->pipe) {
@@ -123,10 +125,12 @@
rv = WaitForSingleObject(file->pOverlapped->hEvent, INFINITE);
}
switch (rv) {
+#ifndef _WIN32_WCE
case WAIT_OBJECT_0:
GetOverlappedResult(file->filehand, file->pOverlapped, nbytes,
TRUE);
rv = APR_SUCCESS;
break;
+#endif
case WAIT_TIMEOUT:
rv = APR_TIMEUP;
break;
@@ -136,10 +140,12 @@
default:
break;
}
+#ifndef _WIN32_WCE
if (rv != APR_SUCCESS) {
if (apr_os_level >= APR_WIN_98)
CancelIo(file->filehand);
}
+#endif
}
else if (rv == APR_FROM_OS_ERROR(ERROR_BROKEN_PIPE)) {
/* Assume ERROR_BROKEN_PIPE signals an EOF reading from a pipe */
@@ -319,10 +325,12 @@
/* Wait for the pending i/o (put a timeout here?) */
rv = WaitForSingleObject(thefile->pOverlapped->hEvent,
INFINITE);
switch (rv) {
+#ifndef _WIN32_WCE
case WAIT_OBJECT_0:
GetOverlappedResult(thefile->filehand,
thefile->pOverlapped, nbytes, TRUE);
rv = APR_SUCCESS;
break;
+#endif
case WAIT_TIMEOUT:
rv = APR_TIMEUP;
break;
@@ -332,10 +340,12 @@
default:
break;
}
+#ifndef _WIN32_WCE
if (rv != APR_SUCCESS) {
if (apr_os_level >= APR_WIN_98)
CancelIo(thefile->filehand);
}
+#endif
}
}
if (rv == APR_SUCCESS && thefile->pOverlapped && !thefile->pipe) {
Index: file_io/win32/seek.c
===================================================================
RCS file: /home/cvs/apr/file_io/win32/seek.c,v
retrieving revision 1.23
diff -u -r1.23 seek.c
--- file_io/win32/seek.c 14 Mar 2002 22:22:32 -0000 1.23
+++ file_io/win32/seek.c 4 Jun 2002 04:59:43 -0000
@@ -54,7 +54,9 @@
#include "win32/fileio.h"
#include "apr_file_io.h"
+#if APR_HAVE_ERRNO_H
#include <errno.h>
+#endif
#include <string.h>
static apr_status_t setptr(apr_file_t *thefile, apr_off_t pos )
Index: include/arch/win32/fileio.h
===================================================================
RCS file: /home/cvs/apr/include/arch/win32/fileio.h,v
retrieving revision 1.67
diff -u -r1.67 fileio.h
--- include/arch/win32/fileio.h 25 Mar 2002 20:15:58 -0000 1.67
+++ include/arch/win32/fileio.h 4 Jun 2002 04:59:44 -0000
@@ -87,7 +87,6 @@
#if APR_HAS_UNICODE_FS
#include "i18n.h"
-#include <wchar.h>
typedef apr_uint16_t apr_wchar_t;