client.c revision eddd9bf1a1369aea4a2715f6be1137da6d17d293
/* Copyright (c) 2002-2007 Dovecot authors, see the included COPYING file */
#include "common.h"
#include "ioloop.h"
#include "str.h"
#include "network.h"
#include "istream.h"
#include "ostream.h"
#include "var-expand.h"
#include "commands.h"
#include "mail-namespace.h"
#include <stdlib.h>
#include <unistd.h>
extern struct mail_storage_callbacks mail_storage_callbacks;
struct mail_namespace *namespaces)
{
/* always use nonblocking I/O */
while (namespaces != NULL) {
}
if (hook_client_created != NULL)
return client;
}
{
bool cmd_ret;
} else {
}
}
{
static struct var_expand_table static_tab[] = {
{ 'i', NULL },
{ 'o', NULL },
{ '\0', NULL }
};
struct var_expand_table *tab;
}
{
t_strdup_printf("Connection closed: %m");
}
{
if (!client->disconnected) {
}
/* finish off all the queued commands. */
i_error("close(client in) failed: %m");
i_error("close(client out) failed: %m");
}
/* quit the program */
}
{
if (client->disconnected)
return;
}
{
}
{
return -1;
return -1;
/* buffer full, try flushing */
}
return 1;
}
{
return;
tag = "*";
}
const char *msg)
{
bool fatal;
if (fatal) {
return;
}
}
else {
}
"Too many invalid IMAP commands.");
}
/* client_read_args() failures rely on this being set, so that the
command processing is stopped even while command function returns
FALSE. */
}
{
int ret;
/* all parameters read successfully */
return TRUE;
} else if (ret == -2) {
/* need more data */
/* disconnected */
}
return FALSE;
} else {
/* error, or missing arguments */
"Missing arguments");
return FALSE;
}
}
unsigned int count, ...)
{
const char *str;
unsigned int i;
return FALSE;
for (i = 0; i < count; i++) {
break;
}
break;
}
}
return i == count;
}
static struct client_command_context *
enum command_flags flags)
{
struct client_command_context *cmd;
return cmd;
}
return NULL;
}
{
enum command_flags flags;
bool broken_client = FALSE;
/* no existing command must be breaking sequences */
/* if existing command uses sequences, we'll have to block */
} else {
return FALSE;
}
/* don't do anything until syncing is finished */
return TRUE;
}
return FALSE;
}
if (broken_client) {
"* BAD Command pipelining results in ambiguity.");
}
return TRUE;
}
static struct client_command_context *
{
struct client_command_context *cmd;
} else {
}
/* add to beginning of the queue */
}
return cmd;
}
{
/* reset input idle time because command output might have taken a
long time and we don't want to disconnect client immediately then */
}
if (!cmd->param_error)
client->bad_counter = 0;
else {
}
else
/* no commands left in the queue, we can clear the pool */
}
}
{
}
}
{
if (client->disconnected) {
return;
}
/* there's a command that has locked the input */
return;
/* the command is waiting for existing ambiguity causing
commands to finish. */
return;
}
/* if there's unread data in buffer, handle it. */
if (size > 0)
}
/* Skip incoming data until newline is found,
returns TRUE if newline was found. */
{
const unsigned char *data;
for (i = 0; i < data_size; i++) {
if (data[i] == '\n') {
i++;
break;
}
}
return !client->input_skip_line;
}
{
/* command is being executed - continue it */
/* command execution was finished */
return TRUE;
}
/* unfinished */
if (cmd->output_pending)
return FALSE;
}
return FALSE; /* need more data */
}
return FALSE; /* need more data */
}
/* command not given - cmd_func is already NULL. */
} else {
/* find the command function */
if (client_command_check_ambiguity(cmd)) {
/* do nothing until existing commands are
finished */
return FALSE;
}
}
}
/* unknown command */
return TRUE;
} else {
return client_command_input(cmd);
}
}
{
return FALSE;
}
if (client->input_skip_line) {
/* first eat the previous command line */
if (!client_skip_line(client))
return FALSE;
}
/* don't bother creating a new client command before there's at least
some input */
if (size == 0)
return FALSE;
/* beginning a new command */
/* wait for some of the commands to finish */
return FALSE;
}
}
{
struct client_command_context *cmd;
int ret;
case -1:
/* disconnected */
return;
case -2:
/* parameter word is longer than max. input buffer size.
this is most likely an error, so skip the new data
until newline is found. */
return;
}
do {
);
else
}
{
bool finished;
/* continue processing command */
if (!finished) {
if (cmd->output_pending)
} else {
/* command execution was finished */
}
}
{
int ret;
return 1;
}
if (!cmd->waiting_unambiguity) {
break;
}
}
}
return 1;
} else {
}
return ret;
}
{
return;
/* client isn't reading our output */
"in reading our output");
} else if (idle_time >= CLIENT_IDLE_TIMEOUT) {
/* client isn't sending us anything */
"* BYE Disconnected for inactivity.");
}
}
}
void clients_init(void)
{
}
void clients_deinit(void)
{
}
}