#include "httpd.h"
#include "ap_config.h"
#include <dirent.h>
extern char ap_server_root[MAX_STRING_LEN];
void ap_os_dso_init(void)
{
}
void *ap_os_dso_load(const char *path)
{
unsigned int nlmHandle;
char *moduleName = NULL;
moduleName = strrchr(path, '/');
if (moduleName) {
moduleName++;
}
nlmHandle = FindNLMHandleInAddressSpace((char*)moduleName, NULL);
if (nlmHandle == NULL) {
spawnlp(P_NOWAIT | P_SPAWN_IN_CURRENT_DOMAIN, path, NULL);
nlmHandle = FindNLMHandleInAddressSpace((char*)moduleName, NULL);
}
return (void *)nlmHandle;
}
void ap_os_dso_unload(void *handle)
{
KillMe(handle);
}
void *ap_os_dso_sym(void *handle, const char *symname)
{
return ImportSymbol((int)GetNLMHandle(), (char *)symname);
}
const char *ap_os_dso_error(void)
{
return NULL;
}
char *remove_filename(char* str)
{
int i, len = strlen(str);
for (i=len; i; i--) {
if (str[i] == '\\' || str[i] == '/') {
str[i] = NULL;
break;
}
}
return str;
}
char *bslash2slash(char* str)
{
int i, len = strlen(str);
for (i=0; i<len; i++) {
if (str[i] == '\\') {
str[i] = '/';
break;
}
}
return str;
}
void init_name_space()
{
UnAugmentAsterisk(TRUE);
SetCurrentNameSpace(NW_NS_LONG);
SetTargetNameSpace(NW_NS_LONG);
}
char *ap_os_canonical_filename(pool *pPool, const char *szFile)
{
char *pNewName = ap_pstrdup(pPool, szFile);
char *slash_test;
bslash2slash(pNewName);
if ((pNewName[0] == '/') && (strchr (pNewName, ':') == NULL))
{
char vol[256];
_splitpath (ap_server_root, vol, NULL, NULL, NULL);
pNewName = ap_pstrcat (pPool, vol, pNewName, NULL);
}
if ((slash_test = strchr(pNewName, ':')) && (*(slash_test+1) != '/'))
{
char vol[_MAX_VOLUME+1], dir[_MAX_DIR+1];
char fname[_MAX_FNAME+1], ext[_MAX_EXT+1];
_splitpath (pNewName, vol, dir, fname, ext);
pNewName = ap_pstrcat (pPool, vol, "/", dir, fname, ext, NULL);
}
strlwr(pNewName);
return pNewName;
}
int ap_os_is_filename_valid(const char *file)
{
const char *segstart;
unsigned int seglength;
const char *pos;
char *colonpos, *fslashpos, *bslashpos;
static const char * const invalid_characters = "?\"<>*|:";
static const char * const invalid_filenames[] = {
"CON", "AUX", "COM1", "COM2", "COM3",
"COM4", "LPT1", "LPT2", "LPT3", "PRN", "NUL", NULL
};
// First check to make sure that we have a file so that we don't abend
if (file == NULL)
return 0;
if (strlen(file) >= _MAX_PATH) {
return 0;
}
pos = file;
colonpos = strchr (file, ':');
fslashpos = strchr (file, '/');
bslashpos = strchr (file, '\\');
// The path must contain a volume specifier and the volume
// specifier must appear before in slashes.
if (colonpos) {
// If a slash appears before the colon then the path
// is invalid until we support remotes server file
// access
if (fslashpos && (fslashpos < colonpos))
return 0;
if (bslashpos && (bslashpos < colonpos))
return 0;
}
else {
return 0;
}
pos = ++colonpos;
if (!*pos) {
return 0;
}
while (*pos) {
unsigned int idx;
unsigned int baselength;
while (*pos == '/' || *pos == '\\') {
pos++;
}
if (*pos == '\0') {
break;
}
segstart = pos;
while (*pos && *pos != '/' && *pos != '\\') {
pos++;
}
seglength = pos - segstart;
for (idx = 0; idx < seglength; idx++) {
if ((segstart[idx] > 0 && segstart[idx] < 32) ||
strchr(invalid_characters, segstart[idx])) {
return 0;
}
}
if (segstart[seglength-1] == '.') {
return 0;
}
for (baselength = 0; baselength < seglength; baselength++) {
if (segstart[baselength] == '.') {
break;
}
}
if (baselength == 3 || baselength == 4) {
for (idx = 0; invalid_filenames[idx]; idx++) {
if (strlen(invalid_filenames[idx]) == baselength &&
!strnicmp(invalid_filenames[idx], segstart, baselength)) {
return 0;
}
}
}
}
return 1;
}