* When saving a Task, if the status is COMPLETED then also set PERCENT-COMPLETE:100...
[citadel.git] / citadel / modules / upgrade / serv_upgrade.c
blob0b09d9f57675f3c896742487db278f0710774bc5
1 /*
2 * $Id$
4 * Transparently handle the upgrading of server data formats.
6 */
8 #include "sysdep.h"
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <stdio.h>
12 #include <fcntl.h>
13 #include <signal.h>
14 #include <pwd.h>
15 #include <errno.h>
16 #include <sys/types.h>
18 #if TIME_WITH_SYS_TIME
19 # include <sys/time.h>
20 # include <time.h>
21 #else
22 # if HAVE_SYS_TIME_H
23 # include <sys/time.h>
24 # else
25 # include <time.h>
26 # endif
27 #endif
29 #include <sys/wait.h>
30 #include <string.h>
31 #include <limits.h>
32 #include <libcitadel.h>
33 #include "citadel.h"
34 #include "server.h"
35 #include "citserver.h"
36 #include "support.h"
37 #include "config.h"
38 #include "control.h"
39 #include "database.h"
40 #include "room_ops.h"
41 #include "user_ops.h"
42 #include "msgbase.h"
43 #include "serv_upgrade.h"
44 #include "euidindex.h"
47 #include "ctdl_module.h"
52 * Fix up the name for Citadel user 0 and try to remove any extra users with number 0
54 void fix_sys_user_name(void)
56 struct ctdluser usbuf;
57 char usernamekey[USERNAME_SIZE];
59 /** If we have a user called Citadel rename them to SYS_Citadel */
60 if (getuser(&usbuf, "Citadel") == 0)
62 rename_user("Citadel", "SYS_Citadel");
65 while (getuserbynumber(&usbuf, 0) == 0)
67 /* delete user with number 0 and no name */
68 if (IsEmptyStr(usbuf.fullname))
69 cdb_delete(CDB_USERS, "", 0);
70 else
71 { /* temporarily set this user to -1 */
72 usbuf.usernum = -1;
73 putuser(&usbuf);
77 /** Make sure user SYS_* is user 0 */
78 while (getuserbynumber(&usbuf, -1) == 0)
80 if (strncmp(usbuf.fullname, "SYS_", 4))
81 { /** Delete any user 0 that doesn't start with SYS_ */
82 makeuserkey(usernamekey, usbuf.fullname);
83 cdb_delete(CDB_USERS, usernamekey, strlen(usernamekey));
85 else
87 usbuf.usernum = 0;
88 putuser(&usbuf);
94 /*
95 * Back end processing function for cmd_bmbx
97 void cmd_bmbx_backend(struct ctdlroom *qrbuf, void *data) {
98 static struct RoomProcList *rplist = NULL;
99 struct RoomProcList *ptr;
100 struct ctdlroom qr;
102 /* Lazy programming here. Call this function as a ForEachRoom backend
103 * in order to queue up the room names, or call it with a null room
104 * to make it do the processing.
106 if (qrbuf != NULL) {
107 ptr = (struct RoomProcList *)
108 malloc(sizeof (struct RoomProcList));
109 if (ptr == NULL) return;
111 safestrncpy(ptr->name, qrbuf->QRname, sizeof ptr->name);
112 ptr->next = rplist;
113 rplist = ptr;
114 return;
117 while (rplist != NULL) {
119 if (lgetroom(&qr, rplist->name) == 0) {
120 CtdlLogPrintf(CTDL_DEBUG, "Processing <%s>...\n", rplist->name);
121 if ( (qr.QRflags & QR_MAILBOX) == 0) {
122 CtdlLogPrintf(CTDL_DEBUG, " -- not a mailbox\n");
124 else {
126 qr.QRgen = time(NULL);
127 CtdlLogPrintf(CTDL_DEBUG, " -- fixed!\n");
129 lputroom(&qr);
132 ptr = rplist;
133 rplist = rplist->next;
134 free(ptr);
139 * quick fix to bump mailbox generation numbers
141 void bump_mailbox_generation_numbers(void) {
142 CtdlLogPrintf(CTDL_WARNING, "Applying security fix to mailbox rooms\n");
143 ForEachRoom(cmd_bmbx_backend, NULL);
144 cmd_bmbx_backend(NULL, NULL);
145 return;
150 * Back end processing function for convert_ctdluid_to_minusone()
152 void cbtm_backend(struct ctdluser *usbuf, void *data) {
153 static struct UserProcList *uplist = NULL;
154 struct UserProcList *ptr;
155 struct ctdluser us;
157 /* Lazy programming here. Call this function as a ForEachUser backend
158 * in order to queue up the room names, or call it with a null user
159 * to make it do the processing.
161 if (usbuf != NULL) {
162 ptr = (struct UserProcList *)
163 malloc(sizeof (struct UserProcList));
164 if (ptr == NULL) return;
166 safestrncpy(ptr->user, usbuf->fullname, sizeof ptr->user);
167 ptr->next = uplist;
168 uplist = ptr;
169 return;
172 while (uplist != NULL) {
174 if (lgetuser(&us, uplist->user) == 0) {
175 CtdlLogPrintf(CTDL_DEBUG, "Processing <%s>...\n", uplist->user);
176 if (us.uid == CTDLUID) {
177 us.uid = (-1);
179 lputuser(&us);
182 ptr = uplist;
183 uplist = uplist->next;
184 free(ptr);
189 * quick fix to change all CTDLUID users to (-1)
191 void convert_ctdluid_to_minusone(void) {
192 CtdlLogPrintf(CTDL_WARNING, "Applying uid changes\n");
193 ForEachUser(cbtm_backend, NULL);
194 cbtm_backend(NULL, NULL);
195 return;
200 * Attempt to guess the name of the time zone currently in use
201 * on the underlying host system.
203 void guess_time_zone(void) {
204 FILE *fp;
205 char buf[PATH_MAX];
207 fp = popen(file_guesstimezone, "r");
208 if (fp) {
209 if (fgets(buf, sizeof buf, fp) && (strlen(buf) > 2)) {
210 buf[strlen(buf)-1] = 0;
211 safestrncpy(config.c_default_cal_zone, buf, sizeof config.c_default_cal_zone);
212 CtdlLogPrintf(CTDL_INFO, "Configuring timezone: %s\n", config.c_default_cal_zone);
214 fclose(fp);
220 * Do various things to our configuration file
222 void update_config(void) {
223 get_config();
225 if (CitControl.version < 606) {
226 config.c_rfc822_strict_from = 0;
229 if (CitControl.version < 609) {
230 config.c_purge_hour = 3;
233 if (CitControl.version < 615) {
234 config.c_ldap_port = 389;
237 if (CitControl.version < 623) {
238 strcpy(config.c_ip_addr, "0.0.0.0");
241 if (CitControl.version < 650) {
242 config.c_enable_fulltext = 0;
245 if (CitControl.version < 652) {
246 config.c_auto_cull = 1;
249 if (CitControl.version < 725) {
250 config.c_xmpp_c2s_port = 5222;
251 config.c_xmpp_s2s_port = 5269;
254 if (IsEmptyStr(config.c_default_cal_zone)) {
255 guess_time_zone();
258 put_config();
264 void check_server_upgrades(void) {
266 get_control();
267 CtdlLogPrintf(CTDL_INFO, "Server-hosted upgrade level is %d.%02d\n",
268 (CitControl.version / 100),
269 (CitControl.version % 100) );
271 if (CitControl.version < REV_LEVEL) {
272 CtdlLogPrintf(CTDL_WARNING,
273 "Server hosted updates need to be processed at "
274 "this time. Please wait...\n");
276 else {
277 return;
280 update_config();
282 if ((CitControl.version > 000) && (CitControl.version < 555)) {
283 CtdlLogPrintf(CTDL_EMERG,
284 "Your data files are from a version of Citadel\n"
285 "that is too old to be upgraded. Sorry.\n");
286 exit(EXIT_FAILURE);
288 if ((CitControl.version > 000) && (CitControl.version < 591)) {
289 bump_mailbox_generation_numbers();
291 if ((CitControl.version > 000) && (CitControl.version < 608)) {
292 convert_ctdluid_to_minusone();
294 if ((CitControl.version > 000) && (CitControl.version < 659)) {
295 rebuild_euid_index();
297 if (CitControl.version < 735) {
298 fix_sys_user_name();
300 if (CitControl.version < 736) {
301 rebuild_usersbynumber();
303 CitControl.version = REV_LEVEL;
304 put_control();
308 CTDL_MODULE_UPGRADE(upgrade)
310 check_server_upgrades();
312 /* return our Subversion id for the Log */
313 return "$Id$";