* $Id$
*
* Citadel "system dependent" stuff.
- * See copyright.txt for copyright information.
+ * See COPYING for copyright information.
*
* Here's where we (hopefully) have most parts of the Citadel server that
* would need to be altered to run the server in a non-POSIX environment.
int enable_syslog = 0;
+/* Flag for single user mode */
+static int want_single_user = 0;
+
+/* Try to go single user */
+
+int CtdlTrySingleUser(void)
+{
+ int can_do = 0;
+
+ begin_critical_section(S_SINGLE_USER);
+ if (want_single_user)
+ can_do = 0;
+ else
+ {
+ can_do = 1;
+ want_single_user = 1;
+ }
+ end_critical_section(S_SINGLE_USER);
+ return can_do;
+}
+
+void CtdlEndSingleUser(void)
+{
+ begin_critical_section(S_SINGLE_USER);
+ want_single_user = 0;
+ end_critical_section(S_SINGLE_USER);
+}
+
+
+int CtdlWantSingleUser(void)
+{
+ return want_single_user;
+}
+
+int CtdlIsSingleUser(void)
+{
+ if (want_single_user)
+ {
+ /* check for only one context here */
+ if (num_sessions == 1)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
/*
* CtdlLogPrintf() ... Write logging information
*/
if (actual_queue_len < 5) actual_queue_len = 5;
i = unlink(sockpath);
- if (i != 0) if (errno != ENOENT) {
+ if ((i != 0) && (errno != ENOENT)) {
*errormessage = (char*) malloc(SIZ + 1);
snprintf(*errormessage, SIZ, "citserver: can't unlink %s: %s",
sockpath, strerror(errno));
}
/*
- * The following functions implement output buffering. If the kernel supplies
- * native TCP buffering (Linux & *BSD), use that; otherwise, emulate it with
- * user-space buffering.
+ * The following functions implement output buffering on operating systems which
+ * support it (such as Linux and various BSD flavors).
*/
#ifndef HAVE_DARWIN
#ifdef TCP_CORK
#endif /* TCP_CORK */
#endif /* HAVE_DARWIN */
-#ifdef HAVE_TCP_BUFFERING
static unsigned on = 1, off = 0;
-void buffer_output(void) {
- struct CitContext *ctx = MyContext();
- setsockopt(ctx->client_socket, IPPROTO_TCP, TCP_CORK, &on, 4);
- ctx->buffering = 1;
-}
-
-void unbuffer_output(void) {
- struct CitContext *ctx = MyContext();
- setsockopt(ctx->client_socket, IPPROTO_TCP, TCP_CORK, &off, 4);
- ctx->buffering = 0;
-}
-void flush_output(void) {
- struct CitContext *ctx = MyContext();
- setsockopt(ctx->client_socket, IPPROTO_TCP, TCP_CORK, &off, 4);
- setsockopt(ctx->client_socket, IPPROTO_TCP, TCP_CORK, &on, 4);
-}
-#else
-#ifdef HAVE_DARWIN
-/* Stub functions for Darwin/OS X where TCP buffering isn't liked at all */
void buffer_output(void) {
- CC->buffering = 0;
+#ifdef HAVE_TCP_BUFFERING
+ setsockopt(CC->client_socket, IPPROTO_TCP, TCP_CORK, &on, 4);
+#endif
}
+
void unbuffer_output(void) {
- CC->buffering = 0;
-}
-void flush_output(void) {
-}
-#else
-void buffer_output(void) {
- if (CC->buffering == 0) {
- CC->buffering = 1;
- CC->buffer_len = 0;
- CC->output_buffer = malloc(SIZ);
- }
+#ifdef HAVE_TCP_BUFFERING
+ setsockopt(CC->client_socket, IPPROTO_TCP, TCP_CORK, &off, 4);
+#endif
}
void flush_output(void) {
- if (CC->buffering == 1) {
- client_write(CC->output_buffer, CC->buffer_len);
- CC->buffer_len = 0;
- }
-}
-
-void unbuffer_output(void) {
- if (CC->buffering == 1) {
- CC->buffering = 0;
- /* We don't call flush_output because we can't. */
- client_write(CC->output_buffer, CC->buffer_len);
- CC->buffer_len = 0;
- free(CC->output_buffer);
- CC->output_buffer = NULL;
- }
+#ifdef HAVE_TCP_BUFFERING
+ struct CitContext *CCC = CC;
+ setsockopt(CCC->client_socket, IPPROTO_TCP, TCP_CORK, &off, 4);
+ setsockopt(CCC->client_socket, IPPROTO_TCP, TCP_CORK, &on, 4);
+#endif
}
-#endif /* HAVE_DARWIN */
-#endif /* HAVE_TCP_BUFFERING */
return 0;
}
-#ifndef HAVE_TCP_BUFFERING
- /* If we're buffering for later, do that now. */
- if (Ctx->buffering) {
- old_buffer_len = Ctx->buffer_len;
- Ctx->buffer_len += nbytes;
- Ctx->output_buffer = realloc(Ctx->output_buffer, Ctx->buffer_len);
- memcpy(&Ctx->output_buffer[old_buffer_len], buf, nbytes);
- return 0;
- }
-#endif
-
- /* Ok, at this point we're not buffering. Go ahead and write. */
-
#ifdef HAVE_OPENSSL
if (Ctx->redirect_ssl) {
client_write_ssl(buf, nbytes);
/*
- * cprintf() ... Send formatted printable data to the client. It is
- * implemented in terms of client_write() but remains in
- * sysdep.c in case we port to somewhere without va_args...
+ * cprintf() Send formatted printable data to the client.
+ * Implemented in terms of client_write() so it's technically not sysdep...
*/
void cprintf(const char *format, ...) {
va_list arg_ptr;
- char buf[1024];
+ char buf[1024];
va_start(arg_ptr, format);
if (vsnprintf(buf, sizeof buf, format, arg_ptr) == -1)