Update of /cvsroot/wonder/Wonder/Adaptors/Adaptor In directory usw-pr-cvs1:/tmp/cvs-serv18031/Adaptors/Adaptor Added Files: Makefile MoreURLCUtilities.c MoreURLCUtilities.h PB.project Platform.c Platform.h WOAppReq.h WOURLCUtilities.c WOURLCUtilities.h WOURLCUtilities_3.c WOURLCUtilities_3.h appcfg.c appcfg.h cfgparse.c config.c config.h errors.h hostlookup.c hostlookup.h httperrors.h httpheaders.h list.c list.h listing.c listing.h loadaverage.c loadbalancing.c loadbalancing.h log.c log.h nbsocket.c random.c request.c request.h response.c response.h roundrobin.c shmem.c shmem.h strdict.c strdict.h strtbl.c strtbl.h transaction.c transaction.h transport.c transport.h wastring.c wastring.h womalloc.c womalloc.h xmlcdefines.h xmlcdocument.h xmlcparser.c xmlcparser.h xmlctokenizer.c xmlctokenizer.h xmlparse.c Log Message: added Adaptors folder --- NEW FILE: Makefile --- all: rm -f make.preamble make.postamble @echo "COMMON_SRCFILES = \\" >> make.preamble for file in *.c; do \ echo "$${file}: ../Adaptor/$${file}" | sed s/\\.c/.o/ >> make.postamble ; \ echo " $$""{CC} $$""{CFLAGS} -c ../Adaptor/$${file}" >> make.postamble ; \ echo " $${file} \\" >> make.preamble ; \ done @echo "" >> make.preamble @echo "COMMON_OBJFILES = \\" >> make.preamble for file in *.c; do \ echo " $${file} \\" | sed s/\\.c/.o/ >> make.preamble ; \ done @echo "" >> make.preamble clean: rm -f make.preamble make.postamble --- NEW FILE: MoreURLCUtilities.c --- /* Copyright © 2000 Apple Computer, Inc. All Rights Reserved. The contents of this file constitute Original Code as defined in and are subject to the Apple Public Source License Version 1.1 (the 'License'). You may not use this file except in compliance with the License. Please obtain a copy of the License at http://www.apple.com/publicsource and read it before usingthis file. This Original Code and all software distributed under the License are distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the License for the specific language governing rights and limitations under the License. */ #include "config.h" #include "MoreURLCUtilities.h" #ifdef SUPPORT_V3_URLS #include "WOURLCUtilities_3.h" #endif #include "errors.h" #include "log.h" #include <string.h> #include <ctype.h> /* * fudge the version indicator here */ static const char * const wo_versions = "34"; #define v4_url wo_versions+1 #define v3_url wo_versions #define URLVersionLen 1 #define WebObjects_STR "/"WEBOBJECTS #define WEBOBJECTS_STR "/WEBOBJECTS" #define WebObjects_LEN strlen(WebObjects_STR) /* assume both same length */ const char * const cgi_extensions[] = { ".exe", ".EXE", ".dll", ".DLL", NULL }; const char * const app_extensions[] = {WOADAPTOR_APP_EXTENSION, WOADAPTOR_APP_EXTENSION_UPPERCASE, NULL }; /* * to better deal with URL syntax changes, we parse just the application * name from the URL ... * * We assume the struct is correctly initialized on entry to the function, via WOURLComponents_Initializer. */ WOURLError WOParseApplicationName(WOURLComponents *wc, const char *url) { int len; const char *s; const char *webobjects, *extension, *version, *start, *end; int i; len = strlen(url); webobjects = NULL; /* * spot our marker in the URL. It'll look like "/WebObjects-n.ext/" */ s = (url != NULL) ? url : ""; while ( (s <= url + (len - WebObjects_LEN)) && (webobjects == NULL) && (*s != '?') ) { while ((*s != '/') && (s <= url + (len - WebObjects_LEN))) s++; if ((strncmp(s, WebObjects_STR, WebObjects_LEN) == 0) || (strncmp(s, WEBOBJECTS_STR, WebObjects_LEN) == 0) ) webobjects = s; else s++; } if (webobjects == NULL) return WOURLInvalidPrefix; /* bail if "WebObjects" not in URL */ s = webobjects + WebObjects_LEN; /* just beyond "WebObjects" */ for (end = s; (end < url + len) && (*end != '?') && (*end != '/'); end++) /* find end of CGI moniker */; version = (*s == '-') ? s : NULL; /* do we have a version? */ extension = NULL; for (i=0; (extension == NULL) && (cgi_extensions[i] != NULL); i++) { int n = strlen(cgi_extensions[i]); if ((end - n >= version) && (strncmp(end-n, cgi_extensions[i], n) == 0)) extension = end - n; } /* * just validate the prefix gunk.... */ if (extension != NULL) { if (version && ((extension - (version+1) < 1) || ( !isdigit(*(extension-1)) ))) return WOURLInvalidWebObjectsVersion; } else if (version != NULL) { if ((end - (version+1) < 1) || ( !isdigit(*(end-1)) )) return WOURLInvalidWebObjectsVersion; } else if ((end - s) > 1 ) return WOURLInvalidPrefix; wc->prefix.start = url; wc->prefix.length = end - url; if (version != NULL) { wc->webObjectsVersion.start = version + 1; wc->webObjectsVersion.length = ((extension) ? extension : end)-version; } /* * find the application name * - we're not supporting WO version 2 URLs here.... * - this is probably more convoluted than it need be */ start = ((end < url + len) && (*end != '?')) ? end + 1 : end; end = url + len; extension = end; for (i=0; (extension == end) && (app_extensions[i] != NULL); i++) { int n = strlen(app_extensions[i]); for (s=start; (s+n <= url+len) && (*s != '?') && (extension == end); ++s) { if ( (strncmp(s, app_extensions[i], n) == 0) && ((s + n == url + len) || (*(s+n) == '?') || (*(s+n) == '/')) ) { extension = s; end = s + n; } } if (*s == '?') end = s; } /* start == pointer to first character of name. */ /* extension == pointer to first character after name. */ /* end == pointer to first character after extension. */ wc->applicationName.length = (end < extension) ? end - start : extension - start; if (wc->applicationName.length != 0) { wc->applicationName.start = start; /* get rid of trailing slashes in case the app name is last */ /* and followed by trailing slashes */ while(wc->applicationName.length && wc->applicationName.start[wc->applicationName.length-1] == '/') wc->applicationName.length--; return WOURLOK; } else return WOURLInvalidApplicationName; } /* * cover functions for the different versions... */ void ComposeURL(char *string, WOURLComponents *wc) { if (wc->webObjectsVersion.length) { switch (*(wc->webObjectsVersion.start)) { case '4': #if defined(SUPPORT_V4_URLS) WOComposeURL_40(string, wc); #else /* SUPPORT_V4_URLS */ WOLog(WO_ERR,"Unknown URL version"); #endif /* SUPPORT_V4_URLS */ break; case '3': #if defined(SUPPORT_V3_URLS) WOComposeURL(string, wc); #else /* SUPPORT_V3_URLS */ WOLog(WO_ERR,"Unknown URL version"); #endif /* SUPPORT_V3_URLS */ break; default: WOLog(WO_ERR,"Unknown URL version"); break; } } #if !defined(SUPPORT_V3_URLS) && !defined(SUPPORT_V4_URLS) #error "URL Version support is mucked up!" #endif /* logComponents(wc); */ WOLog(WO_DBG,"Composed URL to '%s'",string); } unsigned int SizeURL(WOURLComponents *wc) { if (wc->webObjectsVersion.length) { switch (*(wc->webObjectsVersion.start)) { case '4': #if defined(SUPPORT_V4_URLS) return WOSizeURL_40(wc); #endif /* SUPPORT_V4_URLS */ break; case '3': #if defined(SUPPORT_V3_URLS) return WOSizeURL(wc); #endif /* SUPPORT_V3_URLS */ break; default: WOLog(WO_ERR,"SizeURL: Unknown URL version"); break; } } return 4096; /* .. and hope it's enough */ } /* * Dealing with URLs. Most code is provided with WebObjects and must * be used without modification to insure forward compatibility. * Here, though, we want to provide a little more functionality to * allow cleaner interface and support different URL syntax's. */ const char *WOParseAndCheckURL(WOURLComponents *wc, const char *url, int version) { WOURLError result = WOURLOK; switch (version) { case 4: #ifdef SUPPORT_V4_URLS WOParseURL_40(wc, url); /* parse a V4 syntax URL */ result = WOCheckURL_40(wc); if (result == WOURLOK) { wc->webObjectsVersion.start = v4_url; wc->webObjectsVersion.length = URLVersionLen; WOLog(WO_INFO,"V4 URL: %s",url); return NULL; } #endif /* SUPPORT_V4_URLS */ break; case 3: #ifdef SUPPORT_V3_URLS WOParseURL(wc, url); /* parse a V3 syntax URL */ result = WOCheckURL(wc); if (result == WOURLOK) { wc->webObjectsVersion.start = v3_url; wc->webObjectsVersion.length = URLVersionLen; WOLog(WO_INFO,"V3 URL: %s",url); return NULL; /* no error */ } #endif /* SUPPORT_V3_URLS */ break; default: break; } if (result == WOURLOK) /* still in initialized state? */ return "Unsupported URL version"; else return WOURLstrerror(result); } const char *WOURLstrerror(WOURLError err) { const char *errStr; switch (err) { case WOURLOK: errStr = NULL; break; case WOURLInvalidPrefix: errStr = INV_PREFIX; break; case WOURLInvalidSuffix: errStr = INV_SUFFIX; break; case WOURLInvalidApplicationName: errStr = INV_APPNAME; break; case WOURLInvalidApplicationNumber: errStr = INV_APPNUM; break; case WOURLInvalidApplicationHost: errStr = INV_HOST; break; case WOURLInvalidRequestHandlerKey: errStr = INV_RHKEY; break; case WOURLInvalidRequestHandlerPath: errStr = INV_RHPATH; break; case WOURLInvalidPageName: errStr = INV_PAGE; break; case WOURLInvalidSessionID: errStr = INV_SESSID; break; case WOURLInvalidContextID: errStr = INV_CTXID; break; case WOURLInvalidSenderID: errStr = INV_SENDER; break; case WOURLInvalidQueryString: errStr = INV_QUERY; break; case WOURLInvalidPostData: errStr = INV_FORM_DATA; break; case WOURLNoPostData: errStr = NO_FORM_DATA; break; default: errStr = INV_URL; break; } return errStr; } /* * debugging aid - no need to inline */ static char *_doappnd(const char *d,char *s, WOURLComponent *c) { int dl = strlen(d); memcpy(s,d,dl); s += dl; if (c->start != NULL) { memcpy(s, c->start, c->length); s += c->length; } else { memcpy(s, "(null)", 6); s += 6; } return s; } void logComponents(WOURLComponents *wc) { char msg[4096], *c; /* clearly for debugging only .. */ strcpy(msg,"URL Components:"); c = _doappnd("\n\tPrefix:\t",msg+strlen(msg), &(wc->prefix)); c = _doappnd("\n\tWOVersion:\t",c, &(wc->webObjectsVersion)); c = _doappnd("\n\tAppName:\t",c, &(wc->applicationName)); c = _doappnd("\n\tAppNumber:\t",c, &(wc->applicationNumber)); c = _doappnd("\n\tAppHost:\t",c, &(wc->applicationHost)); c = _doappnd("\n\tSessionID:\t",c, &(wc->sessionID)); c = _doappnd("\n\tPageName:\t",c, &(wc->pageName)); c = _doappnd("\n\tContextId:\t",c, &(wc->contextID)); c = _doappnd("\n\tSenderId:\t",c, &(wc->senderID)); c = _doappnd("\n\tQueryString:\t",c, &(wc->queryString)); c = _doappnd("\n\tSuffix:\t",c, &(wc->suffix)); *c = '\0'; WOLog(WO_INFO,msg); } --- NEW FILE: MoreURLCUtilities.h --- /* Copyright © 2000 Apple Computer, Inc. All Rights Reserved. The contents of this file constitute Original Code as defined in and are subject to the Apple Public Source License Version 1.1 (the 'License'). You may not use this file except in compliance with the License. Please obtain a copy of the License at http://www.apple.com/publicsource and read it before usingthis file. This Original Code and all software distributed under the License are distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the License for the specific language governing rights and limitations under the License. */ #ifndef MORE_URL_C_UTILITIES_H #define MORE_URL_C_UTILITIES_H /* * * companion to WOURLCUtilities.... * * things that all adaptors will do, so we may as well not duplicate code * * handles URL syntax versioning between V2 - V3 as well */ #include "WOURLCUtilities.h" #define NULL_WOURLComponent ((WOURLComponent){NULL,0}) #define WOURLComponents_Initializer ((WOURLComponents) { \ NULL_WOURLComponent, \ NULL_WOURLComponent, \ NULL_WOURLComponent, \ NULL_WOURLComponent, \ NULL_WOURLComponent, \ NULL_WOURLComponent, \ NULL_WOURLComponent, \ NULL_WOURLComponent, \ NULL_WOURLComponent, \ NULL_WOURLComponent, \ NULL_WOURLComponent, \ NULL_WOURLComponent, \ NULL_WOURLComponent \ }) /* * Cover some functions to support URL versioning */ void ComposeURL(char *string, WOURLComponents *components); unsigned int SizeURL(WOURLComponents *components); /* * parses just the application name from the url, returns 0 on * success & fills in only wc.prefix, wc.webobjectsVersion and * wc.applicationName */ WOURLError WOParseApplicationName(WOURLComponents *wc, const char *url); /* * calls WOParseURL and then WOCheckURL */ const char *WOParseAndCheckURL(WOURLComponents *wc, const char *url, int version); /* * err code to string */ const char *WOURLstrerror(WOURLError err); unsigned int SizeURL(WOURLComponents *wc); void ComposeURL(char *string, WOURLComponents *wc); /* * for debugging, I guess */ void logComponents(WOURLComponents *wc); #endif --- NEW FILE: PB.project --- { DYNAMIC_CODE_GEN = YES; FILESTABLE = { H_FILES = ( MoreURLCUtilities.h, WOAppReq.h, WOURLCUtilities.h, WOURLCUtilities_3.h, appcfg.h, config.h, errors.h, hostlookup.h, list.h, listing.h, loadbalancing.h, log.h, Platform.h, request.h, response.h, shmem.h, strdict.h, strtbl.h, transaction.h, transport.h, womalloc.h, xmlcparser.h, xmlcdocument.h, xmlcdefines.h, xmlctokenizer.h, wastring.h, httperrors.h ); OTHER_LINKED = ( MoreURLCUtilities.c, WOURLCUtilities.c, WOURLCUtilities_3.c, appcfg.c, cfgparse.c, config.c, hostlookup.c, list.c, listing.c, loadaverage.c, loadbalancing.c, log.c, nbsocket.c, Platform.c, random.c, request.c, response.c, roundrobin.c, shmem.c, strdict.c, strtbl.c, transaction.c, transport.c, womalloc.c, xmlparse.c, xmlctokenizer.c, wastring.c, xmlcparser.c ); OTHER_SOURCES = (Makefile); PRECOMPILED_HEADERS = (); PROJECT_HEADERS = (); PUBLIC_HEADERS = (); SUBPROJECTS = (); }; LANGUAGE = English; NEXTSTEP_BUILDTOOL = /bin/gnumake; NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; PROJECTNAME = Adaptor; PROJECTTYPE = Legacy; PROJECTVERSION = 2.8; WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; } --- NEW FILE: Platform.c --- /* Copyright © 2000 Apple Computer, Inc. All Rights Reserved. The contents of this file constitute Original Code as defined in and are subject to the Apple Public Source License Version 1.1 (the 'License'). You may not use this file except in compliance with the License. Please obtain a copy of the License at http://www.apple.com/publicsource and read it before usingthis file. This Original Code and all software distributed under the License are distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the License for the specific language governing rights and limitations under the License. */ /* * This file provides a template implementation for all the platform * specific adaptor requirements. */ #include "log.h" #include <stdlib.h> #include <errno.h> #include <string.h> #ifdef WIN32 #include <windows.h> #include <winsock.h> #endif #include "Platform.h" #include "womalloc.h" /* * Error functions. This template is based on the unix errno facilities. * A more sophisticated implementation may be required for multithreaded * environments. Some sample source applicable to Windows platforms is also * shown. */ int WA_error() { #ifdef WIN32 return WSAGetLastError(); #else return errno; #endif } #ifndef WIN32 char *WA_errorDescription(int error) { return strerror(error); } extern void WA_freeErrorDescription(char *msg) { /* This is a no-op because WA_errorDescription doesn't copy the string. */ } #else /* * implementation for the Windows platform. */ char *WA_errorDescription(int error) { LPVOID lpMsgBuf = 0; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ (LPTSTR) &lpMsgBuf, 0, NULL ); return lpMsgBuf; } extern void WA_freeErrorDescription(char *msg) { LocalFree((LPVOID)msg); } #if (THREAD_MODEL == WIN32_THREADS) typedef struct { HANDLE lock; const char *name; } WinRecursiveLock; WA_recursiveLock WA_createLock(const char *name) { WinRecursiveLock *lock; lock = WOMALLOC(sizeof(WinRecursiveLock)); if (lock) { lock->lock = CreateMutex(NULL, FALSE, NULL); if (name) lock->name = name; else lock->name = "(unnamed)"; } else WOLog(WO_ERR, "WA_createLock(): could not malloc"); return (WA_recursiveLock)lock; } #ifdef EXTRA_DEBUGGING_LOGS void _WA_lock(WA_recursiveLock _lock, const char *file, int line) #else void WA_lock(WA_recursiveLock _lock) #endif { WinRecursiveLock *lock = (WinRecursiveLock *)_lock; #ifdef EXTRA_DEBUGGING_LOGS if (_lock != logMutex) WOLog(WO_DBG, "locking %s from %s:%d", lock->name, file, line); #endif WaitForSingleObject(lock->lock, INFINITE); } #ifdef EXTRA_DEBUGGING_LOGS void _WA_unlock(WA_recursiveLock _lock, const char *file, int line) #else void WA_unlock(WA_recursiveLock _lock) #endif { WinRecursiveLock *lock = (WinRecursiveLock *)_lock; #ifdef EXTRA_DEBUGGING_LOGS if (_lock != logMutex) WOLog(WO_DBG, "unlocking %s from %s:%d", lock->name, file, line); #endif ReleaseMutex(lock->lock); } void WA_yield() { SleepEx(0,0); } #endif /* THREAD_MODEL */ #endif /* WIN32 */ #if (THREAD_MODEL == CTHREADS) #include <mach/cthreads.h> typedef struct { cthread_t lockingThread; unsigned int lockCount; struct mutex m; struct condition c; const char *name; } CThreadRecursiveLock; WA_recursiveLock WA_createLock(const char *name) { CThreadRecursiveLock *lock; lock = WOMALLOC(sizeof(CThreadRecursiveLock)); if (lock) { mutex_init(&lock->m); condition_init(&lock->c); lock->lockCount = 0; lock->lockingThread = NULL; if (name) lock->name = name; else lock->name = "(unnamed)"; } return lock; } /* * Lock the mutex. */ #ifdef EXTRA_DEBUGGING_LOGS void _WA_lock(WA_recursiveLock _lock, const char *file, int line) #else void WA_lock(WA_recursiveLock _lock) #endif { CThreadRecursiveLock *lock = (CThreadRecursiveLock *)_lock; cthread_t self = cthread_self(); #ifdef EXTRA_DEBUGGING_LOGS if (_lock != logMutex) WOLog(WO_DBG, "thread %x locking %s from %s:%d", self, lock->name, file, line); #endif mutex_lock(&lock->m); while (lock->lockingThread != self && lock->lockingThread != NULL) condition_wait(&lock->c, &lock->m); lock->lockingThread = self; lock->lockCount++; mutex_unlock(&lock->m); } /* * Unlock the mutex. */ #ifdef EXTRA_DEBUGGING_LOGS void _WA_unlock(WA_recursiveLock _lock, const char *file, int line) #else void WA_unlock(WA_recursiveLock _lock) #endif { CThreadRecursiveLock *lock = (CThreadRecursiveLock *)_lock; #ifdef EXTRA_DEBUGGING_LOGS if (_lock != logMutex) WOLog(WO_DBG, "thread unlocking %s from %s:%d", cthread_self(), lock->name, file, line); #endif mutex_lock(&lock->m); lock->lockCount--; if (lock->lockCount == 0) { lock->lockingThread = NULL; condition_signal(&lock->c); } mutex_unlock(&lock->m); } void WA_yield() { cthread_yield(cthread_self()); } #endif /* cthreads */ #if (THREAD_MODEL == PTHREADS) #include <pthread.h> #include <sched.h> typedef struct { pthread_t lockingThread; unsigned int lockCount; pthread_mutex_t m; pthread_cond_t c; const char *name; } PThreadRecursiveLock; WA_recursiveLock WA_createLock(const char *name) { PThreadRecursiveLock *lock; lock = WOMALLOC(sizeof(PThreadRecursiveLock)); if (lock) { pthread_mutex_init(&lock->m, NULL); pthread_cond_init(&lock->c, NULL); lock->lockCount = 0; lock->lockingThread = 0; if (name) lock->name = name; else lock->name = "(unnamed)"; } return lock; } /* * Lock the mutex. */ #ifdef EXTRA_DEBUGGING_LOGS void _WA_lock(WA_recursiveLock _lock, const char *file, int line) #else void WA_lock(WA_recursiveLock _lock) #endif { PThreadRecursiveLock *lock = (PThreadRecursiveLock *)_lock; pthread_t self = pthread_self(); #ifdef EXTRA_DEBUGGING_LOGS if (_lock != logMutex) WOLog(WO_DBG, "thread %x locking %s from %s:%d", self, lock->name, file, line); #endif pthread_mutex_lock(&lock->m); while (!pthread_equal(lock->lockingThread,self) && lock->lockCount != 0) pthread_cond_wait(&lock->c, &lock->m); lock->lockingThread = self; lock->lockCount++; pthread_mutex_unlock(&lock->m); } /* * Unlock the mutex. */ #ifdef EXTRA_DEBUGGING_LOGS void _WA_unlock(WA_recursiveLock _lock, const char *file, int line) #else void WA_unlock(WA_recursiveLock _lock) #endif { PThreadRecursiveLock *lock = (PThreadRecursiveLock *)_lock; #ifdef EXTRA_DEBUGGING_LOGS if (_lock != logMutex) WOLog(WO_DBG, "thread %x unlocking %s from %s:%d", pthread_self(), lock->name, file, line); #endif pthread_mutex_lock(&lock->m); lock->lockCount--; if (lock->lockCount == 0) { lock->lockingThread = 0; pthread_cond_signal(&lock->c); } pthread_mutex_unlock(&lock->m); } void WA_yield() { sched_yield(); } #endif /* pthreads */ --- NEW FILE: Platform.h --- /* Copyright © 2000 Apple Computer, Inc. All Rights Reserved. The contents of this file constitute Original Code as defined in and are subject to the Apple Public Source License Version 1.1 (the 'License'). You may not use this file except in compliance with the License. Please obtain a copy of the License at http://www.apple.com/publicsource and read it before usingthis file. This Original Code and all software distributed under the License are distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the License for the specific language governing rights and limitations under the License. */ #ifndef _PLATFORM_H_ #define _PLATFORM_H_ /* Define this to log each lock/unlock */ /* #define EXTRA_DEBUGGING_LOGS */ #ifdef EXTRA_DEBUGGING_LOGS #warning Building with EXTRA_DEBUGGING_LOGS on. #endif #ifndef SINGLE_THREADED_ADAPTOR #ifndef MULTITHREADED_ADAPTOR #error Must define either SINGLE_THREADED_ADAPTOR or MULTITHREADED_ADAPTOR. Fix the makefile. #endif #endif #define SINGLE 0 #define CTHREADS 1 #define PTHREADS 2 #define WIN32_THREADS 3 #ifdef SINGLE_THREADED_ADAPTOR #define THREAD_MODEL SINGLE #else #ifdef WIN32 #define THREAD_MODEL WIN32_THREADS #endif #ifdef SOLARIS #define THREAD_MODEL PTHREADS #endif #ifdef HPUX #define THREAD_MODEL PTHREADS #endif #endif /* * A short text string which identifies the adaptor version. * This is passed to instances as the x-webobjects-adaptor-version header. * For example: "CGI/4.5", "Apache/4.5", etc. */ extern char *WA_adaptorName; /********************************************** * Functions relating to error codes/messages.* **********************************************/ /* * Return the error code associated with the last system call. */ extern int WA_error(); /* * Returns a human readable description of the error code. */ extern char *WA_errorDescription(int error); /* * Free the error string previouly returned by WA_errorDescription(). */ extern void WA_freeErrorDescription(char *msg); /********************* * Locking functions * *********************/ /* * If adaptor will be running in a multithreaded environment, these primitives are used for locking. * They are meant to encapsulate a system dependent implementation of a recursive lock. A thread * calls WA_lock to aquire the lock. It should block if any other thread is holding the lock * but proceed if the lock is held by the calling thread. WA_unlock is called when a thread wants to * release the lock. It should only allow other threads to aquire the lock after WA_unlock has been * called by the thread the same number of times as WA_lock. */ /* * An opaque typedef for a system dependent lock. */ typedef void *WA_recursiveLock; /* * Allocates, initializes, and returns a mutex. * Depending on the locking implementation, name may be associated with the lock * to simplify debugging. Name should be unique, or may be NULL. */ WA_recursiveLock WA_createLock(const char *name); #ifndef EXTRA_DEBUGGING_LOGS /* * Lock the mutex. */ void WA_lock(WA_recursiveLock); /* * Unlock the mutex. */ void WA_unlock(WA_recursiveLock); #else /* For debugging, pass the location of the lock call */ void _WA_lock(WA_recursiveLock, const char *file, int line); void _WA_unlock(WA_recursiveLock, const char *file, int line); #define WA_lock(lock) _WA_lock(lock, __FILE__, __LINE__) #define WA_unlock(lock) _WA_unlock(lock, __FILE__, __LINE__) #endif /* * yield the current thread */ void WA_yield(); /* * If the adaptor is single threaded we don't need any of these. */ #ifdef SINGLE_THREADED_ADAPTOR #define WA_createLock(name) ((WA_recursiveLock)1) #undef WA_lock #define WA_lock(lock) #undef WA_unlock #define WA_unlock(lock) #define WA_yield() #endif #endif /* _PLATFORM_H_ */ --- NEW FILE: WOAppReq.h --- /* Copyright © 2000 Apple Computer, Inc. All Rights Reserved. The contents of this file constitute Original Code as defined in and are subject to the Apple Public Source License Version 1.1 (the 'License'). You may not use this file except in compliance with the License. Please obtain a copy of the License at http://www.apple.com/publicsource and read it before usingthis file. This Original Code and all software distributed under the License are distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the License for the specific language governing rights and limitations under the License. */ #ifndef WOAPPREQ_H_INCLUDED #define WOAPPREQ_H_INCLUDED /* * the struct used to pass information regarding this request */ typedef enum { err_none = 0, /* everything's ok */ err_notFound, /* application name not found */ err_noInstance, /* no available instances */ err_connect, /* can't connect */ err_send, /* error occured while sending request */ err_response, /* invalid response recieved */ } RequestError; /* * information regarding the app */ typedef struct _WOAppReq { char name[WA_MAX_APP_NAME_LENGTH]; /* relative to ../WebObjects */ char host[WA_MAX_HOST_NAME_LENGTH]; /* target host */ void *hostent; /* (struct hostent *) for target host */ int port; /* listen port */ char instance[WA_MAX_INSTANCE_NUMBER_LENGTH]; /* instance (if load balancing) */ RequestError error; /* some error occured */ unsigned char urlVersion; /* wof version 2, 3 or 4 url syntax */ const char *docroot; /* doc root for this request */ void *request; /* (HTTPRequest *) */ void *response; /* (HTTPResponse *) */ struct _scheduler *scheduler; /* the scheduler to use for picking an instance for this request */ char attemptedInstances[WA_MAX_APP_INSTANCE_COUNT+7/8]; /* bit array of which instances have been tried (and failed) */ unsigned int schedulerFailed; /* if the scheduler fails to select an instance for this request */ char redirect_url[WA_MAX_URL_LENGTH]; /* in case of error */ } WOAppReq; #endif --- NEW FILE: WOURLCUtilities.c --- /* Copyright © 2000 Apple Computer, Inc. All Rights Reserved. The contents of this file constitute Original Code as defined in and are subject to the Apple Public Source License Version 1.1 (the 'License'). You may not use this file except in compliance with the License. Please obtain a copy of the License at http://www.apple.com/publicsource and read it before usingthis file. This Original Code and all software distributed under the License are distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the License for the specific language governing rights and limitations under the License. */ /* * WARNING : The WOF URL format is common to the adaptor and the WebObjects framework. * If you modify the following code, your adaptor may not be able to communicate with WebObjects applications ! * * Currently (WebObjects 4.0/4.5), the WOF URL format is: * <PREFIX>/<APPLICATION-NAME>[.woa[/<APPLICATION-NUMBER>][/<REQUEST-HANDLER-KEY>[/<REQUEST-HANDLER-PATH>]]][?<QUERY-STRING>] * Where <PREFIX> is: * <*>/WebObjects[-<WEBOBJECTS-VERSION>][.exe|.dll] */ #include "config.h" #include "WOURLCUtilities.h" #include <stdio.h> #include <ctype.h> #include <string.h> void WOParseSizedURL_40(WOURLComponents *components, const char *string, unsigned length) { WOURLComponent *c[7] = { &(components->prefix), &(components->webObjectsVersion), &(components->applicationName), &(components->applicationNumber), &(components->requestHandlerKey),&(components->requestHandlerPath), &(components->queryString) }; const char *start; const char *version; const char *extension; const char *end; const char *s; int i, j; /* Extract prefix and WebObjects version. */ start = (string ? string : ""); /* Find start of version. */ version = start; for (s = start; s <= string + length - 11 && *s != '?' && version == start; ++s) { if (strncmp(s, "/WebObjects", 11) == 0 || strncmp(s, "/WEBOBJECTS", 11) == 0) { version = s + 11; } else { for (; s < string + length - 11 && *s == '/'; ++s); } } /* Find end of prefix. */ if (version > start) { for (s = version; s < string + length && *s != '?' && *s != '/'; ++s); end = s; } else { end = start; } /* Find start of extension. */ { const char *extensions[] = { ".exe", ".EXE", ".dll", ".DLL", NULL }; extension = end; for (i = 0; extensions[i] && extension == end; ++i) { int n = strlen(extensions[i]); if (end - n >= version && strncmp(end - n, extensions[i], n) == 0) { extension = end - n; } } } /* Treat invalid versions as invalid prefix. */ if (version < extension && (*version != '-' || (extension - (version + 1)) < 1)) { version = start; extension = start; end = start; } /* start == pointer to first character of prefix. */ /* version == pointer to first character after "/WebObjects". */ /* extension == pointer to first character after WebObjects version. */ /* end == pointer to first character after prefix. */ c[0]->start = start; c[0]->length = end - start; c[1]->start = ((version < extension) ? version + 1 : version); c[1]->length = ((version < extension) ? extension - (version + 1) : 0); /* Extract application name. */ { const char *extensions[3] = {WOADAPTOR_APP_EXTENSION, WOADAPTOR_APP_EXTENSION_UPPERCASE, NULL }; start = ((start < end && end < string + length && *end != '?') ? end + 1 : end); extension = string + length; end = string + length; for (j = 0; extensions[j] && extension == end; ++j) { int n = strlen(extensions[j]); for (s = start; s + n <= string + length && *s != '?' && extension == end; ++s) { if (strncmp(s, extensions[j], n) == 0 && (s + n == string + length || *(s + n) == '?' || *(s + n) == '/')) { extension = s; end = s + n; } } if (*s == '?') end = s; } /* start == pointer to first character of name. */ /* extension == pointer to first character after name. */ /* end == pointer to first character after extension. */ c[2]->start = start; c[2]->length = (end < extension) ? end - start : extension - start; /* get rid of trailing slashes in case the app name is last */ /* and followed by trailing slashes */ while(c[2]->length && c[2]->start[c[2]->length-1] == '/') c[2]->length--; } /* Extract Instance Number */ start = ((end < string + length && *end != '?') ? end + 1 : end); /* First skip any extra slashes */ while(*start == '/') start++; for (s = start; s < string + length && *s != '?' && *s != '/'; ++s); end = s; /* start == pointer to first character of component. */ /* end == pointer to first character after component. */ c[3]->start = start; c[3]->length = (end > start) ? end - start : 0; /* Now check if this is really an instance number * For that we will check that all characters are digits in c[3], or c[3] == "-1" */ for (s = c[3]->start; s < c[3]->length + c[3]->start && (isdigit(*s) || ((s == c[3]->start) && (*s == '-'))); s++); if (s != c[3]->length + c[3]->start) { /* This field is not just digits. This field has to be the request handler key */ c[4]->start = c[3]->start; c[4]->length = c[3]->length; /* let's just leave c[3] as is right now (we'll do more with the query string later) */ c[3]->length = 0; } else { /* Let's look for the request handler key now. */ start = ((end < string + length && *end != '?') ? end + 1 : end); /* First skip any extra slashes */ while(*start == '/') start++; for (s = start; s < string + length && *s != '?' && *s != '/'; ++s); end = s; /* start == pointer to first character of request handler key. */ /* end == pointer to first character after request handler key. */ c[4]->start = start; c[4]->length = (end > start) ? end - start : 0; } /* Extract request handler path. */ start = ((end < string + length && *end != '?') ? end + 1 : end); for (s = start; s < string + length && *s != '?'; ++s); end = s; /* start == pointer to first character of request handler path. */ /* end == pointer to first character after request handler path. */ c[5]->start = start; c[5]->length = end - start; /* Extract query string. */ /* N.B. aB. Only do this if we haven't already stored the query string in the components */ if (c[6]->start == NULL) { start = ((end < string + length) ? end + 1 : end); end = string + length; c[6]->start = start; c[6]->length = end - start; } } void WOParseURL_40(WOURLComponents *components, const char *string) { WOParseSizedURL_40(components, string, (string ? strlen(string) : 0)); } WOURLError WOCheckURL_40(WOURLComponents *components) { WOURLComponent *c[7] = { &(components->prefix), &(components->webObjectsVersion), &(components->applicationName), &(components->applicationNumber), &(components->requestHandlerKey), &(components->requestHandlerPath), &(components->queryString) }; const WOURLError e[7] = { WOURLInvalidPrefix, WOURLInvalidWebObjectsVersion, WOURLInvalidApplicationName, WOURLInvalidApplicationNumber, WOURLInvalidRequestHandlerKey, WOURLInvalidRequestHandlerPath, WOURLInvalidQueryString }; WOURLComponents prefixComponents; int i, j; /* Check component starts. */ for (i = 0; i <= 6; ++i) { if (!c[i]->start) { return e[i]; } } /* Check component characters. */ for (i = 0; i <= 6; ++i) { for (j = 0 ; j < c[i]->length; ++j) { if (c[i]->start[j] == '\0') { /* One of the components is just empty ! */ return e[i]; } else if (i <= 5 && c[i]->start[j] == '?') { /* One of the components contains a ? , which should indicate a query string ! */ return e[i]; } } } /* Check component consistency. */ if (!c[0]->length) { /* There is no prefix ! */ return e[0]; } else if (!c[2]->length) { /* There is no application name ! */ return e[2]; } else if (!c[4]->length && ( c[5]->length)) { /* There is a no request handler key, but there is a request handler path or a query string ! */ return e[4]; } /* Check prefix syntax. */ WOParseSizedURL_40(&prefixComponents, c[0]->start, c[0]->length); if (c[0]->length != prefixComponents.prefix.length) { return e[0]; } return WOURLOK; } unsigned int WOSizeURL_40(WOURLComponents *components) { WOURLComponent *c[7] = { &(components->prefix), &(components->webObjectsVersion), &(components->applicationName), &(components->applicationNumber), &(components->requestHandlerKey), &(components->requestHandlerPath), &(components->queryString) }; unsigned int length; length = 0; /* prefix */ length += c[0]->length; #if 0 /* webobjects version should not be added as it is in the prefix */ if (c[1]->length) { length += 1 + c[1]->length; } #endif /* application name */ length += 1 + c[2]->length + 4; /* instance number */ if (c[3]->length) { length += 1 + c[3]->length; } /* request handler key */ if (c[4]->length) { length += 1 + c[4]->length; } /* request handler path */ if (c[5]->length) { length += 1 + c[5]->length; } /* query string */ if (c[6]->length) { length += 1 + c[6]->length; } /* finish the string. Do not add 1 to account for the null terminator. */ return length; } void WOComposeURL_40(char *string, WOURLComponents *components) { WOURLComponent *c[11] = { &(components->prefix), &(components->webObjectsVersion), &(components->applicationName), &(components->applicationNumber), &(components->requestHandlerKey), &(components->requestHandlerPath), &(components->queryString) }; char *s; s = string; /* prefix */ strncpy(s, c[0]->start, c[0]->length); s += c[0]->length; #if 0 /* webobjects version should not be added as it is in the prefix */ if (c[1]->length) { *s++ = '-'; strncpy(s, c[1]->start, c[1]->length); s += c[1]->length; } #endif /* application name */ *s++ = '/'; strncpy(s, c[2]->start, c[2]->length); s += c[2]->length; strncpy(s, WOADAPTOR_APP_EXTENSION, 4); s += 4; /* instance number */ if (c[3]->length) { *s++ = '/'; strncpy(s, c[3]->start, c[3]->length); s += c[3]->length; } /* request handler key */ if (c[4]->length) { *s++ = '/'; strncpy(s, c[4]->start, c[4]->length); s += c[4]->length; } /* request handler path */ if (c[5]->length) { *s++ = '/'; strncpy(s, c[5]->start, c[5]->length); s += c[5]->length; } /* query string */ if (c[6]->length) { *s++ = '?'; strncpy(s, c[6]->start, c[6]->length); s += c[6]->length; } /* finish the string */ *s = '\0'; } --- NEW FILE: WOURLCUtilities.h --- /* Copyright © 2000 Apple Computer, Inc. All Rights Reserved. The contents of this file constitute Original Code as defined in and are subject to the Apple Public Source License Version 1.1 (the 'License'). You may not use this file except in compliance with the License. Please obtain a copy of the License at http://www.apple.com/publicsource and read it before usingthis file. This Original Code and all software distributed under the License are distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the License for the specific language governing rights and limitations under the License. */ /* * The utilities defined in this file help with the manipulation of WOF dynamic URLs. * WOF dynamic URLs are composed of the following components: * <APPLICATION-NUMBER>: The instance number of the URL's application. * <APPLICATION-NAME>: The name of the application the URL refers to. * <REQUEST-HANDLER-KEY>: The key of the request handler that should handle the request * <REQUEST-HANDLER-PATH>: The information specific to this request handler - not parsed. * <QUERY-STRING>: What is after the question mark. * <WEBOBJECTS-VERSION>: A string identifying the version of WebObjects run by the URL's application. * <PREFIX>: A server-specific string. * These utilitie allow parsing of a WOF dynamic URL string for its components and generation of a * WOF dynamic URL string from its components. Because the format of a WOF dynamic URL may change over * time, these utilities should always be used to access a WOF dynamic URL's components or to generate * a WOF dynamic URL (i.e. no assumptions should be made about a WOF dynamic URL's format). Once inside * the request handler specified by the key, it is up to the developer of the request handler to handle * the decoding of the url and the format generation on the following pages, if needed. */ #ifndef _WOF_URL_C_UTILITIES_H #define _WOF_URL_C_UTILITIES_H /* * Extension definitions */ #define WOADAPTOR_APP_EXTENSION ".woa" #define WOADAPTOR_APP_EXTENSION_UPPERCASE ".WOA" /*********** WOF dynamic URL types. ***********/ typedef struct _WOURLComponent { const char *start; unsigned int length; } WOURLComponent; typedef struct _WOURLComponents { WOURLComponent prefix; WOURLComponent webObjectsVersion; WOURLComponent applicationName; WOURLComponent applicationNumber; WOURLComponent applicationHost; WOURLComponent sessionID; WOURLComponent pageName; WOURLComponent contextID; WOURLComponent senderID; WOURLComponent queryString; WOURLComponent suffix; WOURLComponent requestHandlerKey; WOURLComponent requestHandlerPath; } WOURLComponents; typedef enum { WOURLOK = 0, WOURLInvalidPrefix = 1, WOURLInvalidWebObjectsVersion = 2, WOURLInvalidApplicationName = 3, WOURLInvalidApplicationNumber = 4, WOURLInvalidRequestHandlerKey = 5, WOURLInvalidRequestHandlerPath = 6, WOURLInvalidApplicationHost, WOURLInvalidPageName, WOURLInvalidSessionID, WOURLInvalidContextID, WOURLInvalidSenderID, WOURLInvalidQueryString, WOURLInvalidSuffix, WOURLInvalidPostData, WOURLNoPostData } WOURLError; /*********** WOF dynamic URL functions. ***********/ void WOParseURL_40(WOURLComponents *components, const char *string); /* ... */ WOURLError WOCheckURL_40(WOURLComponents *components); /* ... */ unsigned int WOSizeURL_40(WOURLComponents *components); /* ... */ void WOComposeURL_40(char *string, WOURLComponents *components); /* ... */ #endif /* _WOF_URL_C_UTILITIES_H */ --- NEW FILE: WOURLCUtilities_3.c --- /* Copyright © 2000 Apple Computer, Inc. All Rights Reserved. The contents of this file constitute Original Code as defined in and are subject to the Apple Public Source License Version 1.1 (the 'License'). You may not use this file except in compliance with the License. Please obtain a copy of the License at http://www.apple.com/publicsource and read it before usingthis file. This Original Code and all software distributed under the License are distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the License for the specific language governing rights and limitations under the License. */ /* * WARNING : The WOF URL format is common to the adaptor and the WebObjects framework. * If you modify the following code, your adaptor may not be able to communicate with WebObjects applications ! * * Currently, the WOF URL format is: * <PREFIX>/[<APPLICATION-NAME>][.woa[/<SESSION-ID>/[<PAGE-NAME>][.wo[/<CONTEXT-ID>/<SENDER-ID>[/<APPLICATION-NUMBER>[/<HOST-NAME>]]]]]][?QUERY-STRING] * Where <PREFIX> is: * <*>/WebObjects[-<WEBOBJECTS-VERSION>][.exe|.dll] */ #include "config.h" #include "WOURLCUtilities.h" #include <stdio.h> #include <ctype.h> #include <string.h> void WOParseSizedURL(WOURLComponents *components, const char *string, unsigned length) { WOURLComponent *c[11] = { &(components->prefix), &(components->webObjectsVersion), &(components->applicationName), &(components->sessionID), &(components->pageName),&(components->contextID), &(components->senderID), &(components->applicationNumber), &(components->applicationHost), &(components->suffix), &(components->queryString) }; const char *start; const char *version; const char *extension; const char *end; const char *s; int i, j; /* Extract prefix and WebObjects version. */ start = (string ? string : ""); /* Find start of version. */ version = start; for (s = start; s <= string + length - 11 && *s != '?' && version == start; ++s) { if (strncmp(s, "/WebObjects", 11) == 0 || strncmp(s, "/WEBOBJECTS", 11) == 0) { version = s + 11; } else { for (; s < string + length - 11 && *s == '/'; ++s); } } /* Find end of prefix. */ if (version > start) { for (s = version; s < string + length && *s != '?' && *s != '/'; ++s); end = s; } else { end = start; } /* Find start of extension. */ { const char *extensions[] = { ".exe", ".EXE", ".dll", ".DLL", NULL }; extension = end; for (i = 0; extensions[i] && extension == end; ++i) { int n = strlen(extensions[i]); if (end - n >= version && strncmp(end - n, extensions[i], n) == 0) { extension = end - n; } } } /* Treat invalid versions as invalid prefix. */ if (version < extension && (*version != '-' || (extension - (version + 1)) < 1)) { version = start; extension = start; end = start; } /* start == pointer to first character of prefix. */ /* version == pointer to first character after "/WebObjects". */ /* extension == pointer to first character after WebObjects version. */ /* end == pointer to first character after prefix. */ c[0]->start = start; c[0]->length = end - start; c[1]->start = ((version < extension) ? version + 1 : version); c[1]->length = ((version < extension) ? extension - (version + 1) : 0); /* Extract application name. */ { const char *extensions[3] = {".woa", ".WOA", NULL }; start = ((start < end && end < string + length && *end != '?') ? end + 1 : end); extension = string + length; end = string + length; for (j = 0; extensions[j] && extension == end; ++j) { int n = strlen(extensions[j]); for (s = start; s + n <= string + length && *s != '?' && extension == end; ++s) { if (strncmp(s, extensions[j], n) == 0 && (s + n == string + length || *(s + n) == '?' || *(s + n) == '/')) { extension = s; end = s + n; } } } /* start == pointer to first character of name. */ /* extension == pointer to first character after name. */ /* end == pointer to first character after extension. */ c[2]->start = start; c[2]->length = extension - start; } /* Extract session id */ start = ((end < string + length && *end != '?') ? end + 1 : end); for (s = start; s < string + length && *s != '?' && *s != '/'; ++s); end = s; /* start == pointer to first character of component. */ /* end == pointer to first character after component. */ c[3]->start = start; c[3]->length = (end > start + 1 || *start != '-') ? end - start : 0; /* Extract page name. */ { const char *extensions[3] = { ".wo", ".WO", NULL}; start = ((start < end && end < string + length && *end != '?') ? end + 1 : end); extension = string + length; end = string + length; for (j = 0; extensions[j] && extension == end; ++j) { int n = strlen(extensions[j]); for (s = start; s + n <= string + length && *s != '?' && extension == end; ++s) { if (strncmp(s, extensions[j], n) == 0 && (s + n == string + length || *(s + n) == '?' || *(s + n) == '/')) { extension = s; end = s + n; } } } /* start == pointer to first character of name. */ /* extension == pointer to first character after name. */ /* end == pointer to first character after extension. */ c[4]->start = start; c[4]->length = extension - start; } /* Extract session ID, context ID, sender ID, application number, and application host. */ for (i = 5; i <= 8; ++i) { start = ((end < string + length && *end != '?') ? end + 1 : end); for (s = start; s < string + length && *s != '?' && *s != '/'; ++s); end = s; /* start == pointer to first character of component. */ /* end == pointer to first character after component. */ c[i]->start = start; c[i]->length = (end > start + 1 || *start != '-') ? end - start : 0; } /* Extract suffix. */ start = ((end < string + length && *end != '?') ? end + 1 : end); for (s = start; s < string + length && *s != '?'; ++s); end = s; /* start == pointer to first character of suffix. */ /* end == pointer to first character after suffix. */ c[9]->start = start; c[9]->length = end - start; /* Extract query string. */ start = ((end < string + length) ? end + 1 : end); end = string + length; c[10]->start = start; c[10]->length = end - start; } void WOParseURL(WOURLComponents *components, const char *string) { WOParseSizedURL(components, string, (string ? strlen(string) : 0)); } WOURLError WOCheckURL(WOURLComponents *components) { WOURLComponent *c[11] = { &(components->prefix), &(components->webObjectsVersion), &(components->applicationName), &(components->sessionID), &(components->pageName), &(components->contextID), &(components->senderID), &(components->applicationNumber), &(components->applicationHost), &(components->suffix), &(components->queryString) }; const WOURLError e[11] = { WOURLInvalidPrefix, WOURLInvalidWebObjectsVersion, WOURLInvalidApplicationName, WOURLInvalidSessionID, WOURLInvalidPageName, WOURLInvalidContextID, WOURLInvalidSenderID, WOURLInvalidApplicationNumber, WOURLInvalidApplicationHost, WOURLInvalidSuffix, WOURLInvalidQueryString }; WOURLComponents prefixComponents; int i, j; /* Check component starts. */ for (i = 0; i <= 10; ++i) { if (!c[i]->start) { return e[i]; } } /* Check component characters. */ for (i = 0; i <= 10; ++i) { for (j = 0 ; j < c[i]->length; ++j) { if (c[i]->start[j] == '\0') { return e[i]; } else if (i <= 8 && c[i]->start[j] == '?') { return e[i]; } else if (i >= 5 && i <= 8 && c[i]->start[j] == '/') { return e[i]; } else if (i == 7 && !isdigit(c[i]->start[j])) { return e[i]; } } } /* Check component consistency. */ if (!c[0]->length) { return e[0]; } else if (!c[2]->length) { return e[2]; } else if (!c[3]->length && (c[5]->length || c[6]->length)) { return e[3]; } else if (!c[5]->length && c[3]->length) { return e[5]; } else if (c[9]->length) { return e[9]; } /* Check prefix syntax. */ WOParseSizedURL(&prefixComponents, c[0]->start, c[0]->length); if (c[0]->length != prefixComponents.prefix.length) { return e[0]; } return WOURLOK; } unsigned int WOSizeURL(WOURLComponents *components) { WOURLComponent *c[11] = { &(components->prefix), &(components->webObjectsVersion), &(components->applicationName), &(components->sessionID), &(components->pageName), &(components->contextID), &(components->senderID), &(components->applicationNumber), &(components->applicationHost), &(components->suffix), &(components->queryString) }; unsigned int length; int n; int i; length = 0; for (n = 10; n >= 0 && !c[n]->length; --n); for (i = 0; i <= 10; ++i) { if (i >= 2 && i <= n) { length += 1; } else if (i == 10 && c[i]->length) { length += 1; } if (c[i]->length && i != 1) { length += c[i]->length; } else if (i == 0) { length += 11; } else if ((i == 3 || i >= 5) && i < n) { length += 1; } if (i == 2) { length += 4; } else if (i == 4) { length += 3; } } return length; } void WOComposeURL(char *string, WOURLComponents *components) { WOURLComponent *c[11] = { &(components->prefix), &(components->webObjectsVersion), &(components->applicationName), &(components->sessionID), &(components->pageName), &(components->contextID), &(components->senderID), &(components->applicationNumber), &(components->applicationHost), &(components->suffix), &(components->queryString) }; char *s; int n; int i; s = string; for (n = 9; n >= 0 && !c[n]->length; --n); for (i = 0; i <= 10; ++i) { if (i >= 2 && i <= n) { *s++ = '/'; } else if (i == 10 && c[i]->length) { *s++ = '?'; } if (c[i]->length && i != 1) { strncpy(s, c[i]->start, c[i]->length); s += c[i]->length; } else if (i == 0) { strncpy(s, "/WebObjects", 11); s += 11; } else if ((i == 3 || i >= 5) && i < n) { *s++ = '-'; } if (i == 2) { strncpy(s, ".woa", 4); s += 4; } else if (i == 4 && i < n) { strncpy(s, ".wo", 3); s += 3; } } *s = '\0'; } --- NEW FILE: WOURLCUtilities_3.h --- /* Copyright © 2000 Apple Computer, Inc. All Rights Reserved. The contents of this file constitute Original Code as defined in and are subject to the Apple Public Source License Version 1.1 (the 'License'). You may not use this file except in compliance with the License. Please obtain a copy of the License at http://www.apple.com/publicsource and read it before usingthis file. This Original Code and all software distributed under the License are distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the License for the specific language governing rights and limitations under the License. */ /* * The utilities defined in this file help with the manipulation of WOF dynamic URLs. * WOF dynamic URLs are composed of the following components: * <APPLICATION-NAME>: The name of the application the URL refers to. * <PAGE-NAME>: The name of the page in which the URL was generated. * <SESSION-ID>: The ID of the session in which the URL was generated. * <CONTEXT-ID>: The ID of the context in which the URL was generated. * <SENDER-ID>: The ID of the element associated with the URL. * <APPLICATION-NUMBER>: The instance number of the URL's application. * <APPLICATION-HOST>: The name of the host running the URL's application. * <WEBOBJECTS-VERSION>: A string identifying the version of WebObjects run by the URL's application. * <PREFIX>: A server-specific string. * These utilities allow parsing of a WOF dynamic URL string for its components and generation * of a WOF dynamic URL string from its components. Because the format of a WOF dynamic URL * may change over time, these utilities should always be used to access a WOF dynamic URL's * components or to generate a WOF dynamic URL (i.e. no assumptions should be made about a WOF * dynamic URL's format). */ #ifndef _WOF_URL_C_UTILITIES_H #define _WOF_URL_C_UTILITIES_H #define WOADAPTOR_APP_EXTENSION ".woa" #define WOADAPTOR_APP_EXTENSION_UPPERCASE ".WOA" /*********** WOF dynamic URL functions. ***********/ void WOParseURL(WOURLComponents *components, const char *string); /* ... */ WOURLError WOCheckURL(WOURLComponents *components); /* ... */ unsigned int WOSizeURL(WOURLComponents *components); /* ... */ void WOComposeURL(char *string, WOURLComponents *components); /* ... */ #endif /* _WOF_URL_C_UTILITIES_H */ --- NEW FILE: appcfg.c --- /* Copyright © 2000 Apple Computer, Inc. All Rights Reserved... [truncated message content] |