bool command_exec(struct client_command_context *cmd) { const struct command_hook *hook; long long diff; bool finished; if (cmd->last_ioloop_time.tv_sec != 0) { diff = timeval_diff_usecs(&ioloop_timeval, &cmd->last_ioloop_time); if (diff > 0) cmd->usecs_in_ioloop += diff; } array_foreach(&command_hooks, hook) hook->pre(cmd); finished = cmd->func(cmd); array_foreach(&command_hooks, hook) hook->post(cmd); if (cmd->state == CLIENT_COMMAND_STATE_DONE) finished = TRUE; if (!finished) { io_loop_time_refresh(); cmd->last_ioloop_time = ioloop_timeval; } return finished; }
void client_send_tagline(struct client_command_context *cmd, const char *data) { struct client *client = cmd->client; const char *tag = cmd->tag; int time_msecs; if (client->output->closed || cmd->cancel) return; i_assert(!cmd->tagline_sent); cmd->tagline_sent = TRUE; if (tag == NULL || *tag == '\0') tag = "*"; T_BEGIN { string_t *str = t_str_new(256); str_printfa(str, "%s %s", tag, data); if (cmd->start_time.tv_sec != 0) { if (str_data(str)[str_len(str)-1] == '.') str_truncate(str, str_len(str)-1); io_loop_time_refresh(); time_msecs = timeval_diff_msecs(&ioloop_timeval, &cmd->start_time); time_msecs -= cmd->usecs_in_ioloop/1000; if (time_msecs >= 0) { str_printfa(str, " (%d.%03d secs).", time_msecs/1000, time_msecs%1000); } } str_append(str, "\r\n"); o_stream_nsend(client->output, str_data(str), str_len(str)); } T_END; client->last_output = ioloop_time; }
static int driver_mysql_connect(struct sql_db *_db) { struct mysql_db *db = (struct mysql_db *)_db; const char *unix_socket, *host; unsigned long client_flags = db->client_flags; unsigned int secs_used; bool failed; i_assert(db->api.state == SQL_DB_STATE_DISCONNECTED); sql_db_set_state(&db->api, SQL_DB_STATE_CONNECTING); if (*db->host == '/') { unix_socket = db->host; host = NULL; } else { unix_socket = NULL; host = db->host; } if (db->option_file != NULL) { mysql_options(db->mysql, MYSQL_READ_DEFAULT_FILE, db->option_file); } mysql_options(db->mysql, MYSQL_READ_DEFAULT_GROUP, db->option_group != NULL ? db->option_group : "client"); if (!db->ssl_set && (db->ssl_ca != NULL || db->ssl_ca_path != NULL)) { #ifdef HAVE_MYSQL_SSL mysql_ssl_set(db->mysql, db->ssl_key, db->ssl_cert, db->ssl_ca, db->ssl_ca_path #ifdef HAVE_MYSQL_SSL_CIPHER , db->ssl_cipher #endif ); db->ssl_set = TRUE; #else i_fatal("mysql: SSL support not compiled in " "(remove ssl_ca and ssl_ca_path settings)"); #endif } alarm(SQL_CONNECT_TIMEOUT_SECS); #ifdef CLIENT_MULTI_RESULTS client_flags |= CLIENT_MULTI_RESULTS; #endif /* CLIENT_MULTI_RESULTS allows the use of stored procedures */ failed = mysql_real_connect(db->mysql, host, db->user, db->password, db->dbname, db->port, unix_socket, client_flags) == NULL; secs_used = SQL_CONNECT_TIMEOUT_SECS - alarm(0); if (failed) { /* connecting could have taken a while. make sure that any timeouts that get added soon will get a refreshed timestamp. */ io_loop_time_refresh(); if (db->api.connect_delay < secs_used) db->api.connect_delay = secs_used; sql_db_set_state(&db->api, SQL_DB_STATE_DISCONNECTED); i_error("%s: Connect failed to database (%s): %s - " "waiting for %u seconds before retry", mysql_prefix(db), db->dbname, mysql_error(db->mysql), db->api.connect_delay); return -1; } else { db->last_success = ioloop_time; sql_db_set_state(&db->api, SQL_DB_STATE_IDLE); return 1; } }
static int lmtp_client_send_data(struct lmtp_client *client) { const unsigned char *data; unsigned char add; size_t i, size; bool sent_bytes = FALSE; int ret; if (client->output_finished) return 0; while ((ret = i_stream_read_more(client->data_input, &data, &size)) > 0) { add = '\0'; for (i = 0; i < size; i++) { if (data[i] == '\n') { if ((i == 0 && client->output_last != '\r') || (i > 0 && data[i-1] != '\r')) { /* missing CR */ add = '\r'; break; } } else if (data[i] == '.' && ((i == 0 && client->output_last == '\n') || (i > 0 && data[i-1] == '\n'))) { /* escape the dot */ add = '.'; break; } } if (i > 0) { if (o_stream_send(client->output, data, i) < 0) break; client->output_last = data[i-1]; i_stream_skip(client->data_input, i); sent_bytes = TRUE; } if (o_stream_get_buffer_used_size(client->output) >= 4096) { if ((ret = o_stream_flush(client->output)) < 0) break; if (ret == 0) { /* continue later */ o_stream_set_flush_pending(client->output, TRUE); return 0; } } if (add != '\0') { if (o_stream_send(client->output, &add, 1) < 0) break; client->output_last = add; } } if (client->data_input->stream_errno != 0) { i_error("lmtp client: read(%s) failed: %s", i_stream_get_name(client->data_input), i_stream_get_error(client->data_input)); lmtp_client_fail(client, "451 4.3.0 Internal failure while reading DATA input"); return -1; } if (sent_bytes && client->data_output_callback != NULL) client->data_output_callback(client->data_output_context); if (ret == 0 || ret == -2) { /* -2 can happen with tee istreams */ return 0; } if (client->output_last != '\n') { /* didn't end with CRLF */ o_stream_nsend(client->output, "\r\n", 2); } o_stream_nsend(client->output, ".\r\n", 3); client->output_finished = TRUE; io_loop_time_refresh(); client->times.data_sent = ioloop_timeval; return 0; }