Mercurial > dovecot > original-hg > dovecot-1.2
diff src/imap/client.c @ 3141:61abed5f7864 HEAD
Moved command-specific variables from struct client to struct
client_command_context and changed code to use it.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 05 Feb 2005 20:07:26 +0200 |
parents | 10d1fd8d0865 |
children | a3a72d5bdfce |
line wrap: on
line diff
--- a/src/imap/client.c Sat Feb 05 20:05:24 2005 +0200 +++ b/src/imap/client.c Sat Feb 05 20:07:26 2005 +0200 @@ -36,7 +36,9 @@ imap_max_line_length); client->last_input = ioloop_time; - client->cmd_pool = pool_alloconly_create("command pool", 8192); + client->cmd.pool = pool_alloconly_create("command pool", 8192); + client->cmd.client = client; + client->keywords.pool = pool_alloconly_create("mailbox_keywords", 512); client->namespaces = namespaces; @@ -62,7 +64,7 @@ /* try to deinitialize the command */ i_stream_close(client->input); o_stream_close(client->output); - ret = client->cmd_func(client); + ret = client->cmd.func(&client->cmd); i_assert(ret); } @@ -78,7 +80,7 @@ o_stream_unref(client->output); pool_unref(client->keywords.pool); - pool_unref(client->cmd_pool); + pool_unref(client->cmd.pool); i_free(client); /* quit the program */ @@ -119,9 +121,10 @@ CLIENT_OUTPUT_OPTIMAL_SIZE; } -void client_send_tagline(struct client *client, const char *data) +void client_send_tagline(struct client_command_context *cmd, const char *data) { - const char *tag = client->cmd_tag; + struct client *client = cmd->client; + const char *tag = cmd->tag; if (client->output->closed) return; @@ -135,9 +138,11 @@ (void)o_stream_send(client->output, "\r\n", 2); } -void client_send_command_error(struct client *client, const char *msg) +void client_send_command_error(struct client_command_context *cmd, + const char *msg) { - const char *error, *cmd; + struct client *client = cmd->client; + const char *error, *cmd_name; int fatal; if (msg == NULL) { @@ -148,17 +153,17 @@ } } - if (client->cmd_tag == NULL) + if (cmd->tag == NULL) error = t_strconcat("BAD Error in IMAP tag: ", msg, NULL); - else if (client->cmd_name == NULL) + else if (cmd->name == NULL) error = t_strconcat("BAD Error in IMAP command: ", msg, NULL); else { - cmd = t_str_ucase(client->cmd_name); + cmd_name = t_str_ucase(cmd->name); error = t_strconcat("BAD Error in IMAP command ", - cmd, ": ", msg, NULL); + cmd_name, ": ", msg, NULL); } - client_send_tagline(client, error); + client_send_tagline(cmd, error); if (++client->bad_counter >= CLIENT_MAX_BAD_COMMANDS) { client_disconnect_with_error(client, @@ -168,17 +173,17 @@ /* client_read_args() failures rely on this being set, so that the command processing is stopped even while command function returns FALSE. */ - client->cmd_param_error = TRUE; + cmd->param_error = TRUE; } -int client_read_args(struct client *client, unsigned int count, +int client_read_args(struct client_command_context *cmd, unsigned int count, unsigned int flags, struct imap_arg **args) { int ret; i_assert(count <= INT_MAX); - ret = imap_parser_read_args(client->parser, count, flags, args); + ret = imap_parser_read_args(cmd->client->parser, count, flags, args); if (ret >= (int)count) { /* all parameters read successfully */ return TRUE; @@ -187,20 +192,21 @@ return FALSE; } else { /* error, or missing arguments */ - client_send_command_error(client, ret < 0 ? NULL : + client_send_command_error(cmd, ret < 0 ? NULL : "Missing arguments"); return FALSE; } } -int client_read_string_args(struct client *client, unsigned int count, ...) +int client_read_string_args(struct client_command_context *cmd, + unsigned int count, ...) { struct imap_arg *imap_args; va_list va; const char *str; unsigned int i; - if (!client_read_args(client, count, 0, &imap_args)) + if (!client_read_args(cmd, count, 0, &imap_args)) return FALSE; va_start(va, count); @@ -208,13 +214,13 @@ const char **ret = va_arg(va, const char **); if (imap_args[i].type == IMAP_ARG_EOL) { - client_send_command_error(client, "Missing arguments."); + client_send_command_error(cmd, "Missing arguments."); break; } str = imap_arg_string(&imap_args[i]); if (str == NULL) { - client_send_command_error(client, "Invalid arguments."); + client_send_command_error(cmd, "Invalid arguments."); break; } @@ -228,6 +234,8 @@ void _client_reset_command(struct client *client) { + pool_t pool; + /* reset input idle time because command output might have taken a long time and we don't want to disconnect client immediately then */ client->last_input = ioloop_time; @@ -238,13 +246,13 @@ IO_READ, _client_input, client); } - client->cmd_tag = NULL; - client->cmd_name = NULL; - client->cmd_func = NULL; - client->cmd_uid = FALSE; - client->cmd_param_error = FALSE; + pool = client->cmd.pool; + memset(&client->cmd, 0, sizeof(client->cmd)); - p_clear(client->cmd_pool); + p_clear(pool); + client->cmd.pool = pool; + client->cmd.client = client; + imap_parser_reset(client->parser); } @@ -269,11 +277,13 @@ return !client->input_skip_line; } -static int client_handle_input(struct client *client) +static int client_handle_input(struct client_command_context *cmd) { - if (client->cmd_func != NULL) { + struct client *client = cmd->client; + + if (cmd->func != NULL) { /* command is being executed - continue it */ - if (client->cmd_func(client) || client->cmd_param_error) { + if (cmd->func(cmd) || cmd->param_error) { /* command execution was finished */ client->bad_counter = 0; _client_reset_command(client); @@ -293,35 +303,35 @@ /* pass through to parse next command */ } - if (client->cmd_tag == NULL) { - client->cmd_tag = imap_parser_read_word(client->parser); - if (client->cmd_tag == NULL) + if (cmd->tag == NULL) { + cmd->tag = imap_parser_read_word(client->parser); + if (cmd->tag == NULL) return FALSE; /* need more data */ - client->cmd_tag = p_strdup(client->cmd_pool, client->cmd_tag); + cmd->tag = p_strdup(cmd->pool, cmd->tag); } - if (client->cmd_name == NULL) { - client->cmd_name = imap_parser_read_word(client->parser); - if (client->cmd_name == NULL) + if (cmd->name == NULL) { + cmd->name = imap_parser_read_word(client->parser); + if (cmd->name == NULL) return FALSE; /* need more data */ - client->cmd_name = p_strdup(client->cmd_pool, client->cmd_name); + cmd->name = p_strdup(cmd->pool, cmd->name); } - if (client->cmd_name == '\0') { + if (cmd->name == '\0') { /* command not given - cmd_func is already NULL. */ } else { /* find the command function */ - client->cmd_func = command_find(client->cmd_name); + cmd->func = command_find(cmd->name); } - if (client->cmd_func == NULL) { + if (cmd->func == NULL) { /* unknown command */ - client_send_command_error(client, "Unknown command."); + client_send_command_error(cmd, "Unknown command."); client->input_skip_line = TRUE; _client_reset_command(client); } else { client->input_skip_line = TRUE; - if (client->cmd_func(client) || client->cmd_param_error) { + if (cmd->func(cmd) || cmd->param_error) { /* command execution was finished. */ client->bad_counter = 0; _client_reset_command(client); @@ -337,6 +347,7 @@ void _client_input(void *context) { struct client *client = context; + struct client_command_context *cmd = &client->cmd; if (client->command_pending) { /* already processing one command. wait. */ @@ -359,13 +370,13 @@ until newline is found. */ client->input_skip_line = TRUE; - client_send_command_error(client, "Too long argument."); + client_send_command_error(cmd, "Too long argument."); _client_reset_command(client); break; } o_stream_cork(client->output); - while (client_handle_input(client)) + while (client_handle_input(cmd)) ; o_stream_uncork(client->output); @@ -379,6 +390,7 @@ int _client_output(void *context) { struct client *client = context; + struct client_command_context *cmd = &client->cmd; int ret, finished; client->last_output = ioloop_time; @@ -394,7 +406,7 @@ /* continue processing command */ o_stream_cork(client->output); client->output_pending = TRUE; - finished = client->cmd_func(client) || client->cmd_param_error; + finished = cmd->func(cmd) || cmd->param_error; o_stream_uncork(client->output); /* a bit kludgy. normally we would want to get back here, but IDLE