int ScheduledShutdown = 0;
int do_defrag = 0;
time_t server_startup_time;
+char pid_file_name[PATH_MAX];
/*
* Various things that need to be initialized at startup
unsigned int seed;
FILE *urandom;
struct ctdlroom qrbuf;
+ FILE *pidfile_fp;
lprintf(CTDL_DEBUG, "master_startup() started\n");
time(&server_startup_time);
+ /* pid file. If we go FSSTND this should end up in 'localstatedir' */
+ snprintf(pid_file_name, sizeof pid_file_name, "./citadel.pid");
+ pidfile_fp = fopen(pid_file_name, "w");
+ if (pidfile_fp != NULL) {
+ fprintf(pidfile_fp, "%d\n", (int)getpid());
+ fclose(pidfile_fp);
+ }
+
lprintf(CTDL_INFO, "Opening databases\n");
open_databases();
void master_cleanup(int exitcode) {
struct CleanupFunctionHook *fcn;
static int already_cleaning_up = 0;
- int i;
if (already_cleaning_up) while(1) sleep(1);
already_cleaning_up = 1;
lprintf(CTDL_NOTICE, "citserver: Exiting with status %d\n", exitcode);
fflush(stdout); fflush(stderr);
+ unlink(pid_file_name);
exit(exitcode);
}
-/*
- * Free any per-session data allocated by modules or whatever
- */
-void deallocate_user_data(struct CitContext *con)
-{
- struct CtdlSessData *ptr;
-
- begin_critical_section(S_SESSION_TABLE);
- while (con->FirstSessData != NULL) {
- lprintf(CTDL_DEBUG, "Deallocating user data symbol %ld\n",
- con->FirstSessData->sym_id);
- if (con->FirstSessData->sym_data != NULL)
- free(con->FirstSessData->sym_data);
- ptr = con->FirstSessData->next;
- free(con->FirstSessData);
- con->FirstSessData = ptr;
- }
- end_critical_section(S_SESSION_TABLE);
-}
-
-
-
/*
* Terminate a session and remove its context data structure.
*/
lprintf(CTDL_DEBUG, "Removing context for session %d\n", con->cs_pid);
begin_critical_section(S_SESSION_TABLE);
- if (con->prev) con->prev->next = con->next; else ContextList = con->next;
- if (con->next) con->next->prev = con->prev;
- --num_sessions;
+ if (con->prev) {
+ con->prev->next = con->next;
+ }
+ else {
+ ContextList = con->next;
+ }
+ if (con->next) {
+ con->next->prev = con->prev;
+ }
+ --num_sessions;
end_critical_section(S_SESSION_TABLE);
/* Run any cleanup routines registered by loadable modules.
- * Note 1: This must occur *before* deallocate_user_data() because the
- * cleanup functions might touch dynamic session data.
- * Note 2: We have to "become_session()" because the cleanup functions
- * might make references to "CC" assuming it's the right one.
+ * Note: We have to "become_session()" because the cleanup functions
+ * might make references to "CC" assuming it's the right one.
*/
become_session(con);
PerformSessionHooks(EVT_STOP);
unlink(con->temp);
lprintf(CTDL_NOTICE, "[%3d] Session ended.\n", con->cs_pid);
- /* Deallocate any user-data attached to this session */
- deallocate_user_data(con);
-
/* If the client is still connected, blow 'em away. */
lprintf(CTDL_DEBUG, "Closing socket %d\n", con->client_socket);
close(con->client_socket);
-/*
- * Return a pointer to some generic per-session user data.
- * (This function returns NULL if the requested symbol is not allocated.)
- *
- * NOTE: we use critical sections for allocating and de-allocating these,
- * but not for locating one.
- */
-void *CtdlGetUserData(unsigned long requested_sym)
-{
- struct CtdlSessData *ptr;
-
- for (ptr = CC->FirstSessData; ptr != NULL; ptr = ptr->next)
- if (ptr->sym_id == requested_sym)
- return(ptr->sym_data);
-
- lprintf(CTDL_ERR, "ERROR! CtdlGetUserData(%ld) symbol not allocated\n",
- requested_sym);
- return NULL;
-}
-
-
-/*
- * Allocate some generic per-session user data.
- */
-void CtdlAllocUserData(unsigned long requested_sym, size_t num_bytes)
-{
- struct CtdlSessData *ptr;
-
- lprintf(CTDL_DEBUG, "CtdlAllocUserData(%ld) called\n", requested_sym);
-
- /* Fail silently if the symbol is already registered. */
- for (ptr = CC->FirstSessData; ptr != NULL; ptr = ptr->next) {
- if (ptr->sym_id == requested_sym) {
- return;
- }
- }
-
- /* Grab us some memory! Dem's good eatin' !! */
- ptr = malloc(sizeof(struct CtdlSessData));
- ptr->sym_id = requested_sym;
- ptr->sym_data = malloc(num_bytes);
- memset(ptr->sym_data, 0, num_bytes);
-
- begin_critical_section(S_SESSION_TABLE);
- ptr->next = CC->FirstSessData;
- CC->FirstSessData = ptr;
- end_critical_section(S_SESSION_TABLE);
-
- lprintf(CTDL_DEBUG, "CtdlAllocUserData(%ld) finished\n", requested_sym);
-}
-
-
-/*
- * Change the size of a buffer allocated with CtdlAllocUserData()
- */
-void CtdlReallocUserData(unsigned long requested_sym, size_t num_bytes)
-{
- struct CtdlSessData *ptr;
-
- for (ptr = CC->FirstSessData; ptr != NULL; ptr = ptr->next) {
- if (ptr->sym_id == requested_sym) {
- ptr->sym_data = realloc(ptr->sym_data, num_bytes);
- return;
- }
- }
-
- lprintf(CTDL_ERR, "CtdlReallocUserData() ERROR: symbol %ld not found!\n",
- requested_sym);
-}
-
-
-
-
-
-
/*
* cmd_info() - tell the client about this server
*/
*/
if (!CC->is_local_socket) {
sleep(5);
- cprintf("%d Authentication failed.\n", ERROR + PASSWORD_REQUIRED);
+ cprintf("%d Authentication failed.\n",
+ ERROR + PASSWORD_REQUIRED);
}
else if (secret == config.c_ipgm_secret) {
CC->internal_pgm = 1;
}
else {
sleep(5);
- cprintf("%d Authentication failed.\n", ERROR + PASSWORD_REQUIRED);
+ cprintf("%d Authentication failed.\n",
+ ERROR + PASSWORD_REQUIRED);
lprintf(CTDL_ERR, "Warning: ipgm authentication failed.\n");
CC->kill_me = 1;
}
- /* Now change the ipgm secret for the next round. */
+ /* Now change the ipgm secret for the next round.
+ * (Disabled because it breaks concurrent scripts. The fact that
+ * we no longer accept IPGM over the network should be sufficient
+ * to prevent brute-force attacks. If you don't agree, uncomment
+ * this block.)
get_config();
config.c_ipgm_secret = rand();
put_config();
+ */
}
con->cs_flags = 0;
con->upload_type = UPL_FILE;
con->dl_is_net = 0;
- con->FirstSessData = NULL;
con->nologin = 0;
if ((config.c_maxsessions > 0)&&(num_sessions > config.c_maxsessions))
CC->kill_me = 1;
return;
}
- lprintf(CTDL_INFO, "Citadel: %s\n", cmdbuf);
+
+ /* Log the server command, but don't show passwords... */
+ if ( (strncasecmp(cmdbuf, "PASS", 4))
+ && (strncasecmp(cmdbuf, "SETP", 4)) ) {
+ lprintf(CTDL_INFO, "%s\n", cmdbuf);
+ }
+ else {
+ lprintf(CTDL_INFO, "<password command sent>\n");
+ }
buffer_output();