X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fcitserver.c;h=6a85744a55ce04d0a653223c7af813b2d0bc07f4;hb=1e656d277fe91b7c4f5d73eab4a0dd0b7a173145;hp=39f0fb66daa394cd0196e32c83227550cf4c895a;hpb=01cc19a4c2da27b4db0e980ccd3ca54d834319c8;p=citadel.git diff --git a/citadel/citserver.c b/citadel/citserver.c index 39f0fb66d..6a85744a5 100644 --- a/citadel/citserver.c +++ b/citadel/citserver.c @@ -26,6 +26,10 @@ # endif #endif +#if HAVE_BACKTRACE +#include +#endif + #include #include #include @@ -36,6 +40,7 @@ #include #include #include +#include #include "citadel.h" #include "server.h" #include "sysdep_decls.h" @@ -51,9 +56,7 @@ #include "file_ops.h" #include "policy.h" #include "control.h" -#include "tools.h" #include "euidindex.h" -#include "serv_network.h" #ifndef HAVE_SNPRINTF #include "snprintf.h" @@ -65,6 +68,54 @@ 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,6 +176,7 @@ 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); @@ -138,21 +190,16 @@ void master_cleanup(int exitcode) { /* Close the AdjRefCount queue file */ AdjRefCount(-1, 0); - /* Shut down the indexer thread */ - lprintf(CTDL_INFO, "Waiting for the indexer thread to shut down\n"); - pthread_join(indexer_thread_tid, NULL); - - /* Shut down the checkpoint thread */ - lprintf(CTDL_INFO, "Waiting for the checkpoint thread to shut down\n"); - pthread_join(checkpoint_thread_tid, NULL); + 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(); @@ -175,6 +222,8 @@ void master_cleanup(int exitcode) { lprintf(CTDL_NOTICE, "citserver: Exiting with status %d\n", exitcode); fflush(stdout); fflush(stderr); + if (restart_server != 0) + exit(1); exit(exitcode); } @@ -333,11 +382,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; ibuf && isspace(*ptr)) { + *(ptr--) = 0; } if (hostname_to_dotted_quad(addrbuf, buf) == 0) { if ((strlen(public_clients) + @@ -402,7 +458,7 @@ void cmd_iden(char *argbuf) safestrncpy(CC->cs_clientname, desc, sizeof CC->cs_clientname); CC->cs_clientname[31] = 0; - if (strlen(from_host) > 0) { + if (!IsEmptyStr(from_host)) { if (CC->is_local_socket) do_lookup = 1; else if (is_public_client()) do_lookup = 1; } @@ -473,12 +529,12 @@ void cmd_mesg(char *mname) /* Otherwise, look for the requested file by name. */ else { mesg_locate(targ, sizeof targ, buf2, 2, (const char **)dirs); - if (strlen(targ) == 0) { + if (IsEmptyStr(targ)) { snprintf(buf2, sizeof buf2, "%s.%d", buf, CC->cs_clientdev); mesg_locate(targ, sizeof targ, buf2, 2, (const char **)dirs); - if (strlen(targ) == 0) { + if (IsEmptyStr(targ)) { mesg_locate(targ, sizeof targ, buf, 2, (const char **)dirs); } @@ -488,7 +544,7 @@ void cmd_mesg(char *mname) free(dirs[0]); free(dirs[1]); - if (strlen(targ)==0) { + if (IsEmptyStr(targ)) { cprintf("%d '%s' not found. (Searching in %s and %s)\n", ERROR + FILE_NOT_FOUND, mname, @@ -533,7 +589,7 @@ void cmd_emsg(char *mname) if (CtdlAccessCheck(ac_aide)) return; extract_token(buf, mname, 0, '|', sizeof buf); - for (a=0; a 0) + Reply = "%d Restarting server. See you soon.\n"; + if ((restart_server > 0) && !running_as_daemon) + { + lprintf(CTDL_ERR, "The user requested restart, but not running as deamon! Geronimooooooo!\n"); + Reply = "%d Warning, not running in deamon mode. maybe we will come up again, but don't lean on it.\n"; + state = ERROR; + } + cprintf(Reply, state); + } + else + { + cprintf(Reply, CIT_OK + SERVER_SHUTTING_DOWN); + } time_to_die = 1; } @@ -772,14 +847,29 @@ void cmd_halt(void) { void cmd_scdn(char *argbuf) { int new_state; + int state = CIT_OK; + char *Reply = "%d %d\n"; if (CtdlAccessCheck(ac_aide)) return; new_state = extract_int(argbuf, 0); + if ((new_state == 2) || (new_state == 3)) + { + restart_server = 1; + if (!running_as_daemon) + { + lprintf(CTDL_ERR, "The user requested restart, but not running as deamon! Geronimooooooo!\n"); + Reply = "%d %d Warning, not running in deamon mode. maybe we will come up again, but don't lean on it.\n"; + state = ERROR; + } + + restart_server = extract_int(argbuf, 0); + new_state -= 2; + } if ((new_state == 0) || (new_state == 1)) { ScheduledShutdown = new_state; } - cprintf("%d %d\n", CIT_OK, ScheduledShutdown); + cprintf(Reply, state, ScheduledShutdown); } @@ -838,10 +928,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); @@ -1237,7 +1327,7 @@ void do_command_loop(void) { } else if (!strncasecmp(cmdbuf,"DOWN",4)) { - cmd_down(); + cmd_down(&cmdbuf[5]); } else if (!strncasecmp(cmdbuf,"HALT",4)) {