X-Git-Url: https://code.citadel.org/?p=citadel.git;a=blobdiff_plain;f=citadel%2Fmodules%2Fmigrate%2Fserv_migrate.c;fp=citadel%2Fmodules%2Fmigrate%2Fserv_migrate.c;h=83173268239cbc2f69074ee6e24d7ce8f5c2f2f6;hp=97181a1c64763850523c23d60c07b99d29a87aa6;hb=9571de81331e169c042c630800bff1bde499c8a9;hpb=c51a64e8f8b42b6efd85f17c91178437d73a9c3d diff --git a/citadel/modules/migrate/serv_migrate.c b/citadel/modules/migrate/serv_migrate.c index 97181a1c6..831732682 100644 --- a/citadel/modules/migrate/serv_migrate.c +++ b/citadel/modules/migrate/serv_migrate.c @@ -1,7 +1,7 @@ /* * This module dumps and/or loads the Citadel database in XML format. * - * Copyright (c) 1987-2014 by the citadel.org team + * Copyright (c) 1987-2015 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3. @@ -16,8 +16,7 @@ * Explanation of tags: * * 0% nothing - * 1% finished exporting config - * 2% finished exporting control + * 2% finished exporting configuration * 7% finished exporting users * 12% finished exporting openids * 17% finished exporting rooms @@ -61,7 +60,6 @@ #include "database.h" #include "msgbase.h" #include "user_ops.h" -#include "control.h" #include "euidindex.h" #include "ctdl_module.h" @@ -73,9 +71,9 @@ FILE *migr_global_message_list; int total_msgs = 0; -/* - * Code which implements the export appears in this section - */ +/****************************************************************************** + * Code which implements the export appears in this section * + ******************************************************************************/ /* * Output a string to the client with these characters escaped: & < > @@ -90,19 +88,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 +114,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 +125,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 +142,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 +163,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 +218,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 +266,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 +317,18 @@ 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); + cprintf("%ld\n", smi.meta_rfc822_length); + client_write(HKEY("")); xml_strout(smi.meta_content_type); client_write(HKEY("\n")); + client_write(HKEY("")); xml_strout(smi.mimetype); 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,20 +365,43 @@ 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); } } +void migr_export_configs(void) { + struct cdbdata *cdbcfg; + int keylen = 0; + char *key = NULL; + char *value = NULL; + + cdb_rewind(CDB_CONFIG); + while (cdbcfg = cdb_next_item(CDB_CONFIG), cdbcfg != NULL) { + + keylen = strlen(cdbcfg->ptr); + key = cdbcfg->ptr; + value = cdbcfg->ptr + keylen + 1; + + client_write("", 2); + xml_strout(value); + client_write("\n", 10); + cdb_free(cdbcfg); + } +} + + void migr_export_messages(void) { @@ -425,101 +448,15 @@ 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); - 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); - 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); - cprintf("%d\n", config.c_maxsessions); - client_write("", 11); xml_strout(config.c_ip_addr); client_write("\n", 13); - 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); - cprintf("%d\n", config.c_createax); - cprintf("%ld\n", config.c_maxmsglen); - cprintf("%d\n", config.c_min_workers); - cprintf("%d\n", config.c_max_workers); - cprintf("%d\n", config.c_pop3_port); - cprintf("%d\n", config.c_smtp_port); - cprintf("%d\n", config.c_rfc822_strict_from); - cprintf("%d\n", config.c_aide_zap); - cprintf("%d\n", config.c_imap_port); - 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); - 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); - 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); - cprintf("%d\n", config.c_msa_port); - cprintf("%d\n", config.c_imaps_port); - cprintf("%d\n", config.c_pop3s_port); - cprintf("%d\n", config.c_smtps_port); - cprintf("%d\n", config.c_auto_cull); - 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); - 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); - 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); - 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); - cprintf("%d\n", config.c_imap_keep_from); - cprintf("%d\n", config.c_xmpp_c2s_port); - cprintf("%d\n", config.c_xmpp_s2s_port); - cprintf("%ld\n", config.c_pop3_fetch); - cprintf("%ld\n", config.c_pop3_fastest); - 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); - cprintf("%d\n", 1); - - /* Export the control file */ - get_control(); - client_write("\n", 10); - 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); + /* export the configuration database */ + migr_export_configs(); cprintf("%d\n", 2); - + if (Ctx->kill_me == 0) migr_export_users(); cprintf("%d\n", 7); if (Ctx->kill_me == 0) migr_export_openids(); @@ -531,22 +468,22 @@ 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; } - -/* - * Here's the code that implements the import side. It's going to end up being - * one big loop with lots of global variables. I don't care. You wouldn't run - * multiple concurrent imports anyway. If this offends your delicate sensibilities - * then go rewrite it in Ruby on Rails or something. - */ +/****************************************************************************** + * Import code * + * Here's the code that implements the import side. It's going to end up * + * being one big loop with lots of global variables. I don't care. * + * You wouldn't run multiple concurrent imports anyway. If this offends your * + * delicate sensibilities then go rewrite it in Ruby on Rails or something. * + ******************************************************************************/ int citadel_migrate_data = 0; /* Are we inside a tag pair? */ @@ -614,105 +551,9 @@ void migr_xml_start(void *data, const char *el, const char **attr) { memset(&smi, 0, sizeof (struct MetaData)); import_msgnum = 0; } - -} - - -int migr_config(void *data, const char *el) -{ - if (!strcasecmp(el, "c_nodename")) SET_CFGSTRBUF(c_nodename, migr_chardata); - else if (!strcasecmp(el, "c_fqdn")) SET_CFGSTRBUF(c_fqdn, migr_chardata); - else if (!strcasecmp(el, "c_humannode")) SET_CFGSTRBUF(c_humannode, migr_chardata); - else if (!strcasecmp(el, "c_phonenum")) SET_CFGSTRBUF(c_phonenum, migr_chardata); - else if (!strcasecmp(el, "c_ctdluid")) config.c_ctdluid = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_creataide")) config.c_creataide = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_sleeping")) config.c_sleeping = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_initax")) config.c_initax = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_regiscall")) config.c_regiscall = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_twitdetect")) config.c_twitdetect = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_twitroom")) SET_CFGSTRBUF(c_twitroom, migr_chardata); - else if (!strcasecmp(el, "c_moreprompt")) SET_CFGSTRBUF(c_moreprompt, migr_chardata); - else if (!strcasecmp(el, "c_restrict")) config.c_restrict = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_site_location")) SET_CFGSTRBUF(c_site_location, migr_chardata); - else if (!strcasecmp(el, "c_sysadm")) SET_CFGSTRBUF(c_sysadm, migr_chardata); - else if (!strcasecmp(el, "c_maxsessions")) config.c_maxsessions = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_ip_addr")) SET_CFGSTRBUF(c_ip_addr, migr_chardata); - else if (!strcasecmp(el, "c_port_number")) config.c_port_number = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_ep_expire_mode")) config.c_ep.expire_mode = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_ep_expire_value")) config.c_ep.expire_value = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_userpurge")) config.c_userpurge = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_roompurge")) config.c_roompurge = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_logpages")) SET_CFGSTRBUF(c_logpages, migr_chardata); - else if (!strcasecmp(el, "c_createax")) config.c_createax = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_maxmsglen")) config.c_maxmsglen = atol(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_min_workers")) config.c_min_workers = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_max_workers")) config.c_max_workers = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_pop3_port")) config.c_pop3_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_smtp_port")) config.c_smtp_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_rfc822_strict_from")) config.c_rfc822_strict_from = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_aide_zap")) config.c_aide_zap = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_imap_port")) config.c_imap_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_net_freq")) config.c_net_freq = atol(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_disable_newu")) config.c_disable_newu = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_enable_fulltext")) config.c_enable_fulltext = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_baseroom")) SET_CFGSTRBUF(c_baseroom, migr_chardata); - else if (!strcasecmp(el, "c_aideroom")) SET_CFGSTRBUF(c_aideroom, migr_chardata); - else if (!strcasecmp(el, "c_purge_hour")) config.c_purge_hour = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_mbxep_expire_mode")) config.c_mbxep.expire_mode = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_mbxep_expire_value")) config.c_mbxep.expire_value = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_ldap_host")) SET_CFGSTRBUF(c_ldap_host, migr_chardata); - else if (!strcasecmp(el, "c_ldap_port")) config.c_ldap_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_ldap_base_dn")) SET_CFGSTRBUF(c_ldap_base_dn, migr_chardata); - else if (!strcasecmp(el, "c_ldap_bind_dn")) SET_CFGSTRBUF(c_ldap_bind_dn, migr_chardata); - else if (!strcasecmp(el, "c_ldap_bind_pw")) SET_CFGSTRBUF(c_ldap_bind_pw, migr_chardata); - else if (!strcasecmp(el, "c_msa_port")) config.c_msa_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_imaps_port")) config.c_imaps_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_pop3s_port")) config.c_pop3s_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_smtps_port")) config.c_smtps_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_auto_cull")) config.c_auto_cull = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_allow_spoofing")) config.c_allow_spoofing = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_journal_email")) config.c_journal_email = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_journal_pubmsgs")) config.c_journal_pubmsgs = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_journal_dest")) SET_CFGSTRBUF(c_journal_dest, migr_chardata); - else if (!strcasecmp(el, "c_default_cal_zone")) SET_CFGSTRBUF(c_default_cal_zone, migr_chardata); - else if (!strcasecmp(el, "c_pftcpdict_port")) config.c_pftcpdict_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_managesieve_port")) config.c_managesieve_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_auth_mode")) config.c_auth_mode = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_funambol_host")) SET_CFGSTRBUF(c_funambol_host, migr_chardata); - else if (!strcasecmp(el, "c_funambol_port")) config.c_funambol_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_funambol_source")) SET_CFGSTRBUF(c_funambol_source, migr_chardata); - else if (!strcasecmp(el, "c_funambol_auth")) SET_CFGSTRBUF(c_funambol_auth, migr_chardata); - else if (!strcasecmp(el, "c_rbl_at_greeting")) config.c_rbl_at_greeting = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_master_user")) SET_CFGSTRBUF(c_master_user, migr_chardata); - else if (!strcasecmp(el, "c_master_pass")) SET_CFGSTRBUF(c_master_pass, migr_chardata); - else if (!strcasecmp(el, "c_pager_program")) SET_CFGSTRBUF(c_pager_program, migr_chardata); - else if (!strcasecmp(el, "c_imap_keep_from")) config.c_imap_keep_from = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_xmpp_c2s_port")) config.c_xmpp_c2s_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_xmpp_s2s_port")) config.c_xmpp_s2s_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_pop3_fetch")) config.c_pop3_fetch = atol(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_pop3_fastest")) config.c_pop3_fastest = atol(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_spam_flag_only")) config.c_spam_flag_only = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_nntp_port")) config.c_nntp_port = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "c_nntps_port")) config.c_nntps_port = atoi(ChrPtr(migr_chardata)); - else return 0; - return 1; /* Found above...*/ -} - -int migr_controlrecord(void *data, const char *el) -{ - if (!strcasecmp(el, "control_highest")) CitControl.MMhighest = atol(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "control_flags")) CitControl.MMflags = atoi(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "control_nextuser")) CitControl.MMnextuser = atol(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "control_nextroom")) CitControl.MMnextroom = atol(ChrPtr(migr_chardata)); - else if (!strcasecmp(el, "control_version")) CitControl.version = atoi(ChrPtr(migr_chardata)); - - else if (!strcasecmp(el, "control")) { - CitControl.MMfulltext = (-1L); /* always flush */ - put_control(); - syslog(LOG_INFO, "Completed import of control record\n"); + else if (!strcasecmp(el, "config")) { + syslog(LOG_DEBUG, "\033[31m IMPORT OF CONFIG START ELEMENT FIXME\033\0m"); } - else return 0; - return 1; } @@ -794,6 +635,8 @@ int migr_visitrecord(void *data, const char *el) else return 0; return 1; } + + void migr_xml_end(void *data, const char *el) { const char *ptr; @@ -817,20 +660,12 @@ void migr_xml_end(void *data, const char *el) /*** CONFIG ***/ - if (!strcasecmp(el, "config")) { - config.c_enable_fulltext = 0; /* always disable */ - put_config(); - syslog(LOG_INFO, "Completed import of server configuration\n"); + if (!strcasecmp(el, "config")) + { + syslog(LOG_DEBUG, "\033[31m IMPORT OF CONFIG END ELEMENT FIXME\033\0m"); + CtdlSetConfigInt("c_enable_fulltext", 0); /* always disable FIXME put this somewhere more appropriate */ } - else if ((!strncasecmp(el, HKEY("c_"))) && - migr_config(data, el)) - ; /* Nothing to do anymore */ - - /*** CONTROL ***/ - else if ((!strncasecmp(el, HKEY("control"))) && - migr_controlrecord(data, el)) - ; /* Nothing to do anymore */ /*** USER ***/ else if ((!strncasecmp(el, HKEY("u_"))) && migr_userrecord(data, el)) @@ -931,31 +766,44 @@ void migr_xml_end(void *data, const char *el) /*** MESSAGES ***/ - else if (!strcasecmp(el, "msg_msgnum")) import_msgnum = atol(ChrPtr(migr_chardata)); + else if (!strcasecmp(el, "msg_msgnum")) smi.meta_msgnum = import_msgnum = atol(ChrPtr(migr_chardata)); else if (!strcasecmp(el, "msg_meta_refcount")) smi.meta_refcount = atoi(ChrPtr(migr_chardata)); + else if (!strcasecmp(el, "msg_meta_rfc822_length")) smi.meta_rfc822_length = atoi(ChrPtr(migr_chardata)); else if (!strcasecmp(el, "msg_meta_content_type")) safestrncpy(smi.meta_content_type, ChrPtr(migr_chardata), sizeof smi.meta_content_type); + else if (!strcasecmp(el, "msg_mimetype")) safestrncpy(smi.mimetype, ChrPtr(migr_chardata), sizeof smi.mimetype); else if (!strcasecmp(el, "msg_text")) { + long rc; + struct CtdlMessage *msg; FlushStrBuf(migr_MsgData); - StrBufDecodeBase64To(migr_MsgData, migr_MsgData); - - cdb_store(CDB_MSGMAIN, - &import_msgnum, - sizeof(long), - ChrPtr(migr_MsgData), - StrLength(migr_MsgData) + 1); - - smi.meta_msgnum = import_msgnum; - PutMetaData(&smi); + 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, bodylength=%ld, content-type: %s / %s \n", + (rc!= 0)?"failed to import ":"Imported ", import_msgnum, StrLength(migr_MsgData), smi.meta_refcount, - smi.meta_content_type); + smi.meta_rfc822_length, + smi.meta_content_type, + smi.mimetype); + memset(&smi, 0, sizeof(smi)); } /*** MORE GENERAL STUFF ***/ @@ -1022,6 +870,9 @@ void migr_do_import(void) { +/****************************************************************************** + * Dispatcher, Common code * + ******************************************************************************/ /* * Dump out the pathnames of directories which can be copied "as is" */ @@ -1038,12 +889,200 @@ void migr_do_listdirs(void) { cprintf("000\n"); } +/****************************************************************************** + * Repair database integrity * + ******************************************************************************/ -/* - * Common code appears in this section - */ +StrBuf *PlainMessageBuf = NULL; +HashList *UsedMessageIDS = NULL; + +int migr_restore_message_metadata(long msgnum, int refcount) +{ + CitContext *CCC = MyContext(); + struct MetaData smi; + struct CtdlMessage *msg; + char *mptr = NULL; + + /* We can use a static buffer here because there will never be more than + * one of this operation happening at any given time, and it's really best + * to just keep it allocated once instead of torturing malloc/free. + * Call this function with msgnum "-1" to free the buffer when finished. + */ + static int encoded_alloc = 0; + static char *encoded_msg = NULL; + if (msgnum < 0) { + if ((encoded_alloc == 0) && (encoded_msg != NULL)) { + free(encoded_msg); + encoded_alloc = 0; + encoded_msg = NULL; + // todo FreeStrBuf(&PlainMessageBuf); PlainMessageBuf = NULL; + } + return 0; + } + + if (PlainMessageBuf == NULL) { + PlainMessageBuf = NewStrBufPlain(NULL, 10*SIZ); + } + /* Ok, here we go ... */ + + msg = CtdlFetchMessage(msgnum, 1, 0); + if (msg == NULL) { + return 1; + } + + GetMetaData(&smi, msgnum); + smi.meta_msgnum = msgnum; + smi.meta_refcount = refcount; + + /* restore the content type from the message body: */ + mptr = bmstrcasestr(msg->cm_fields[eMesageText], "Content-type:"); + if (mptr != NULL) { + char *aptr; + safestrncpy(smi.meta_content_type, &mptr[13], sizeof smi.meta_content_type); + striplt(smi.meta_content_type); + aptr = smi.meta_content_type; + while (!IsEmptyStr(aptr)) { + if ((*aptr == ';') + || (*aptr == ' ') + || (*aptr == 13) + || (*aptr == 10)) { + memset(aptr, 0, sizeof(smi.meta_content_type) - (aptr - smi.meta_content_type)); + } + else aptr++; + } + } + + CCC->redirect_buffer = PlainMessageBuf; + CtdlOutputPreLoadedMsg(msg, MT_RFC822, HEADERS_ALL, 0, 1, QP_EADDR); + smi.meta_rfc822_length = StrLength(CCC->redirect_buffer); + CCC->redirect_buffer = NULL; + + + syslog(LOG_INFO, + "Setting message #%ld meta data to: refcount=%d, bodylength=%ld, content-type: %s / %s \n", + smi.meta_msgnum, + smi.meta_refcount, + smi.meta_rfc822_length, + smi.meta_content_type, + smi.mimetype); + + PutMetaData(&smi); + + CM_Free(msg); + + return 0; +} + +void migr_check_room_msg(long msgnum, void *userdata) { + fprintf(migr_global_message_list, "%ld %s\n", msgnum, CC->room.QRname); +} + + +void migr_check_rooms_backend(struct ctdlroom *buf, void *data) { + + /* message list goes inside this tag */ + + CtdlGetRoom(&CC->room, buf->QRname); + CtdlForEachMessage(MSGS_ALL, 0L, NULL, NULL, NULL, migr_check_room_msg, NULL); +} + +void RemoveMessagesFromRooms(StrBuf *RoomNameVec, long msgnum) { + struct MetaData smi; + const char *Pos = NULL; + StrBuf *oneRoom = NewStrBuf(); + + syslog(LOG_INFO, "removing message pointer %ld from these rooms: %s", msgnum, ChrPtr(RoomNameVec)); + + while (Pos != StrBufNOTNULL){ + StrBufExtract_NextToken(oneRoom, RoomNameVec, &Pos, '|'); + CtdlDeleteMessages(ChrPtr(oneRoom), &msgnum, 1, ""); + }; + GetMetaData(&smi, msgnum); + TDAP_AdjRefCount(msgnum, -smi.meta_refcount); +} + +void migr_do_restore_meta(void) { + char buf[SIZ]; + int failGetMessage; + long msgnum; + int lastnum = 0; + int refcount = 0; + CitContext *Ctx; + char *prn; + StrBuf *RoomNames; + char cmd[SIZ]; + + migr_global_message_list = fopen(migr_tempfilename1, "w"); + if (migr_global_message_list != NULL) { + CtdlForEachRoom(migr_check_rooms_backend, NULL); + fclose(migr_global_message_list); + } + + /* + * Process the 'global' message list. (Sort it and remove dups. + * Dups are ok because a message may be in more than one room, but + * this will be handled by exporting the reference count, not by + * exporting the message multiple times.) + */ + snprintf(cmd, sizeof cmd, "sort -n <%s >%s", migr_tempfilename1, migr_tempfilename2); + if (system(cmd) != 0) syslog(LOG_ALERT, "Error %d\n", errno); + + RoomNames = NewStrBuf(); + Ctx = CC; + migr_global_message_list = fopen(migr_tempfilename2, "r"); + if (migr_global_message_list != NULL) { + syslog(LOG_INFO, "Opened %s\n", migr_tempfilename1); + while ((Ctx->kill_me == 0) && + (fgets(buf, sizeof(buf), migr_global_message_list) != NULL)) { + msgnum = atol(buf); + if (msgnum == 0L) + continue; + if (lastnum == 0) { + lastnum = msgnum; + } + prn = strchr(buf, ' '); + if (lastnum != msgnum) { + failGetMessage = migr_restore_message_metadata(lastnum, refcount); + if (failGetMessage) { + RemoveMessagesFromRooms(RoomNames, lastnum); + } + refcount = 1; + lastnum = msgnum; + if (prn != NULL) + StrBufPlain(RoomNames, prn + 1, -1); + StrBufTrim(RoomNames); + } + else { + if (prn != NULL) { + if (StrLength(RoomNames) > 0) + StrBufAppendBufPlain(RoomNames, HKEY("|"), 0); + StrBufAppendBufPlain(RoomNames, prn, -1, 1); + StrBufTrim(RoomNames); + } + refcount ++; + } + lastnum = msgnum; + } + failGetMessage = migr_restore_message_metadata(msgnum, refcount); + if (failGetMessage) { + RemoveMessagesFromRooms(RoomNames, lastnum); + } + fclose(migr_global_message_list); + } + + migr_restore_message_metadata(-1L, -1); /* This frees the encoding buffer */ + cprintf("%d system analysis completed", CIT_OK); + Ctx->kill_me = 1; +} + + + + +/****************************************************************************** + * Dispatcher, Common code * + ******************************************************************************/ void cmd_migr(char *cmdbuf) { char cmd[32]; @@ -1051,6 +1090,7 @@ void cmd_migr(char *cmdbuf) { if (CtdlTrySingleUser()) { + CtdlDisableHouseKeeping(); CtdlMakeTempFileName(migr_tempfilename1, sizeof migr_tempfilename1); CtdlMakeTempFileName(migr_tempfilename2, sizeof migr_tempfilename2); @@ -1064,13 +1104,17 @@ void cmd_migr(char *cmdbuf) { else if (!strcasecmp(cmd, "listdirs")) { migr_do_listdirs(); } + else if (!strcasecmp(cmd, "restoremeta")) { + migr_do_restore_meta(); + } else { cprintf("%d illegal command\n", ERROR + ILLEGAL_VALUE); } unlink(migr_tempfilename1); unlink(migr_tempfilename2); - + + CtdlEnableHouseKeeping(); CtdlEndSingleUser(); } else @@ -1079,6 +1123,9 @@ void cmd_migr(char *cmdbuf) { } } +/****************************************************************************** + * Module Hook * + ******************************************************************************/ CTDL_MODULE_INIT(migrate) {