That didn't work.
[citadel.git] / citadel / sysdep.c
index d634c5496a01a21dfac30edc6be95564ef9fd9ef..0170b4956bafe0770f93748797971dc1aae8c72b 100644 (file)
@@ -71,6 +71,9 @@
 
 #include "ctdl_module.h"
 #include "threads.h"
+#include "user_ops.h"
+#include "control.h"
+
 
 #ifdef DEBUG_MEMORY_LEAKS
 struct igheap {
@@ -96,6 +99,52 @@ int syslog_facility = LOG_DAEMON;
 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
  */
@@ -331,7 +380,7 @@ int ig_uds_server(char *sockpath, int queue_len, char **errormessage)
        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));
@@ -420,8 +469,12 @@ struct CitContext *CreateNewContext(void) {
                CtdlLogPrintf(CTDL_ALERT, "citserver: can't allocate memory!!\n");
                return NULL;
        }
-       memset(me, 0, sizeof(struct CitContext));
 
+       memset(me, 0, sizeof(struct CitContext));
+       
+       /* Give the contaxt a name. Hopefully makes it easier to track */
+       strcpy (me->user.fullname, "SYS_notauth");
+       
        /* The new context will be created already in the CON_EXECUTING state
         * in order to prevent another thread from grabbing it while it's
         * being set up.
@@ -463,6 +516,37 @@ struct CitContext *CtdlGetContextArray(int *count)
        return nptr;
 }
 
+
+
+/**
+ * This function fills in a context and its user field correctly
+ * Then creates/loads that user
+ */
+void CtdlFillSystemContext(struct CitContext *context, char *name)
+{
+       char sysname[USERNAME_SIZE];
+
+       memset(context, 0, sizeof(struct CitContext));
+       context->internal_pgm = 1;
+       context->cs_pid = 0;
+       strcpy (sysname, "SYS_");
+       strcat (sysname, name);
+       /* internal_create_user has the side effect of loading the user regardless of wether they
+        * already existed or needed to be created
+        */
+       internal_create_user (sysname, &(context->user), -1) ;
+       
+       /* Check to see if the system user needs upgrading */
+       if (context->user.usernum == 0)
+       {       /* old system user with number 0, upgrade it */
+               context->user.usernum = get_new_user_number();
+               CtdlLogPrintf(CTDL_DEBUG, "Upgrading system user \"%s\" from user number 0 to user number %d\n", context->user.fullname, context->user.usernum);
+               /* add user to the database */
+               putuser(&(context->user));
+               cdb_store(CDB_USERSBYNUMBER, &(context->user.usernum), sizeof(long), context->user.fullname, strlen(context->user.fullname)+1);
+       }
+}
+
 /*
  * The following functions implement output buffering. If the kernel supplies
  * native TCP buffering (Linux & *BSD), use that; otherwise, emulate it with
@@ -623,13 +707,12 @@ int client_write(char *buf, int 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)
@@ -1051,8 +1134,6 @@ void InitializeMasterCC(void) {
 
 
 
-
-
 /*
  * Bind a thread to a context.  (It's inline merely to speed things up.)
  */