From cf09c5cb779279f9ad24545e68414edc0340d6fa Mon Sep 17 00:00:00 2001 From: Wilfried Goesgens Date: Fri, 24 Jul 2015 12:32:35 +0200 Subject: [PATCH] Modularise msgbase - offer to not call the msg hooks (and set the preivous default in all places) - move the serialization of messages into own functions - split saving of messages and saving of new messages and make them use each other Fix import / export - don't use fingercount strlen(), CPP can do that way better. - properly de-serialize messages so we know they're good. - don't roll our own message saving facilities, use the common one (which then also does the big message data splitting) --- citadel/config.c | 2 +- citadel/euidindex.c | 2 +- .../autocompletion/serv_autocompletion.c | 2 +- citadel/modules/calendar/serv_calendar.c | 14 +- citadel/modules/ctdlproto/serv_messages.c | 6 +- citadel/modules/expire/serv_expire.c | 4 +- citadel/modules/extnotify/extnotify_main.c | 4 +- citadel/modules/fulltext/serv_fulltext.c | 2 +- citadel/modules/imap/imap_fetch.c | 8 +- citadel/modules/imap/imap_search.c | 32 +-- citadel/modules/inetcfg/serv_inetcfg.c | 2 +- citadel/modules/migrate/serv_migrate.c | 173 ++++++++-------- citadel/modules/network/serv_netmail.c | 2 +- citadel/modules/nntp/serv_nntp.c | 2 +- citadel/modules/sieve/serv_sieve.c | 6 +- citadel/modules/smtp/serv_smtp.c | 2 +- citadel/modules/smtp/serv_smtpqueue.c | 2 +- citadel/modules/vcard/serv_vcard.c | 10 +- citadel/modules/wiki/serv_wiki.c | 10 +- citadel/modules/xmpp/xmpp_presence.c | 2 +- citadel/msgbase.c | 185 +++++++++++------- citadel/msgbase.h | 10 +- citadel/utils/ctdlmigrate.c | 6 + 23 files changed, 272 insertions(+), 216 deletions(-) diff --git a/citadel/config.c b/citadel/config.c index 34028abb0..b2d27c8b6 100644 --- a/citadel/config.c +++ b/citadel/config.c @@ -320,7 +320,7 @@ char *CtdlGetSysConfig(char *sysconfname) { conf = NULL; } else { - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg != NULL) { conf = strdup(msg->cm_fields[eMesageText]); CM_Free(msg); diff --git a/citadel/euidindex.c b/citadel/euidindex.c index aa41d50dc..770c37c1a 100644 --- a/citadel/euidindex.c +++ b/citadel/euidindex.c @@ -127,7 +127,7 @@ void index_message_by_euid(char *euid, struct ctdlroom *qrbuf, long msgnum) { void rebuild_euid_index_for_msg(long msgnum, void *userdata) { struct CtdlMessage *msg = NULL; - msg = CtdlFetchMessage(msgnum, 0); + msg = CtdlFetchMessage(msgnum, 0, 1); if (msg == NULL) return; if (!CM_IsEmpty(msg, eExclusiveID)) { index_message_by_euid(msg->cm_fields[eExclusiveID], &CC->room, msgnum); diff --git a/citadel/modules/autocompletion/serv_autocompletion.c b/citadel/modules/autocompletion/serv_autocompletion.c index 00e190839..146cc292d 100644 --- a/citadel/modules/autocompletion/serv_autocompletion.c +++ b/citadel/modules/autocompletion/serv_autocompletion.c @@ -59,7 +59,7 @@ void hunt_for_autocomplete(long msgnum, char *search_string) { int i = 0; char *nnn = NULL; - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) return; v = vcard_load(msg->cm_fields[eMesageText]); diff --git a/citadel/modules/calendar/serv_calendar.c b/citadel/modules/calendar/serv_calendar.c index 1504fcc93..2fa2b6dd6 100644 --- a/citadel/modules/calendar/serv_calendar.c +++ b/citadel/modules/calendar/serv_calendar.c @@ -375,7 +375,7 @@ void ical_respond(long msgnum, char *partnum, char *action) { return; } - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) { cprintf("%d Message %ld not found.\n", ERROR + ILLEGAL_VALUE, @@ -636,7 +636,7 @@ int ical_update_my_calendar_with_reply(icalcomponent *cal) { * us the ability to load the event into memory so we can diddle the * attendees. */ - msg = CtdlFetchMessage(msgnum_being_replaced, 1); + msg = CtdlFetchMessage(msgnum_being_replaced, 1, 1); if (msg == NULL) { return(2); /* internal error */ } @@ -716,7 +716,7 @@ void ical_handle_rsvp(long msgnum, char *partnum, char *action) { return; } - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) { cprintf("%d Message %ld not found.\n", ERROR + ILLEGAL_VALUE, @@ -1154,7 +1154,7 @@ void ical_hunt_for_conflicts_backend(long msgnum, void *data) { proposed_event = (icalcomponent *)data; - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) return; memset(&ird, 0, sizeof ird); strcpy(ird.desired_partnum, "_HUNT_"); @@ -1215,7 +1215,7 @@ void ical_conflicts(long msgnum, char *partnum) { struct CtdlMessage *msg = NULL; struct ical_respond_data ird; - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) { cprintf("%d Message %ld not found\n", ERROR + ILLEGAL_VALUE, @@ -1402,7 +1402,7 @@ void ical_freebusy_backend(long msgnum, void *data) { fb = (icalcomponent *)data; /* User-supplied data will be the VFREEBUSY component */ - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) return; memset(&ird, 0, sizeof ird); strcpy(ird.desired_partnum, "_HUNT_"); @@ -1602,7 +1602,7 @@ void ical_getics_backend(long msgnum, void *data) { /* Look for the calendar event... */ - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) return; memset(&ird, 0, sizeof ird); strcpy(ird.desired_partnum, "_HUNT_"); diff --git a/citadel/modules/ctdlproto/serv_messages.c b/citadel/modules/ctdlproto/serv_messages.c index 2d3208a22..2bb50633f 100644 --- a/citadel/modules/ctdlproto/serv_messages.c +++ b/citadel/modules/ctdlproto/serv_messages.c @@ -42,7 +42,7 @@ void headers_listing(long msgnum, void *userdata) { struct CtdlMessage *msg; - msg = CtdlFetchMessage(msgnum, 0); + msg = CtdlFetchMessage(msgnum, 0, 1); if (msg == NULL) { cprintf("%ld|0|||||\n", msgnum); return; @@ -66,7 +66,7 @@ void headers_euid(long msgnum, void *userdata) { struct CtdlMessage *msg; - msg = CtdlFetchMessage(msgnum, 0); + msg = CtdlFetchMessage(msgnum, 0, 1); if (msg == NULL) { cprintf("%ld||\n", msgnum); return; @@ -228,7 +228,7 @@ void cmd_msg3(char *cmdbuf) } msgnum = extract_long(cmdbuf, 0); - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) { cprintf("%d Message %ld not found.\n", ERROR + MESSAGE_NOT_FOUND, msgnum); diff --git a/citadel/modules/expire/serv_expire.c b/citadel/modules/expire/serv_expire.c index 583b86dd5..398b8f680 100644 --- a/citadel/modules/expire/serv_expire.c +++ b/citadel/modules/expire/serv_expire.c @@ -197,7 +197,7 @@ void GatherPurgeMessages(struct ctdlroom *qrbuf, void *data) { for (a=0; acm_fields[eTimestamp]); CM_Free(msg); @@ -771,7 +771,7 @@ int PurgeEuidIndexTable(void) { memcpy(&msgnum, cdbei->ptr, sizeof(long)); - msg = CtdlFetchMessage(msgnum, 0); + msg = CtdlFetchMessage(msgnum, 0, 1); if (msg != NULL) { CM_Free(msg); /* it still exists, so do nothing */ } diff --git a/citadel/modules/extnotify/extnotify_main.c b/citadel/modules/extnotify/extnotify_main.c index 8eafc036a..9244a26fa 100644 --- a/citadel/modules/extnotify/extnotify_main.c +++ b/citadel/modules/extnotify/extnotify_main.c @@ -184,7 +184,7 @@ eNotifyType extNotify_getConfigMessage(char *username, return eNone; /* No messages at all? No further action. */ } for (a = 0; a < num_msgs; ++a) { - msg = CtdlFetchMessage(msglist[a], 1); + msg = CtdlFetchMessage(msglist[a], 1, 1); if (msg != NULL) { if (!CM_IsEmpty(msg, eMsgSubject) && (strncasecmp(msg->cm_fields[eMsgSubject], @@ -279,7 +279,7 @@ void process_notify(long NotifyMsgnum, void *usrdata) Ctx = (NotifyContext*) usrdata; - msg = CtdlFetchMessage(NotifyMsgnum, 1); + msg = CtdlFetchMessage(NotifyMsgnum, 1, 1); if (!CM_IsEmpty(msg, eExtnotify)) { Type = extNotify_getConfigMessage( diff --git a/citadel/modules/fulltext/serv_fulltext.c b/citadel/modules/fulltext/serv_fulltext.c index 6288bfc9a..4589859d4 100644 --- a/citadel/modules/fulltext/serv_fulltext.c +++ b/citadel/modules/fulltext/serv_fulltext.c @@ -120,7 +120,7 @@ void ft_index_message(long msgnum, int op) { int tok; struct CtdlMessage *msg = NULL; - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) { syslog(LOG_ERR, "ft_index_message() could not load msg %ld", msgnum); return; diff --git a/citadel/modules/imap/imap_fetch.c b/citadel/modules/imap/imap_fetch.c index 3f00d3f3f..7e4710607 100644 --- a/citadel/modules/imap/imap_fetch.c +++ b/citadel/modules/imap/imap_fetch.c @@ -710,7 +710,7 @@ void imap_fetch_body(long msgnum, ConstStr item, int is_peek) { if (Imap->cached_body == NULL) { CCC->redirect_buffer = NewStrBufPlain(NULL, SIZ); loading_body_now = 1; - msg = CtdlFetchMessage(msgnum, (need_body ? 1 : 0)); + msg = CtdlFetchMessage(msgnum, (need_body ? 1 : 0), 1); } /* Now figure out what the client wants, and get it */ @@ -1085,7 +1085,7 @@ void imap_do_fetch_msg(int seq, citimap_command *Cmd) { msg = NULL; } if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); body_loaded = 1; } imap_fetch_bodystructure(Imap->msgids[seq-1], @@ -1093,14 +1093,14 @@ void imap_do_fetch_msg(int seq, citimap_command *Cmd) { } else if (!strcasecmp(Cmd->Params[i].Key, "ENVELOPE")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 0); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 0, 1); body_loaded = 0; } imap_fetch_envelope(msg); } else if (!strcasecmp(Cmd->Params[i].Key, "INTERNALDATE")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 0); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 0, 1); body_loaded = 0; } imap_fetch_internaldate(msg); diff --git a/citadel/modules/imap/imap_search.c b/citadel/modules/imap/imap_search.c index cad499ceb..d5c5bfc35 100644 --- a/citadel/modules/imap/imap_search.c +++ b/citadel/modules/imap/imap_search.c @@ -121,7 +121,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "BCC")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -138,7 +138,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "BEFORE")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -164,7 +164,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, /* Otherwise, we have to do a slow search. */ else { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -179,7 +179,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "CC")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -225,7 +225,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "FROM")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -247,7 +247,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, * examining the message body. */ if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } @@ -277,7 +277,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "LARGER")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -304,7 +304,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "ON")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -334,7 +334,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "SENTBEFORE")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -350,7 +350,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "SENTON")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -366,7 +366,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "SENTSINCE")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -382,7 +382,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "SINCE")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -398,7 +398,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "SMALLER")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -411,7 +411,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "SUBJECT")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -424,7 +424,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "TEXT")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { @@ -439,7 +439,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, else if (!strcasecmp(itemlist[pos].Key, "TO")) { if (msg == NULL) { - msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1, 1); need_to_free_msg = 1; } if (msg != NULL) { diff --git a/citadel/modules/inetcfg/serv_inetcfg.c b/citadel/modules/inetcfg/serv_inetcfg.c index c37dd24fb..615a48b42 100644 --- a/citadel/modules/inetcfg/serv_inetcfg.c +++ b/citadel/modules/inetcfg/serv_inetcfg.c @@ -119,7 +119,7 @@ int inetcfg_aftersave(struct CtdlMessage *msg, recptypes *recp) { void inetcfg_init_backend(long msgnum, void *userdata) { struct CtdlMessage *msg; - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg != NULL) { inetcfg_setTo(msg); CM_Free(msg); diff --git a/citadel/modules/migrate/serv_migrate.c b/citadel/modules/migrate/serv_migrate.c index bb30479e2..d375da4a6 100644 --- a/citadel/modules/migrate/serv_migrate.c +++ b/citadel/modules/migrate/serv_migrate.c @@ -90,19 +90,19 @@ void xml_strout(char *str) { while (*c != 0) { if (*c == '\"') { - client_write(""", 6); + client_write(HKEY(""")); } else if (*c == '\'') { - client_write("'", 6); + client_write(HKEY("'")); } else if (*c == '<') { - client_write("<", 4); + client_write(HKEY("<")); } else if (*c == '>') { - client_write(">", 4); + client_write(HKEY(">")); } else if (*c == '&') { - client_write("&", 5); + client_write(HKEY("&")); } else { client_write(c, 1); @@ -116,10 +116,10 @@ void xml_strout(char *str) { * Export a user record as XML */ void migr_export_users_backend(struct ctdluser *buf, void *data) { - client_write("\n", 7); + client_write(HKEY("\n")); cprintf("%d\n", buf->version); cprintf("%ld\n", (long)buf->uid); - client_write("", 12); xml_strout(buf->password); client_write("\n", 14); + client_write(HKEY("")); xml_strout(buf->password); client_write(HKEY("\n")); cprintf("%u\n", buf->flags); cprintf("%ld\n", buf->timescalled); cprintf("%ld\n", buf->posted); @@ -127,8 +127,8 @@ void migr_export_users_backend(struct ctdluser *buf, void *data) { cprintf("%ld\n", buf->usernum); cprintf("%ld\n", (long)buf->lastcall); cprintf("%d\n", buf->USuserpurge); - client_write("", 12); xml_strout(buf->fullname); client_write("\n", 14); - client_write("\n", 8); + client_write(HKEY("")); xml_strout(buf->fullname); client_write(HKEY("\n")); + client_write(HKEY("\n")); } @@ -144,17 +144,17 @@ void migr_export_room_msg(long msgnum, void *userdata) { void migr_export_rooms_backend(struct ctdlroom *buf, void *data) { - client_write("\n", 7); - client_write("", 8); xml_strout(buf->QRname); client_write("\n", 10); - client_write("", 10); xml_strout(buf->QRpasswd); client_write("\n", 12); + client_write(HKEY("\n")); + client_write(HKEY("")); xml_strout(buf->QRname); client_write(HKEY("\n")); + client_write(HKEY("")); xml_strout(buf->QRpasswd); client_write(HKEY("\n")); cprintf("%ld\n", buf->QRroomaide); cprintf("%ld\n", buf->QRhighest); cprintf("%ld\n", (long)buf->QRgen); cprintf("%u\n", buf->QRflags); if (buf->QRflags & QR_DIRECTORY) { - client_write("", 11); + client_write(HKEY("")); xml_strout(buf->QRdirname); - client_write("\n", 13); + client_write(HKEY("\n")); } cprintf("%ld\n", buf->QRinfo); cprintf("%d\n", buf->QRfloor); @@ -165,17 +165,17 @@ void migr_export_rooms_backend(struct ctdlroom *buf, void *data) { cprintf("%d\n", buf->QRorder); cprintf("%u\n", buf->QRflags2); cprintf("%d\n", buf->QRdefaultview); - client_write("\n", 8); + client_write(HKEY("\n")); /* message list goes inside this tag */ CtdlGetRoom(&CC->room, buf->QRname); - client_write("", 15); - client_write("", 8); xml_strout(CC->room.QRname); client_write("\n", 10); - client_write("", 11); + client_write(HKEY("")); + client_write(HKEY("")); xml_strout(CC->room.QRname); client_write(HKEY("\n")); + client_write(HKEY("")); CtdlForEachMessage(MSGS_ALL, 0L, NULL, NULL, NULL, migr_export_room_msg, NULL); - client_write("\n", 13); - client_write("\n", 17); + client_write(HKEY("\n")); + client_write(HKEY("\n")); } @@ -220,16 +220,16 @@ void migr_export_floors(void) { int i; for (i=0; i < MAXFLOORS; ++i) { - client_write("\n", 8); + client_write(HKEY("\n")); cprintf("%d\n", i); CtdlGetFloor(&qfbuf, i); buf = &qfbuf; cprintf("%u\n", buf->f_flags); - client_write("", 8); xml_strout(buf->f_name); client_write("\n", 10); + client_write(HKEY("")); xml_strout(buf->f_name); client_write(HKEY("\n")); cprintf("%d\n", buf->f_ref_count); cprintf("%d\n", buf->f_ep.expire_mode); cprintf("%d\n", buf->f_ep.expire_value); - client_write("\n", 9); + client_write(HKEY("\n")); } } @@ -268,29 +268,29 @@ void migr_export_visits(void) { sizeof(visit) : cdbv->len)); cdb_free(cdbv); - client_write("\n", 8); + client_write(HKEY("\n")); cprintf("%ld\n", vbuf.v_roomnum); cprintf("%ld\n", vbuf.v_roomgen); cprintf("%ld\n", vbuf.v_usernum); - client_write("", 8); + client_write(HKEY("")); if ( (!IsEmptyStr(vbuf.v_seen)) && (is_sequence_set(vbuf.v_seen)) ) { xml_strout(vbuf.v_seen); } else { cprintf("%ld", vbuf.v_lastseen); } - client_write("", 9); + client_write(HKEY("")); if ( (!IsEmptyStr(vbuf.v_answered)) && (is_sequence_set(vbuf.v_answered)) ) { - client_write("", 12); + client_write(HKEY("")); xml_strout(vbuf.v_answered); - client_write("\n", 14); + client_write(HKEY("\n")); } cprintf("%u\n", vbuf.v_flags); cprintf("%d\n", vbuf.v_view); - client_write("\n", 9); + client_write(HKEY("\n")); } } @@ -319,16 +319,16 @@ void migr_export_message(long msgnum) { /* Ok, here we go ... */ - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 0); if (msg == NULL) return; /* fail silently */ - client_write("\n", 10); + client_write(HKEY("\n")); GetMetaData(&smi, msgnum); cprintf("%ld\n", msgnum); cprintf("%d\n", smi.meta_refcount); - client_write("", 23); xml_strout(smi.meta_content_type); client_write("\n", 25); + client_write(HKEY("")); xml_strout(smi.meta_content_type); client_write(HKEY("\n")); - client_write("", 10); + client_write(HKEY("")); CtdlSerializeMessage(&smr, msg); CM_Free(msg); @@ -351,8 +351,8 @@ void migr_export_message(long msgnum) { free(smr.ser); - client_write("\n", 12); - client_write("\n", 11); + client_write(HKEY("\n")); + client_write(HKEY("\n")); } @@ -365,14 +365,14 @@ void migr_export_openids(void) { cdb_rewind(CDB_OPENID); while (cdboi = cdb_next_item(CDB_OPENID), cdboi != NULL) { if (cdboi->len > sizeof(long)) { - client_write("\n", 9); + client_write(HKEY("\n")); memcpy(&usernum, cdboi->ptr, sizeof(long)); snprintf(url, sizeof url, "%s", (cdboi->ptr)+sizeof(long) ); - client_write("", 9); + client_write(HKEY("")); xml_strout(url); - client_write("\n", 11); + client_write(HKEY("\n")); cprintf("%ld\n", usernum); - client_write("\n", 10); + client_write(HKEY("\n")); } cdb_free(cdboi); } @@ -425,36 +425,36 @@ void migr_do_export(void) { cprintf("%d Exporting all Citadel databases.\n", LISTING_FOLLOWS); Ctx->dont_term = 1; - client_write("\n", 40); - client_write("\n", 23); + client_write(HKEY("\n")); + client_write(HKEY("\n")); cprintf("%d\n", REV_LEVEL); cprintf("%d\n", 0); /* export the config file (this is done using x-macros) */ - client_write("\n", 9); - client_write("", 12); xml_strout(config.c_nodename); client_write("\n", 14); - client_write("", 8); xml_strout(config.c_fqdn); client_write("\n", 10); - client_write("", 13); xml_strout(config.c_humannode); client_write("\n", 15); - client_write("", 12); xml_strout(config.c_phonenum); client_write("\n", 14); + client_write(HKEY("\n")); + client_write(HKEY("")); xml_strout(config.c_nodename); client_write(HKEY("\n")); + client_write(HKEY("")); xml_strout(config.c_fqdn); client_write(HKEY("\n")); + client_write(HKEY("")); xml_strout(config.c_humannode); client_write(HKEY("\n")); + client_write(HKEY("")); xml_strout(config.c_phonenum); client_write(HKEY("\n")); cprintf("%d\n", config.c_ctdluid); cprintf("%d\n", config.c_creataide); cprintf("%d\n", config.c_sleeping); cprintf("%d\n", config.c_initax); cprintf("%d\n", config.c_regiscall); cprintf("%d\n", config.c_twitdetect); - client_write("", 12); xml_strout(config.c_twitroom); client_write("\n", 14); - client_write("", 14); xml_strout(config.c_moreprompt); client_write("\n", 16); + client_write(HKEY("")); xml_strout(config.c_twitroom); client_write(HKEY("\n")); + client_write(HKEY("")); xml_strout(config.c_moreprompt); client_write(HKEY("\n")); cprintf("%d\n", config.c_restrict); - client_write("", 17); xml_strout(config.c_site_location); client_write("\n", 19); - client_write("", 10); xml_strout(config.c_sysadm); client_write("\n", 12); + client_write(HKEY("")); xml_strout(config.c_site_location); client_write(HKEY("\n")); + client_write(HKEY("")); xml_strout(config.c_sysadm); client_write(HKEY("\n")); cprintf("%d\n", config.c_maxsessions); - client_write("", 11); xml_strout(config.c_ip_addr); client_write("\n", 13); + client_write(HKEY("")); xml_strout(config.c_ip_addr); client_write(HKEY("\n")); cprintf("%d\n", config.c_port_number); cprintf("%d\n", config.c_ep.expire_mode); cprintf("%d\n", config.c_ep.expire_value); cprintf("%d\n", config.c_userpurge); cprintf("%d\n", config.c_roompurge); - client_write("", 12); xml_strout(config.c_logpages); client_write("\n", 14); + client_write(HKEY("")); xml_strout(config.c_logpages); client_write(HKEY("\n")); cprintf("%d\n", config.c_createax); cprintf("%ld\n", config.c_maxmsglen); cprintf("%d\n", config.c_min_workers); @@ -467,16 +467,16 @@ void migr_do_export(void) { cprintf("%ld\n", config.c_net_freq); cprintf("%d\n", config.c_disable_newu); cprintf("%d\n", config.c_enable_fulltext); - client_write("", 12); xml_strout(config.c_baseroom); client_write("\n", 14); - client_write("", 12); xml_strout(config.c_aideroom); client_write("\n", 14); + client_write(HKEY("")); xml_strout(config.c_baseroom); client_write(HKEY("\n")); + client_write(HKEY("")); xml_strout(config.c_aideroom); client_write(HKEY("\n")); cprintf("%d\n", config.c_purge_hour); cprintf("%d\n", config.c_mbxep.expire_mode); cprintf("%d\n", config.c_mbxep.expire_value); - client_write("", 13); xml_strout(config.c_ldap_host); client_write("\n", 15); + client_write(HKEY("")); xml_strout(config.c_ldap_host); client_write(HKEY("\n")); cprintf("%d\n", config.c_ldap_port); - client_write("", 16); xml_strout(config.c_ldap_base_dn); client_write("\n", 18); - client_write("", 16); xml_strout(config.c_ldap_bind_dn); client_write("\n", 18); - client_write("", 16); xml_strout(config.c_ldap_bind_pw); client_write("\n", 18); + client_write(HKEY("")); xml_strout(config.c_ldap_base_dn); client_write(HKEY("\n")); + client_write(HKEY("")); xml_strout(config.c_ldap_bind_dn); client_write(HKEY("\n")); + client_write(HKEY("")); xml_strout(config.c_ldap_bind_pw); client_write(HKEY("\n")); cprintf("%d\n", config.c_msa_port); cprintf("%d\n", config.c_imaps_port); cprintf("%d\n", config.c_pop3s_port); @@ -485,19 +485,19 @@ void migr_do_export(void) { cprintf("%d\n", config.c_allow_spoofing); cprintf("%d\n", config.c_journal_email); cprintf("%d\n", config.c_journal_pubmsgs); - client_write("", 16); xml_strout(config.c_journal_dest); client_write("\n", 18); - client_write("", 20); xml_strout(config.c_default_cal_zone); client_write("\n", 22); + client_write(HKEY("")); xml_strout(config.c_journal_dest); client_write(HKEY("\n")); + client_write(HKEY("")); xml_strout(config.c_default_cal_zone); client_write(HKEY("\n")); cprintf("%d\n", config.c_pftcpdict_port); cprintf("%d\n", config.c_managesieve_port); cprintf("%d\n", config.c_auth_mode); - client_write("", 17); xml_strout(config.c_funambol_host); client_write("\n", 19); + client_write(HKEY("")); xml_strout(config.c_funambol_host); client_write(HKEY("\n")); cprintf("%d\n", config.c_funambol_port); - client_write("", 19); xml_strout(config.c_funambol_source); client_write("\n", 21); - client_write("", 17); xml_strout(config.c_funambol_auth); client_write("\n", 19); + client_write(HKEY("")); xml_strout(config.c_funambol_source); client_write(HKEY("\n")); + client_write(HKEY("")); xml_strout(config.c_funambol_auth); client_write(HKEY("\n")); cprintf("%d\n", config.c_rbl_at_greeting); - client_write("", 15); xml_strout(config.c_master_user); client_write("\n", 17); - client_write("", 15); xml_strout(config.c_master_pass); client_write("\n", 17); - client_write("", 17); xml_strout(config.c_pager_program); client_write("\n", 19); + client_write(HKEY("")); xml_strout(config.c_master_user); client_write(HKEY("\n")); + client_write(HKEY("")); xml_strout(config.c_master_pass); client_write(HKEY("\n")); + client_write(HKEY("")); xml_strout(config.c_pager_program); client_write(HKEY("\n")); cprintf("%d\n", config.c_imap_keep_from); cprintf("%d\n", config.c_xmpp_c2s_port); cprintf("%d\n", config.c_xmpp_s2s_port); @@ -506,18 +506,18 @@ void migr_do_export(void) { cprintf("%d\n", config.c_spam_flag_only); cprintf("%d\n", config.c_nntp_port); cprintf("%d\n", config.c_nntps_port); - client_write("\n", 10); + client_write(HKEY("\n")); cprintf("%d\n", 1); /* Export the control file */ get_control(); - client_write("\n", 10); + client_write(HKEY("\n")); cprintf("%ld\n", CitControl.MMhighest); cprintf("%u\n", CitControl.MMflags); cprintf("%ld\n", CitControl.MMnextuser); cprintf("%ld\n", CitControl.MMnextroom); cprintf("%d\n", CitControl.version); - client_write("\n", 11); + client_write(HKEY("\n")); cprintf("%d\n", 2); if (Ctx->kill_me == 0) migr_export_users(); @@ -531,9 +531,9 @@ void migr_do_export(void) { if (Ctx->kill_me == 0) migr_export_visits(); cprintf("%d\n", 25); if (Ctx->kill_me == 0) migr_export_messages(); - client_write("\n", 24); + client_write(HKEY("\n")); cprintf("%d\n", 100); - client_write("000\n", 4); + client_write(HKEY("000\n")); Ctx->dont_term = 0; } @@ -937,21 +937,30 @@ void migr_xml_end(void *data, const char *el) else if (!strcasecmp(el, "msg_text")) { - - FlushStrBuf(migr_MsgData); - StrBufDecodeBase64To(migr_MsgData, migr_MsgData); - - cdb_store(CDB_MSGMAIN, - &import_msgnum, - sizeof(long), - ChrPtr(migr_MsgData), - StrLength(migr_MsgData) + 1); + long rc; + struct CtdlMessage *msg; smi.meta_msgnum = import_msgnum; - PutMetaData(&smi); + FlushStrBuf(migr_MsgData); + StrBufDecodeBase64To(migr_chardata, migr_MsgData); + + msg = CtdlDeserializeMessage(import_msgnum, -1, + ChrPtr(migr_MsgData), + StrLength(migr_MsgData)); + if (msg != NULL) { + rc = CtdlSaveThisMessage(msg, import_msgnum, 0); + if (rc > 0) { + PutMetaData(&smi); + } + CM_Free(msg); + } + else { + rc = -1; + } syslog(LOG_INFO, - "Imported message #%ld, size=%d, refcount=%d, content-type: %s\n", + "%s message #%ld, size=%d, refcount=%d, content-type: %s\n", + (rc!= 0)?"failed to import ":"Imported ", import_msgnum, StrLength(migr_MsgData), smi.meta_refcount, diff --git a/citadel/modules/network/serv_netmail.c b/citadel/modules/network/serv_netmail.c index c4038869f..10d957e71 100644 --- a/citadel/modules/network/serv_netmail.c +++ b/citadel/modules/network/serv_netmail.c @@ -595,7 +595,7 @@ void network_spool_msg(long msgnum, sc = (SpoolControl *)userdata; - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) { diff --git a/citadel/modules/nntp/serv_nntp.c b/citadel/modules/nntp/serv_nntp.c index b5b91db79..a89558198 100644 --- a/citadel/modules/nntp/serv_nntp.c +++ b/citadel/modules/nntp/serv_nntp.c @@ -977,7 +977,7 @@ void nntp_xover_backend(long msgnum, void *userdata) { if (msgnum < lr->lo) return; if ((lr->hi != 0) && (msgnum > lr->hi)) return; - struct CtdlMessage *msg = CtdlFetchMessage(msgnum, 0); + struct CtdlMessage *msg = CtdlFetchMessage(msgnum, 0, 1); if (msg == NULL) { return; } diff --git a/citadel/modules/sieve/serv_sieve.c b/citadel/modules/sieve/serv_sieve.c index ed69de858..a2523217f 100644 --- a/citadel/modules/sieve/serv_sieve.c +++ b/citadel/modules/sieve/serv_sieve.c @@ -124,7 +124,7 @@ int ctdl_redirect(sieve2_context_t *s, void *my) return SIEVE2_ERROR_BADARGS; } - msg = CtdlFetchMessage(cs->msgnum, 1); + msg = CtdlFetchMessage(cs->msgnum, 1, 1); if (msg == NULL) { SV_syslog(LOG_WARNING, "REDIRECT failed: unable to fetch msg %ld", cs->msgnum); free_recipients(valid); @@ -553,7 +553,7 @@ void sieve_do_msg(long msgnum, void *userdata) { /* * Make sure you include message body so you can get those second-level headers ;) */ - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) return; /* @@ -749,7 +749,7 @@ void get_sieve_config_backend(long msgnum, void *userdata) { long conflen; u->config_msgnum = msgnum; - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) { u->config_msgnum = (-1) ; return; diff --git a/citadel/modules/smtp/serv_smtp.c b/citadel/modules/smtp/serv_smtp.c index a93bb438e..2f9ea6532 100644 --- a/citadel/modules/smtp/serv_smtp.c +++ b/citadel/modules/smtp/serv_smtp.c @@ -318,7 +318,7 @@ void smtp_webcit_preferences_hack_backend(long msgnum, void *userdata) { return; // already got it } - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) { return; } diff --git a/citadel/modules/smtp/serv_smtpqueue.c b/citadel/modules/smtp/serv_smtpqueue.c index df04bdcc5..10496eac5 100644 --- a/citadel/modules/smtp/serv_smtpqueue.c +++ b/citadel/modules/smtp/serv_smtpqueue.c @@ -842,7 +842,7 @@ void smtp_do_procmsg(long msgnum, void *userdata) { SMTPC_syslog(LOG_DEBUG, "smtp_do_procmsg(%ld)\n", msgnum); ///strcpy(envelope_from, ""); - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) { SMTPC_syslog(LOG_ERR, "tried %ld but no such message!\n", msgnum); diff --git a/citadel/modules/vcard/serv_vcard.c b/citadel/modules/vcard/serv_vcard.c index 39820f776..202c806e9 100644 --- a/citadel/modules/vcard/serv_vcard.c +++ b/citadel/modules/vcard/serv_vcard.c @@ -185,7 +185,7 @@ int vcard_directory_add_user(char *internet_addr, char *citadel_addr) { void vcard_add_to_directory(long msgnum, void *data) { struct CtdlMessage *msg; - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg != NULL) { vcard_extract_internet_addresses(msg, vcard_directory_add_user); } @@ -653,7 +653,7 @@ struct vCard *vcard_get_user(struct ctdluser *u) { if (VCmsgnum < 0L) return vcard_new(); - msg = CtdlFetchMessage(VCmsgnum, 1); + msg = CtdlFetchMessage(VCmsgnum, 1, 1); if (msg == NULL) return vcard_new(); v = vcard_load(msg->cm_fields[eMesageText]); @@ -1010,7 +1010,7 @@ void vcard_delete_remove(char *room, long msgnum) { return; } - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) return; if (CM_IsEmpty(msg, eMesageText)) @@ -1137,7 +1137,7 @@ void dvca_mime_callback(char *name, char *filename, char *partnum, char *disp, void dvca_callback(long msgnum, void *userdata) { struct CtdlMessage *msg = NULL; - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) return; mime_parser(CM_RANGE(msg, eMesageText), *dvca_mime_callback, /* callback function */ @@ -1361,7 +1361,7 @@ void strip_addresses_already_have(long msgnum, void *userdata) { collected_addresses = (char *)userdata; - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) return; v = vcard_load(msg->cm_fields[eMesageText]); CM_Free(msg); diff --git a/citadel/modules/wiki/serv_wiki.c b/citadel/modules/wiki/serv_wiki.c index 79845fa8a..20a310398 100644 --- a/citadel/modules/wiki/serv_wiki.c +++ b/citadel/modules/wiki/serv_wiki.c @@ -127,7 +127,7 @@ int wiki_upload_beforesave(struct CtdlMessage *msg, recptypes *recp) { /* See if we can retrieve the previous version. */ old_msgnum = CtdlLocateMessageByEuid(msg->cm_fields[eExclusiveID], &CCC->room); if (old_msgnum > 0L) { - old_msg = CtdlFetchMessage(old_msgnum, 1); + old_msg = CtdlFetchMessage(old_msgnum, 1, 1); } else { old_msg = NULL; @@ -208,7 +208,7 @@ int wiki_upload_beforesave(struct CtdlMessage *msg, recptypes *recp) { history_msgnum = CtdlLocateMessageByEuid(history_page, &CCC->room); history_msg = NULL; if (history_msgnum > 0L) { - history_msg = CtdlFetchMessage(history_msgnum, 1); + history_msg = CtdlFetchMessage(history_msgnum, 1, 1); } /* Create a new history message if necessary */ @@ -390,7 +390,7 @@ void wiki_history(char *pagename) { snprintf(history_page_name, sizeof history_page_name, "%s_HISTORY_", pagename); msgnum = CtdlLocateMessageByEuid(history_page_name, &CC->room); if (msgnum > 0L) { - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); } else { msg = NULL; @@ -522,7 +522,7 @@ void wiki_rev(char *pagename, char *rev, char *operation) */ msgnum = CtdlLocateMessageByEuid(pagename, &CCC->room); if (msgnum > 0L) { - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); } else { msg = NULL; @@ -556,7 +556,7 @@ void wiki_rev(char *pagename, char *rev, char *operation) snprintf(history_page_name, sizeof history_page_name, "%s_HISTORY_", pagename); msgnum = CtdlLocateMessageByEuid(history_page_name, &CCC->room); if (msgnum > 0L) { - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); } else { msg = NULL; diff --git a/citadel/modules/xmpp/xmpp_presence.c b/citadel/modules/xmpp/xmpp_presence.c index d716d4b1a..85feda708 100644 --- a/citadel/modules/xmpp/xmpp_presence.c +++ b/citadel/modules/xmpp/xmpp_presence.c @@ -229,7 +229,7 @@ void xmpp_fetch_mortuary_backend(long msgnum, void *userdata) { char *ptr = NULL; char *lasts = NULL; - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) { return; } diff --git a/citadel/msgbase.c b/citadel/msgbase.c index ddc12aafd..bcbc21c0e 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -737,7 +737,7 @@ int CtdlForEachMessage(int mode, long ref, char *search_string, free(msglist); return -1; } - msg = CtdlFetchMessage(msglist[a], 1); + msg = CtdlFetchMessage(msglist[a], 1, 1); if (msg != NULL) { if (CtdlMsgCmp(msg, compare)) { msglist[a] = 0L; @@ -1083,33 +1083,18 @@ void mime_spew_section(char *name, char *filename, char *partnum, char *disp, } } - -/* - * Load a message from disk into memory. - * This is used by CtdlOutputMsg() and other fetch functions. - * - * NOTE: Caller is responsible for freeing the returned CtdlMessage struct - * using the CtdlMessageFree() function. - */ -struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body) +struct CtdlMessage *CtdlDeserializeMessage(long msgnum, int with_body, const char *Buffer, long Length) { struct CitContext *CCC = CC; - struct cdbdata *dmsgtext; struct CtdlMessage *ret = NULL; - char *mptr; - char *upper_bound; + const char *mptr; + const char *upper_bound; cit_uint8_t ch; cit_uint8_t field_header; eMsgField which; - MSG_syslog(LOG_DEBUG, "CtdlFetchMessage(%ld, %d)\n", msgnum, with_body); - dmsgtext = cdb_fetch(CDB_MSGMAIN, &msgnum, sizeof(long)); - if (dmsgtext == NULL) { - MSG_syslog(LOG_ERR, "CtdlFetchMessage(%ld, %d) Failed!\n", msgnum, with_body); - return NULL; - } - mptr = dmsgtext->ptr; - upper_bound = mptr + dmsgtext->len; + mptr = Buffer; + upper_bound = Buffer + Length; /* Parse the three bytes that begin EVERY message on disk. * The first is always 0xFF, the on-disk magic number. @@ -1119,7 +1104,6 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body) ch = *mptr++; if (ch != 255) { MSG_syslog(LOG_ERR, "Message %ld appears to be corrupted.\n", msgnum); - cdb_free(dmsgtext); return NULL; } ret = (struct CtdlMessage *) malloc(sizeof(struct CtdlMessage)); @@ -1129,13 +1113,6 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body) ret->cm_anon_type = *mptr++; /* Anon type byte */ ret->cm_format_type = *mptr++; /* Format type byte */ - - if (dmsgtext->ptr[dmsgtext->len - 1] != '\0') - { - MSG_syslog(LOG_ERR, "CtdlFetchMessage(%ld, %d) Forcefully terminating message!!\n", msgnum, with_body); - dmsgtext->ptr[dmsgtext->len - 1] = '\0'; - } - /* * The rest is zero or more arbitrary fields. Load them in. * We're done when we encounter either a zero-length field or @@ -1165,8 +1142,44 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body) } while ((mptr < upper_bound) && (field_header != 'M')); + return (ret); +} + + +/* + * Load a message from disk into memory. + * This is used by CtdlOutputMsg() and other fetch functions. + * + * NOTE: Caller is responsible for freeing the returned CtdlMessage struct + * using the CtdlMessageFree() function. + */ +struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body, int run_msg_hooks) +{ + struct CitContext *CCC = CC; + struct cdbdata *dmsgtext; + struct CtdlMessage *ret = NULL; + + MSG_syslog(LOG_DEBUG, "CtdlFetchMessage(%ld, %d)\n", msgnum, with_body); + dmsgtext = cdb_fetch(CDB_MSGMAIN, &msgnum, sizeof(long)); + if (dmsgtext == NULL) { + MSG_syslog(LOG_ERR, "CtdlFetchMessage(%ld, %d) Failed!\n", msgnum, with_body); + return NULL; + } + + if (dmsgtext->ptr[dmsgtext->len - 1] != '\0') + { + MSG_syslog(LOG_ERR, "CtdlFetchMessage(%ld, %d) Forcefully terminating message!!\n", msgnum, with_body); + dmsgtext->ptr[dmsgtext->len - 1] = '\0'; + } + + ret = CtdlDeserializeMessage(msgnum, with_body, dmsgtext->ptr, dmsgtext->len); + cdb_free(dmsgtext); + if (ret == NULL) { + return NULL; + } + /* Always make sure there's something in the msg text field. If * it's NULL, the message text is most likely stored separately, * so go ahead and fetch that. Failing that, just set a dummy @@ -1184,7 +1197,7 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body) } /* Perform "before read" hooks (aborting if any return nonzero) */ - if (PerformMessageHooks(ret, NULL, EVT_BEFOREREAD) > 0) { + if (run_msg_hooks && (PerformMessageHooks(ret, NULL, EVT_BEFOREREAD) > 0)) { CM_Free(ret); return NULL; } @@ -1584,10 +1597,10 @@ int CtdlOutputMsg(long msg_num, /* message number (local) to fetch */ * request that we don't even bother loading the body into memory. */ if (headers_only == HEADERS_FAST) { - TheMessage = CtdlFetchMessage(msg_num, 0); + TheMessage = CtdlFetchMessage(msg_num, 0, 1); } else { - TheMessage = CtdlFetchMessage(msg_num, 1); + TheMessage = CtdlFetchMessage(msg_num, 1, 1); } if (TheMessage == NULL) { @@ -2425,7 +2438,7 @@ int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newms msg = supplied_msg; } else { - msg = CtdlFetchMessage(msgid, 0); + msg = CtdlFetchMessage(msgid, 0, 1); } if (msg != NULL) { @@ -2491,75 +2504,101 @@ int CtdlSaveMsgPointerInRoom(char *roomname, long msgid, * called by server-side modules. * */ -long send_message(struct CtdlMessage *msg) { +long CtdlSaveThisMessage(struct CtdlMessage *msg, long msgid, int Reply) { struct CitContext *CCC = CC; - long newmsgid; long retval; - char msgidbuf[256]; - long msgidbuflen; struct ser_ret smr; int is_bigmsg = 0; char *holdM = NULL; long holdMLen = 0; - /* Get a new message number */ - newmsgid = get_new_message_number(); - msgidbuflen = snprintf(msgidbuf, sizeof msgidbuf, "%08lX-%08lX@%s", - (long unsigned int) time(NULL), - (long unsigned int) newmsgid, - config.c_fqdn - ); - - /* Generate an ID if we don't have one already */ - if (CM_IsEmpty(msg, emessageId)) { - CM_SetField(msg, emessageId, msgidbuf, msgidbuflen); - } - - /* If the message is big, set its body aside for storage elsewhere */ - if (!CM_IsEmpty(msg, eMesageText)) { - if (msg->cm_lengths[eMesageText] > BIGMSG) { - is_bigmsg = 1; - holdM = msg->cm_fields[eMesageText]; - msg->cm_fields[eMesageText] = NULL; - holdMLen = msg->cm_lengths[eMesageText]; - msg->cm_lengths[eMesageText] = 0; - } + /* + * If the message is big, set its body aside for storage elsewhere + * and we hide the message body from the serializer + */ + if (!CM_IsEmpty(msg, eMesageText) && msg->cm_lengths[eMesageText] > BIGMSG) + { + is_bigmsg = 1; + holdM = msg->cm_fields[eMesageText]; + msg->cm_fields[eMesageText] = NULL; + holdMLen = msg->cm_lengths[eMesageText]; + msg->cm_lengths[eMesageText] = 0; } /* Serialize our data structure for storage in the database */ CtdlSerializeMessage(&smr, msg); if (is_bigmsg) { + /* put the message body back into the message */ msg->cm_fields[eMesageText] = holdM; msg->cm_lengths[eMesageText] = holdMLen; } if (smr.len == 0) { - cprintf("%d Unable to serialize message\n", - ERROR + INTERNAL_ERROR); + if (Reply) { + cprintf("%d Unable to serialize message\n", + ERROR + INTERNAL_ERROR); + } + else { + MSGM_syslog(LOG_ERR, "CtdlSaveMessage() unable to serialize message"); + + } return (-1L); } /* Write our little bundle of joy into the message base */ - if (cdb_store(CDB_MSGMAIN, &newmsgid, (int)sizeof(long), - smr.ser, smr.len) < 0) { - MSGM_syslog(LOG_ERR, "Can't store message\n"); - retval = 0L; - } else { + retval = cdb_store(CDB_MSGMAIN, &msgid, (int)sizeof(long), + smr.ser, smr.len); + if (retval < 0) { + MSG_syslog(LOG_ERR, "Can't store message %ld: %ld", msgid, retval); + } + else { if (is_bigmsg) { - cdb_store(CDB_BIGMSGS, - &newmsgid, - (int)sizeof(long), - holdM, - (holdMLen + 1) + retval = cdb_store(CDB_BIGMSGS, + &msgid, + (int)sizeof(long), + holdM, + (holdMLen + 1) ); + if (retval < 0) { + MSG_syslog(LOG_ERR, "failed to store message body for msgid %ld: %ld", + msgid, retval); + } } - retval = newmsgid; } /* Free the memory we used for the serialized message */ free(smr.ser); + return(retval); +} + +long send_message(struct CtdlMessage *msg) { + long newmsgid; + long retval; + char msgidbuf[256]; + long msgidbuflen; + + /* Get a new message number */ + newmsgid = get_new_message_number(); + + /* Generate an ID if we don't have one already */ + if (CM_IsEmpty(msg, emessageId)) { + msgidbuflen = snprintf(msgidbuf, sizeof msgidbuf, "%08lX-%08lX@%s", + (long unsigned int) time(NULL), + (long unsigned int) newmsgid, + config.c_fqdn + ); + + CM_SetField(msg, emessageId, msgidbuf, msgidbuflen); + } + + retval = CtdlSaveThisMessage(msg, newmsgid, 1); + + if (retval == 0) { + retval = newmsgid; + } + /* Return the *local* message ID to the caller * (even if we're storing an incoming network message) */ @@ -2576,7 +2615,7 @@ long send_message(struct CtdlMessage *msg) { * serialized message in memory. THE LATTER MUST BE FREED BY THE CALLER. */ void CtdlSerializeMessage(struct ser_ret *ret, /* return values */ - struct CtdlMessage *msg) /* unserialized msg */ + struct CtdlMessage *msg) /* unserialized msg */ { struct CitContext *CCC = CC; size_t wlen; diff --git a/citadel/msgbase.h b/citadel/msgbase.h index 6d5f726ba..404ce6c5d 100644 --- a/citadel/msgbase.h +++ b/citadel/msgbase.h @@ -126,7 +126,7 @@ void CtdlWriteObject(char *req_room, /* Room to stuff it in */ int is_unique, /* Del others of this type? */ unsigned int flags /* Internal save flags */ ); -struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body); +struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body, int run_msg_hooks); struct CtdlMessage * CM_Duplicate (struct CtdlMessage *OrgMsg); int CM_IsEmpty (struct CtdlMessage *Msg, eMsgField which); @@ -150,10 +150,12 @@ int CM_IsValidMsg (struct CtdlMessage *msg); Message->cm_fields[Which] + Message->cm_lengths[Which] void CtdlSerializeMessage(struct ser_ret *, struct CtdlMessage *); +struct CtdlMessage *CtdlDeserializeMessage(long msgnum, int with_body, const char *Buffer, long Length); void ReplicationChecks(struct CtdlMessage *); int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newmsgs, - int do_repl_check, struct CtdlMessage *supplied_msg, int suppress_refcount_adj); + int do_repl_check, struct CtdlMessage *supplied_msg, int suppress_refcount_adj); int CtdlSaveMsgPointerInRoom(char *roomname, long msgid, int do_repl_check, struct CtdlMessage *msg); +long CtdlSaveThisMessage(struct CtdlMessage *msg, long msgid, int Reply); char *CtdlReadMessageBody(char *terminator, long tlen, size_t maxlen, StrBuf *exist, int crlf, int *sock); StrBuf *CtdlReadMessageBodyBuf(char *terminator, /* token signalling EOT */ long tlen, @@ -265,12 +267,12 @@ extern int MessageDebugEnabled; #define CCCID CCC->cs_pid #define MSG_syslog(LEVEL, FORMAT, ...) \ MSGDBGLOG(LEVEL) syslog(LEVEL, \ - "CC[%d]MSG" FORMAT, \ + "CC[%d]MSG " FORMAT, \ CCCID, __VA_ARGS__) #define MSGM_syslog(LEVEL, FORMAT) \ MSGDBGLOG(LEVEL) syslog(LEVEL, \ - "CC[%d]MSG" FORMAT, \ + "CC[%d]MSG " FORMAT, \ CCCID) diff --git a/citadel/utils/ctdlmigrate.c b/citadel/utils/ctdlmigrate.c index 5a5d0c474..baa5f6de7 100644 --- a/citadel/utils/ctdlmigrate.c +++ b/citadel/utils/ctdlmigrate.c @@ -137,10 +137,14 @@ int main(int argc, char *argv[]) "(example: ctdl.foo.org)\n" "--> "); getz(remote_host); + +get_remote_user: printf("\nEnter the name of a user on %s who has full access to Citadel files\n" "(usually root)\n--> ", remote_host); getz(remote_user); + if (IsEmptyStr(remote_user)) + goto get_remote_user; printf("\nEstablishing an SSH connection to the source system...\n\n"); unlink(socket_path); @@ -194,6 +198,8 @@ int main(int argc, char *argv[]) } printf("ctdlmigrate will now begin a database migration...\n"); + printf(" if the system doesn't start working, \n"); + printf(" have a look at the syslog for pending jobs needing to be terminated.\n"); snprintf(cmd, sizeof cmd, "ssh -S %s %s@%s %s -w3600 MIGR export", socket_path, remote_user, remote_host, remote_sendcommand); -- 2.30.2