* add more module handlers:
authorWilfried Göesgens <willi@citadel.org>
Sun, 10 May 2009 18:05:56 +0000 (18:05 +0000)
committerWilfried Göesgens <willi@citadel.org>
Sun, 10 May 2009 18:05:56 +0000 (18:05 +0000)
  * start (alloc structures here; don't depend on others...)
  * init (fill your structs, register with others...)
  * shutdown (free your static structs etc.

  * Session New: for allocation etc.
  * Session Attach: on each request before it gets hot.
  * Session Detach: clean up your session local stuff
  * Session Destroy: the user is gone; flush your memory.

* more news: WC is set before the SessionNew; so you can use WC there.

* shuffled some more stuff arround:
  * i/o related stuff
  * directory calculation
  * local css detection is now part of the start handler...
  * all creates/frees of structures that can be done in the above handrlers is done there now.

16 files changed:
webcit/auth.c
webcit/context_loop.c
webcit/gettext.c
webcit/ical_subst.c
webcit/iconbar.c
webcit/messages.c
webcit/mk_module_init.sh
webcit/msg_renderers.c
webcit/paramhandling.c
webcit/preferences.c
webcit/siteconfig.c
webcit/subst.c
webcit/tcp_sockets.c
webcit/webcit.c
webcit/webcit.h
webcit/webserver.c

index 5d24144f1fbf30ba9b40ce9dad60f2d3fc45aab4..7cb7bc83cf7626322c8fd0ecccaa20a8b2e6da03 100644 (file)
@@ -929,3 +929,17 @@ InitModule_AUTH
 
        return ;
 }
+
+
+void 
+SessionDestroyModule_AUTH
+(wcsession *sess)
+{
+       FreeStrBuf(&sess->wc_username);
+       FreeStrBuf(&sess->wc_fullname);
+       FreeStrBuf(&sess->wc_password);
+       FreeStrBuf(&sess->wc_roomname);
+       FreeStrBuf(&sess->httpauth_user);
+       FreeStrBuf(&sess->httpauth_pass);
+       FreeStrBuf(&sess->cs_inet_email);
+}
index 39a85d5c94bd2392533d88849664257b2f91d12e..208521386eb318cefe76e92a27da39b1a5a6462c 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "webcit.h"
 #include "webserver.h"
+#include "modules_init.h"
 
 /* Only one thread may manipulate SessionList at a time... */
 pthread_mutex_t SessionListMutex;
@@ -33,28 +34,10 @@ void DestroySession(wcsession **sessions_to_kill)
                free((*sessions_to_kill)->cache_fold);
        }
        DeleteServInfo(&((*sessions_to_kill)->serv_info));
-       DeleteHash(&((*sessions_to_kill)->attachments));
        free_march_list((*sessions_to_kill));
-       DeleteHash(&((*sessions_to_kill)->hash_prefs));
-       DeleteHash(&((*sessions_to_kill)->IconBarSettings));
-       DeleteHash(&((*sessions_to_kill)->ServCfg));
-       FreeStrBuf(&((*sessions_to_kill)->ReadBuf));
-       FreeStrBuf(&((*sessions_to_kill)->UrlFragment1));
-       FreeStrBuf(&((*sessions_to_kill)->UrlFragment2));
-       FreeStrBuf(&((*sessions_to_kill)->UrlFragment3));
-       FreeStrBuf(&((*sessions_to_kill)->UrlFragment4));
-       FreeStrBuf(&((*sessions_to_kill)->WBuf));
-       FreeStrBuf(&((*sessions_to_kill)->HBuf));
-       FreeStrBuf(&((*sessions_to_kill)->CLineBuf));
-       FreeStrBuf(&((*sessions_to_kill)->wc_username));
-       FreeStrBuf(&((*sessions_to_kill)->wc_fullname));
-       FreeStrBuf(&((*sessions_to_kill)->wc_password));
-       FreeStrBuf(&((*sessions_to_kill)->wc_roomname));
-       FreeStrBuf(&((*sessions_to_kill)->httpauth_user));
-       FreeStrBuf(&((*sessions_to_kill)->httpauth_pass));
-       FreeStrBuf(&((*sessions_to_kill)->ImportantMsg));
-       FreeStrBuf(&((*sessions_to_kill)->cs_inet_email));
-       FreeStrBuf(&((*sessions_to_kill)->MigrateReadLineBuf));
+       
+       session_destroy_modules(*sessions_to_kill);
+
        free((*sessions_to_kill));
        (*sessions_to_kill) = NULL;
 }
@@ -236,7 +219,7 @@ int is_bogus(StrBuf *http_cmd) {
 }
 
 
-const char *nix(void *vptr) {return ChrPtr( (StrBuf*)vptr);}
+/*const char *nix(void *vptr) {return ChrPtr( (StrBuf*)vptr);}*/
 
 /*
  * handle one request
@@ -267,7 +250,6 @@ void context_loop(int *sock)
        int LineLen;
        void *vLine;
        StrBuf *Buf, *Line, *LastLine, *HeaderName, *ReqLine, *ReqType, *HTTPVersion;
-       StrBuf *accept_language = NULL;
        const char *pch, *pchs, *pche;
        HashList *HTTPHeaders;
 
@@ -378,10 +360,6 @@ void context_loop(int *sock)
                if_modified_since = httpdate_to_timestamp((StrBuf*)vLine);
        }
 
-       if (GetHash(HTTPHeaders, HKEY("ACCEPT-LANGUAGE"), &vLine) && 
-           (vLine != NULL)) {
-               accept_language = (StrBuf*) vLine;
-       }
 
 
        ReqType = NewStrBuf();
@@ -464,7 +442,9 @@ void context_loop(int *sock)
 
        if (TheSession == NULL) {
                pthread_mutex_lock(&SessionListMutex);
-               for (sptr = SessionList; sptr != NULL; sptr = sptr->next) {
+               for (sptr = SessionList; 
+                    ((sptr != NULL) && (TheSession == NULL)); 
+                     sptr = sptr->next) {
 
                        /** If HTTP-AUTH, look for a session with matching credentials */
                        if ( (!IsEmptyStr(httpauth_user))
@@ -490,6 +470,7 @@ void context_loop(int *sock)
                TheSession = (wcsession *)
                        malloc(sizeof(wcsession));
                memset(TheSession, 0, sizeof(wcsession));
+               TheSession->headers = HTTPHeaders;
                TheSession->serv_sock = (-1);
                TheSession->chat_sock = (-1);
        
@@ -506,22 +487,12 @@ void context_loop(int *sock)
                        TheSession->wc_session = desired_session;
                }
 
-               if (TheSession->httpauth_user != NULL){
-                       FlushStrBuf(TheSession->httpauth_user);
-                       StrBufAppendBufPlain(TheSession->httpauth_user, httpauth_user, -1, 0);
-               }
-               else TheSession->httpauth_user = NewStrBufPlain(httpauth_user, -1);
-               if (TheSession->httpauth_user != NULL){
-                       FlushStrBuf(TheSession->httpauth_pass);
-                       StrBufAppendBufPlain(TheSession->httpauth_pass, httpauth_user, -1, 0);
-               }
-               else TheSession->httpauth_pass = NewStrBufPlain(httpauth_user, -1);
+               TheSession->httpauth_user = NewStrBufPlain(httpauth_user, -1);
+               TheSession->httpauth_pass = NewStrBufPlain(httpauth_user, -1);
+
+               pthread_setspecific(MyConKey, (void *)TheSession);
+               session_new_modules(TheSession);
 
-               if (TheSession->MigrateReadLineBuf != NULL)
-                       FlushStrBuf(TheSession->MigrateReadLineBuf);
-               else TheSession->MigrateReadLineBuf = NewStrBuf();
-               TheSession->CLineBuf = NewStrBuf();
-               TheSession->hash_prefs = NewHash(1,NULL);       /* Get a hash table for the user preferences */
                pthread_mutex_init(&TheSession->SessionMutex, NULL);
                pthread_mutex_lock(&SessionListMutex);
                TheSession->nonce = rand();
@@ -531,6 +502,7 @@ void context_loop(int *sock)
                pthread_mutex_unlock(&SessionListMutex);
                session_is_new = 1;
        }
+       TheSession->headers = HTTPHeaders;
 
        /*
         * A future improvement might be to check the session integrity
@@ -543,30 +515,16 @@ void context_loop(int *sock)
        pthread_mutex_lock(&TheSession->SessionMutex);          /* bind */
        pthread_setspecific(MyConKey, (void *)TheSession);
        
-       if (TheSession->ImportantMsg == NULL)
-               TheSession->ImportantMsg = NewStrBuf();
-       TheSession->urlstrings = NewHash(1,NULL);
-       TheSession->vars = NewHash(1,NULL);
-       TheSession->http_sock = *sock;
        TheSession->lastreq = time(NULL);                       /* log */
+       TheSession->http_sock = *sock;
        TheSession->gzip_ok = gzip_ok;
-#ifdef ENABLE_NLS
-       if (session_is_new) {
-               httplang_to_locale(accept_language);
-       }
-       go_selected_language();                                 /* set locale */
-#endif
-       session_loop(HTTPHeaders, ReqLine, ReqType, Buf, &Pos);                         /* do transaction */
-#ifdef ENABLE_NLS
-       stop_selected_language();                               /* unset locale */
-#endif
-       DeleteHash(&TheSession->summ);
-       DeleteHash(&TheSession->urlstrings);
-       DeleteHash(&TheSession->vars);
-       FreeStrBuf(&TheSession->WBuf);
-       FreeStrBuf(&TheSession->HBuf);
-       
-       
+
+       session_attach_modules(TheSession);
+
+       session_loop(ReqLine, ReqType, Buf, &Pos);                              /* do transaction */
+       session_detach_modules(TheSession);
+
+       TheSession->headers = NULL;
        pthread_mutex_unlock(&TheSession->SessionMutex);        /* unbind */
 
        /* Free the request buffer */
@@ -574,12 +532,6 @@ void context_loop(int *sock)
        FreeStrBuf(&ReqLine);
        FreeStrBuf(&ReqType);
        FreeStrBuf(&Buf);
-       /*
-        * Free up any session-local substitution variables which
-        * were set during this transaction
-        */
-       
-       
 }
 
 void tmplput_nonce(StrBuf *Target, WCTemplputParams *TP)
index 0fa2450946b835ee6a66070999c212410f6d4127..f3472b3617779f02e2826fb35dd62b38985b05a0 100644 (file)
@@ -388,3 +388,37 @@ InitModule_GETTEXT
 {
        RegisterNamespace("LANG:SELECT", 0, 0, tmplput_offer_languages, CTX_NONE);
 }
+
+
+void
+SessionNewModule_GETTEXT
+(wcsession *sess)
+{
+#ifdef ENABLE_NLS
+       void *vLine;
+       
+       if (GetHash(WC->headers, HKEY("ACCEPT-LANGUAGE"), &vLine) && 
+           (vLine != NULL)) {
+               StrBuf *accept_language = (StrBuf*) vLine;
+               httplang_to_locale(accept_language);
+       }
+#endif
+}
+
+void
+SessionAttachModule_GETTEXT
+(wcsession *sess)
+{
+#ifdef ENABLE_NLS
+       go_selected_language();                                 /* set locale */
+#endif
+}
+
+void 
+SessionDestroyModule_GETTEXT
+(wcsession *sess)
+{
+#ifdef ENABLE_NLS
+       stop_selected_language();                               /* unset locale */
+#endif
+}
index 8d44830fea2aececc8dac3b87d48887b73b5bd8f..3de772c882843aaa8fddfe6502aa00c72b4d3070 100644 (file)
@@ -116,3 +116,10 @@ InitModule_ICAL_SUBST
        CreateIcalComponendKindLookup ();
 
 }
+
+void 
+ServerShutdownModule_ICAL
+(void)
+{
+       DeleteHash(&IcalComponentMap);
+}
index c1ba02ca01abc7e35950de6c73cc6e4ca7e893a7..5abdee85ea4f925740c3bdc3969b7562c7510372 100644 (file)
@@ -489,4 +489,12 @@ InitModule_ICONBAR
 }
 
 
+
+void 
+SessionDestroyModule_ICONBAR
+(wcsession *sess)
+{
+       DeleteHash(&sess->IconBarSettings);
+}
+
 /*@}*/
index c6d1c6e75602ef741d3949d1318c5914b825dcdf..dde57cc4a2f2761d53818c81cea621958ef895cb 100644 (file)
@@ -1765,3 +1765,10 @@ InitModule_MSG
        WebcitAddUrlHandler(HKEY("roommsgs"), jsonMessageList,0);
        return ;
 }
+
+void
+SessionDetachModule_MSG
+(wcsession *sess)
+{
+       DeleteHash(&sess->summ);
+}
index 4f58db1e395a29983611314ef6df8d41520fd233..e3c91a1a311c5212069c10c851e833a2c6825d7c 100755 (executable)
@@ -29,6 +29,61 @@ U_FILE="$CUR_DIR/modules_upgrade.c"
 
 /usr/bin/printf "Scanning extension modules for entry points.\n"
 
+rm -f $C_FILE $H_FILE
+
+# server lifetime:
+START_FUNCS=`grep ServerStartModule_ *.c |sed "s;.*:;;" |sort -u`
+INIT_FUNCS=`grep InitModule_ *.c |sed "s;.*:;;" |sort -u`
+FINALIZE_FUNCS=`grep FinalizeModule_ *.c |sed "s;.*:;;" |sort -u`
+SHUTDOWN_FUNCS=`grep ServerShutdownModule_ *.c |sed "s;.*:;;" |sort -u`
+
+# session hooks:
+SESS_NEW_FUNCS=`grep SessionNewModule_ *.c |sed "s;.*:;;" |sort -u`
+SESS_ATTACH_FUNCS=`grep SessionAttachModule_ *.c |sed "s;.*:;;" |sort -u`
+SESS_DETACH_FUNCS=`grep SessionDetachModule_ *.c |sed "s;.*:;;" |sort -u`
+SESS_DESTROY_FUNCS=`grep SessionDestroyModule_ *.c |sed "s;.*:;;" |sort -u`
+
+
+#SESS_NEW_FUNCS=`grep SessionNewModule_ *.c |sed "s;.*:;;" |sort -u`
+
+
+#start the header file
+cat <<EOF > $H_FILE
+/* 
+ * $H_FILE
+ * Auto generated by mk_modules_init.sh DO NOT EDIT THIS FILE
+ */
+
+
+#ifndef MODULES_INIT_H
+#define MODULES_INIT_H
+extern size_t nSizErrmsg;
+
+
+/* 
+ * server lifetime: 
+ */
+void initialise_modules (void);
+void start_modules (void);
+void shutdown_modules (void);
+
+
+/*
+ * Session lifetime:
+ */
+void session_new_modules (wcsession *sess);
+void session_attach_modules (wcsession *sess);
+void session_detach_modules (wcsession *sess);
+void session_destroy_modules (wcsession *sess);
+
+
+
+/*
+ * forwards...
+ */
+
+EOF
+
 
 #start of the files which inturn removes any existing file
 #
@@ -77,49 +132,239 @@ cat <<EOF  >$C_FILE
 void LogPrintMessages(long err);
 extern long DetailErrorFlags;
 
+void start_modules (void)
+{
+EOF
+#********************************************************************************
+# server  ******** start ********  module logic.
+#********************************************************************************
+cat <<EOF >> $H_FILE
+
+/* Server Start Hooks: */
+EOF
+for HOOK in $START_FUNCS; do
+HOOKNAME=`echo $HOOK |sed "s;ServerStartModule_;;"`
+# Add this entry point to the .c file
+cat <<EOF >> $C_FILE
+#ifdef DBG_PRINNT_HOOKS_AT_START
+       lprintf (CTDL_INFO, "Starting $HOOKNAME\n");
+#endif
+       $HOOK();
+EOF
+# Add this entry point to the .h file
+cat <<EOF >> $H_FILE
+extern void $HOOK(void);
+EOF
+done
+
+
+#********************************************************************************
+# server module  ******** initialisation ********  logic.
+#********************************************************************************
+cat <<EOF >> $H_FILE
+
+/* Server Init Hooks: */
+EOF
+
+cat <<EOF  >>$C_FILE
+}
 
 
 void initialise_modules (void)
 {
 
 EOF
+for HOOK in $INIT_FUNCS; do
+    HOOKNAME=`echo $HOOK |sed "s;InitModule_;;"`
+# Add this entry point to the .c file
+    cat <<EOF >> $C_FILE
+#ifdef DBG_PRINNT_HOOKS_AT_START
+       lprintf (CTDL_INFO, "Initializing $HOOKNAME\n");
+#endif
+       $HOOK();
+EOF
+# Add this entry point to the .h file
+    cat <<EOF >> $H_FILE
+extern void $HOOK(void);
+EOF
+done
 
 
-#start the header file
-cat <<EOF > $H_FILE
-/* 
- * $H_FILE
- * Auto generated by mk_modules_init.sh DO NOT EDIT THIS FILE
- */
 
 
-#ifndef MODULES_INIT_H
-#define MODULES_INIT_H
-extern size_t nSizErrmsg;
-void initialise_modules (void);
+#********************************************************************************
+# server module    ***** shutdown *****  logic.
+#********************************************************************************
+cat <<EOF >> $H_FILE
+
+/* Server shutdown Hooks: */
+EOF
+cat <<EOF  >>$C_FILE
+}
+
+
+void shutdown_modules (void)
+{
+
+EOF
+for HOOK in $SHUTDOWN_FUNCS; do
+HOOKNAME=`echo $HOOK |sed "s;ServerShutdownModule_;;"`
+# Add this entry point to the .c file
+cat <<EOF >> $C_FILE
+#ifdef DBG_PRINNT_HOOKS_AT_START
+       lprintf (CTDL_INFO, "Shutting down $HOOKNAME\n");
+#endif
+       $HOOK();
+EOF
+# Add this entry point to the .h file
+cat <<EOF >> $H_FILE
+extern void $HOOK(void);
+EOF
+done
 
 
+
+
+#********************************************************************************
+# NEW-session module logic.
+#********************************************************************************
+cat <<EOF >> $H_FILE
+
+/* Session New Hooks: */
 EOF
+cat <<EOF  >>$C_FILE
+}
 
 
-INIT_FUNCS=`grep InitModule_ *.c |sed "s;.*:;;"`
+void session_new_modules (wcsession *sess)
+{
 
-for HOOK in $INIT_FUNCS; do
-HOOKNAME=`echo $HOOK |sed "s;InitModule_;;"`
+EOF
+for HOOK in $SESS_NEW_FUNCS; do
+HOOKNAME=`echo $HOOK |sed "s;SessionNewModule_;;"`
 # Add this entry point to the .c file
 cat <<EOF >> $C_FILE
 #ifdef DBG_PRINNT_HOOKS_AT_START
        lprintf (CTDL_INFO, "Initializing $HOOKNAME\n");
 #endif
-       $HOOK();
+       $HOOK(sess);
+EOF
+# Add this entry point to the .h file
+cat <<EOF >> $H_FILE
+extern void $HOOK(wcsession *sess);
+EOF
+done
+
+
+
+#********************************************************************************
+# ATTACH-Session module logic.
+#********************************************************************************
+cat <<EOF >> $H_FILE
+
+/* Session Attach Hooks: */
+EOF
+cat <<EOF  >>$C_FILE
+}
+
+
+void session_attach_modules (wcsession *sess)
+{
+
+EOF
+for HOOK in $SESS_ATTACH_FUNCS; do
+HOOKNAME=`echo $HOOK |sed "s;SessionAttachModule_;;"`
+# Add this entry point to the .c file
+cat <<EOF >> $C_FILE
+#ifdef DBG_PRINNT_HOOKS_AT_START
+       lprintf (CTDL_INFO, "Attaching Session; $HOOKNAME\n");
+#endif
+       $HOOK(sess);
 EOF
 # Add this entry point to the .h file
 cat <<EOF >> $H_FILE
-       extern void $HOOK(void);
+extern void $HOOK(wcsession *sess);
 EOF
 done
 
 
-/usr/bin/printf "}\n" >> $C_FILE
 
-/usr/bin/printf "\n#endif /* MODULES_INIT_H */\n" >> $H_FILE
+#********************************************************************************
+# DETACH-Session module logic.
+#********************************************************************************
+cat <<EOF >> $H_FILE
+
+/* Session detach Hooks: */
+EOF
+cat <<EOF  >>$C_FILE
+}
+
+
+void session_detach_modules (wcsession *sess)
+{
+
+EOF
+for HOOK in $SESS_DETACH_FUNCS; do
+HOOKNAME=`echo $HOOK |sed "s;SessionDetachModule_;;"`
+# Add this entry point to the .c file
+cat <<EOF >> $C_FILE
+#ifdef DBG_PRINNT_HOOKS_AT_START
+       lprintf (CTDL_INFO, "Initializing $HOOKNAME\n");
+#endif
+       $HOOK(sess);
+EOF
+# Add this entry point to the .h file
+cat <<EOF >> $H_FILE
+extern void $HOOK(wcsession *sess);
+EOF
+done
+
+
+
+
+#********************************************************************************
+# DESTROY-Session module logic.
+#********************************************************************************
+cat <<EOF >> $H_FILE
+
+/* Session destroy Hooks: */
+EOF
+cat <<EOF  >>$C_FILE
+}
+
+
+void session_destroy_modules (wcsession *sess)
+{
+
+EOF
+for HOOK in $SESS_DESTROY_FUNCS; do
+HOOKNAME=`echo $HOOK |sed "s;SessionDestroyModule_;;"`
+# Add this entry point to the .c file
+cat <<EOF >> $C_FILE
+#ifdef DBG_PRINNT_HOOKS_AT_START
+       lprintf (CTDL_INFO, "Initializing $HOOKNAME\n");
+#endif
+       $HOOK(sess);
+EOF
+# Add this entry point to the .h file
+cat <<EOF >> $H_FILE
+extern void $HOOK(wcsession *sess);
+EOF
+done
+
+
+
+
+
+
+cat <<EOF  >>$C_FILE
+}
+
+EOF
+
+
+cat <<EOF  >> $H_FILE
+
+#endif /* MODULES_INIT_H */
+
+EOF
index e1800d17ee9ae6c6403b487bd5069cbedf552a79..f33cd782b18e24c35c96456eccb85940e6993af0 100644 (file)
@@ -1247,3 +1247,28 @@ InitModule_MSGRENDERERS
        RegisterMsgHdr(HKEY("suff"), examine_suff, 0);
        RegisterMsgHdr(HKEY("path"), examine_path, 0);
 }
+
+void 
+ServerStartModule_MSGRENDERERS
+(void)
+{
+       MsgHeaderHandler = NewHash(1, NULL);
+       MimeRenderHandler = NewHash(1, NULL);
+}
+
+void 
+ServerShutdownModule_MSGRENDERERS
+(void)
+{
+       DeleteHash(&MsgHeaderHandler);
+       DeleteHash(&MimeRenderHandler);
+}
+
+
+
+void 
+SessionDestroyModule_MSGRENDERERS
+(wcsession *sess)
+{
+       DeleteHash(&sess->attachments);
+}
index c514c44a86dc160c256e0a58ace5aa9391fd5095..8ab501bea0586984bbfe2d4a8c137df8a0b088dd 100644 (file)
@@ -420,3 +420,18 @@ InitModule_PARAMHANDLING
        RegisterNamespace("BSTR", 1, 2, tmplput_bstr, CTX_NONE);
        RegisterNamespace("URLPART", 1, 2, tmplput_url_part, CTX_NONE);
 }
+
+
+void
+SessionAttachModule_PARAMHANDLING
+(wcsession *sess)
+{
+       sess->urlstrings = NewHash(1,NULL);
+}
+
+void
+SessionDetachModule_PARAMHANDLING
+(wcsession *sess)
+{
+       DeleteHash(&sess->urlstrings);
+}
index 3ee036cba47f78712059b2a23de752ad7a4ee561..4161ad18954659e4731dba3b4bb2001a868b6e29 100644 (file)
@@ -795,12 +795,6 @@ int ConditionalHasRoomPreference(StrBuf *Target, WCTemplputParams *TP)
   
        return 0;
 }
-void CfgZoneTempl(StrBuf *TemplBuffer, WCTemplputParams *TP)
-{
-       StrBuf *Zone = (StrBuf*) CTX;
-
-       SVPutBuf("ZONENAME", Zone, 1);
-}
 
 int ConditionalPreference(StrBuf *Target, WCTemplputParams *TP)
 {
@@ -975,7 +969,6 @@ InitModule_PREFERENCES
        RegisterNamespace("PREF:ROOM:VALUE", 1, 2, tmplput_CFG_RoomValue,  CTX_NONE);
        RegisterNamespace("PREF:VALUE", 1, 2, tmplput_CFG_Value, CTX_NONE);
        RegisterNamespace("PREF:DESCR", 1, 1, tmplput_CFG_Descr, CTX_NONE);
-       RegisterIterator("PREF:ZONE", 0, ZoneHash, NULL, CfgZoneTempl, NULL, CTX_PREF, CTX_NONE, IT_NOFLAG);
 
        RegisterConditional(HKEY("COND:PREF"), 4, ConditionalPreference, CTX_NONE);
        RegisterConditional(HKEY("COND:PREF:SET"), 4, ConditionalHasPreference, CTX_NONE);
@@ -987,4 +980,37 @@ InitModule_PREFERENCES
                         GetGVSNHash, NULL, DeleteGVSNHash, CTX_STRBUF, CTX_NONE, IT_NOFLAG);
 
 }
+
+
+void 
+ServerStartModule_PREFERENCES
+(void)
+{
+       PreferenceHooks = NewHash(1, NULL);
+}
+
+void 
+ServerShutdownModule_PREFERENCES
+(void)
+{
+       DeleteHash(&PreferenceHooks);
+}
+
+
+void
+SessionNewModule_PREFERENCES
+(wcsession *sess)
+{
+       sess->hash_prefs = NewHash(1,NULL);
+}
+
+void 
+SessionDestroyModule_PREFERENCES
+(wcsession *sess)
+{
+       DeleteHash(&sess->hash_prefs);
+}
+
+
+
 /*@}*/
index 785a54d36a55658846e6015be4ae45acb50fb236..b15b41e209667ac9adceb2159c7774a2a953c1d6 100644 (file)
@@ -301,6 +301,13 @@ int ConditionalServCfgSubst(StrBuf *Target, WCTemplputParams *TP)
        else return 0;
 }
 
+void CfgZoneTempl(StrBuf *TemplBuffer, WCTemplputParams *TP)
+{
+       StrBuf *Zone = (StrBuf*) CTX;
+
+       SVPutBuf("ZONENAME", Zone, 1);
+}
+
 void 
 InitModule_SITECONFIG
 (void)
@@ -310,4 +317,27 @@ InitModule_SITECONFIG
        RegisterNamespace("SERV:CFG", 1, 2, tmplput_servcfg, CTX_NONE);
        RegisterConditional(HKEY("COND:SERVCFG"), 3, ConditionalServCfg, CTX_NONE);
        RegisterConditional(HKEY("COND:SERVCFG:SUBST"), 4, ConditionalServCfgSubst, CTX_NONE);
+       RegisterIterator("PREF:ZONE", 0, ZoneHash, NULL, CfgZoneTempl, NULL, CTX_PREF, CTX_NONE, IT_NOFLAG);
+}
+
+void 
+ServerStartModule_SITECONFIG
+(void)
+{
+       LoadZoneFiles();
+}
+
+void 
+ServerShutdownModule_SITECONFIG
+(void)
+{
+       DeleteHash(&ZoneHash);
+}
+
+
+void 
+SessionDestroyModule_SITECONFIG
+(wcsession *sess)
+{
+       DeleteHash(&sess->ServCfg);
 }
index 19049c531ad6d5a0431e928bb72ff5810643dcc2..46569a11b64fd71aeb8b5b2e3a48cf605a17217c 100644 (file)
@@ -177,6 +177,9 @@ void LogTemplateError (StrBuf *Target, const char *Type, int ErrorPos, WCTemplpu
                return;
 */
        WCC = WC;
+       if (WCC == NULL)
+               return;
+
        Header = NewStrBuf();
        if (TP->Tokens != NULL) 
        {
@@ -2531,4 +2534,74 @@ InitModule_SUBST
        RegisterControlNS(HKEY("ITERATE:N"), 0, 0, tmplput_ITERATE_LASTN, CTX_ITERATE);
 }
 
+void
+ServerStartModule_SUBST
+(void)
+{
+       WirelessTemplateCache = NewHash(1, NULL);
+       WirelessLocalTemplateCache = NewHash(1, NULL);
+       LocalTemplateCache = NewHash(1, NULL);
+       TemplateCache = NewHash(1, NULL);
+
+       GlobalNS = NewHash(1, NULL);
+       Iterators = NewHash(1, NULL);
+       Conditionals = NewHash(1, NULL);
+       SortHash = NewHash(1, NULL);
+}
+
+void
+FinalizeModule_SUBST
+(void)
+{
+
+}
+
+void 
+ServerShutdownModule_SUBST
+(void)
+{
+       DeleteHash(&WirelessTemplateCache);
+       DeleteHash(&WirelessLocalTemplateCache);
+       DeleteHash(&TemplateCache);
+       DeleteHash(&LocalTemplateCache);
+
+       DeleteHash(&GlobalNS);
+       DeleteHash(&Iterators);
+       DeleteHash(&Conditionals);
+       DeleteHash(&SortHash);
+
+}
+
+
+void
+SessionNewModule_SUBST
+(wcsession *sess)
+{
+
+}
+
+void
+SessionAttachModule_SUBST
+(wcsession *sess)
+{
+       sess->vars = NewHash(1,NULL);
+}
+
+void
+SessionDetachModule_SUBST
+(wcsession *sess)
+{
+       DeleteHash(&sess->vars);
+}
+
+void 
+SessionDestroyModule_SUBST  
+(wcsession *sess)
+{
+
+}
+
+
+
+
 /*@}*/
index a74b3ec9759be606529ffa9954bbb9c83d1d9e2d..42419b179ed28ce2a5dad341b10cff24e8b3039b 100644 (file)
@@ -11,6 +11,8 @@
 #include "webcit.h"
 #include "webserver.h"
 
+extern int DisableGzip;
+
 /*
  *  register the timeout
  *  signum signalhandler number
@@ -99,6 +101,16 @@ int tcp_connectsock(char *host, char *service)
                lprintf(1, "Can't create socket: %s\n", strerror(errno));
                return (-1);
        }
+
+       fdflags = fcntl(s, F_GETFL);
+       if (fdflags < 0)
+               lprintf(1, "unable to get socket flags!  %s.%s: %s \n",
+                       host, service, strerror(errno));
+       fdflags = fdflags | O_NONBLOCK;
+       if (fcntl(s, F_SETFD, fdflags) < 0)
+               lprintf(1, "unable to set socket nonblocking flags!  %s.%s: %s \n",
+                       host, service, strerror(errno));
+
        signal(SIGALRM, timeout);
        alarm(30);
 
@@ -112,8 +124,13 @@ int tcp_connectsock(char *host, char *service)
        signal(SIGALRM, SIG_IGN);
 
        fdflags = fcntl(s, F_GETFL);
+       if (fdflags < 0)
+               lprintf(1, "unable to get socket flags!  %s.%s: %s \n",
+                       host, service, strerror(errno));
        fdflags = fdflags | O_NONBLOCK;
-       fcntl(s, F_SETFD, fdflags);
+       if (fcntl(s, F_SETFD, fdflags) < 0)
+               lprintf(1, "unable to set socket nonblocking flags!  %s.%s: %s \n",
+                       host, service, strerror(errno));
        return (s);
 }
 
@@ -301,3 +318,372 @@ void serv_printf(const char *format,...)
 #endif
 }
 
+
+
+
+int ClientGetLine(int *sock, StrBuf *Target, StrBuf *CLineBuf, const char **Pos)
+{
+       const char *Error, *pch, *pchs;
+       int rlen, len, retval = 0;
+
+#ifdef HAVE_OPENSSL
+       if (is_https) {
+               int ntries = 0;
+               if (StrLength(CLineBuf) > 0) {
+                       pchs = ChrPtr(CLineBuf);
+                       pch = strchr(pchs, '\n');
+                       if (pch != NULL) {
+                               rlen = 0;
+                               len = pch - pchs;
+                               if (len > 0 && (*(pch - 1) == '\r') )
+                                       rlen ++;
+                               StrBufSub(Target, CLineBuf, 0, len - rlen);
+                               StrBufCutLeft(CLineBuf, len + 1);
+                               return len - rlen;
+                       }
+               }
+
+               while (retval == 0) { 
+                               pch = NULL;
+                               pchs = ChrPtr(CLineBuf);
+                               if (*pchs != '\0')
+                                       pch = strchr(pchs, '\n');
+                               if (pch == NULL) {
+                                       retval = client_read_sslbuffer(CLineBuf, SLEEPING);
+                                       pchs = ChrPtr(CLineBuf);
+                                       pch = strchr(pchs, '\n');
+                               }
+                               if (retval == 0) {
+                                       sleeeeeeeeeep(1);
+                                       ntries ++;
+                               }
+                               if (ntries > 10)
+                                       return 0;
+               }
+               if ((retval > 0) && (pch != NULL)) {
+                       rlen = 0;
+                       len = pch - pchs;
+                       if (len > 0 && (*(pch - 1) == '\r') )
+                               rlen ++;
+                       StrBufSub(Target, CLineBuf, 0, len - rlen);
+                       StrBufCutLeft(CLineBuf, len + 1);
+                       return len - rlen;
+
+               }
+               else 
+                       return -1;
+       }
+       else 
+#endif
+               return StrBufTCP_read_buffered_line_fast(Target, 
+                                                        CLineBuf,
+                                                        Pos,
+                                                        sock,
+                                                        5,
+                                                        1,
+                                                        &Error);
+}
+
+/* 
+ * This is a generic function to set up a master socket for listening on
+ * a TCP port.  The server shuts down if the bind fails.
+ *
+ * ip_addr     IP address to bind
+ * port_number port number to bind
+ * queue_len   number of incoming connections to allow in the queue
+ */
+int ig_tcp_server(char *ip_addr, int port_number, int queue_len)
+{
+       struct sockaddr_in sin;
+       int s, i;
+
+       memset(&sin, 0, sizeof(sin));
+       sin.sin_family = AF_INET;
+       if (ip_addr == NULL) {
+               sin.sin_addr.s_addr = INADDR_ANY;
+       } else {
+               sin.sin_addr.s_addr = inet_addr(ip_addr);
+       }
+
+       if (sin.sin_addr.s_addr == INADDR_NONE) {
+               sin.sin_addr.s_addr = INADDR_ANY;
+       }
+
+       if (port_number == 0) {
+               lprintf(1, "Cannot start: no port number specified.\n");
+               exit(WC_EXIT_BIND);
+       }
+       sin.sin_port = htons((u_short) port_number);
+
+       s = socket(PF_INET, SOCK_STREAM, (getprotobyname("tcp")->p_proto));
+       if (s < 0) {
+               lprintf(1, "Can't create a socket: %s\n", strerror(errno));
+               exit(WC_EXIT_BIND);
+       }
+       /* Set some socket options that make sense. */
+       i = 1;
+       setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
+
+       #ifndef __APPLE__
+       fcntl(s, F_SETFL, O_NONBLOCK); /* maide: this statement is incorrect
+                                         there should be a preceding F_GETFL
+                                         and a bitwise OR with the previous
+                                         fd flags */
+       #endif
+       
+       if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
+               lprintf(1, "Can't bind: %s\n", strerror(errno));
+               exit(WC_EXIT_BIND);
+       }
+       if (listen(s, queue_len) < 0) {
+               lprintf(1, "Can't listen: %s\n", strerror(errno));
+               exit(WC_EXIT_BIND);
+       }
+       return (s);
+}
+
+
+
+/*
+ * Create a Unix domain socket and listen on it
+ * sockpath - file name of the unix domain socket
+ * queue_len - Number of incoming connections to allow in the queue
+ */
+int ig_uds_server(char *sockpath, int queue_len)
+{
+       struct sockaddr_un addr;
+       int s;
+       int i;
+       int actual_queue_len;
+
+       actual_queue_len = queue_len;
+       if (actual_queue_len < 5) actual_queue_len = 5;
+
+       i = unlink(sockpath);
+       if ((i != 0) && (errno != ENOENT)) {
+               lprintf(1, "webcit: can't unlink %s: %s\n",
+                       sockpath, strerror(errno));
+               exit(WC_EXIT_BIND);
+       }
+
+       memset(&addr, 0, sizeof(addr));
+       addr.sun_family = AF_UNIX;
+       safestrncpy(addr.sun_path, sockpath, sizeof addr.sun_path);
+
+       s = socket(AF_UNIX, SOCK_STREAM, 0);
+       if (s < 0) {
+               lprintf(1, "webcit: Can't create a socket: %s\n",
+                       strerror(errno));
+               exit(WC_EXIT_BIND);
+       }
+
+       if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+               lprintf(1, "webcit: Can't bind: %s\n",
+                       strerror(errno));
+               exit(WC_EXIT_BIND);
+       }
+
+       if (listen(s, actual_queue_len) < 0) {
+               lprintf(1, "webcit: Can't listen: %s\n",
+                       strerror(errno));
+               exit(WC_EXIT_BIND);
+       }
+
+       chmod(sockpath, 0777);
+       return(s);
+}
+
+
+
+
+/*
+ * Read data from the client socket.
+ *
+ * sock                socket fd to read from
+ * buf         buffer to read into 
+ * bytes       number of bytes to read
+ * timeout     Number of seconds to wait before timing out
+ *
+ * Possible return values:
+ *      1       Requested number of bytes has been read.
+ *      0       Request timed out.
+ *     -1      Connection is broken, or other error.
+ */
+int client_read_to(int *sock, StrBuf *Target, StrBuf *Buf, const char **Pos, int bytes, int timeout)
+{
+       const char *Error;
+       int retval = 0;
+
+#ifdef HAVE_OPENSSL
+       if (is_https) {
+               long bufremain = StrLength(Buf) - (*Pos - ChrPtr(Buf));
+               StrBufAppendBufPlain(Target, *Pos, bufremain, 0);
+               *Pos = NULL;
+               FlushStrBuf(Buf);
+
+               while ((StrLength(Buf) + StrLength(Target) < bytes) &&
+                      (retval >= 0))
+                       retval = client_read_sslbuffer(Buf, timeout);
+               if (retval >= 0) {
+                       StrBufAppendBuf(Target, Buf, 0); /* todo: Buf > bytes? */
+#ifdef HTTP_TRACING
+                       write(2, "\033[32m", 5);
+                       write(2, buf, bytes);
+                       write(2, "\033[30m", 5);
+#endif
+                       return 1;
+               }
+               else {
+                       lprintf(2, "client_read_ssl() failed\n");
+                       return -1;
+               }
+       }
+#endif
+
+       retval = StrBufReadBLOBBuffered(Target, 
+                                       Buf, Pos, 
+                                       sock, 
+                                       1, 
+                                       bytes,
+                                       O_TERM,
+                                       &Error);
+       if (retval < 0) {
+               lprintf(2, "client_read() failed: %s\n",
+                       Error);
+               return retval;
+       }
+
+#ifdef HTTP_TRACING
+       write(2, "\033[32m", 5);
+       write(2, buf, bytes);
+       write(2, "\033[30m", 5);
+#endif
+       return 1;
+}
+
+
+/*
+ * Begin buffering HTTP output so we can transmit it all in one write operation later.
+ */
+void begin_burst(void)
+{
+       if (WC->WBuf == NULL) {
+               WC->WBuf = NewStrBufPlain(NULL, 32768);
+       }
+}
+
+
+/*
+ * Finish buffering HTTP output.  [Compress using zlib and] output with a Content-Length: header.
+ */
+long end_burst(void)
+{
+       wcsession *WCC = WC;
+        const char *ptr, *eptr;
+        long count;
+       ssize_t res;
+        fd_set wset;
+        int fdflags;
+
+       if (!DisableGzip && (WCC->gzip_ok) && CompressBuffer(WCC->WBuf))
+       {
+               hprintf("Content-encoding: gzip\r\n");
+       }
+
+       hprintf("Content-length: %d\r\n\r\n", StrLength(WCC->WBuf));
+
+       ptr = ChrPtr(WCC->HBuf);
+       count = StrLength(WCC->HBuf);
+       eptr = ptr + count;
+
+#ifdef HAVE_OPENSSL
+       if (is_https) {
+               client_write_ssl(WCC->HBuf);
+               client_write_ssl(WCC->WBuf);
+               return (count);
+       }
+#endif
+
+       
+#ifdef HTTP_TRACING
+       
+       write(2, "\033[34m", 5);
+       write(2, ptr, StrLength(WCC->WBuf));
+       write(2, "\033[30m", 5);
+#endif
+       fdflags = fcntl(WC->http_sock, F_GETFL);
+
+       while (ptr < eptr) {
+                if ((fdflags & O_NONBLOCK) == O_NONBLOCK) {
+                        FD_ZERO(&wset);
+                        FD_SET(WCC->http_sock, &wset);
+                        if (select(WCC->http_sock + 1, NULL, &wset, NULL, NULL) == -1) {
+                                lprintf(2, "client_write: Socket select failed (%s)\n", strerror(errno));
+                                return -1;
+                        }
+                }
+
+                if ((res = write(WCC->http_sock, 
+                                ptr,
+                                count)) == -1) {
+                        lprintf(2, "client_write: Socket write failed (%s)\n", strerror(errno));
+                       wc_backtrace();
+                        return res;
+                }
+                count -= res;
+               ptr += res;
+        }
+
+       ptr = ChrPtr(WCC->WBuf);
+       count = StrLength(WCC->WBuf);
+       eptr = ptr + count;
+
+#ifdef HTTP_TRACING
+       
+       write(2, "\033[34m", 5);
+       write(2, ptr, StrLength(WCC->WBuf));
+       write(2, "\033[30m", 5);
+#endif
+
+        while (ptr < eptr) {
+                if ((fdflags & O_NONBLOCK) == O_NONBLOCK) {
+                        FD_ZERO(&wset);
+                        FD_SET(WCC->http_sock, &wset);
+                        if (select(WCC->http_sock + 1, NULL, &wset, NULL, NULL) == -1) {
+                                lprintf(2, "client_write: Socket select failed (%s)\n", strerror(errno));
+                                return -1;
+                        }
+                }
+
+                if ((res = write(WCC->http_sock, 
+                                ptr,
+                                count)) == -1) {
+                        lprintf(2, "client_write: Socket write failed (%s)\n", strerror(errno));
+                       wc_backtrace();
+                        return res;
+                }
+                count -= res;
+               ptr += res;
+        }
+
+       return StrLength(WCC->WBuf);
+}
+
+
+
+void
+SessionNewModule_TCPSOCKETS
+(wcsession *sess)
+{
+       sess->CLineBuf = NewStrBuf();
+       sess->MigrateReadLineBuf = NewStrBuf();
+}
+
+void 
+SessionDestroyModule_TCPSOCKETS
+(wcsession *sess)
+{
+       FreeStrBuf(&sess->CLineBuf);
+       FreeStrBuf(&sess->ReadBuf);
+       FreeStrBuf(&sess->MigrateReadLineBuf);
+}
index 9b3a926fbb67b05249ae56812e71e7ad5cd34468..e1e9c5ded3184482631f9182f979f41e40acd405 100644 (file)
@@ -19,7 +19,7 @@
  * the exact minute.  :)
  */
 static char *unset = "; expires=28-May-1971 18:10:00 GMT";
-
+StrBuf *csslocal = NULL;
 HashList *HandlerHash = NULL;
 
 void WebcitAddUrlHandler(const char * UrlString, 
@@ -563,8 +563,7 @@ int is_mobile_ua(char *user_agent) {
 /*
  * Entry point for WebCit transaction
  */
-void session_loop(HashList *HTTPHeaders, 
-                 StrBuf *ReqLine, 
+void session_loop(StrBuf *ReqLine, 
                  StrBuf *request_method, 
                  StrBuf *ReadBuf,
                  const char **Pos)
@@ -617,13 +616,6 @@ void session_loop(HashList *HTTPHeaders,
        c_httpauth_pass = NewStrBufPlain(HKEY(DEFAULT_HTTPAUTH_PASS));
 
        WCC= WC;
-       if (WCC->WBuf == NULL)
-               WC->WBuf = NewStrBufPlain(NULL, 32768);
-       FlushStrBuf(WCC->WBuf);
-
-       if (WCC->HBuf == NULL)
-               WCC->HBuf = NewStrBuf();
-       FlushStrBuf(WCC->HBuf);
 
        WCC->upload_length = 0;
        WCC->upload = NULL;
@@ -654,28 +646,28 @@ void session_loop(HashList *HTTPHeaders,
        }
 
 
-       if (GetHash(HTTPHeaders, HKEY("COOKIE"), &vLine) && 
+       if (GetHash(WCC->headers, HKEY("COOKIE"), &vLine) && 
            (vLine != NULL)){
                cookie_to_stuff((StrBuf *)vLine, NULL,
                                c_username,
                                c_password,
                                c_roomname);
        }
-       if (GetHash(HTTPHeaders, HKEY("AUTHORIZATION"), &vLine) &&
+       if (GetHash(WCC->headers, HKEY("AUTHORIZATION"), &vLine) &&
            (vLine!=NULL)) {
                StrBufDecodeBase64((StrBuf*)vLine);
                StrBufExtract_token(c_httpauth_user, (StrBuf*)vLine, 0, ':');
                StrBufExtract_token(c_httpauth_pass, (StrBuf*)vLine, 1, ':');
        }
-       if (GetHash(HTTPHeaders, HKEY("CONTENT-LENGTH"), &vLine) &&
+       if (GetHash(WCC->headers, HKEY("CONTENT-LENGTH"), &vLine) &&
            (vLine!=NULL)) {
                ContentLength = StrToi((StrBuf*)vLine);
        }
-       if (GetHash(HTTPHeaders, HKEY("CONTENT-TYPE"), &vLine) &&
+       if (GetHash(WCC->headers, HKEY("CONTENT-TYPE"), &vLine) &&
            (vLine!=NULL)) {
                ContentType = (StrBuf*)vLine;
        }
-       if (GetHash(HTTPHeaders, HKEY("USER-AGENT"), &vLine) &&
+       if (GetHash(WCC->headers, HKEY("USER-AGENT"), &vLine) &&
            (vLine!=NULL)) {
                safestrncpy(user_agent, ChrPtr((StrBuf*)vLine), sizeof user_agent);
 #ifdef TECH_PREVIEW
@@ -688,17 +680,17 @@ void session_loop(HashList *HTTPHeaders,
 #endif
        }
        if ((follow_xff) &&
-           GetHash(HTTPHeaders, HKEY("X-FORWARDED-HOST"), &vLine) &&
+           GetHash(WCC->headers, HKEY("X-FORWARDED-HOST"), &vLine) &&
            (vLine != NULL)) {
                WCC->http_host = (StrBuf*)vLine;
        }
        if ((StrLength(WCC->http_host) == 0) && 
-           GetHash(HTTPHeaders, HKEY("HOST"), &vLine) &&
+           GetHash(WCC->headers, HKEY("HOST"), &vLine) &&
            (vLine!=NULL)) {
                WCC->http_host = (StrBuf*)vLine;
        }
 
-       if (GetHash(HTTPHeaders, HKEY("X-FORWARDED-FOR"), &vLine) &&
+       if (GetHash(WCC->headers, HKEY("X-FORWARDED-FOR"), &vLine) &&
            (vLine!=NULL)) {
                browser_host = (StrBuf*) vLine;
 
@@ -861,7 +853,7 @@ void session_loop(HashList *HTTPHeaders,
                        if ( (!follow_xff) || (StrLength(browser_host) == 0) ) {
                                if (browser_host == NULL) {
                                        browser_host = NewStrBuf();
-                                       Put(HTTPHeaders, HKEY("FreeMeWithTheOtherHeaders"), 
+                                       Put(WCC->headers, HKEY("FreeMeWithTheOtherHeaders"), 
                                            browser_host, HFreeStrBuf);
                                }
                                locate_host(browser_host, WCC->http_sock);
@@ -962,7 +954,7 @@ void session_loop(HashList *HTTPHeaders,
         * our session's authentication.
         */
        if (!strncasecmp(action, "groupdav", 8)) {
-               groupdav_main(HTTPHeaders, 
+               groupdav_main(WCC->headers, 
                              ReqLine, request_method,
                              ContentType, /* do GroupDAV methods */
                              ContentLength, content, body_start);
@@ -978,7 +970,7 @@ void session_loop(HashList *HTTPHeaders,
         * POST to the GroupDAV code as well.
         */
        if ((strcasecmp(ChrPtr(request_method), "GET")) && (strcasecmp(ChrPtr(request_method), "POST"))) {
-               groupdav_main(HTTPHeaders, ReqLine, 
+               groupdav_main(WCC->headers, ReqLine, 
                              request_method, ContentType, /** do GroupDAV methods */
                              ContentLength, content, body_start);
                if (!WCC->logged_in) {
@@ -1152,18 +1144,17 @@ void tmplput_trailing_javascript(StrBuf *Target, WCTemplputParams *TP)
 
 void tmplput_csslocal(StrBuf *Target, WCTemplputParams *TP)
 {
-       extern StrBuf *csslocal;
        StrBufAppendBuf(Target, 
                        csslocal, 0);
 }
 
-
-
+extern char static_local_dir[PATH_MAX];
 
 void 
 InitModule_WEBCIT
 (void)
 {
+       char dir[SIZ];
        WebcitAddUrlHandler(HKEY("blank"), blank_page, ANONYMOUS);
        WebcitAddUrlHandler(HKEY("do_template"), url_do_template, ANONYMOUS);
        WebcitAddUrlHandler(HKEY("sslg"), seconds_since_last_gexp, AJAX);
@@ -1173,4 +1164,68 @@ InitModule_WEBCIT
        RegisterNamespace("CSSLOCAL", 0, 0, tmplput_csslocal, CTX_NONE);
        RegisterNamespace("IMPORTANTMESSAGE", 0, 0, tmplput_importantmessage, CTX_NONE);
        RegisterNamespace("TRAILING_JAVASCRIPT", 0, 0, tmplput_trailing_javascript, CTX_NONE);
+
+       snprintf(dir, SIZ, "%s/static.local/webcit.css", static_local_dir);
+       if (!access(dir, R_OK)) {
+               lprintf(9, "Using local Stylesheet [%s]\n", dir);
+               csslocal = NewStrBufPlain(HKEY("<link href=\"static.local/webcit.css\" rel=\"stylesheet\" type=\"text/css\">"));
+       }
+       else
+               lprintf(9, "Didn't find site local Stylesheet [%s]\n", dir);
+
+}
+
+void
+ServerStartModule_WEBCIT
+(void)
+{
+       HandlerHash = NewHash(1, NULL);
+}
+
+
+void 
+ServerShutdownModule_WEBCIT
+(void)
+{
+       FreeStrBuf(&csslocal);
+       DeleteHash(&HandlerHash);
+}
+
+
+
+void
+SessionNewModule_WEBCIT
+(wcsession *sess)
+{
+       sess->ImportantMsg = NewStrBuf();
+       sess->WBuf = NewStrBuf();
+       sess->HBuf = NewStrBuf();
+}
+
+void
+SessionDetachModule_WEBCIT
+(wcsession *sess)
+{
+       if (StrLength(sess->WBuf) > SIZ * 30) /* Bigger than 120K? release. */
+       {
+               FreeStrBuf(&sess->WBuf);
+               sess->WBuf = NewStrBuf();
+       }
+       else
+               FlushStrBuf(sess->WBuf);
+       FlushStrBuf(sess->HBuf);
 }
+
+void 
+SessionDestroyModule_WEBCIT
+(wcsession *sess)
+{
+       FreeStrBuf(&sess->WBuf);
+       FreeStrBuf(&sess->HBuf);
+       FreeStrBuf(&sess->UrlFragment1);
+       FreeStrBuf(&sess->UrlFragment2);
+       FreeStrBuf(&sess->UrlFragment3);
+       FreeStrBuf(&sess->UrlFragment4);
+       FreeStrBuf(&sess->ImportantMsg);
+}
+
index 55490f89a752549c3adb10ae4dff58d5dcb35c02..1efdeec091589fb36e8cb1f3a598f78508486306 100644 (file)
@@ -364,6 +364,7 @@ struct wcsession {
        StrBuf *this_page;                      /**< URL of current page */
        HashList *urlstrings;                   /**< variables passed to webcit in a URL */
        HashList *vars;                         /**< HTTP variable substitutions for this page */
+       HashList *headers;                      /**< the headers the client sent us */
        StrBuf *http_host;                      /**< HTTP Host: header */
        int is_ajax;                            /** < are we doing an ajax request? */
        int gzip_ok;                            /**< Nonzero if Accept-encoding: gzip */
@@ -510,10 +511,6 @@ extern int setup_wizard;
 extern char wizard_filename[];
 extern time_t if_modified_since;
 extern int follow_xff;
-extern HashList *HandlerHash;
-extern HashList *PreferenceHooks;
-extern HashList *ZoneHash;
-extern HashList *SortHash;
 
 void InitialiseSemaphores(void);
 void begin_critical_section(int which_one);
@@ -621,8 +618,7 @@ void shutdown_sessions(void);
 void do_housekeeping(void);
 void smart_goto(const StrBuf *);
 void worker_entry(void);
-void session_loop(HashList *HTTPHeaders, 
-                 StrBuf *ReqLine, 
+void session_loop(StrBuf *ReqLine, 
                  StrBuf *ReqType, 
                  StrBuf *ReadBuf, 
                  const char **Pos);
index 74bff8c4812c2627fd3c88e7d5103c813ffa6d7d..8488020effca4a1cae9f12ea8aed938d4de86b5a 100644 (file)
@@ -33,6 +33,9 @@ extern void *housekeeping_loop(void);
 extern pthread_mutex_t SessionListMutex;
 extern pthread_key_t MyConKey;
 
+extern int ig_tcp_server(char *ip_addr, int port_number, int queue_len);
+extern int ig_uds_server(char *sockpath, int queue_len);
+
 
 char ctdl_key_dir[PATH_MAX]=SSL_DIR;
 char file_crpt_file_key[PATH_MAX]="";
@@ -40,10 +43,10 @@ char file_crpt_file_csr[PATH_MAX]="";
 char file_crpt_file_cer[PATH_MAX]="";
 
 char socket_dir[PATH_MAX];                     /* where to talk to our citadel server */
-static const char editor_absolut_dir[PATH_MAX]=EDITORDIR;      /* nailed to what configure gives us. */
-static char static_dir[PATH_MAX];              /* calculated on startup */
-static char static_local_dir[PATH_MAX];                /* calculated on startup */
-static char static_icon_dir[PATH_MAX];          /* where should we find our mime icons? */
+const char editor_absolut_dir[PATH_MAX]=EDITORDIR;     /* nailed to what configure gives us. */
+char static_dir[PATH_MAX];             /* calculated on startup */
+char static_local_dir[PATH_MAX];               /* calculated on startup */
+char static_icon_dir[PATH_MAX];          /* where should we find our mime icons? */
 char  *static_dirs[]={                         /* needs same sort order as the web mapping */
        (char*)static_dir,                      /* our templates on disk */
        (char*)static_local_dir,                /* user provided templates disk */
@@ -74,291 +77,6 @@ char wizard_filename[PATH_MAX];     /* where's the setup wizard? */
 int running_as_daemon = 0;     /* should we deamonize on startup? */
 
 
-/* 
- * This is a generic function to set up a master socket for listening on
- * a TCP port.  The server shuts down if the bind fails.
- *
- * ip_addr     IP address to bind
- * port_number port number to bind
- * queue_len   number of incoming connections to allow in the queue
- */
-int ig_tcp_server(char *ip_addr, int port_number, int queue_len)
-{
-       struct sockaddr_in sin;
-       int s, i;
-
-       memset(&sin, 0, sizeof(sin));
-       sin.sin_family = AF_INET;
-       if (ip_addr == NULL) {
-               sin.sin_addr.s_addr = INADDR_ANY;
-       } else {
-               sin.sin_addr.s_addr = inet_addr(ip_addr);
-       }
-
-       if (sin.sin_addr.s_addr == INADDR_NONE) {
-               sin.sin_addr.s_addr = INADDR_ANY;
-       }
-
-       if (port_number == 0) {
-               lprintf(1, "Cannot start: no port number specified.\n");
-               exit(WC_EXIT_BIND);
-       }
-       sin.sin_port = htons((u_short) port_number);
-
-       s = socket(PF_INET, SOCK_STREAM, (getprotobyname("tcp")->p_proto));
-       if (s < 0) {
-               lprintf(1, "Can't create a socket: %s\n", strerror(errno));
-               exit(WC_EXIT_BIND);
-       }
-       /* Set some socket options that make sense. */
-       i = 1;
-       setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
-
-       #ifndef __APPLE__
-       fcntl(s, F_SETFL, O_NONBLOCK); /* maide: this statement is incorrect
-                                         there should be a preceding F_GETFL
-                                         and a bitwise OR with the previous
-                                         fd flags */
-       #endif
-       
-       if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
-               lprintf(1, "Can't bind: %s\n", strerror(errno));
-               exit(WC_EXIT_BIND);
-       }
-       if (listen(s, queue_len) < 0) {
-               lprintf(1, "Can't listen: %s\n", strerror(errno));
-               exit(WC_EXIT_BIND);
-       }
-       return (s);
-}
-
-
-
-/*
- * Create a Unix domain socket and listen on it
- * sockpath - file name of the unix domain socket
- * queue_len - Number of incoming connections to allow in the queue
- */
-int ig_uds_server(char *sockpath, int queue_len)
-{
-       struct sockaddr_un addr;
-       int s;
-       int i;
-       int actual_queue_len;
-
-       actual_queue_len = queue_len;
-       if (actual_queue_len < 5) actual_queue_len = 5;
-
-       i = unlink(sockpath);
-       if ((i != 0) && (errno != ENOENT)) {
-               lprintf(1, "webcit: can't unlink %s: %s\n",
-                       sockpath, strerror(errno));
-               exit(WC_EXIT_BIND);
-       }
-
-       memset(&addr, 0, sizeof(addr));
-       addr.sun_family = AF_UNIX;
-       safestrncpy(addr.sun_path, sockpath, sizeof addr.sun_path);
-
-       s = socket(AF_UNIX, SOCK_STREAM, 0);
-       if (s < 0) {
-               lprintf(1, "webcit: Can't create a socket: %s\n",
-                       strerror(errno));
-               exit(WC_EXIT_BIND);
-       }
-
-       if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
-               lprintf(1, "webcit: Can't bind: %s\n",
-                       strerror(errno));
-               exit(WC_EXIT_BIND);
-       }
-
-       if (listen(s, actual_queue_len) < 0) {
-               lprintf(1, "webcit: Can't listen: %s\n",
-                       strerror(errno));
-               exit(WC_EXIT_BIND);
-       }
-
-       chmod(sockpath, 0777);
-       return(s);
-}
-
-
-
-
-/*
- * Read data from the client socket.
- *
- * sock                socket fd to read from
- * buf         buffer to read into 
- * bytes       number of bytes to read
- * timeout     Number of seconds to wait before timing out
- *
- * Possible return values:
- *      1       Requested number of bytes has been read.
- *      0       Request timed out.
- *     -1      Connection is broken, or other error.
- */
-int client_read_to(int *sock, StrBuf *Target, StrBuf *Buf, const char **Pos, int bytes, int timeout)
-{
-       const char *Error;
-       int retval = 0;
-
-#ifdef HAVE_OPENSSL
-       if (is_https) {
-               long bufremain = StrLength(Buf) - (*Pos - ChrPtr(Buf));
-               StrBufAppendBufPlain(Target, *Pos, bufremain, 0);
-               *Pos = NULL;
-               FlushStrBuf(Buf);
-
-               while ((StrLength(Buf) + StrLength(Target) < bytes) &&
-                      (retval >= 0))
-                       retval = client_read_sslbuffer(Buf, timeout);
-               if (retval >= 0) {
-                       StrBufAppendBuf(Target, Buf, 0); /* todo: Buf > bytes? */
-#ifdef HTTP_TRACING
-                       write(2, "\033[32m", 5);
-                       write(2, buf, bytes);
-                       write(2, "\033[30m", 5);
-#endif
-                       return 1;
-               }
-               else {
-                       lprintf(2, "client_read_ssl() failed\n");
-                       return -1;
-               }
-       }
-#endif
-
-       retval = StrBufReadBLOBBuffered(Target, 
-                                       Buf, Pos, 
-                                       sock, 
-                                       1, 
-                                       bytes,
-                                       O_TERM,
-                                       &Error);
-       if (retval < 0) {
-               lprintf(2, "client_read() failed: %s\n",
-                       Error);
-               return retval;
-       }
-
-#ifdef HTTP_TRACING
-       write(2, "\033[32m", 5);
-       write(2, buf, bytes);
-       write(2, "\033[30m", 5);
-#endif
-       return 1;
-}
-
-
-/*
- * Begin buffering HTTP output so we can transmit it all in one write operation later.
- */
-void begin_burst(void)
-{
-       if (WC->WBuf == NULL) {
-               WC->WBuf = NewStrBufPlain(NULL, 32768);
-       }
-}
-
-
-/*
- * Finish buffering HTTP output.  [Compress using zlib and] output with a Content-Length: header.
- */
-long end_burst(void)
-{
-       wcsession *WCC = WC;
-        const char *ptr, *eptr;
-        long count;
-       ssize_t res;
-        fd_set wset;
-        int fdflags;
-
-       if (!DisableGzip && (WCC->gzip_ok) && CompressBuffer(WCC->WBuf))
-       {
-               hprintf("Content-encoding: gzip\r\n");
-       }
-
-       hprintf("Content-length: %d\r\n\r\n", StrLength(WCC->WBuf));
-
-       ptr = ChrPtr(WCC->HBuf);
-       count = StrLength(WCC->HBuf);
-       eptr = ptr + count;
-
-#ifdef HAVE_OPENSSL
-       if (is_https) {
-               client_write_ssl(WCC->HBuf);
-               client_write_ssl(WCC->WBuf);
-               return (count);
-       }
-#endif
-
-       
-#ifdef HTTP_TRACING
-       
-       write(2, "\033[34m", 5);
-       write(2, ptr, StrLength(WCC->WBuf));
-       write(2, "\033[30m", 5);
-#endif
-       fdflags = fcntl(WC->http_sock, F_GETFL);
-
-       while (ptr < eptr) {
-                if ((fdflags & O_NONBLOCK) == O_NONBLOCK) {
-                        FD_ZERO(&wset);
-                        FD_SET(WCC->http_sock, &wset);
-                        if (select(WCC->http_sock + 1, NULL, &wset, NULL, NULL) == -1) {
-                                lprintf(2, "client_write: Socket select failed (%s)\n", strerror(errno));
-                                return -1;
-                        }
-                }
-
-                if ((res = write(WCC->http_sock, 
-                                ptr,
-                                count)) == -1) {
-                        lprintf(2, "client_write: Socket write failed (%s)\n", strerror(errno));
-                       wc_backtrace();
-                        return res;
-                }
-                count -= res;
-               ptr += res;
-        }
-
-       ptr = ChrPtr(WCC->WBuf);
-       count = StrLength(WCC->WBuf);
-       eptr = ptr + count;
-
-#ifdef HTTP_TRACING
-       
-       write(2, "\033[34m", 5);
-       write(2, ptr, StrLength(WCC->WBuf));
-       write(2, "\033[30m", 5);
-#endif
-
-        while (ptr < eptr) {
-                if ((fdflags & O_NONBLOCK) == O_NONBLOCK) {
-                        FD_ZERO(&wset);
-                        FD_SET(WCC->http_sock, &wset);
-                        if (select(WCC->http_sock + 1, NULL, &wset, NULL, NULL) == -1) {
-                                lprintf(2, "client_write: Socket select failed (%s)\n", strerror(errno));
-                                return -1;
-                        }
-                }
-
-                if ((res = write(WCC->http_sock, 
-                                ptr,
-                                count)) == -1) {
-                        lprintf(2, "client_write: Socket write failed (%s)\n", strerror(errno));
-                       wc_backtrace();
-                        return res;
-                }
-                count -= res;
-               ptr += res;
-        }
-
-       return StrLength(WCC->WBuf);
-}
-
 
 /*
  * Shut us down the regular way.
@@ -373,69 +91,6 @@ void graceful_shutdown_watcher(int signum) {
 }
 
 
-int ClientGetLine(int *sock, StrBuf *Target, StrBuf *CLineBuf, const char **Pos)
-{
-       const char *Error, *pch, *pchs;
-       int rlen, len, retval = 0;
-
-#ifdef HAVE_OPENSSL
-       if (is_https) {
-               int ntries = 0;
-               if (StrLength(CLineBuf) > 0) {
-                       pchs = ChrPtr(CLineBuf);
-                       pch = strchr(pchs, '\n');
-                       if (pch != NULL) {
-                               rlen = 0;
-                               len = pch - pchs;
-                               if (len > 0 && (*(pch - 1) == '\r') )
-                                       rlen ++;
-                               StrBufSub(Target, CLineBuf, 0, len - rlen);
-                               StrBufCutLeft(CLineBuf, len + 1);
-                               return len - rlen;
-                       }
-               }
-
-               while (retval == 0) { 
-                               pch = NULL;
-                               pchs = ChrPtr(CLineBuf);
-                               if (*pchs != '\0')
-                                       pch = strchr(pchs, '\n');
-                               if (pch == NULL) {
-                                       retval = client_read_sslbuffer(CLineBuf, SLEEPING);
-                                       pchs = ChrPtr(CLineBuf);
-                                       pch = strchr(pchs, '\n');
-                               }
-                               if (retval == 0) {
-                                       sleeeeeeeeeep(1);
-                                       ntries ++;
-                               }
-                               if (ntries > 10)
-                                       return 0;
-               }
-               if ((retval > 0) && (pch != NULL)) {
-                       rlen = 0;
-                       len = pch - pchs;
-                       if (len > 0 && (*(pch - 1) == '\r') )
-                               rlen ++;
-                       StrBufSub(Target, CLineBuf, 0, len - rlen);
-                       StrBufCutLeft(CLineBuf, len + 1);
-                       return len - rlen;
-
-               }
-               else 
-                       return -1;
-       }
-       else 
-#endif
-               return StrBufTCP_read_buffered_line_fast(Target, 
-                                                        CLineBuf,
-                                                        Pos,
-                                                        sock,
-                                                        5,
-                                                        1,
-                                                        &Error);
-}
-
 
 
 /*
@@ -603,8 +258,54 @@ extern int DumpTemplateI18NStrings;
 extern StrBuf *I18nDump;
 void InitTemplateCache(void);
 extern int LoadTemplates;
-extern void LoadZoneFiles(void);
-StrBuf *csslocal = NULL;
+
+extern HashList *HandlerHash;
+
+
+void
+webcit_calc_dirs_n_files(int relh, const char *basedir, int home, char *webcitdir, char *relhome)
+{
+       char dirbuffer[PATH_MAX]="";
+       /* calculate all our path on a central place */
+    /* where to keep our config */
+       
+#define COMPUTE_DIRECTORY(SUBDIR) memcpy(dirbuffer,SUBDIR, sizeof dirbuffer);\
+       snprintf(SUBDIR,sizeof SUBDIR,  "%s%s%s%s%s%s%s", \
+                        (home&!relh)?webcitdir:basedir, \
+             ((basedir!=webcitdir)&(home&!relh))?basedir:"/", \
+             ((basedir!=webcitdir)&(home&!relh))?"/":"", \
+                        relhome, \
+             (relhome[0]!='\0')?"/":"",\
+                        dirbuffer,\
+                        (dirbuffer[0]!='\0')?"/":"");
+       basedir=RUNDIR;
+       COMPUTE_DIRECTORY(socket_dir);
+       basedir=WWWDIR "/static";
+       COMPUTE_DIRECTORY(static_dir);
+       basedir=WWWDIR "/static/icons";
+       COMPUTE_DIRECTORY(static_icon_dir);
+       basedir=WWWDIR "/static.local";
+       COMPUTE_DIRECTORY(static_local_dir);
+
+       snprintf(file_crpt_file_key,
+                sizeof file_crpt_file_key, 
+                "%s/citadel.key",
+                ctdl_key_dir);
+       snprintf(file_crpt_file_csr,
+                sizeof file_crpt_file_csr, 
+                "%s/citadel.csr",
+                ctdl_key_dir);
+       snprintf(file_crpt_file_cer,
+                sizeof file_crpt_file_cer, 
+                "%s/citadel.cer",
+                ctdl_key_dir);
+
+       /* we should go somewhere we can leave our coredump, if enabled... */
+       lprintf(9, "Changing directory to %s\n", socket_dir);
+       if (chdir(webcitdir) != 0) {
+               perror("chdir");
+       }
+}
 /*
  * Here's where it all begins.
  */
@@ -615,7 +316,6 @@ int main(int argc, char **argv)
        int a, i;                       /* General-purpose variables */
        char tracefile[PATH_MAX];
        char ip_addr[256]="0.0.0.0";
-       char dirbuffer[PATH_MAX]="";
        int relh=0;
        int home=0;
        int home_specified=0;
@@ -633,23 +333,10 @@ int main(int argc, char **argv)
 
        WildFireInitBacktrace(argv[0], 2);
 
-       HandlerHash = NewHash(1, NULL);
-       PreferenceHooks = NewHash(1, NULL);
-       WirelessTemplateCache = NewHash(1, NULL);
-       WirelessLocalTemplateCache = NewHash(1, NULL);
-       LocalTemplateCache = NewHash(1, NULL);
-       TemplateCache = NewHash(1, NULL);
-       GlobalNS = NewHash(1, NULL);
-       Iterators = NewHash(1, NULL);
-       Conditionals = NewHash(1, NULL);
-       MsgHeaderHandler = NewHash(1, NULL);
-       MimeRenderHandler = NewHash(1, NULL);
-       SortHash = NewHash(1, NULL);
-
-       LoadZoneFiles();
+       start_modules ();
 
 #ifdef DBG_PRINNT_HOOKS_AT_START
-       dbg_PrintHash(HandlerHash, nix, NULL);
+/*     dbg_PrintHash(HandlerHash, nix, NULL);*/
 #endif
 
        /* Ensure that we are linked to the correct version of libcitadel */
@@ -768,6 +455,9 @@ int main(int argc, char **argv)
                signal(SIGHUP, graceful_shutdown);
        }
 
+       webcit_calc_dirs_n_files(relh, basedir, home, webcitdir, relhome);
+       LoadIconDir(static_icon_dir);
+
        /* Tell 'em who's in da house */
        lprintf(1, PACKAGE_STRING "\n");
        lprintf(1, "Copyright (C) 1996-2009 by the Citadel development team.\n"
@@ -791,46 +481,13 @@ int main(int argc, char **argv)
 #endif
 
 
-       /* calculate all our path on a central place */
-    /* where to keep our config */
-       
-#define COMPUTE_DIRECTORY(SUBDIR) memcpy(dirbuffer,SUBDIR, sizeof dirbuffer);\
-       snprintf(SUBDIR,sizeof SUBDIR,  "%s%s%s%s%s%s%s", \
-                        (home&!relh)?webcitdir:basedir, \
-             ((basedir!=webcitdir)&(home&!relh))?basedir:"/", \
-             ((basedir!=webcitdir)&(home&!relh))?"/":"", \
-                        relhome, \
-             (relhome[0]!='\0')?"/":"",\
-                        dirbuffer,\
-                        (dirbuffer[0]!='\0')?"/":"");
-       basedir=RUNDIR;
-       COMPUTE_DIRECTORY(socket_dir);
-       basedir=WWWDIR "/static";
-       COMPUTE_DIRECTORY(static_dir);
-       basedir=WWWDIR "/static/icons";
-       COMPUTE_DIRECTORY(static_icon_dir);
-       basedir=WWWDIR "/static.local";
-       COMPUTE_DIRECTORY(static_local_dir);
 
-       snprintf(file_crpt_file_key,
-                sizeof file_crpt_file_key, 
-                "%s/citadel.key",
-                ctdl_key_dir);
-       snprintf(file_crpt_file_csr,
-                sizeof file_crpt_file_csr, 
-                "%s/citadel.csr",
-                ctdl_key_dir);
-       snprintf(file_crpt_file_cer,
-                sizeof file_crpt_file_cer, 
-                "%s/citadel.cer",
-                ctdl_key_dir);
 
-       /* we should go somewhere we can leave our coredump, if enabled... */
-       lprintf(9, "Changing directory to %s\n", socket_dir);
-       if (chdir(webcitdir) != 0) {
-               perror("chdir");
-       }
-       LoadIconDir(static_icon_dir);
+
+
+
+
+
 
        initialise_modules();
        initialize_viewdefs();
@@ -858,9 +515,6 @@ int main(int argc, char **argv)
                return 0;
        }
 
-       if (!access("static.local/webcit.css", R_OK)) {
-               csslocal = NewStrBufPlain(HKEY("<link href=\"static.local/webcit.css\" rel=\"stylesheet\" type=\"text/css\">"));
-       }
 
        /* Tell libical to return an error instead of aborting if it sees badly formed iCalendar data. */
        icalerror_errors_are_fatal = 0;
@@ -936,31 +590,17 @@ int main(int argc, char **argv)
        /* now the original thread becomes another worker */
        worker_entry();
        ShutDownLibCitadel ();
-       DeleteHash(&HandlerHash);
-       DeleteHash(&PreferenceHooks);
        return 0;
 }
 
 
 void ShutDownWebcit(void)
 {
-       DeleteHash(&ZoneHash);
        free_zone_directory ();
        icaltimezone_release_zone_tab ();
        icalmemory_free_ring ();
        ShutDownLibCitadel ();
-       DeleteHash(&HandlerHash);
-       DeleteHash(&PreferenceHooks);
-       DeleteHash(&GlobalNS);
-       DeleteHash(&WirelessTemplateCache);
-       DeleteHash(&WirelessLocalTemplateCache);
-       DeleteHash(&TemplateCache);
-       DeleteHash(&LocalTemplateCache);
-       DeleteHash(&Iterators);
-       DeleteHash(&MimeRenderHandler);
-       DeleteHash(&Conditionals);
-       DeleteHash(&MsgHeaderHandler);
-       DeleteHash(&SortHash);
+       shutdown_modules ();
 #ifdef ENABLE_NLS
        ShutdownLocale();
 #endif
@@ -1066,6 +706,18 @@ void worker_entry(void)
                                        close(ssock);
                                }
                        }
+                       else 
+                       {
+                               int fdflags; 
+                               fdflags = fcntl(ssock, F_GETFL);
+                               if (fdflags < 0)
+                                       lprintf(1, "unable to get server socket flags! %s \n",
+                                               strerror(errno));
+                               fdflags = fdflags | O_NONBLOCK;
+                               if (fcntl(ssock, F_SETFD, fdflags) < 0)
+                                       lprintf(1, "unable to set server socket nonblocking flags! %s \n",
+                                               strerror(errno));
+                       }
 #endif
 
                        if (fail_this_transaction == 0) {
@@ -1138,3 +790,6 @@ void wc_backtrace(void)
 #endif
 }
 
+
+
+