4 * Transparently handle the upgrading of server data formats.
16 #include <sys/types.h>
18 #if TIME_WITH_SYS_TIME
19 # include <sys/time.h>
23 # include <sys/time.h>
34 #include "sysdep_decls.h"
35 #include "citserver.h"
39 #include "serv_extensions.h"
45 #include "serv_upgrade.h"
47 void do_pre555_user_upgrade(void) {
48 struct pre555user usbuf;
50 struct cdbdata *cdbus;
51 char tempfilename[PATH_MAX];
53 static char vcard[1024];
55 lprintf(5, "Upgrading user file\n");
58 lprintf(1, "%s\n", strerror(errno));
61 strcpy(tempfilename, tmpnam(NULL));
63 /* First, back out all old version records to a flat file */
64 cdb_rewind(CDB_USERS);
65 while(cdbus = cdb_next_item(CDB_USERS), cdbus != NULL) {
66 memset(&usbuf, 0, sizeof(struct pre555user));
67 memcpy(&usbuf, cdbus->ptr,
68 ( (cdbus->len > sizeof(struct pre555user)) ?
69 sizeof(struct pre555user) : cdbus->len) );
71 fwrite(&usbuf, sizeof(struct pre555user), 1, fp);
74 /* ...and overwrite the records with new format records */
76 while (fread(&usbuf, sizeof(struct pre555user), 1, fp) > 0) {
77 if (strlen(usbuf.fullname) > 0) {
78 lprintf(9, "Upgrading <%s>\n", usbuf.fullname);
79 memset(&newus, 0, sizeof(struct user));
81 newus.uid = usbuf.USuid;
82 strcpy(newus.password, usbuf.password);
83 newus.flags = usbuf.flags;
84 newus.timescalled = (long) usbuf.timescalled;
85 newus.posted = (long) usbuf.posted;
86 newus.axlevel = (cit_uint8_t) usbuf.axlevel;
87 newus.usernum = (long) usbuf.usernum;
88 newus.lastcall = (long) usbuf.lastcall;
89 newus.USuserpurge = (int) usbuf.USuserpurge;
90 strcpy(newus.fullname, usbuf.fullname);
91 newus.USscreenwidth = (cit_uint8_t) usbuf.USscreenwidth;
92 newus.USscreenheight = (cit_uint8_t) usbuf.USscreenheight;
97 snprintf(vcard, sizeof vcard,
98 "Content-type: text/x-vcard\n\n"
102 "email;internet:%s\n"
103 "adr:;;%s;%s;%s;%s;USA\n"
113 tp = fopen(tempfilename, "w");
114 fwrite(vcard, strlen(vcard)+1, 1, tp);
117 CtdlWriteObject(USERCONFIGROOM, "text/x-vcard",
118 tempfilename, &newus, 0, 1, CM_SKIP_HOOKS);
119 unlink(tempfilename);
123 fclose(fp); /* this file deletes automatically */
134 * Back end processing function for cmd_bmbx
136 void cmd_bmbx_backend(struct room *qrbuf, void *data) {
137 static struct RoomProcList *rplist = NULL;
138 struct RoomProcList *ptr;
141 /* Lazy programming here. Call this function as a ForEachRoom backend
142 * in order to queue up the room names, or call it with a null room
143 * to make it do the processing.
146 ptr = (struct RoomProcList *)
147 mallok(sizeof (struct RoomProcList));
148 if (ptr == NULL) return;
150 safestrncpy(ptr->name, qrbuf->QRname, sizeof ptr->name);
156 while (rplist != NULL) {
158 if (lgetroom(&qr, rplist->name) == 0) {
159 lprintf(9, "Processing <%s>...\n", rplist->name);
160 if ( (qr.QRflags & QR_MAILBOX) == 0) {
161 lprintf(9, " -- not a mailbox\n");
165 qr.QRgen = time(NULL);
166 lprintf(9, " -- fixed!\n");
172 rplist = rplist->next;
178 * quick fix to bump mailbox generation numbers
180 void bump_mailbox_generation_numbers(void) {
181 lprintf(5, "Applying security fix to mailbox rooms\n");
182 ForEachRoom(cmd_bmbx_backend, NULL);
183 cmd_bmbx_backend(NULL, NULL);
189 * Back end processing function for convert_bbsuid_to_minusone()
191 void cbtm_backend(struct user *usbuf, void *data) {
192 static struct UserProcList *uplist = NULL;
193 struct UserProcList *ptr;
196 /* Lazy programming here. Call this function as a ForEachUser backend
197 * in order to queue up the room names, or call it with a null user
198 * to make it do the processing.
201 ptr = (struct UserProcList *)
202 mallok(sizeof (struct UserProcList));
203 if (ptr == NULL) return;
205 safestrncpy(ptr->user, usbuf->fullname, sizeof ptr->user);
211 while (uplist != NULL) {
213 if (lgetuser(&us, uplist->user) == 0) {
214 lprintf(9, "Processing <%s>...\n", uplist->user);
215 if (us.uid == BBSUID) {
222 uplist = uplist->next;
228 * quick fix to change all BBSUID users to (-1)
230 void convert_bbsuid_to_minusone(void) {
231 lprintf(5, "Applying uid changes\n");
232 ForEachUser(cbtm_backend, NULL);
233 cbtm_backend(NULL, NULL);
239 * This field was originally used for something else, so when we upgrade
240 * we have to initialize it to 0 in case there was trash in that space.
242 void initialize_c_rfc822_strict_from(void) {
244 config.c_rfc822_strict_from = 0;
251 void check_server_upgrades(void) {
254 lprintf(5, "Server-hosted upgrade level is %d.%02d\n",
255 (CitControl.version / 100),
256 (CitControl.version % 100) );
258 if (CitControl.version < REV_LEVEL) {
259 lprintf(5, "Server hosted updates need to be processed at "
260 "this time. Please wait...\n");
266 if (CitControl.version < 555) do_pre555_user_upgrade();
267 if (CitControl.version < 591) bump_mailbox_generation_numbers();
268 if (CitControl.version < 606) initialize_c_rfc822_strict_from();
269 if (CitControl.version < 608) convert_bbsuid_to_minusone();
271 CitControl.version = REV_LEVEL;
285 char *serv_upgrade_init(void)
287 check_server_upgrades();