static bool test_string_set(struct ConfigSet *cs, struct Buffer *err) { log_line(__func__); const char *valid[] = { "*****@*****.**", "*****@*****.**", NULL }; const char *name = "Damson"; char *addr = NULL; int rc; for (unsigned int i = 0; i < mutt_array_size(valid); i++) { mutt_buffer_reset(err); rc = cs_str_string_set(cs, name, valid[i], err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", err->data); return false; } addr = VarDamson ? VarDamson->mailbox : NULL; if (!TEST_CHECK(mutt_str_strcmp(addr, valid[i]) == 0)) { TEST_MSG("Value of %s wasn't changed\n", name); return false; } TEST_MSG("%s = '%s', set by '%s'\n", name, NONULL(addr), NONULL(valid[i])); } name = "Elderberry"; for (unsigned int i = 0; i < mutt_array_size(valid); i++) { mutt_buffer_reset(err); rc = cs_str_string_set(cs, name, valid[i], err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", err->data); return false; } addr = VarElderberry ? VarElderberry->mailbox : NULL; if (!TEST_CHECK(mutt_str_strcmp(addr, valid[i]) == 0)) { TEST_MSG("Value of %s wasn't changed\n", name); return false; } TEST_MSG("%s = '%s', set by '%s'\n", name, NONULL(addr), NONULL(valid[i])); } log_line(__func__); return true; }
static bool test_native_set(struct ConfigSet *cs, struct Buffer *err) { log_line(__func__); struct Address *a = address_new("*****@*****.**"); const char *name = "Ilama"; char *addr = NULL; bool result = false; mutt_buffer_reset(err); int rc = cs_str_native_set(cs, name, (intptr_t) a, err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", err->data); goto tbns_out; } addr = VarIlama ? VarIlama->mailbox : NULL; if (!TEST_CHECK(mutt_str_strcmp(addr, a->mailbox) == 0)) { TEST_MSG("Value of %s wasn't changed\n", name); goto tbns_out; } TEST_MSG("%s = '%s', set by '%s'\n", name, NONULL(addr), a->mailbox); name = "Jackfruit"; mutt_buffer_reset(err); rc = cs_str_native_set(cs, name, 0, err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", err->data); goto tbns_out; } if (!TEST_CHECK(VarJackfruit == NULL)) { TEST_MSG("Value of %s wasn't changed\n", name); goto tbns_out; } addr = VarJackfruit ? VarJackfruit->mailbox : NULL; TEST_MSG("%s = '%s', set by NULL\n", name, NONULL(addr)); log_line(__func__); result = true; tbns_out: address_free(&a); return result; }
void config_address(void) { struct Buffer err; mutt_buffer_init(&err); err.dsize = 256; err.data = mutt_mem_calloc(1, err.dsize); mutt_buffer_reset(&err); struct ConfigSet *cs = cs_new(30); address_init(cs); dont_fail = true; if (!cs_register_variables(cs, Vars, 0)) return; dont_fail = false; cs_add_listener(cs, log_listener); set_list(cs); TEST_CHECK(test_initial_values(cs, &err)); TEST_CHECK(test_string_set(cs, &err)); TEST_CHECK(test_string_get(cs, &err)); TEST_CHECK(test_native_set(cs, &err)); TEST_CHECK(test_native_get(cs, &err)); TEST_CHECK(test_reset(cs, &err)); TEST_CHECK(test_validator(cs, &err)); TEST_CHECK(test_inherit(cs, &err)); cs_free(&cs); FREE(&err.data); }
static bool test_string_get(struct ConfigSet *cs, struct Buffer *err) { log_line(__func__); const char *name = "Fig"; char *addr = NULL; mutt_buffer_reset(err); int rc = cs_str_string_get(cs, name, err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("Get failed: %s\n", err->data); return false; } addr = VarFig ? VarFig->mailbox : NULL; TEST_MSG("%s = '%s', '%s'\n", name, NONULL(addr), err->data); name = "Guava"; mutt_buffer_reset(err); rc = cs_str_string_get(cs, name, err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("Get failed: %s\n", err->data); return false; } addr = VarGuava ? VarGuava->mailbox : NULL; TEST_MSG("%s = '%s', '%s'\n", name, NONULL(addr), err->data); name = "Hawthorn"; rc = cs_str_string_set(cs, name, "hawthorn", err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) return false; mutt_buffer_reset(err); rc = cs_str_string_get(cs, name, err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("Get failed: %s\n", err->data); return false; } addr = VarHawthorn ? VarHawthorn->mailbox : NULL; TEST_MSG("%s = '%s', '%s'\n", name, NONULL(addr), err->data); log_line(__func__); return true; }
/** * mutt_parse_icommand - Parse an informational command * @param line Command to execute * @param err Buffer for error messages * @retval #MUTT_CMD_SUCCESS Success * @retval #MUTT_CMD_ERROR Error (no message): command not found * @retval #MUTT_CMD_ERROR Error with message: command failed * @retval #MUTT_CMD_WARNING Warning with message: command failed */ enum CommandResult mutt_parse_icommand(/* const */ char *line, struct Buffer *err) { if (!line || !*line || !err) return MUTT_CMD_ERROR; enum CommandResult rc = MUTT_CMD_ERROR; struct Buffer expn, token; mutt_buffer_init(&expn); mutt_buffer_init(&token); expn.data = expn.dptr = line; expn.dsize = mutt_str_strlen(line); mutt_buffer_reset(err); SKIPWS(expn.dptr); while (*expn.dptr) { mutt_extract_token(&token, &expn, 0); for (size_t i = 0; ICommandList[i].name; i++) { if (mutt_str_strcmp(token.data, ICommandList[i].name) != 0) continue; rc = ICommandList[i].func(&token, &expn, ICommandList[i].data, err); if (rc != 0) goto finish; break; /* Continue with next command */ } } finish: if (expn.destroy) FREE(&expn.data); return rc; }
static bool test_native_get(struct ConfigSet *cs, struct Buffer *err) { log_line(__func__); const char *name = "Kumquat"; if (!TEST_CHECK(cs_str_string_set(cs, name, "*****@*****.**", err) != INT_MIN)) return false; mutt_buffer_reset(err); intptr_t value = cs_str_native_get(cs, name, err); struct Address *a = (struct Address *) value; if (!TEST_CHECK(VarKumquat == a)) { TEST_MSG("Get failed: %s\n", err->data); return false; } char *addr1 = VarKumquat ? VarKumquat->mailbox : NULL; char *addr2 = a ? a->mailbox : NULL; TEST_MSG("%s = '%s', '%s'\n", name, NONULL(addr1), NONULL(addr2)); log_line(__func__); return true; }
void config_set(void) { log_line(__func__); struct Buffer err; mutt_buffer_init(&err); err.dsize = 256; err.data = mutt_mem_calloc(1, err.dsize); mutt_buffer_reset(&err); struct ConfigSet *cs = cs_new(30); if (!TEST_CHECK(cs != NULL)) return; cs_add_listener(cs, log_listener); cs_add_listener(cs, log_listener); /* dupe */ cs_remove_listener(cs, log_listener); cs_remove_listener(cs, log_listener); /* non-existant */ const struct ConfigSetType cst_dummy = { "dummy", NULL, NULL, NULL, NULL, NULL, NULL, }; if (TEST_CHECK(!cs_register_type(cs, DT_STRING, &cst_dummy))) { TEST_MSG("Expected error\n"); } else { TEST_MSG("This test should have failed\n"); return; } const struct ConfigSetType cst_dummy2 = { "dummy2", dummy_string_set, dummy_string_get, dummy_native_set, dummy_native_get, dummy_reset, dummy_destroy, }; if (TEST_CHECK(!cs_register_type(cs, 25, &cst_dummy2))) { TEST_MSG("Expected error\n"); } else { TEST_MSG("This test should have failed\n"); return; } bool_init(cs); bool_init(cs); /* second one should fail */ if (TEST_CHECK(!cs_register_variables(cs, Vars, 0))) { TEST_MSG("Expected error\n"); } else { TEST_MSG("This test should have failed\n"); return; } const char *name = "Unknown"; int result = cs_str_string_set(cs, name, "hello", &err); if (TEST_CHECK(CSR_RESULT(result) == CSR_ERR_UNKNOWN)) { TEST_MSG("Expected error: Unknown var '%s'\n", name); } else { TEST_MSG("This should have failed 1\n"); return; } result = cs_str_string_get(cs, name, &err); if (TEST_CHECK(CSR_RESULT(result) == CSR_ERR_UNKNOWN)) { TEST_MSG("Expected error: Unknown var '%s'\n", name); } else { TEST_MSG("This should have failed 2\n"); return; } result = cs_str_native_set(cs, name, IP "hello", &err); if (TEST_CHECK(CSR_RESULT(result) == CSR_ERR_UNKNOWN)) { TEST_MSG("Expected error: Unknown var '%s'\n", name); } else { TEST_MSG("This should have failed 3\n"); return; } intptr_t native = cs_str_native_get(cs, name, &err); if (TEST_CHECK(native == INT_MIN)) { TEST_MSG("Expected error: Unknown var '%s'\n", name); } else { TEST_MSG("This should have failed 4\n"); return; } struct HashElem *he = cs_get_elem(cs, "Banana"); if (!TEST_CHECK(he != NULL)) return; set_list(cs); const struct ConfigSetType *cst = cs_get_type_def(cs, 15); if (!TEST_CHECK(!cst)) return; cs_free(&cs); FREE(&err.data); log_line(__func__); }
/** * imap_auth_gss - GSS Authentication support * @param adata Imap Account data * @param method Name of this authentication method * @retval enum Result, e.g. #IMAP_AUTH_SUCCESS */ enum ImapAuthRes imap_auth_gss(struct ImapAccountData *adata, const char *method) { gss_buffer_desc request_buf, send_token; gss_buffer_t sec_token; gss_name_t target_name; gss_ctx_id_t context; gss_OID mech_name; char server_conf_flags; gss_qop_t quality; int cflags; OM_uint32 maj_stat, min_stat; unsigned long buf_size; int rc, retval = IMAP_AUTH_FAILURE; if (!(adata->capabilities & IMAP_CAP_AUTH_GSSAPI)) return IMAP_AUTH_UNAVAIL; if (mutt_account_getuser(&adata->conn->account) < 0) return IMAP_AUTH_FAILURE; struct Buffer *buf1 = mutt_buffer_pool_get(); struct Buffer *buf2 = mutt_buffer_pool_get(); /* get an IMAP service ticket for the server */ mutt_buffer_printf(buf1, "imap@%s", adata->conn->account.host); request_buf.value = buf1->data; request_buf.length = mutt_buffer_len(buf1); maj_stat = gss_import_name(&min_stat, &request_buf, gss_nt_service_name, &target_name); if (maj_stat != GSS_S_COMPLETE) { mutt_debug(LL_DEBUG2, "Couldn't get service name for [%s]\n", buf1); retval = IMAP_AUTH_UNAVAIL; goto cleanup; } else if (C_DebugLevel >= 2) { gss_display_name(&min_stat, target_name, &request_buf, &mech_name); mutt_debug(LL_DEBUG2, "Using service name [%s]\n", (char *) request_buf.value); gss_release_buffer(&min_stat, &request_buf); } /* Acquire initial credentials - without a TGT GSSAPI is UNAVAIL */ sec_token = GSS_C_NO_BUFFER; context = GSS_C_NO_CONTEXT; /* build token */ maj_stat = gss_init_sec_context(&min_stat, GSS_C_NO_CREDENTIAL, &context, target_name, GSS_C_NO_OID, GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG, 0, GSS_C_NO_CHANNEL_BINDINGS, sec_token, NULL, &send_token, (unsigned int *) &cflags, NULL); if ((maj_stat != GSS_S_COMPLETE) && (maj_stat != GSS_S_CONTINUE_NEEDED)) { print_gss_error(maj_stat, min_stat); mutt_debug(LL_DEBUG1, "Error acquiring credentials - no TGT?\n"); gss_release_name(&min_stat, &target_name); retval = IMAP_AUTH_UNAVAIL; goto cleanup; } /* now begin login */ mutt_message(_("Authenticating (GSSAPI)...")); imap_cmd_start(adata, "AUTHENTICATE GSSAPI"); /* expect a null continuation response ("+") */ do rc = imap_cmd_step(adata); while (rc == IMAP_CMD_CONTINUE); if (rc != IMAP_CMD_RESPOND) { mutt_debug(LL_DEBUG2, "Invalid response from server: %s\n", buf1); gss_release_name(&min_stat, &target_name); goto bail; } /* now start the security context initialisation loop... */ mutt_debug(LL_DEBUG2, "Sending credentials\n"); mutt_b64_buffer_encode(buf1, send_token.value, send_token.length); gss_release_buffer(&min_stat, &send_token); mutt_buffer_addstr(buf1, "\r\n"); mutt_socket_send(adata->conn, mutt_b2s(buf1)); while (maj_stat == GSS_S_CONTINUE_NEEDED) { /* Read server data */ do rc = imap_cmd_step(adata); while (rc == IMAP_CMD_CONTINUE); if (rc != IMAP_CMD_RESPOND) { mutt_debug(LL_DEBUG1, "#1 Error receiving server response\n"); gss_release_name(&min_stat, &target_name); goto bail; } if (mutt_b64_buffer_decode(buf2, adata->buf + 2) < 0) { mutt_debug(LL_DEBUG1, "Invalid base64 server response\n"); gss_release_name(&min_stat, &target_name); goto err_abort_cmd; } request_buf.value = buf2->data; request_buf.length = mutt_buffer_len(buf2); sec_token = &request_buf; /* Write client data */ maj_stat = gss_init_sec_context( &min_stat, GSS_C_NO_CREDENTIAL, &context, target_name, GSS_C_NO_OID, GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG, 0, GSS_C_NO_CHANNEL_BINDINGS, sec_token, NULL, &send_token, (unsigned int *) &cflags, NULL); if ((maj_stat != GSS_S_COMPLETE) && (maj_stat != GSS_S_CONTINUE_NEEDED)) { print_gss_error(maj_stat, min_stat); mutt_debug(LL_DEBUG1, "Error exchanging credentials\n"); gss_release_name(&min_stat, &target_name); goto err_abort_cmd; } mutt_b64_buffer_encode(buf1, send_token.value, send_token.length); gss_release_buffer(&min_stat, &send_token); mutt_buffer_addstr(buf1, "\r\n"); mutt_socket_send(adata->conn, mutt_b2s(buf1)); } gss_release_name(&min_stat, &target_name); /* get security flags and buffer size */ do rc = imap_cmd_step(adata); while (rc == IMAP_CMD_CONTINUE); if (rc != IMAP_CMD_RESPOND) { mutt_debug(LL_DEBUG1, "#2 Error receiving server response\n"); goto bail; } if (mutt_b64_buffer_decode(buf2, adata->buf + 2) < 0) { mutt_debug(LL_DEBUG1, "Invalid base64 server response\n"); goto err_abort_cmd; } request_buf.value = buf2->data; request_buf.length = mutt_buffer_len(buf2); maj_stat = gss_unwrap(&min_stat, context, &request_buf, &send_token, &cflags, &quality); if (maj_stat != GSS_S_COMPLETE) { print_gss_error(maj_stat, min_stat); mutt_debug(LL_DEBUG2, "Couldn't unwrap security level data\n"); gss_release_buffer(&min_stat, &send_token); goto err_abort_cmd; } mutt_debug(LL_DEBUG2, "Credential exchange complete\n"); /* first octet is security levels supported. We want NONE */ server_conf_flags = ((char *) send_token.value)[0]; if (!(((char *) send_token.value)[0] & GSS_AUTH_P_NONE)) { mutt_debug(LL_DEBUG2, "Server requires integrity or privacy\n"); gss_release_buffer(&min_stat, &send_token); goto err_abort_cmd; } /* we don't care about buffer size if we don't wrap content. But here it is */ ((char *) send_token.value)[0] = '\0'; buf_size = ntohl(*((long *) send_token.value)); gss_release_buffer(&min_stat, &send_token); mutt_debug(LL_DEBUG2, "Unwrapped security level flags: %c%c%c\n", (server_conf_flags & GSS_AUTH_P_NONE) ? 'N' : '-', (server_conf_flags & GSS_AUTH_P_INTEGRITY) ? 'I' : '-', (server_conf_flags & GSS_AUTH_P_PRIVACY) ? 'P' : '-'); mutt_debug(LL_DEBUG2, "Maximum GSS token size is %ld\n", buf_size); /* agree to terms (hack!) */ buf_size = htonl(buf_size); /* not relevant without integrity/privacy */ mutt_buffer_reset(buf1); mutt_buffer_addch(buf1, GSS_AUTH_P_NONE); mutt_buffer_addstr_n(buf1, ((char *) &buf_size) + 1, 3); /* server decides if principal can log in as user */ mutt_buffer_addstr(buf1, adata->conn->account.user); request_buf.value = buf1->data; request_buf.length = mutt_buffer_len(buf1); maj_stat = gss_wrap(&min_stat, context, 0, GSS_C_QOP_DEFAULT, &request_buf, &cflags, &send_token); if (maj_stat != GSS_S_COMPLETE) { mutt_debug(LL_DEBUG2, "Error creating login request\n"); goto err_abort_cmd; } mutt_b64_buffer_encode(buf1, send_token.value, send_token.length); mutt_debug(LL_DEBUG2, "Requesting authorisation as %s\n", adata->conn->account.user); mutt_buffer_addstr(buf1, "\r\n"); mutt_socket_send(adata->conn, mutt_b2s(buf1)); /* Joy of victory or agony of defeat? */ do rc = imap_cmd_step(adata); while (rc == IMAP_CMD_CONTINUE); if (rc == IMAP_CMD_RESPOND) { mutt_debug(LL_DEBUG1, "Unexpected server continuation request\n"); goto err_abort_cmd; } if (imap_code(adata->buf)) { /* flush the security context */ mutt_debug(LL_DEBUG2, "Releasing GSS credentials\n"); maj_stat = gss_delete_sec_context(&min_stat, &context, &send_token); if (maj_stat != GSS_S_COMPLETE) mutt_debug(LL_DEBUG1, "Error releasing credentials\n"); /* send_token may contain a notification to the server to flush * credentials. RFC1731 doesn't specify what to do, and since this * support is only for authentication, we'll assume the server knows * enough to flush its own credentials */ gss_release_buffer(&min_stat, &send_token); retval = IMAP_AUTH_SUCCESS; goto cleanup; } else goto bail; err_abort_cmd: mutt_socket_send(adata->conn, "*\r\n"); do rc = imap_cmd_step(adata); while (rc == IMAP_CMD_CONTINUE); bail: mutt_error(_("GSSAPI authentication failed")); retval = IMAP_AUTH_FAILURE; cleanup: mutt_buffer_pool_release(&buf1); mutt_buffer_pool_release(&buf2); return retval; }
static bool test_initial_values(struct ConfigSet *cs, struct Buffer *err) { log_line(__func__); TEST_MSG("Apple = '%s'\n", VarApple->mailbox); TEST_MSG("Banana = '%s'\n", VarBanana->mailbox); const char *apple_orig = "*****@*****.**"; const char *banana_orig = "*****@*****.**"; if (!TEST_CHECK(mutt_str_strcmp(VarApple->mailbox, apple_orig) == 0)) { TEST_MSG("Error: initial values were wrong\n"); return false; } if (!TEST_CHECK(mutt_str_strcmp(VarBanana->mailbox, banana_orig) == 0)) { TEST_MSG("Error: initial values were wrong\n"); return false; } cs_str_string_set(cs, "Apple", "*****@*****.**", err); cs_str_string_set(cs, "Banana", NULL, err); struct Buffer value; mutt_buffer_init(&value); value.dsize = 256; value.data = mutt_mem_calloc(1, value.dsize); mutt_buffer_reset(&value); int rc; mutt_buffer_reset(&value); rc = cs_str_initial_get(cs, "Apple", &value); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", value.data); FREE(&value.data); return false; } if (!TEST_CHECK(mutt_str_strcmp(value.data, apple_orig) == 0)) { TEST_MSG("Apple's initial value is wrong: '%s'\n", value.data); FREE(&value.data); return false; } TEST_MSG("Apple = '%s'\n", VarApple->mailbox); TEST_MSG("Apple's initial value is '%s'\n", value.data); mutt_buffer_reset(&value); rc = cs_str_initial_get(cs, "Banana", &value); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", value.data); FREE(&value.data); return false; } if (!TEST_CHECK(mutt_str_strcmp(value.data, banana_orig) == 0)) { TEST_MSG("Banana's initial value is wrong: '%s'\n", value.data); FREE(&value.data); return false; } TEST_MSG("Banana = '%s'\n", VarBanana ? VarBanana->mailbox : ""); TEST_MSG("Banana's initial value is '%s'\n", NONULL(value.data)); mutt_buffer_reset(&value); rc = cs_str_initial_set(cs, "Cherry", "*****@*****.**", &value); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", value.data); FREE(&value.data); return false; } mutt_buffer_reset(&value); rc = cs_str_initial_set(cs, "Cherry", "*****@*****.**", &value); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", value.data); FREE(&value.data); return false; } mutt_buffer_reset(&value); rc = cs_str_initial_get(cs, "Cherry", &value); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", value.data); FREE(&value.data); return false; } TEST_MSG("Cherry = '%s'\n", VarCherry ? VarCherry->mailbox : ""); TEST_MSG("Cherry's initial value is '%s'\n", NONULL(value.data)); FREE(&value.data); log_line(__func__); return true; }
static bool test_inherit(struct ConfigSet *cs, struct Buffer *err) { log_line(__func__); bool result = false; const char *account = "fruit"; const char *parent = "Quince"; char child[128]; snprintf(child, sizeof(child), "%s:%s", account, parent); const char *AccountVarAddr[] = { parent, NULL, }; struct CfgAccount *ac = ac_new(cs, account, AccountVarAddr); // set parent mutt_buffer_reset(err); int rc = cs_str_string_set(cs, parent, "*****@*****.**", err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("Error: %s\n", err->data); goto ti_out; } dump_native(cs, parent, child); // set child mutt_buffer_reset(err); rc = cs_str_string_set(cs, child, "*****@*****.**", err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("Error: %s\n", err->data); goto ti_out; } dump_native(cs, parent, child); // reset child mutt_buffer_reset(err); rc = cs_str_reset(cs, child, err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("Error: %s\n", err->data); goto ti_out; } dump_native(cs, parent, child); // reset parent mutt_buffer_reset(err); rc = cs_str_reset(cs, parent, err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("Error: %s\n", err->data); goto ti_out; } dump_native(cs, parent, child); log_line(__func__); result = true; ti_out: ac_free(cs, &ac); return result; }
static bool test_validator(struct ConfigSet *cs, struct Buffer *err) { log_line(__func__); char *addr = NULL; struct Address *a = address_new("*****@*****.**"); bool result = false; const char *name = "Nectarine"; mutt_buffer_reset(err); int rc = cs_str_string_set(cs, name, "*****@*****.**", err); if (TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", err->data); } else { TEST_MSG("%s\n", err->data); goto tv_out; } addr = VarNectarine ? VarNectarine->mailbox : NULL; TEST_MSG("Address: %s = %s\n", name, NONULL(addr)); mutt_buffer_reset(err); rc = cs_str_native_set(cs, name, IP a, err); if (TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", err->data); } else { TEST_MSG("%s\n", err->data); goto tv_out; } addr = VarNectarine ? VarNectarine->mailbox : NULL; TEST_MSG("Native: %s = %s\n", name, NONULL(addr)); name = "Olive"; mutt_buffer_reset(err); rc = cs_str_string_set(cs, name, "*****@*****.**", err); if (TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", err->data); } else { TEST_MSG("%s\n", err->data); goto tv_out; } addr = VarOlive ? VarOlive->mailbox : NULL; TEST_MSG("Address: %s = %s\n", name, NONULL(addr)); mutt_buffer_reset(err); rc = cs_str_native_set(cs, name, IP a, err); if (TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", err->data); } else { TEST_MSG("%s\n", err->data); goto tv_out; } addr = VarOlive ? VarOlive->mailbox : NULL; TEST_MSG("Native: %s = %s\n", name, NONULL(addr)); name = "Papaya"; mutt_buffer_reset(err); rc = cs_str_string_set(cs, name, "*****@*****.**", err); if (TEST_CHECK(CSR_RESULT(rc) != CSR_SUCCESS)) { TEST_MSG("Expected error: %s\n", err->data); } else { TEST_MSG("%s\n", err->data); goto tv_out; } addr = VarPapaya ? VarPapaya->mailbox : NULL; TEST_MSG("Address: %s = %s\n", name, NONULL(addr)); mutt_buffer_reset(err); rc = cs_str_native_set(cs, name, IP a, err); if (TEST_CHECK(CSR_RESULT(rc) != CSR_SUCCESS)) { TEST_MSG("Expected error: %s\n", err->data); } else { TEST_MSG("%s\n", err->data); goto tv_out; } addr = VarPapaya ? VarPapaya->mailbox : NULL; TEST_MSG("Native: %s = %s\n", name, NONULL(addr)); result = true; tv_out: address_free(&a); log_line(__func__); return result; }
static bool test_reset(struct ConfigSet *cs, struct Buffer *err) { log_line(__func__); const char *name = "Lemon"; mutt_buffer_reset(err); char *addr = VarLemon ? VarLemon->mailbox : NULL; TEST_MSG("Initial: %s = '%s'\n", name, NONULL(addr)); int rc = cs_str_string_set(cs, name, "*****@*****.**", err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) return false; addr = VarLemon ? VarLemon->mailbox : NULL; TEST_MSG("Set: %s = '%s'\n", name, NONULL(addr)); rc = cs_str_reset(cs, name, err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", err->data); return false; } addr = VarLemon ? VarLemon->mailbox : NULL; if (!TEST_CHECK(mutt_str_strcmp(addr, "*****@*****.**") == 0)) { TEST_MSG("Value of %s wasn't changed\n", name); return false; } TEST_MSG("Reset: %s = '%s'\n", name, NONULL(addr)); name = "Mango"; mutt_buffer_reset(err); TEST_MSG("Initial: %s = '%s'\n", name, VarMango->mailbox); dont_fail = true; rc = cs_str_string_set(cs, name, "*****@*****.**", err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) return false; TEST_MSG("Set: %s = '%s'\n", name, VarMango->mailbox); dont_fail = false; rc = cs_str_reset(cs, name, err); if (TEST_CHECK(CSR_RESULT(rc) != CSR_SUCCESS)) { TEST_MSG("Expected error: %s\n", err->data); } else { TEST_MSG("%s\n", err->data); return false; } if (!TEST_CHECK(mutt_str_strcmp(VarMango->mailbox, "*****@*****.**") == 0)) { TEST_MSG("Value of %s changed\n", name); return false; } TEST_MSG("Reset: %s = '%s'\n", name, VarMango->mailbox); log_line(__func__); return true; }
/** * dump_config - Write all the config to a file * @param cs ConfigSet to dump * @param style Output style, e.g. #CS_DUMP_STYLE_MUTT * @param flags Flags, see #ConfigDumpFlags * @param fp File to write config to */ bool dump_config(struct ConfigSet *cs, enum CsDumpStyle style, ConfigDumpFlags flags, FILE *fp) { if (!cs) return false; struct HashElem *he = NULL; struct HashElem **list = get_elem_list(cs); if (!list) return false; /* LCOV_EXCL_LINE */ bool result = true; struct Buffer *value = mutt_buffer_alloc(256); struct Buffer *initial = mutt_buffer_alloc(256); struct Buffer *tmp = mutt_buffer_alloc(256); for (size_t i = 0; list[i]; i++) { mutt_buffer_reset(value); mutt_buffer_reset(initial); he = list[i]; const int type = DTYPE(he->type); if ((type == DT_SYNONYM) && !(flags & CS_DUMP_SHOW_SYNONYMS)) continue; // if ((type == DT_DISABLED) && !(flags & CS_DUMP_SHOW_DISABLED)) // continue; if (type != DT_SYNONYM) { /* If necessary, get the current value */ if ((flags & CS_DUMP_ONLY_CHANGED) || !(flags & CS_DUMP_HIDE_VALUE) || (flags & CS_DUMP_SHOW_DEFAULTS)) { int rc = cs_he_string_get(cs, he, value); if (CSR_RESULT(rc) != CSR_SUCCESS) { result = false; /* LCOV_EXCL_LINE */ break; /* LCOV_EXCL_LINE */ } const struct ConfigDef *cdef = he->data; if (IS_SENSITIVE(*cdef) && (flags & CS_DUMP_HIDE_SENSITIVE) && !mutt_buffer_is_empty(value)) { mutt_buffer_reset(value); mutt_buffer_addstr(value, "***"); } if ((type == DT_PATH) && (value->data[0] == '/')) mutt_pretty_mailbox(value->data, value->dsize); if ((type != DT_BOOL) && (type != DT_NUMBER) && (type != DT_LONG) && (type != DT_QUAD) && !(flags & CS_DUMP_NO_ESCAPING)) { mutt_buffer_reset(tmp); pretty_var(value->data, tmp); mutt_buffer_strcpy(value, tmp->data); } } /* If necessary, get the default value */ if (flags & (CS_DUMP_ONLY_CHANGED | CS_DUMP_SHOW_DEFAULTS)) { int rc = cs_he_initial_get(cs, he, initial); if (CSR_RESULT(rc) != CSR_SUCCESS) { result = false; /* LCOV_EXCL_LINE */ break; /* LCOV_EXCL_LINE */ } if ((type == DT_PATH) && !(he->type & DT_MAILBOX)) mutt_pretty_mailbox(initial->data, initial->dsize); if ((type != DT_BOOL) && (type != DT_NUMBER) && (type != DT_LONG) && (type != DT_QUAD) && !(flags & CS_DUMP_NO_ESCAPING)) { mutt_buffer_reset(tmp); pretty_var(initial->data, tmp); mutt_buffer_strcpy(initial, tmp->data); } } } if (style == CS_DUMP_STYLE_MUTT) dump_config_mutt(cs, he, value, initial, flags, fp); else dump_config_neo(cs, he, value, initial, flags, fp); } FREE(&list); mutt_buffer_free(&value); mutt_buffer_free(&initial); mutt_buffer_free(&tmp); return result; }