#include "stdafx.h" void FreeModuleSettingLL(ModuleSettingLL *msll) { if (msll == nullptr) return; ModSetLinkLinkItem *item = msll->first; while (item) { mir_free(item->name); ModSetLinkLinkItem *temp = item; item = (ModSetLinkLinkItem *)item->next; mir_free(temp); } msll->first = nullptr; msll->last = nullptr; } int enumModulesSettingsProc(const char *setting, void *pParam) { ModuleSettingLL *msll = (ModuleSettingLL *)pParam; if (!msll->first) { msll->first = (ModSetLinkLinkItem *)mir_alloc(sizeof(ModSetLinkLinkItem)); if (!msll->first) return 1; msll->first->name = mir_strdup(setting); msll->first->next = nullptr; msll->last = msll->first; } else { ModSetLinkLinkItem *item = (ModSetLinkLinkItem *)mir_alloc(sizeof(ModSetLinkLinkItem)); if (!item) return 1; msll->last->next = item; msll->last = item; item->name = mir_strdup(setting); item->next = nullptr; } return 0; } int EnumModules(ModuleSettingLL *msll) // 1 = success, 0 = fail { msll->first = nullptr; msll->last = nullptr; if (db_enum_modules(enumModulesSettingsProc, msll)) { msg(TranslateT("Error loading module list")); return 0; } return 1; } int enumSettingsProc(const char *setting, void *lParam) { return enumModulesSettingsProc(setting, lParam); } int EnumSettings(MCONTACT hContact, const char *module, ModuleSettingLL *msll) { // enum all setting the contact has for the module msll->first = nullptr; msll->last = nullptr; if (db_enum_settings(hContact, enumSettingsProc, module, msll)) { msg(TranslateT("Error loading setting list")); return 0; } return 1; } int CheckIfModuleIsEmptyProc(const char*, void*) { return 1; } int IsModuleEmpty(MCONTACT hContact, const char *module) { return 0 > db_enum_settings(hContact, CheckIfModuleIsEmptyProc, module); } static int stringCompare(const char *p1, const char *p2) { return mir_strcmp(p1, p2); } LIST m_lResidentSettings(10, stringCompare); int enumResidentProc(const char *setting, void*) { m_lResidentSettings.insert(mir_strdup(setting)); return 0; } int LoadResidentSettings() { if (g_db) return !g_db->EnumResidentSettings(enumResidentProc, nullptr); return 0; } void FreeResidentSettings() { for (int i = 0; i < m_lResidentSettings.getCount(); i++) mir_free(m_lResidentSettings[i]); m_lResidentSettings.destroy(); } int IsResidentSetting(const char *module, const char *setting) { if (!m_lResidentSettings.getCount()) return 0; if (!setting) return 1; char str[2 * FLD_SIZE]; mir_strncpy(str, module, _countof(str) - 1); mir_strcat(str, "/"); mir_strncat(str, setting, _countof(str)); return m_lResidentSettings.getIndex(str) != -1; } int EnumResidentSettings(const char *module, ModuleSettingLL *msll) { msll->first = nullptr; msll->last = nullptr; if (!module) return 0; if (!m_lResidentSettings.getCount()) return 0; int len = (int)mir_strlen(module); int cnt = 0; for (int i = 0; i < m_lResidentSettings.getCount(); i++) { if (strncmp(module, m_lResidentSettings[i], len)) continue; if (m_lResidentSettings[i][len] != '/' || m_lResidentSettings[i][len + 1] == 0) continue; enumModulesSettingsProc(&m_lResidentSettings[i][len + 1], msll); cnt++; } return cnt; } static int fixing = 0; // previously saved in DB resident settings are unaccessible. // so let's find them and delete from DB int fixResidentSettings() { if (!m_lResidentSettings.getCount() || fixing) return 0; ModuleSettingLL ModuleList; if (!EnumModules(&ModuleList)) return 0; fixing = 1; int cnt = 0; for (MCONTACT hContact = db_find_first(); hContact != 0; hContact = db_find_next(hContact)) { for (ModSetLinkLinkItem *module = ModuleList.first; module; module = module->next) { if (IsModuleEmpty(hContact, module->name)) continue; ModuleSettingLL SettingList; if (!EnumSettings(hContact, module->name, &SettingList)) continue; for (ModSetLinkLinkItem *setting = SettingList.first; setting; setting = setting->next) { char str[2 * FLD_SIZE]; mir_strncpy(str, module->name, _countof(str) - 1); mir_strcat(str, "/"); mir_strncat(str, setting->name, _countof(str)); int idx = m_lResidentSettings.getIndex(str); if (idx == -1) continue; Netlib_Logf(nullptr, "Removing resident setting %s/%s for contact %d", module->name, setting->name, hContact); g_db->SetSettingResident(0, str); db_unset(hContact, module->name, setting->name); g_db->SetSettingResident(1, str); cnt++; } FreeModuleSettingLL(&SettingList); } } FreeModuleSettingLL(&ModuleList); fixing = 0; return cnt; }