From f6bbbbad62ac6fd92e896b59c4adfdd751aa8134 Mon Sep 17 00:00:00 2001 From: "Dirk-Jan C. Binnema" Date: Wed, 19 Sep 2007 11:49:20 +0000 Subject: [PATCH] * optimize the parsing of the provider data, particularly the parsing of the countries list; that one showed up high in oprofile basically, we take the (reasonable) assumptions that the lines have a fixed max len and are valid ascii. this allows us to get rid of all mem allocs. also, we just the clustered-by-mcc values (the provider data has been adapted for this), and with that we can get rid of a lot of strcmps this all should help with NB#64324 pmo-trunk-r3343 --- .../easysetup/modest-easysetup-country-combo-box.c | 328 ++++++++------------ .../easysetup/modest-easysetup-country-combo-box.h | 6 +- .../modest-easysetup-provider-combo-box.c | 82 ++--- .../modest-easysetup-provider-combo-box.h | 3 +- src/maemo/easysetup/modest-easysetup-wizard.c | 6 +- src/maemo/easysetup/modest-presets.c | 10 - 6 files changed, 165 insertions(+), 270 deletions(-) diff --git a/src/maemo/easysetup/modest-easysetup-country-combo-box.c b/src/maemo/easysetup/modest-easysetup-country-combo-box.c index 9bdef19..9c37ebf 100644 --- a/src/maemo/easysetup/modest-easysetup-country-combo-box.c +++ b/src/maemo/easysetup/modest-easysetup-country-combo-box.c @@ -48,6 +48,8 @@ #include #endif +#define MAX_LINE_LEN 128 /* max length of a line in MCC file */ + G_DEFINE_TYPE (EasysetupCountryComboBox, easysetup_country_combo_box, GTK_TYPE_COMBO_BOX); #define COUNTRY_COMBO_BOX_GET_PRIVATE(o) \ @@ -89,29 +91,16 @@ easysetup_country_combo_box_dispose (GObject *object) enum MODEL_COLS { MODEL_COL_NAME = 0, /* string */ - MODEL_COL_IDS = 1 /* A GSList* of guints. */ + MODEL_COL_MCC = 1 /* the 'effective mcc' for this country */ }; -static gboolean -on_model_foreach_release (GtkTreeModel *model, GtkTreePath *path, - GtkTreeIter *iter, gpointer data) -{ - GSList *list = NULL; - gtk_tree_model_get (model, iter, MODEL_COL_IDS, &list, -1); - if (list) - g_slist_free (list); - - return FALSE; /* keep walking. */ -} static void easysetup_country_combo_box_finalize (GObject *object) { EasysetupCountryComboBoxPrivate *priv = COUNTRY_COMBO_BOX_GET_PRIVATE (object); - gtk_tree_model_foreach (priv->model, on_model_foreach_release, NULL); g_object_unref (G_OBJECT (priv->model)); - G_OBJECT_CLASS (easysetup_country_combo_box_parent_class)->finalize (object); } @@ -128,68 +117,92 @@ easysetup_country_combo_box_class_init (EasysetupCountryComboBoxClass *klass) object_class->finalize = easysetup_country_combo_box_finalize; } -/** id and country must be freed. + + + +/* cluster mcc's, based on the list + * http://en.wikipedia.org/wiki/Mobile_country_code */ -static void parse_mcc_mapping_line (const char* line, char** id, char** country) +static int +effective_mcc (gint mcc) { - /* Initialize output parameters: */ - *id = NULL; - *country = NULL; - - g_assert(line); - - const gboolean is_valid_utf8 = g_utf8_validate (line, -1, NULL); - if(!is_valid_utf8) { - g_warning("UTF8 validation failed."); - return; + switch (mcc) { + case 405: return 404; /* india */ + case 441: return 440; /* japan */ + case 235: return 234; /* united kingdom */ + case 311: + case 312: + case 313: + case 314: + case 315: + case 316: return 310; /* united states */ + default: return mcc; } +} + + +/* each line is of the form: + xxx logical_id + + NOTE: this function is NOT re-entrant, the out-param country + are static strings that should NOT be freed. and will change when + calling this function again + + also note, this function will return the "effective mcc", which + is the normalized mcc for a country - ie. even if the there + are multiple entries for the United States with various mccs, + this function will always return 310, even if the real mcc parsed + would be 314. see the 'effective_mcc' function above. +*/ +static int +parse_mcc_mapping_line (const char* line, char** country) +{ + int i, j; + char mcc[4]; /* the mcc code, always 3 bytes*/ + static char my_country[128]; - /* Look at each character, to find the whitespace between the ID and name: */ - char* result_id = NULL; - char* result_country = NULL; + /* Initialize output parameters: */ + *country = NULL; + + g_return_val_if_fail (line && strlen(line) > 20, 0); - const char* p = line; - const char* p_start_of_country = NULL; - while (p && *p) - { - p = g_utf8_next_char(p); - gunichar ch = g_utf8_get_char(p); - if (g_unichar_isspace(ch)) { /* Note: This checks for any whitespace, not just space. */ - if(!result_id) { - /* The text before this must be the ID: */ - const int length = p - line; - result_id = g_malloc (length + 1); /* 1 for null-termination. */ - memcpy(result_id, line, length); - result_id[length] = 0; /* Null-termination. */ - } - else if(p_start_of_country) - { - /* This whitespace is probably the newline after the country. */ - - /* The text after the whitespace, after the ID, must be the country: */ - int length = p - p_start_of_country; - result_country = g_malloc(length + 1); - memcpy(result_country, p_start_of_country, length); - result_country[length] = 0; /* Null-termination. */ + for (i = 3, j = 0; i < 128; ++i) { + char kar = line[i]; + if (kar < '_' ) { /* optimization */ + if (kar == '\n' || kar == '\r') break; - } - } - else if(result_id && !p_start_of_country) { - p_start_of_country = p; + else if (kar == ' ' || kar == '\t') + continue; + else /* error */ + return 0; + } else { + printf ("%c", kar); + my_country [j++] = kar; } } + my_country[j] = '\0'; + + mcc[0] = line[0]; + mcc[1] = line[1]; + mcc[2] = line[2]; + mcc[3] = '\0'; - *id = result_id; - *country = result_country; + *country = my_country; + return effective_mcc (atoi(mcc)); } /** Note that the mcc_mapping file is installed * by the operator-wizard-settings package. */ -static void load_from_file (EasysetupCountryComboBox *self) +static void +load_from_file (EasysetupCountryComboBox *self) { EasysetupCountryComboBoxPrivate *priv = COUNTRY_COMBO_BOX_GET_PRIVATE (self); + GtkListStore *liststore = GTK_LIST_STORE (priv->model); + char line[MAX_LINE_LEN]; + guint previous_mcc = 0; + /* Load the file one line at a time: */ #ifdef MODEST_HILDON_VERSION_0 const gchar* filepath = PROVIDER_DATA_DIR "/mcc_mapping"; @@ -199,115 +212,53 @@ static void load_from_file (EasysetupCountryComboBox *self) #endif /*MODEST_HILDON_VERSION_0*/ /* printf ("DEBUG: %s: filepath=%s\n", __FUNCTION__, filepath); */ FILE *file = fopen(filepath, "r"); - if (!file) - { + if (!file) { const gchar* filepath_hack = HACK_TOP_SRCDIR "src/maemo/easysetup/mcc_mapping"; g_warning ("Could not locate the official mcc_mapping countries list file from %s, " "so attempting to load it instead from %s", filepath, filepath_hack); file = fopen(filepath_hack, "r"); } - if (!file) { g_warning("Could not open mcc_mapping file"); return; } - GtkListStore *liststore = GTK_LIST_STORE (priv->model); + while (fgets (line, MAX_LINE_LEN, file) > 0) { - /* We use the getline() GNU extension, - * because it reads per line, which simplifies our code, - * and it doesn't require us to hard-code a buffer length. - * TODO: Could we make this faster? - */ - unsigned int len = 0; - char *line = NULL; - guint previous_id = 0; - gchar* previous_country = NULL; - GSList *list = NULL; - while (getline (&line, &len, file) > 0) { /* getline will realloc line if necessary. */ - /* printf ("DBEUG: len=%d, line: %s\n", len, line); */ - - char *id_str = NULL; + int mcc; char *country = NULL; - parse_mcc_mapping_line (line, &id_str, &country); - /* printf("DEBUG: parsed: id=%s, country=%s\n", id_str, country); */ - - if(id_str && country) { - - if (previous_country) { - /* printf (" debug: storing id=%d for country=%s\n", previous_id, previous_country); */ - list = g_slist_prepend (list, GUINT_TO_POINTER (previous_id)); - } - - /* Group multiple MMC IDs for the same country together: - * This assumes that they are in sequence. - * We don't know why some countries, such as the USA, have several MMC IDs. - * If they are regions in the country, and we need to show them separately, then - * we would need to have that information in the file to distinguish them. - */ - if (!previous_country || - (previous_country && strcmp (previous_country, country) != 0)) { - - /* Get the translation for the country name: - * Note that the osso_countries_1.0 translation domain files are installed - * by the operator-wizard-settings package. */ - /* For post-Bora, there is a separate (meta)package osso-countries-l10n-mr0 */ - - /* Note: Even when the untranslated names are different, there may still be - * duplicate translated names. They would be translation bugs. - */ - const gchar *name_translated = dgettext ("osso-countries", previous_country); - if(!name_translated) - name_translated = previous_country; - - /* Add the row to the model: */ - GtkTreeIter iter; - gtk_list_store_append (liststore, &iter); - gtk_list_store_set(liststore, &iter, MODEL_COL_IDS, list, MODEL_COL_NAME, name_translated, -1); - - /* The list will be freed in our finalize(). */ - list = NULL; - } - - g_free (previous_country); - previous_country = country; - - const guint id = (guint)g_ascii_strtod(id_str, NULL); /* Note that this parses locale-independent text. */ - previous_id = id; + mcc = parse_mcc_mapping_line (line, &country); + if (!country || mcc == 0) { + g_warning ("%s: error parsing line: '%s'", __FUNCTION__, line); + continue; } - else if (country) { - g_free (country); + + if (mcc == previous_mcc) { + /* g_warning ("already seen: %s", line); */ + continue; } + previous_mcc = mcc; - g_free (id_str); - } - - /* Deal with the last country: */ - const gchar *name_translated = dgettext ("osso-countries", previous_country); - if(!name_translated) - name_translated = previous_country; - - /* Add the row to the model: */ - GtkTreeIter iter; - gtk_list_store_append (liststore, &iter); - gtk_list_store_set(liststore, &iter, MODEL_COL_IDS, list, MODEL_COL_NAME, name_translated, -1); - - g_free(previous_country); - - if (list) { - g_slist_free (list); - list = NULL; - } + /* Get the translation for the country name: + * Note that the osso_countries_1.0 translation domain files are installed + * by the operator-wizard-settings package. */ + /* For post-Bora, there is a separate (meta)package osso-countries-l10n-mr0 */ - - if (line) - free (line); + /* Note: Even when the untranslated names are different, there may still be + * duplicate translated names. They would be translation bugs. + */ + const gchar *name_translated = dgettext ("osso-countries", country); + /* Add the row to the model: */ + GtkTreeIter iter; + gtk_list_store_append (liststore, &iter); + gtk_list_store_set(liststore, &iter, MODEL_COL_MCC, mcc, MODEL_COL_NAME, name_translated, -1); + } fclose (file); /* Sort the items: */ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (liststore), - MODEL_COL_NAME, GTK_SORT_ASCENDING); + MODEL_COL_NAME, GTK_SORT_ASCENDING); } static void @@ -319,14 +270,12 @@ easysetup_country_combo_box_init (EasysetupCountryComboBox *self) * with a string for the name, and an int for the MCC ID. * This must match our MODEL_COLS enum constants. */ - priv->model = GTK_TREE_MODEL (gtk_list_store_new (2, - G_TYPE_STRING, - G_TYPE_POINTER)); - + priv->model = GTK_TREE_MODEL (gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT)); + /* Setup the combo box: */ GtkComboBox *combobox = GTK_COMBO_BOX (self); gtk_combo_box_set_model (combobox, priv->model); - + /* Country column: * The ID model column in not shown in the view. */ GtkCellRenderer *renderer = gtk_cell_renderer_text_new (); @@ -334,6 +283,10 @@ easysetup_country_combo_box_init (EasysetupCountryComboBox *self) gtk_cell_layout_pack_start(GTK_CELL_LAYOUT (combobox), renderer, TRUE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox), renderer, "text", MODEL_COL_NAME, NULL); + + + g_assert (GTK_IS_LIST_STORE(priv->model)); + /* Fill the model with rows: */ load_from_file (self); @@ -347,76 +300,43 @@ easysetup_country_combo_box_new (void) /** * Returns the MCC number of the selected country, or 0 if no country was selected. - * The list should not be freed. */ -GSList * -easysetup_country_combo_box_get_active_country_ids (EasysetupCountryComboBox *self) +gint +easysetup_country_combo_box_get_active_country_mcc (EasysetupCountryComboBox *self) { GtkTreeIter active; const gboolean found = gtk_combo_box_get_active_iter (GTK_COMBO_BOX (self), &active); if (found) { EasysetupCountryComboBoxPrivate *priv = COUNTRY_COMBO_BOX_GET_PRIVATE (self); - - GSList *list = NULL; - gtk_tree_model_get (priv->model, &active, MODEL_COL_IDS, &list, -1); - return list; + gint mcc = 0; + gtk_tree_model_get (priv->model, &active, MODEL_COL_MCC, &mcc, -1); + return mcc; } - - return NULL; /* Failed. */ + return 0; /* Failed. */ } -/* This allows us to pass more than one piece of data to the signal handler, - * and get a result: */ -typedef struct -{ - EasysetupCountryComboBox* self; - guint mcc_id; - gboolean found; -} ForEachData; - -static gboolean -on_model_foreach_select_id(GtkTreeModel *model, - GtkTreePath *path, GtkTreeIter *iter, gpointer user_data) -{ - ForEachData *state = (ForEachData*)(user_data); - - /* Select the item if it has the matching ID: */ - GSList *list = NULL; - gtk_tree_model_get (model, iter, MODEL_COL_IDS, &list, -1); - if(list && g_slist_find (list, GUINT_TO_POINTER (state->mcc_id))) { - gtk_combo_box_set_active_iter (GTK_COMBO_BOX (state->self), iter); - - state->found = TRUE; - return TRUE; /* Stop walking the tree. */ - } - - return FALSE; /* Keep walking the tree. */ -} - /** * Selects the MCC number of the selected country. * Specify 0 to select no country. */ gboolean -easysetup_country_combo_box_set_active_country_id (EasysetupCountryComboBox *self, guint mcc_id) +easysetup_country_combo_box_set_active_country_mcc (EasysetupCountryComboBox *self, guint mcc) { EasysetupCountryComboBoxPrivate *priv = COUNTRY_COMBO_BOX_GET_PRIVATE (self); - - /* Create a state instance so we can send two items of data to the signal handler: */ - ForEachData *state = g_new0 (ForEachData, 1); - state->self = self; - state->mcc_id = mcc_id; - state->found = FALSE; - - /* Look at each item, and select the one with the correct ID: */ - gtk_tree_model_foreach (priv->model, &on_model_foreach_select_id, state); + GtkTreeIter iter; - const gboolean result = state->found; - - /* Free the state instance: */ - g_free(state); + if (!gtk_tree_model_get_iter_first (priv->model, &iter)) + return FALSE; + do { + gint current_mcc = 0; + gtk_tree_model_get (priv->model, &iter, MODEL_COL_MCC, ¤t_mcc, -1); + if (current_mcc == mcc) { + gtk_combo_box_set_active_iter (GTK_COMBO_BOX (self), &iter); + return TRUE; + } + } while (gtk_tree_model_iter_next (priv->model, &iter)); - return result; + return FALSE; /* not found */ } diff --git a/src/maemo/easysetup/modest-easysetup-country-combo-box.h b/src/maemo/easysetup/modest-easysetup-country-combo-box.h index 7f667aa..ef9813f 100644 --- a/src/maemo/easysetup/modest-easysetup-country-combo-box.h +++ b/src/maemo/easysetup/modest-easysetup-country-combo-box.h @@ -68,8 +68,10 @@ GType easysetup_country_combo_box_get_type (void); EasysetupCountryComboBox* easysetup_country_combo_box_new (void); -GSList* easysetup_country_combo_box_get_active_country_ids (EasysetupCountryComboBox *self); -gboolean easysetup_country_combo_box_set_active_country_id (EasysetupCountryComboBox *self, guint mcc_id); +gint easysetup_country_combo_box_get_active_country_mcc (EasysetupCountryComboBox *self); + + +gboolean easysetup_country_combo_box_set_active_country_mcc (EasysetupCountryComboBox *self, guint mcc); G_END_DECLS diff --git a/src/maemo/easysetup/modest-easysetup-provider-combo-box.c b/src/maemo/easysetup/modest-easysetup-provider-combo-box.c index caf321f..5f786b0 100644 --- a/src/maemo/easysetup/modest-easysetup-provider-combo-box.c +++ b/src/maemo/easysetup/modest-easysetup-provider-combo-box.c @@ -142,17 +142,10 @@ easysetup_provider_combo_box_new (void) return g_object_new (EASYSETUP_TYPE_PROVIDER_COMBO_BOX, NULL); } -void easysetup_provider_combo_box_fill (EasysetupProviderComboBox *combobox, ModestPresets *presets, GSList * list_country_id) +void +easysetup_provider_combo_box_fill (EasysetupProviderComboBox *combobox, ModestPresets *presets, + gint mcc) { - /* If the list is empty then use mcc=0 to get the providers for all countries: */ - GSList *list = list_country_id; - GSList *fake_list = NULL; - if (!list_country_id) { - fake_list = g_slist_append(fake_list, GUINT_TO_POINTER(0)); - list = fake_list; - } - - EasysetupProviderComboBoxPrivate *priv = PROVIDER_COMBO_BOX_GET_PRIVATE (combobox); /* Remove any existing rows: */ @@ -161,50 +154,42 @@ void easysetup_provider_combo_box_fill (EasysetupProviderComboBox *combobox, Mod GSList *provider_ids_used_already = NULL; - GSList *iter_ids = list; - while (iter_ids) { - const guint country_id = GPOINTER_TO_UINT (iter_ids->data); - - /* Add the appropriate rows for this country, from the presets file: */ - gchar ** provider_ids = NULL; - gchar ** provider_names = modest_presets_get_providers (presets, country_id, - TRUE /* include_globals */, &provider_ids); + /* Add the appropriate rows for this country, from the presets file: */ + gchar ** provider_ids = NULL; + gchar ** provider_names = modest_presets_get_providers (presets, mcc, + TRUE /* include_globals */, &provider_ids); + gchar ** iter_provider_names = provider_names; + gchar ** iter_provider_ids = provider_ids; + while(iter_provider_names && *iter_provider_names && iter_provider_ids && *iter_provider_ids) { + const gchar* provider_name = *iter_provider_names; + const gchar* provider_id = *iter_provider_ids; - gchar ** iter_provider_names = provider_names; - gchar ** iter_provider_ids = provider_ids; - while(iter_provider_names && *iter_provider_names && iter_provider_ids && *iter_provider_ids) - { - const gchar* provider_name = *iter_provider_names; - const gchar* provider_id = *iter_provider_ids; - - /* Prevent duplicate providers: */ - if (g_slist_find_custom (provider_ids_used_already, - provider_id, (GCompareFunc)strcmp) == NULL) { - /* printf("debug: provider_name=%s\n", provider_name); */ - - /* Add the row: */ - GtkTreeIter iter; - gtk_list_store_append (liststore, &iter); - - gtk_list_store_set(liststore, &iter, - MODEL_COL_ID, provider_id, - MODEL_COL_NAME, provider_name, -1); - - provider_ids_used_already = g_slist_prepend ( - provider_ids_used_already, (gpointer)g_strdup (provider_id)); - } + /* Prevent duplicate providers: */ + if (g_slist_find_custom (provider_ids_used_already, + provider_id, (GCompareFunc)strcmp) == NULL) { + /* printf("debug: provider_name=%s\n", provider_name); */ + + /* Add the row: */ + GtkTreeIter iter; + gtk_list_store_append (liststore, &iter); + + gtk_list_store_set(liststore, &iter, + MODEL_COL_ID, provider_id, + MODEL_COL_NAME, provider_name, -1); + + provider_ids_used_already = g_slist_prepend ( + provider_ids_used_already, (gpointer)g_strdup (provider_id)); + } ++iter_provider_names; ++iter_provider_ids; } - /* Free the result of modest_presets_get_providers() - * as specified by its documentation: */ - g_strfreev (provider_names); - g_strfreev (provider_ids); + /* Free the result of modest_presets_get_providers() + * as specified by its documentation: */ + g_strfreev (provider_names); + g_strfreev (provider_ids); - iter_ids = g_slist_next (iter_ids); - } /* Add the "Other" item: */ /* Note that ID 0 means "Other" for us: */ @@ -218,9 +203,6 @@ void easysetup_provider_combo_box_fill (EasysetupProviderComboBox *combobox, Mod g_slist_foreach (provider_ids_used_already, (GFunc)g_free, NULL); g_slist_free (provider_ids_used_already); - - if (fake_list) - g_slist_free (fake_list); } /** diff --git a/src/maemo/easysetup/modest-easysetup-provider-combo-box.h b/src/maemo/easysetup/modest-easysetup-provider-combo-box.h index d8b66aa..41da709 100644 --- a/src/maemo/easysetup/modest-easysetup-provider-combo-box.h +++ b/src/maemo/easysetup/modest-easysetup-provider-combo-box.h @@ -69,7 +69,8 @@ GType easysetup_provider_combo_box_get_type (void); EasysetupProviderComboBox* easysetup_provider_combo_box_new (void); -void easysetup_provider_combo_box_fill (EasysetupProviderComboBox *combobox, ModestPresets *presets, GSList * list_country_id); +void easysetup_provider_combo_box_fill (EasysetupProviderComboBox *combobox, ModestPresets *presets, + gint mcc); gchar* easysetup_provider_combo_box_get_active_provider_id (EasysetupProviderComboBox *combobox); diff --git a/src/maemo/easysetup/modest-easysetup-wizard.c b/src/maemo/easysetup/modest-easysetup-wizard.c index 5149b02..575b53b 100644 --- a/src/maemo/easysetup/modest-easysetup-wizard.c +++ b/src/maemo/easysetup/modest-easysetup-wizard.c @@ -345,10 +345,10 @@ on_combo_account_country (GtkComboBox *widget, gpointer user_data) priv->dirty = TRUE; /* Fill the providers combo, based on the selected country: */ - GSList *list_mcc_ids = easysetup_country_combo_box_get_active_country_ids ( + gint mcc = easysetup_country_combo_box_get_active_country_mcc ( EASYSETUP_COUNTRY_COMBO_BOX (self->combo_account_country)); easysetup_provider_combo_box_fill ( - EASYSETUP_PROVIDER_COMBO_BOX (self->combo_account_serviceprovider), priv->presets, list_mcc_ids); + EASYSETUP_PROVIDER_COMBO_BOX (self->combo_account_serviceprovider), priv->presets, mcc); } static void @@ -482,7 +482,7 @@ create_page_account_details (ModestEasysetupWizardDialog *self) mcc_id = 244; } - easysetup_country_combo_box_set_active_country_id ( + easysetup_country_combo_box_set_active_country_mcc ( EASYSETUP_COUNTRY_COMBO_BOX (self->combo_account_country), mcc_id); diff --git a/src/maemo/easysetup/modest-presets.c b/src/maemo/easysetup/modest-presets.c index d3c5553..3ac56dd 100644 --- a/src/maemo/easysetup/modest-presets.c +++ b/src/maemo/easysetup/modest-presets.c @@ -63,8 +63,6 @@ modest_presets_new (const gchar *presetfile) g_free (presets); return NULL; } - - /* TODO: Unobfuscate an obfuscated file and then load it with g_key_file_load_from_data() instead. */ if (!g_key_file_load_from_file (presets->keyfile, presetfile, G_KEY_FILE_NONE, &err)) { @@ -278,14 +276,6 @@ modest_presets_get_info_server_security (ModestPresets *self, const gchar *provi } } - /* debug */ -/* g_message ("provider id: %s, apop:%s, secure-incoming:%s, altport: %s, secure-smtp: %s", */ -/* provider_id, */ -/* info & MODEST_PRESETS_SECURITY_APOP ? "yes" : "no", */ -/* info & MODEST_PRESETS_SECURITY_SECURE_INCOMING ? "yes" : "no", */ -/* info & MODEST_PRESETS_SECURITY_SECURE_INCOMING_ALTERNATE_PORT ? "yes" : "no", */ -/* info & MODEST_PRESETS_SECURITY_SECURE_SMTP ? "yes" : "no"); */ - return info; } -- 1.7.9.5