X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fserver_main.c;h=9da255b50f1a8a54cb706122820b4b94e498aa56;hb=51ef89b985072d0bfe423c34575c8851aa16a606;hp=3fb00e3c706b54caa96bbcd09ed88177b9f56dce;hpb=99778f1c3e0ad36441cc2b03885c1bccc949e1ee;p=citadel.git diff --git a/citadel/server_main.c b/citadel/server_main.c index 3fb00e3c7..9da255b50 100644 --- a/citadel/server_main.c +++ b/citadel/server_main.c @@ -1,204 +1,198 @@ /* * citserver's main() function lives here. + * + * Copyright (c) 1987-2014 by the citadel.org team * - * $Id$ + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ - -#include "sysdep.h" -#include -#include #include -#include -#include -#include #include -#include -#include -#include -#include - -#if TIME_WITH_SYS_TIME -# include -# include -#else -# if HAVE_SYS_TIME_H -# include -# else -# include -# endif -#endif - -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#ifdef HAVE_PTHREAD_H -#include -#endif -#ifdef HAVE_SYS_PRCTL_H -#include -#endif -#include "citadel.h" -#include "server.h" -#include "serv_extensions.h" -#include "sysdep_decls.h" +#include + #include "citserver.h" -#include "support.h" +#include "svn_revision.h" +#include "modules_init.h" #include "config.h" #include "control.h" -#include "database.h" -#include "housekeeping.h" -#include "tools.h" -#include "citadel_dirs.c" +#include "serv_extensions.h" +#include "citadel_dirs.h" +#include "user_ops.h" +#include "ecrash.h" + +const char *CitadelServiceUDS="citadel-UDS"; +const char *CitadelServiceTCP="citadel-TCP"; -#ifdef HAVE_SYS_SELECT_H -#include -#endif -#ifndef HAVE_SNPRINTF -#include "snprintf.h" -#endif -int running_as_daemon = 0; +void go_threading(void); /* * Here's where it all begins. */ int main(int argc, char **argv) { + size_t basesize = 64; char facility[32]; - int a, i; /* General-purpose variables */ - struct passwd *pw; + int a; /* General-purpose variables */ + struct passwd pw, *pwp = NULL; + char pwbuf[SIZ]; int drop_root_perms = 1; - size_t size; int relh=0; int home=0; + int dbg=0; char relhome[PATH_MAX]=""; char ctdldir[PATH_MAX]=CTDLDIR; + int syslog_facility = LOG_DAEMON; + const char *eDebuglist[] = {NULL, NULL}; #ifdef HAVE_RUN_DIR struct stat filestats; #endif - +#ifdef HAVE_BACKTRACE + eCrashParameters params; +// eCrashSymbolTable symbol_table; +#endif + /* initialize the master context */ InitializeMasterCC(); + InitializeMasterTSD(); /* parse command-line arguments */ - for (a=1; apw_gid); - +#ifdef HAVE_GETPWUID_R +#ifdef SOLARIS_GETPWUID + pwp = getpwuid_r(config.c_ctdluid, &pw, pwbuf, sizeof(pwbuf)); +#else // SOLARIS_GETPWUID + getpwuid_r(config.c_ctdluid, &pw, pwbuf, sizeof(pwbuf), &pwp); +#endif // SOLARIS_GETPWUID +#else // HAVE_GETPWUID_R + pwp = NULL; +#endif // HAVE_GETPWUID_R + + if ((mkdir(ctdl_run_dir, 0755) != 0) && (errno != EEXIST)) + syslog(LOG_EMERG, + "unable to create run directory [%s]: %s", + ctdl_run_dir, strerror(errno)); + + if (chown(ctdl_run_dir, config.c_ctdluid, (pwp==NULL)?-1:pw.pw_gid) != 0) + syslog(LOG_EMERG, + "unable to set the access rights for [%s]: %s", + ctdl_run_dir, strerror(errno)); } @@ -213,13 +207,47 @@ int main(int argc, char **argv) master_startup(); /* - * Bind the server to a Unix-domain socket. + * Check that the control record is correct and place sensible values if it isn't + */ + check_control(); + + /* + * Run any upgrade entry points + */ + syslog(LOG_INFO, "Upgrading modules."); + upgrade_modules(); + +/* + * Load the user for the masterCC or create them if they don't exist + */ + if (CtdlGetUser(&masterCC.user, "SYS_Citadel")) + { + /* User doesn't exist. We can't use create user here as the user number needs to be 0 */ + strcpy (masterCC.user.fullname, "SYS_Citadel") ; + CtdlPutUser(&masterCC.user); + CtdlGetUser(&masterCC.user, "SYS_Citadel"); /* Just to be safe */ + } + + /* + * Bind the server to a Unix-domain socket (user client access) + */ + CtdlRegisterServiceHook(0, + file_citadel_socket, + citproto_begin_session, + do_command_loop, + do_async_loop, + CitadelServiceUDS); + + /* + * Bind the server to a Unix-domain socket (admin client access) */ CtdlRegisterServiceHook(0, - file_citadel_socket, - citproto_begin_session, - do_command_loop, - do_async_loop); + file_citadel_admin_socket, + citproto_begin_admin_session, + do_command_loop, + do_async_loop, + CitadelServiceUDS); + chmod(file_citadel_admin_socket, S_IRWXU); /* for your eyes only */ /* * Bind the server to our favorite TCP port (usually 504). @@ -228,33 +256,67 @@ int main(int argc, char **argv) NULL, citproto_begin_session, do_command_loop, - do_async_loop); + do_async_loop, + CitadelServiceTCP); + + + /* * Load any server-side extensions available here. */ - lprintf(CTDL_INFO, "Initializing server extensions\n"); - size = strlen(ctdl_home_directory) + 9; - initialize_server_extensions(); + syslog(LOG_INFO, "Initializing server extensions"); + + initialise_modules(0); + + eDebuglist[1] = getenv("CITADEL_LOGDEBUG"); + CtdlSetDebugLogFacilities(eDebuglist, 2); + + /* + * If we need host auth, start our chkpwd daemon. + */ + if (config.c_auth_mode == AUTHMODE_HOST) { + start_chkpwd_daemon(); + } + + + /* + * check, whether we're fired up another time after a crash. + * if, post an aide message, so the admin has a chance to react. + */ + checkcrash (); + /* * Now that we've bound the sockets, change to the Citadel user id and its * corresponding group ids */ if (drop_root_perms) { - if ((pw = getpwuid(CTDLUID)) == NULL) - lprintf(CTDL_CRIT, "WARNING: getpwuid(%ld): %s\n" + cdb_chmod_data(); /* make sure we own our data files */ + +#ifdef HAVE_GETPWUID_R +#ifdef SOLARIS_GETPWUID + pwp = getpwuid_r(config.c_ctdluid, &pw, pwbuf, sizeof(pwbuf)); +#else // SOLARIS_GETPWUID + getpwuid_r(config.c_ctdluid, &pw, pwbuf, sizeof(pwbuf), &pwp); +#endif // SOLARIS_GETPWUID +#else // HAVE_GETPWUID_R + pwp = NULL; +#endif // HAVE_GETPWUID_R + + if (pwp == NULL) + syslog(LOG_CRIT, "WARNING: getpwuid(%ld): %s" "Group IDs will be incorrect.\n", (long)CTDLUID, strerror(errno)); else { - initgroups(pw->pw_name, pw->pw_gid); - if (setgid(pw->pw_gid)) - lprintf(CTDL_CRIT, "setgid(%ld): %s\n", (long)pw->pw_gid, + initgroups(pw.pw_name, pw.pw_gid); + if (setgid(pw.pw_gid)) + syslog(LOG_CRIT, "setgid(%ld): %s", (long)pw.pw_gid, strerror(errno)); } - lprintf(CTDL_INFO, "Changing uid to %ld\n", (long)CTDLUID); + syslog(LOG_INFO, "Changing uid to %ld", (long)CTDLUID); if (setuid(CTDLUID) != 0) { - lprintf(CTDL_CRIT, "setuid() failed: %s\n", strerror(errno)); + syslog(LOG_CRIT, "setuid() failed: %s", strerror(errno)); } #if defined (HAVE_SYS_PRCTL_H) && defined (PR_SET_DUMPABLE) prctl(PR_SET_DUMPABLE, 1); @@ -262,28 +324,10 @@ int main(int argc, char **argv) } /* We want to check for idle sessions once per minute */ - CtdlRegisterSessionHook(terminate_idle_sessions, EVT_TIMER); + CtdlRegisterSessionHook(terminate_idle_sessions, EVT_TIMER, PRIO_CLEANUP + 1); - /* - * Now create a bunch of worker threads. - */ - lprintf(CTDL_DEBUG, "Starting %d worker threads\n", - config.c_min_workers-1); - begin_critical_section(S_WORKER_LIST); - for (i=0; i<(config.c_min_workers-1); ++i) { - create_worker(); - } - end_critical_section(S_WORKER_LIST); - - /* Create the indexer thread. */ - create_maintenance_threads(); - - /* This thread is now useless. It can't be turned into a worker - * thread because its stack is too small, but it can't be killed - * either because the whole server process would exit. So we just - * join to the first worker thread and exit when it exits. - */ - pthread_join(worker_list->tid, NULL); - master_cleanup(0); + go_threading(); + + master_cleanup(exit_signal); return(0); }