#include <stdarg.h>
#include <syslog.h>
#include <grp.h>
+#ifdef __GNUC__
+#include <malloc.h>
+#endif
#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif
return ptr;
}
+char *tracked_strdup(const char *orig, char *tfile, int tline) {
+ char *s;
+
+ s = tracked_malloc( (strlen(orig)+1), tfile, tline);
+ if (s == NULL) return NULL;
+
+ strcpy(s, orig);
+ return s;
+}
void tracked_free(void *ptr) {
struct TheHeap *hptr, *freeme;
cprintf("%20s %5d\n",
hptr->h_file, hptr->h_line);
}
+#ifdef __GNUC__
+ malloc_stats();
+#endif
+
cprintf("000\n");
}
#endif
struct CitContext *CreateNewContext(void) {
struct CitContext *me;
- lprintf(9, "CreateNewContext: calling malloc()\n");
me = (struct CitContext *) mallok(sizeof(struct CitContext));
if (me == NULL) {
lprintf(1, "citserver: can't allocate memory!!\n");
struct CitContext *ptr;
lprintf(7, "Starting RemoveContext()\n");
- lprintf(9, "Session count before RemoveContext is %d\n",
- session_count());
if (con==NULL) {
lprintf(7, "WARNING: RemoveContext() called with null!\n");
return;
lprintf(7, "Closing socket %d\n", con->client_socket);
close(con->client_socket);
- lprintf(9, "Dereferencing session context\n");
if (ContextList==con) {
ContextList = ContextList->next;
}
}
}
- lprintf(9, "Freeing session context...\n");
phree(con);
- lprintf(9, "...done.\n");
end_critical_section(S_SESSION_TABLE);
-
- lprintf(9, "Session count after RemoveContext is %d\n",
- session_count());
-
lprintf(7, "Done with RemoveContext\n");
}
struct CitContext *ptr;
int TheCount = 0;
- lprintf(9, "session_count() starting\n");
begin_critical_section(S_SESSION_TABLE);
for (ptr = ContextList; ptr != NULL; ptr = ptr->next) {
++TheCount;
- lprintf(9, "Counted session %3d (%d)\n", ptr->cs_pid, TheCount);
}
end_critical_section(S_SESSION_TABLE);
- lprintf(9, "session_count() finishing\n");
return(TheCount);
}
struct CitContext *ptr;
THREAD killme = 0;
- lprintf(9, "kill_session() scanning for thread to cancel...\n");
begin_critical_section(S_SESSION_TABLE);
for (ptr = ContextList; ptr != NULL; ptr = ptr->next) {
if (ptr->cs_pid == session_to_kill) {
}
}
end_critical_section(S_SESSION_TABLE);
- lprintf(9, "kill_session() finished scanning.\n");
if (killme != 0) {
#ifdef HAVE_PTHREAD_CANCEL
- lprintf(9, "calling pthread_cancel()\n");
pthread_cancel(killme);
#else
pthread_kill(killme, SIGUSR1);
int alen; /* Data for master socket */
int ssock; /* Descriptor for master socket */
THREAD SessThread; /* Thread descriptor */
+ THREAD HousekeepingThread; /* Thread descriptor */
pthread_attr_t attr; /* Thread attributes */
struct CitContext *con; /* Temporary context pointer */
char tracefile[128]; /* Name of file to log traces to */
int a, i; /* General-purpose variables */
- char convbuf[128];
fd_set readfds;
struct timeval tv;
struct passwd *pw;
int drop_root_perms = 1;
+ char *moddir;
/* specify default port name and trace file */
strcpy(tracefile, "");
/* -x specifies the desired logging level */
else if (!strncmp(argv[a], "-x", 2)) {
- strcpy(convbuf, argv[a]);
- verbosity = atoi(&convbuf[2]);
+ verbosity = atoi(&argv[a][2]);
}
else if (!strncmp(argv[a], "-h", 2)) {
- strcpy(convbuf, argv[a]);
- strcpy(bbs_home_directory, &convbuf[2]);
+ safestrncpy(bbs_home_directory, &argv[a][2],
+ sizeof bbs_home_directory);
home_specified = 1;
}
+ else if (!strncmp(argv[a], "-f", 2)) {
+ do_defrag = 1;
+ }
+
/* -r tells the server not to drop root permissions. don't use
* this unless you know what you're doing. this should be
* removed in the next release if it proves unnecessary. */
/* any other parameter makes it crash and burn */
else {
- lprintf(1, "citserver: usage: ");
- lprintf(1, "citserver [-tTraceFile]");
- lprintf(1, " [-d] [-xLogLevel] [-hHomeDir]\n");
+ lprintf(1, "citserver: usage: "
+ "citserver [-tTraceFile] [-d] [-f]"
+ " [-xLogLevel] [-hHomeDir]\n");
exit(1);
}
}
/* Tell 'em who's in da house */
- lprintf(1, "Multithreaded message server for %s\n", CITADEL);
- lprintf(1, "Copyright (C) 1987-1999 by Art Cancro. ");
- lprintf(1, "All rights reserved.\n\n");
+ lprintf(1,
+"\nMultithreaded message server for Citadel/UX\n"
+"Copyright (C) 1987-1999 by the Citadel/UX development team.\n"
+"Citadel/UX is free software, covered by the GNU General Public License, and\n"
+"you are welcome to change it and/or distribute copies of it under certain\n"
+"conditions. There is absolutely no warranty for this software. Please\n"
+"read the 'COPYING.txt' file for details.\n\n");
/* Initialize... */
init_sysdep();
}
}
- lprintf(7, "Initializing loadable modules\n");
- DLoader_Init(BBSDIR "/modules");
- lprintf(9, "Modules done initializing.\n");
-
/*
* Do non system dependent startup functions.
*/
master_startup();
+ /*
+ * Load any server-side modules (plugins) available here.
+ */
+ lprintf(7, "Initializing loadable modules\n");
+ if ((moddir = malloc(strlen(bbs_home_directory) + 9)) != NULL) {
+ sprintf(moddir, "%s/modules", bbs_home_directory);
+ DLoader_Init(moddir);
+ free(moddir);
+ }
+
+ lprintf(7, "Starting housekeeper thread\n");
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ if (pthread_create(&HousekeepingThread, &attr,
+ (void* (*)(void*)) housekeeping_loop, NULL) != 0) {
+ lprintf(1, "Can't create housekeeping thead: %s\n",
+ strerror(errno));
+ }
+
/*
* Endless loop. Listen on the master socket. When a connection
* comes in, create a socket, a context, and a thread.
}
else {
lprintf(7, "citserver: Client socket %d\n", ssock);
- lprintf(9, "creating context\n");
con = CreateNewContext();
con->client_socket = ssock;
/* Set the SO_REUSEADDR socket option */
- lprintf(9, "setting socket options\n");
i = 1;
setsockopt(ssock, SOL_SOCKET, SO_REUSEADDR,
&i, sizeof(i));
/* set attributes for the new thread */
- lprintf(9, "setting thread attributes\n");
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,
PTHREAD_CREATE_DETACHED);
/* now create the thread */
- lprintf(9, "creating thread\n");
if (pthread_create(&SessThread, &attr,
(void* (*)(void*)) sd_context_loop,
con)
strerror(errno));
}
- /* detach the thread
- * (defunct -- now done at thread creation time)
- * if (pthread_detach(&SessThread) != 0) {
- * lprintf(1,
- * "citserver: can't detach thread: %s\n",
- * strerror(errno));
- * }
- */
- lprintf(9, "done!\n");
}
}
master_cleanup();