]> code.citadel.org Git - citadel.git/blobdiff - citadel/citserver.c
Here it is, the new thread interface.
[citadel.git] / citadel / citserver.c
index c221d6aafbf6949fd9bfa939f283999bcdee13ff..cc27e4363c2d923dfd21c6f787a5f3b5ddc09359 100644 (file)
 # endif
 #endif
 
+#if HAVE_BACKTRACE
+#include <execinfo.h>
+#endif
+
 #include <ctype.h>
 #include <string.h>
 #include <dirent.h>
@@ -36,6 +40,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <libcitadel.h>
 #include "citadel.h"
 #include "server.h"
 #include "sysdep_decls.h"
 #include "file_ops.h"
 #include "policy.h"
 #include "control.h"
-#include "tools.h"
 #include "euidindex.h"
-#include "serv_network.h"      /* Needed for destroy_network_queue_room called from master_cleanup */
 
 #ifndef HAVE_SNPRINTF
 #include "snprintf.h"
 #endif
 
+#include "ctdl_module.h"
+
+
 struct CitContext *ContextList = NULL;
 struct CitContext* next_session = NULL;
 char *unique_session_numbers;
 int ScheduledShutdown = 0;
 int do_defrag = 0;
 time_t server_startup_time;
+int panic_fd;
+
+/**
+ * \brief print the actual stack frame.
+ */
+void cit_backtrace(void)
+{
+#ifdef HAVE_BACKTRACE
+       void *stack_frames[50];
+       size_t size, i;
+       char **strings;
+
+
+       size = backtrace(stack_frames, sizeof(stack_frames) / sizeof(void*));
+       strings = backtrace_symbols(stack_frames, size);
+       for (i = 0; i < size; i++) {
+               if (strings != NULL)
+                       lprintf(1, "%s\n", strings[i]);
+               else
+                       lprintf(1, "%p\n", stack_frames[i]);
+       }
+       free(strings);
+#endif
+}
+
+/**
+ * \brief print the actual stack frame.
+ */
+void cit_panic_backtrace(int SigNum)
+{
+#ifdef HAVE_BACKTRACE
+       void *stack_frames[10];
+       size_t size, i;
+       char **strings;
+
+       printf("caught signal 11\n");
+       size = backtrace(stack_frames, sizeof(stack_frames) / sizeof(void*));
+       strings = backtrace_symbols(stack_frames, size);
+       for (i = 0; i < size; i++) {
+               if (strings != NULL)
+                       lprintf(1, "%s\n", strings[i]);
+               else
+                       lprintf(1, "%p\n", stack_frames[i]);
+       }
+       free(strings);
+#endif
+       exit(-1);
+}
 
 /*
  * Various things that need to be initialized at startup
@@ -125,7 +179,6 @@ void master_startup(void) {
  */
 void master_cleanup(int exitcode) {
        struct CleanupFunctionHook *fcn;
-       struct MaintenanceThreadHook *m_fcn;
        static int already_cleaning_up = 0;
 
        if (already_cleaning_up) while(1) sleep(1);
@@ -139,19 +192,10 @@ void master_cleanup(int exitcode) {
        /* Close the AdjRefCount queue file */
        AdjRefCount(-1, 0);
 
-       for (m_fcn = MaintenanceThreadHookTable; m_fcn != NULL; m_fcn = m_fcn->next) {
-               lprintf(CTDL_INFO, "Waiting for maintenance thread \"%s\" to shut down\n", m_fcn->name);
-               pthread_join(m_fcn->MaintenanceThread_tid, NULL);
-       }
-       
-
        /* Close databases */
        lprintf(CTDL_INFO, "Closing databases\n");
        close_databases();
 
-       /* flush the networker stuff */
-       destroy_network_queue_room();
-
        /* Do system-dependent stuff */
        sysdep_master_cleanup();
        
@@ -334,11 +378,18 @@ int is_public_client(void)
 
                fp = fopen(public_clients_file, "r");
                if (fp != NULL) while (fgets(buf, sizeof buf, fp)!=NULL) {
-                       for (i=0; i<strlen(buf); ++i) {
-                               if (buf[i] == '#') buf[i] = 0;
+                       char *ptr;
+                       ptr = buf;
+                       while (!IsEmptyStr(ptr)) {
+                               if (*ptr == '#') {
+                                       *ptr = 0;
+                                       break;
+                               }
+                               else ptr++;
                        }
-                       while (isspace((buf[strlen(buf)-1]))) {
-                               buf[strlen(buf)-1] = 0;
+                       ptr--;
+                       while (ptr>buf && isspace(*ptr)) {
+                               *(ptr--) = 0;
                        }
                        if (hostname_to_dotted_quad(addrbuf, buf) == 0) {
                                if ((strlen(public_clients) +
@@ -534,7 +585,7 @@ void cmd_emsg(char *mname)
        if (CtdlAccessCheck(ac_aide)) return;
 
        extract_token(buf, mname, 0, '|', sizeof buf);
-       for (a=0; a<strlen(buf); ++a) {         /* security measure */
+       for (a=0; !IsEmptyStr(&buf[a]); ++a) {          /* security measure */
                if (buf[a] == '/') buf[a] = '.';
        }
 
@@ -769,9 +820,9 @@ void cmd_down(char *argbuf) {
        }
        else
        {
-               cprintf(Reply, CIT_OK);
+               cprintf(Reply, CIT_OK + SERVER_SHUTTING_DOWN);
        }
-       time_to_die = 1;
+       CtdlThreadStopAll();
 }
 
 /*
@@ -782,7 +833,7 @@ void cmd_halt(void) {
        if (CtdlAccessCheck(ac_aide)) return;
 
        cprintf("%d Halting server.  Goodbye.\n", CIT_OK);
-       time_to_die = 1;
+       CtdlThreadStopAll();
        shutdown_and_halt = 1;
 }
 
@@ -873,10 +924,10 @@ void begin_session(struct CitContext *con)
        strcpy(con->lastcmdname, "    ");
        strcpy(con->cs_clientname, "(unknown)");
        strcpy(con->curr_user, NLI);
-       strcpy(con->net_node, "");
-       strcpy(con->fake_username, "");
-       strcpy(con->fake_hostname, "");
-       strcpy(con->fake_roomname, "");
+       *con->net_node = '\0';
+       *con->fake_username = '\0';
+       *con->fake_hostname = '\0';
+       *con->fake_roomname = '\0';
        generate_nonce(con);
        safestrncpy(con->cs_host, config.c_fqdn, sizeof con->cs_host);
        safestrncpy(con->cs_addr, "", sizeof con->cs_addr);