static int lmtp_client_data_next(struct lmtp_client *client, const char *line) { struct lmtp_rcpt *rcpt; unsigned int i, count; rcpt = array_get_modifiable(&client->recipients, &count); for (i = client->rcpt_next_data_idx; i < count; i++) { if (rcpt[i].failed) { /* already called rcpt_to_callback with failure */ continue; } client->rcpt_next_data_idx = i + 1; rcpt[i].failed = line[0] != '2'; rcpt[i].data_callback(!rcpt[i].failed, line, rcpt[i].context); if (client->protocol == LMTP_CLIENT_PROTOCOL_LMTP) break; } if (client->rcpt_next_data_idx < count) return 0; o_stream_send_str(client->output, "QUIT\r\n"); lmtp_client_close(client); return -1; }
void lmtp_client_fail(struct lmtp_client *client, const char *line) { struct lmtp_rcpt *recipients; unsigned int i, count; client->global_fail_string = p_strdup(client->pool, line); lmtp_client_ref(client); recipients = array_get_modifiable(&client->recipients, &count); for (i = client->rcpt_next_receive_idx; i < count; i++) { recipients[i].rcpt_to_callback(FALSE, line, recipients[i].context); recipients[i].failed = TRUE; } client->rcpt_next_receive_idx = count; for (i = client->rcpt_next_data_idx; i < count; i++) { if (!recipients[i].failed) { recipients[i].data_callback(FALSE, line, recipients[i].context); } } client->rcpt_next_data_idx = count; lmtp_client_close(client); lmtp_client_unref(&client); }
static void lmtp_client_fail_full(struct lmtp_client *client, const char *line, bool remote) { enum lmtp_client_result result; struct lmtp_rcpt *recipients; unsigned int i, count; client->global_fail_string = p_strdup(client->pool, line); client->global_remote_failure = remote; result = remote ? LMTP_CLIENT_RESULT_REMOTE_ERROR : LMTP_CLIENT_RESULT_INTERNAL_ERROR; lmtp_client_ref(client); recipients = array_get_modifiable(&client->recipients, &count); for (i = client->rcpt_next_receive_idx; i < count; i++) { recipients[i].rcpt_to_callback(result, line, recipients[i].context); recipients[i].failed = TRUE; } client->rcpt_next_receive_idx = count; for (i = client->rcpt_next_data_idx; i < count; i++) { if (!recipients[i].failed) { recipients[i].data_callback(result, line, recipients[i].context); } } client->rcpt_next_data_idx = count; lmtp_client_close(client); lmtp_client_unref(&client); }
void lmtp_client_deinit(struct lmtp_client **_client) { struct lmtp_client *client = *_client; *_client = NULL; lmtp_client_close(client); lmtp_client_unref(&client); }