dict-connection.c revision 0d1b8b6bec79746c5d89d57dd8c1688946bd9237
/* Copyright (c) 2005-2017 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "ioloop.h"
#include "istream.h"
#include "ostream.h"
#include "llist.h"
#include "master-service.h"
#include "dict-client.h"
#include "dict-settings.h"
#include "dict-commands.h"
#include "dict-connection.h"
#include <unistd.h>
#define DICT_CONN_MAX_PENDING_COMMANDS 1000
static struct dict_connection *dict_connections;
static unsigned int dict_connections_count = 0;
const char *line)
{
unsigned int value_type_num;
if (*line++ != DICT_PROTOCOL_CMD_HELLO)
return -1;
/* check major version */
*line++ != '\t')
return -1;
/* read minor version */
return -1;
if (*line++ != '\t')
return -1;
/* get value type */
value_type = line;
if (*line++ != '\t')
return -1;
return -1;
if (value_type_num >= DICT_DATA_TYPE_LAST)
return -1;
/* get username */
if (*line++ != '\t')
return -1;
/* the rest is dict name. since we're looking it with getenv(),
disallow all funny characters that might confuse it, just in case. */
if (*line != '\0')
return -1;
return 0;
}
{
struct dict_settings dict_set;
const char *const *strlist;
unsigned int i, count;
i_error("dict client: No dictionaries configured");
return -1;
}
for (i = 0; i < count; i += 2) {
break;
}
if (i == count) {
i_error("dict client: Unconfigured dictionary name '%s'",
return -1;
}
/* dictionary initialization failed */
i_error("Failed to initialize dictionary '%s': %s",
return -1;
}
return 0;
}
{
const char *line;
int ret;
T_BEGIN {
} T_END;
if (ret < 0) {
break;
}
break;
}
}
}
{
const char *line;
case 0:
return;
case -1:
/* disconnected */
return;
case -2:
/* buffer full */
i_error("dict client: Sent us more than %d bytes",
(int)DICT_CLIENT_MAX_LINE_LENGTH);
return;
}
/* handshake not received yet */
return;
i_error("dict client: Broken handshake");
return;
}
if (dict_connection_dict_init(conn) < 0) {
return;
}
}
}
{
return;
}
{
int ret;
return 1;
}
if (ret > 0)
return ret;
}
{
struct dict_connection *conn;
return conn;
}
{
}
{
struct dict_connection_transaction *transaction;
return TRUE;
/* we should have only transactions that haven't been committed or
rollbacked yet. close those before dict is deinitialized. */
}
}
return FALSE;
}
{
(void)dict_connection_unref(conn);
}
{
/* delayed unref to make sure we don't try to call
dict_deinit() from a dict-callback. that's too much trouble
for each dict driver to be able to handle. */
}
} else {
(void)dict_connection_unref(conn);
}
}
{
i_error("close(dict client) failed: %m");
/* the connection is closed, but there may still be commands left
running. finish them, even if the calling client can't be notified
about whether they succeeded (clients may not even care).
flush the command output here in case we were waiting on iteration
output. */
}
unsigned int dict_connections_current_count(void)
{
return dict_connections_count;
}
void dict_connections_destroy_all(void)
{
while (dict_connections != NULL)
}