75db7e88e0e6cd8d136fb29fc59465eac696007d
[citadel] / citadel / modules / ctdlproto / serv_syscmds.c
1
2 /* 
3  * Main source module for the Citadel server
4  *
5  * Copyright (c) 1987-2011 by the citadel.org team
6  *
7  * This program is open source software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License, version 3.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  */
15
16 #include "sysdep.h"
17 #include <stdlib.h>
18 #include <unistd.h>
19 #include <stdio.h>
20 #include <fcntl.h>
21 #include <signal.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24
25 #if TIME_WITH_SYS_TIME
26 # include <sys/time.h>
27 # include <time.h>
28 #else
29 # if HAVE_SYS_TIME_H
30 #  include <sys/time.h>
31 # else
32 #  include <time.h>
33 # endif
34 #endif
35
36 #if HAVE_BACKTRACE
37 #include <execinfo.h>
38 #endif
39
40 #include <ctype.h>
41 #include <string.h>
42 #include <errno.h>
43 #include <limits.h>
44 #include <netdb.h>
45 #include <sys/types.h>
46 #include <sys/socket.h>
47 #include <netinet/in.h>
48 #include <arpa/inet.h>
49 #include <libcitadel.h>
50 #include "citadel.h"
51 #include "server.h"
52 #include "sysdep_decls.h"
53 #include "threads.h"
54 #include "citserver.h"
55 #include "config.h"
56 #include "database.h"
57 #include "housekeeping.h"
58 #include "user_ops.h"
59 #include "msgbase.h"
60 #include "support.h"
61 #include "locate_host.h"
62 #include "room_ops.h"
63 #include "control.h"
64 #include "euidindex.h"
65 #include "context.h"
66 #include "svn_revision.h"
67 #include "ctdl_module.h"
68
69 void cmd_log_get(char *argbuf)
70 {
71         long HKLen;
72         const char *ch;
73         HashPos *Pos;
74         void *vptr;
75
76         if (CtdlAccessCheck(ac_aide)) return;
77
78         cprintf("%d Log modules enabled:\n", LISTING_FOLLOWS);
79
80         Pos = GetNewHashPos(LogDebugEntryTable, 0);
81
82         while (GetNextHashPos(LogDebugEntryTable, Pos, &HKLen, &ch, &vptr)) {
83                 LogDebugEntry *E = (LogDebugEntry*)vptr;
84                 cprintf("%s|%d\n", ch, *E->LogP);
85         }
86         
87         DeleteHashPos(&Pos);
88         cprintf("000\n");
89 }
90 void cmd_log_set(char *argbuf)
91 {
92         void *vptr;
93         int lset;
94         int wlen;
95         char which[SIZ] = "";
96
97         if (CtdlAccessCheck(ac_aide)) return;
98
99         wlen = extract_token(which, argbuf, 0, '|', sizeof(which));
100         if (wlen < 0) wlen = 0;
101         lset = extract_int(argbuf, 1);
102         if (lset != 0) lset = 1;
103         if (GetHash(LogDebugEntryTable, which, wlen, &vptr) && 
104             (vptr != NULL))
105         {
106                 LogDebugEntry *E = (LogDebugEntry*)vptr;
107                 E->F(lset);
108                 cprintf("%d %s|%d\n", CIT_OK, which, lset);
109         }
110         else {
111                 cprintf("%d Log setting %s not known\n", 
112                         ERROR, which);
113         }
114 }
115
116
117 /*
118  * Shut down the server
119  */
120 void cmd_down(char *argbuf) {
121         char *Reply ="%d Shutting down server.  Goodbye.\n";
122
123         if (CtdlAccessCheck(ac_aide)) return;
124
125         if (!IsEmptyStr(argbuf))
126         {
127                 int state = CIT_OK;
128                 restart_server = extract_int(argbuf, 0);
129                 
130                 if (restart_server > 0)
131                 {
132                         Reply = "%d citserver will now shut down and automatically restart.\n";
133                 }
134                 if ((restart_server > 0) && !running_as_daemon)
135                 {
136                         syslog(LOG_ERR, "The user requested restart, but not running as daemon! Geronimooooooo!\n");
137                         Reply = "%d Warning: citserver is not running in daemon mode and is therefore unlikely to restart automatically.\n";
138                         state = ERROR;
139                 }
140                 cprintf(Reply, state);
141         }
142         else
143         {
144                 cprintf(Reply, CIT_OK + SERVER_SHUTTING_DOWN); 
145         }
146         CC->kill_me = KILLME_SERVER_SHUTTING_DOWN;
147         server_shutting_down = 1;
148 }
149
150
151 /*
152  * Halt the server without exiting the server process.
153  */
154 void cmd_halt(char *argbuf) {
155
156         if (CtdlAccessCheck(ac_aide)) return;
157
158         cprintf("%d Halting server.  Goodbye.\n", CIT_OK);
159         server_shutting_down = 1;
160         shutdown_and_halt = 1;
161 }
162
163
164 /*
165  * Schedule or cancel a server shutdown
166  */
167 void cmd_scdn(char *argbuf)
168 {
169         int new_state;
170         int state = CIT_OK;
171         char *Reply = "%d %d\n";
172
173         if (CtdlAccessCheck(ac_aide)) return;
174
175         new_state = extract_int(argbuf, 0);
176         if ((new_state == 2) || (new_state == 3))
177         {
178                 restart_server = 1;
179                 if (!running_as_daemon)
180                 {
181                         syslog(LOG_ERR, "The user requested restart, but not running as deamon! Geronimooooooo!\n");
182                         Reply = "%d %d Warning, not running in deamon mode. maybe we will come up again, but don't lean on it.\n";
183                         state = ERROR;
184                 }
185
186                 restart_server = extract_int(argbuf, 0);
187                 new_state -= 2;
188         }
189         if ((new_state == 0) || (new_state == 1)) {
190                 ScheduledShutdown = new_state;
191         }
192         cprintf(Reply, state, ScheduledShutdown);
193 }
194
195
196 /*****************************************************************************/
197 /*                      MODULE INITIALIZATION STUFF                          */
198 /*****************************************************************************/
199
200 CTDL_MODULE_INIT(syscmd)
201 {
202         if (!threading) {
203                 CtdlRegisterProtoHook(cmd_log_get, "LOGP", "Print Log-parameters");
204                 CtdlRegisterProtoHook(cmd_log_set, "LOGS", "Set Log-parameters");
205
206                 CtdlRegisterProtoHook(cmd_down, "DOWN", "perform a server shutdown");
207                 CtdlRegisterProtoHook(cmd_halt, "HALT", "halt the server without exiting the server process");
208                 CtdlRegisterProtoHook(cmd_scdn, "SCDN", "schedule or cancel a server shutdown");
209         }
210         /* return our id for the Log */
211         return "syscmd";
212 }