client.c revision edf8c2b4ef6be8af262bc09aac751eae669670ca
/* Copyright (C) 2002-2004 Timo Sirainen */
#include "common.h"
#include "ioloop.h"
#include "network.h"
#include "istream.h"
#include "ostream.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;
if (!cmd_ret) {
} else {
}
}
{
if (!client->disconnected) {
reason = "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 */
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 {
t_push();
t_pop();
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;
/* We mostly want to check last_input here, but if there is a very long
running command (like copying thousands of messages), we don't want
to disconnect the client just after the command was finished.
But any output that IDLE has sent should be ignored. */
/* 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)
{
}
}