rbb 99/06/01 12:29:02
Added: apr/misc/win32 misc.def names.c start.c timetest.c
Log:
First pass at the misc library for Windows. This has much more in it than
the Unix version, but that's because I am putting the "helper" routines like
canonical_filename in it.
Revision Changes Path
1.1 apache-apr/apr/misc/win32/misc.def
Index: misc.def
===================================================================
; misc.def :
LIBRARY misc
DESCRIPTION ''
EXPORTS
; Add new API calls to the end of this list.
ap_os_systemcase_filename @1
canonical_filename @2
ap_create_context @3
ap_set_signal_safe @4
ap_set_cancel_safe @5
ap_destroy_context @6
WinTimeToUnixTime @7
1.1 apache-apr/apr/misc/win32/names.c
Index: names.c
===================================================================
/* ====================================================================
* Copyright (c) 1999 The Apache Group. 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. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" 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 names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``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 GROUP 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 Group.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
#ifdef WIN32
#include "apr_win.h"
#endif
#include "apr_file_io.h"
#include "apr_general.h"
#include "apr_lib.h"
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
/* Returns TRUE if the input string is a string
* of one or more '.' characters.
*/
static BOOL OnlyDots(char *pString)
{
char *c;
if (*pString == '\0')
return FALSE;
for (c = pString;*c;c++)
if (*c != '.')
return FALSE;
return TRUE;
}
/* Accepts as input a pathname, and tries to match it to an
* existing path and return the pathname in the case that
* is present on the existing path. This routine also
* converts alias names to long names.
*/
API_EXPORT(char *) ap_os_systemcase_filename(ap_pool_t *pPool,
const char *szFile)
{
char buf[HUGE_STRING_LEN];
char *pInputName;
char *p, *q;
BOOL bDone = FALSE;
BOOL bFileExists = TRUE;
HANDLE hFind;
WIN32_FIND_DATA wfd;
if (!szFile || strlen(szFile) == 0 || strlen(szFile) >= sizeof(buf))
return ap_pstrdup(pPool, "");
buf[0] = '\0';
pInputName = ap_pstrdup(pPool, szFile);
/* First convert all slashes to \ so Win32 calls work OK */
for (p = pInputName; *p; p++) {
if (*p == '/')
*p = '\\';
}
p = pInputName;
/* If there is drive information, copy it over. */
if (pInputName[1] == ':') {
buf[0] = tolower(*p++);
buf[1] = *p++;
buf[2] = '\0';
/* If all we have is a drive letter, then we are done */
if (strlen(pInputName) == 2)
bDone = TRUE;
}
q = p;
if (*p == '\\') {
p++;
if (*p == '\\') /* Possible UNC name */
{
p++;
/* Get past the machine name. FindFirstFile */
/* will not find a machine name only */
p = strchr(p, '\\');
if (p)
{
p++;
/* Get past the share name. FindFirstFile */
/* will not find a \\machine\share name only */
p = strchr(p, '\\');
if (p) {
strncat(buf,q,p-q);
q = p;
p++;
}
}
if (!p)
p = q;
}
}
p = strchr(p, '\\');
while (!bDone) {
if (p)
*p = '\0';
if (strchr(q, '*') || strchr(q, '?'))
bFileExists = FALSE;
/* If the path exists so far, call FindFirstFile
* again. However, if this portion of the path contains
* only '.' charaters, skip the call to FindFirstFile
* since it will convert '.' and '..' to actual names.
* Note: in the call to OnlyDots, we may have to skip
* a leading slash.
*/
if (bFileExists && !OnlyDots((*q == '.' ? q : q+1))) {
hFind = FindFirstFile(pInputName, &wfd);
if (hFind == INVALID_HANDLE_VALUE) {
bFileExists = FALSE;
}
else {
FindClose(hFind);
if (*q == '\\')
strcat(buf,"\\");
strcat(buf, wfd.cFileName);
}
}
if (!bFileExists || OnlyDots((*q == '.' ? q : q+1))) {
strcat(buf, q);
}
if (p) {
q = p;
*p++ = '\\';
p = strchr(p, '\\');
}
else {
bDone = TRUE;
}
}
/* First convert all slashes to / so server code handles it ok */
for (p = buf; *p; p++) {
if (*p == '\\')
*p = '/';
}
return ap_pstrdup(pPool, buf);
}
/* Perform canonicalization with the exception that the
* input case is preserved.
*/
char * canonical_filename(ap_pool_t *pPool, const char *szFile)
{
char *pNewStr;
char *s;
char *p;
char *q;
if (szFile == NULL || strlen(szFile) == 0)
return ap_pstrdup(pPool, "");
pNewStr = ap_pstrdup(pPool, szFile);
/* Change all '\' characters to '/' characters.
* While doing this, remove any trailing '.'.
* Also, blow away any directories with 3 or
* more '.'
*/
for (p = pNewStr,s = pNewStr; *s; s++,p++) {
if (*s == '\\' || *s == '/') {
q = p;
while (p > pNewStr && *(p-1) == '.')
p--;
if (p == pNewStr && q-p <= 2 && *p == '.')
p = q;
else if (p > pNewStr && p < q && *(p-1) == '/') {
if (q-p > 2)
p--;
else
p = q;
}
*p = '/';
}
else {
*p = *s;
}
}
*p = '\0';
/* Blow away any final trailing '.' since on Win32
* foo.bat == foo.bat. == foo.bat... etc.
* Also blow away any trailing spaces since
* "filename" == "filename "
*/
q = p;
while (p > pNewStr && (*(p-1) == '.' || *(p-1) == ' '))
p--;
if ((p > pNewStr) ||
(p == pNewStr && q-p > 2))
*p = '\0';
/* One more security issue to deal with. Win32 allows
* you to create long filenames. However, alias filenames
* are always created so that the filename will
* conform to 8.3 rules. According to the Microsoft
* Developer's network CD (1/98)
* "Automatically generated aliases are composed of the
* first six characters of the filename plus ~n
* (where n is a number) and the first three characters
* after the last period."
* Here, we attempt to detect and decode these names.
*/
p = strchr(pNewStr, '~');
if (p != NULL) {
char *pConvertedName, *pQstr, *pPstr;
char buf[HUGE_STRING_LEN];
/* We potentially have a short name. Call
* ap_os_systemcase_filename to examine the filesystem
* and possibly extract the long name.
*/
pConvertedName = ap_os_systemcase_filename(pPool, pNewStr);
/* Since we want to preserve the incoming case as much
* as we can, compare for differences in the string and
* only substitute in the path names that changed.
*/
if (stricmp(pNewStr, pConvertedName)) {
buf[0] = '\0';
q = pQstr = pConvertedName;
p = pPstr = pNewStr;
do {
q = strchr(q,'/');
p = strchr(p,'/');
if (p != NULL) {
*q = '\0';
*p = '\0';
}
if (stricmp(pQstr, pPstr))
strcat(buf, pQstr); /* Converted name */
else
strcat(buf, pPstr); /* Original name */
if (p != NULL) {
pQstr = q;
pPstr = p;
*q++ = '/';
*p++ = '/';
}
} while (p != NULL);
pNewStr = ap_pstrdup(pPool, buf);
}
}
return pNewStr;
}
1.1 apache-apr/apr/misc/win32/start.c
Index: start.c
===================================================================
/* ====================================================================
* Copyright (c) 1999 The Apache Group. 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. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" 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 names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``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 GROUP 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 Group.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
#include "apr_win.h"
#include "apr_general.h"
#include "apr_errno.h"
#include "apr_pools.h"
#include "apr_lib.h"
#include <string.h>
ap_status_t ap_create_context(ap_context_t *cont, void *data, ap_context_t
**newcont)
{
ap_context_t *new;
ap_pool_t *pool;
if (cont) {
pool = ap_make_sub_pool(cont->pool);
}
else {
pool = ap_init_alloc();;
}
if (pool == NULL) {
return APR_ENOPOOL;
}
new = (ap_context_t *)ap_palloc(pool, sizeof(ap_context_t));
new->pool = pool;
if (data == NULL && cont) {
new->prog_data = cont->prog_data;
}
else {
new->prog_data = data;
}
if (cont) {
new->signal_safe = cont->signal_safe;
new->cancel_safe = cont->cancel_safe;
}
else {
new->signal_safe = 0;
new->cancel_safe = 0;
}
*newcont = new;
return APR_SUCCESS;
}
ap_status_t ap_set_signal_safe(ap_context_t *cont, ap_int16_t safe)
{
if (cont) {
cont->signal_safe = safe;
return APR_SUCCESS;
}
return APR_ENOCONT;
}
ap_status_t ap_set_cancel_safe(ap_context_t *cont, ap_int16_t safe)
{
if (cont) {
cont->cancel_safe = safe;
return APR_SUCCESS;
}
return APR_ENOCONT;
}
ap_status_t ap_destroy_context(ap_context_t *cont)
{
ap_destroy_pool(cont->pool);
return APR_SUCCESS;
}
1.1 apache-apr/apr/misc/win32/timetest.c
Index: timetest.c
===================================================================
#include <windows.h>
#include <time.h>
#include <stdio.h>
time_t WinTimeToUnixTime(FILETIME *time)
{
LONGLONG temp = 0;
/* Convert to one 64 bit number so we can work with it. */
temp = time->dwHighDateTime;
temp = temp << 32;
temp |= time->dwLowDateTime;
/* Convert from Windows epoch (Jan 1, 1600) to Unix
* epoch (Jan 1, 1970)
*/
temp -= 116444736000000000;
/* Convert from 100 nano-sec blocks to seconds. */
temp /= 10000000;
return (time_t) temp;
}