Don't register commands twice, only register them before threading begins.
[citadel.git] / citadel / citserver.c
index df75a28a0d06c4f7c8e0d546d56134ef09ab1439..2f5f24690fa0b0277967e9344db044c48c9a3632 100644 (file)
@@ -3,6 +3,21 @@
  *
  * Main source module for the Citadel server
  *
+ * Copyright (c) 1987-2009 by the citadel.org team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  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.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #include "sysdep.h"
@@ -129,6 +144,7 @@ void master_startup(void) {
        unsigned int seed;
        FILE *urandom;
        struct ctdlroom qrbuf;
+       int rv;
        
        CtdlLogPrintf(CTDL_DEBUG, "master_startup() started\n");
        time(&server_startup_time);
@@ -143,27 +159,27 @@ void master_startup(void) {
        check_ref_counts();
 
        CtdlLogPrintf(CTDL_INFO, "Creating base rooms (if necessary)\n");
-       create_room(config.c_baseroom,  0, "", 0, 1, 0, VIEW_BBS);
-       create_room(AIDEROOM,           3, "", 0, 1, 0, VIEW_BBS);
-       create_room(SYSCONFIGROOM,      3, "", 0, 1, 0, VIEW_BBS);
-       create_room(config.c_twitroom,  0, "", 0, 1, 0, VIEW_BBS);
+       CtdlCreateRoom(config.c_baseroom,       0, "", 0, 1, 0, VIEW_BBS);
+       CtdlCreateRoom(AIDEROOM,                3, "", 0, 1, 0, VIEW_BBS);
+       CtdlCreateRoom(SYSCONFIGROOM,   3, "", 0, 1, 0, VIEW_BBS);
+       CtdlCreateRoom(config.c_twitroom,       0, "", 0, 1, 0, VIEW_BBS);
 
        /* The "Local System Configuration" room doesn't need to be visible */
-        if (lgetroom(&qrbuf, SYSCONFIGROOM) == 0) {
+        if (CtdlGetRoomLock(&qrbuf, SYSCONFIGROOM) == 0) {
                 qrbuf.QRflags2 |= QR2_SYSTEM;
-                lputroom(&qrbuf);
+                CtdlPutRoomLock(&qrbuf);
         }
 
        /* Aide needs to be public postable, else we're not RFC conformant. */
-        if (lgetroom(&qrbuf, AIDEROOM) == 0) {
+        if (CtdlGetRoomLock(&qrbuf, AIDEROOM) == 0) {
                 qrbuf.QRflags2 |= QR2_SMTP_PUBLIC;
-                lputroom(&qrbuf);
+                CtdlPutRoomLock(&qrbuf);
         }
 
        CtdlLogPrintf(CTDL_INFO, "Seeding the pseudo-random number generator...\n");
        urandom = fopen("/dev/urandom", "r");
        if (urandom != NULL) {
-               fread(&seed, sizeof seed, 1, urandom);
+               rv = fread(&seed, sizeof seed, 1, urandom);
                fclose(urandom);
        }
        else {
@@ -966,6 +982,7 @@ void begin_session(struct CitContext *con)
        generate_nonce(con);
        safestrncpy(con->cs_host, config.c_fqdn, sizeof con->cs_host);
        safestrncpy(con->cs_addr, "", sizeof con->cs_addr);
+       con->cs_UDSclientUID = -1;
        con->cs_host[sizeof con->cs_host - 1] = 0;
        len = sizeof sin;
        if (!CC->is_local_socket) {
@@ -978,6 +995,34 @@ void begin_session(struct CitContext *con)
        }
        else {
                strcpy(con->cs_host, "");
+#ifdef HAVE_STRUCT_UCRED
+               {
+                       /* as http://www.wsinnovations.com/softeng/articles/uds.html told us... */
+                       struct ucred credentials;
+                       socklen_t ucred_length = sizeof(struct ucred);
+                       
+                       /*fill in the user data structure */
+                       if(getsockopt(con->client_socket, SOL_SOCKET, SO_PEERCRED, &credentials, &ucred_length)) {
+                               CtdlLogPrintf(CTDL_NOTICE, "could obtain credentials from unix domain socket");
+                               
+                       }
+                       else {          
+                               /* the process ID of the process on the other side of the socket */
+                               /* credentials.pid; */
+                               
+                               /* the effective UID of the process on the other side of the socket  */
+                               con->cs_UDSclientUID = credentials.uid;
+                               
+                               /* the effective primary GID of the process on the other side of the socket */
+                               /* credentials.gid; */
+                               
+                               /* To get supplemental groups, we will have to look them up in our account
+                                  database, after a reverse lookup on the UID to get the account name.
+                                  We can take this opportunity to check to see if this is a legit account.
+                               */
+                       }
+               }
+#endif
        }
        con->cs_flags = 0;
        con->upload_type = UPL_FILE;
@@ -1009,8 +1054,8 @@ void citproto_begin_session() {
                CC->kill_me = 1;
        }
        else {
-               cprintf("%d %s Citadel server ready.\n",
-                       CIT_OK, config.c_nodename);
+               cprintf("%d %s Citadel server ready.\n", CIT_OK, config.c_nodename);
+               CC->can_receive_im = 1;
        }
 }
 
@@ -1123,23 +1168,25 @@ void do_async_loop(void) {
 
 CTDL_MODULE_INIT(citserver)
 {
-       CtdlRegisterProtoHook(cmd_noop, "NOOP", "Autoconverted. TODO: document me.");
-       CtdlRegisterProtoHook(cmd_qnop, "QNOP", "Autoconverted. TODO: document me.");
-       CtdlRegisterProtoHook(cmd_quit, "QUIT", "Autoconverted. TODO: document me.");
-       CtdlRegisterProtoHook(cmd_lout, "LOUT", "Autoconverted. TODO: document me.");
-       CtdlRegisterProtoHook(cmd_asyn, "ASYN", "Autoconverted. TODO: document me.");
-       CtdlRegisterProtoHook(cmd_info, "INFO", "Autoconverted. TODO: document me.");
-       CtdlRegisterProtoHook(cmd_mesg, "MESG", "Autoconverted. TODO: document me.");
-       CtdlRegisterProtoHook(cmd_emsg, "EMSG", "Autoconverted. TODO: document me.");
-       CtdlRegisterProtoHook(cmd_echo, "ECHO", "Autoconverted. TODO: document me.");
-       CtdlRegisterProtoHook(cmd_more, "MORE", "Autoconverted. TODO: document me.");
-       CtdlRegisterProtoHook(cmd_iden, "IDEN", "Autoconverted. TODO: document me.");
-       CtdlRegisterProtoHook(cmd_ipgm, "IPGM", "Autoconverted. TODO: document me.");
-       CtdlRegisterProtoHook(cmd_term, "TERM", "Autoconverted. TODO: document me.");
-       CtdlRegisterProtoHook(cmd_down, "DOWN", "Autoconverted. TODO: document me.");
-       CtdlRegisterProtoHook(cmd_halt, "HALT", "Autoconverted. TODO: document me.");
-       CtdlRegisterProtoHook(cmd_scdn, "SCDN", "Autoconverted. TODO: document me.");
-       CtdlRegisterProtoHook(cmd_time, "TIME", "Autoconverted. TODO: document me.");
+       if (!threading) {
+               CtdlRegisterProtoHook(cmd_noop, "NOOP", "Autoconverted. TODO: document me.");
+               CtdlRegisterProtoHook(cmd_qnop, "QNOP", "Autoconverted. TODO: document me.");
+               CtdlRegisterProtoHook(cmd_quit, "QUIT", "Autoconverted. TODO: document me.");
+               CtdlRegisterProtoHook(cmd_lout, "LOUT", "Autoconverted. TODO: document me.");
+               CtdlRegisterProtoHook(cmd_asyn, "ASYN", "Autoconverted. TODO: document me.");
+               CtdlRegisterProtoHook(cmd_info, "INFO", "Autoconverted. TODO: document me.");
+               CtdlRegisterProtoHook(cmd_mesg, "MESG", "Autoconverted. TODO: document me.");
+               CtdlRegisterProtoHook(cmd_emsg, "EMSG", "Autoconverted. TODO: document me.");
+               CtdlRegisterProtoHook(cmd_echo, "ECHO", "Autoconverted. TODO: document me.");
+               CtdlRegisterProtoHook(cmd_more, "MORE", "Autoconverted. TODO: document me.");
+               CtdlRegisterProtoHook(cmd_iden, "IDEN", "Autoconverted. TODO: document me.");
+               CtdlRegisterProtoHook(cmd_ipgm, "IPGM", "Autoconverted. TODO: document me.");
+               CtdlRegisterProtoHook(cmd_term, "TERM", "Autoconverted. TODO: document me.");
+               CtdlRegisterProtoHook(cmd_down, "DOWN", "Autoconverted. TODO: document me.");
+               CtdlRegisterProtoHook(cmd_halt, "HALT", "Autoconverted. TODO: document me.");
+               CtdlRegisterProtoHook(cmd_scdn, "SCDN", "Autoconverted. TODO: document me.");
+               CtdlRegisterProtoHook(cmd_time, "TIME", "Autoconverted. TODO: document me.");
+       }
         /* return our Subversion id for the Log */
        return "$Id$";
 }