Mercurial > dovecot > core-2.2
view src/director/auth-connection.c @ 18137:3009a1a6f6d5
global: freshen copyright
Robomatically:
git ls-files | xargs perl -p -i -e 's/(\d+)-201[0-4]/$1-2015/g;s/ (201[0-4]) Dovecot/ $1-2015 Dovecot/'
Happy 2015 everyone!
Signed-off-by: Phil Carmody <phil@dovecot.fi>
author | Phil Carmody <phil@dovecot.fi> |
---|---|
date | Mon, 05 Jan 2015 22:20:10 +0200 |
parents | add8c00fb3cc |
children | e178413a905d |
line wrap: on
line source
/* Copyright (c) 2010-2015 Dovecot authors, see the included COPYING file */ #include "lib.h" #include "ioloop.h" #include "istream.h" #include "ostream.h" #include "net.h" #include "llist.h" #include "safe-memset.h" #include "auth-client-interface.h" #include "auth-connection.h" #include <unistd.h> struct auth_connection { struct auth_connection *prev, *next; char *path; int fd; struct io *io; struct istream *input; struct ostream *output; auth_input_callback *callback; void *context; }; static struct auth_connection *auth_connections; static void auth_connection_disconnected(struct auth_connection **conn); static void auth_connection_input(struct auth_connection *conn) { char *line; switch (i_stream_read(conn->input)) { case 0: return; case -1: /* disconnected */ i_error("Auth server disconnected unexpectedly"); auth_connection_disconnected(&conn); return; case -2: /* buffer full */ i_error("BUG: Auth server sent us more than %d bytes", (int)AUTH_CLIENT_MAX_LINE_LENGTH); auth_connection_disconnected(&conn); return; } while ((line = i_stream_next_line(conn->input)) != NULL) { T_BEGIN { conn->callback(line, conn->context); safe_memset(line, 0, strlen(line)); } T_END; } } struct auth_connection *auth_connection_init(const char *path) { struct auth_connection *conn; conn = i_new(struct auth_connection, 1); conn->fd = -1; conn->path = i_strdup(path); DLLIST_PREPEND(&auth_connections, conn); return conn; } void auth_connection_set_callback(struct auth_connection *conn, auth_input_callback *callback, void *context) { conn->callback = callback; conn->context = context; } int auth_connection_connect(struct auth_connection *conn) { i_assert(conn->fd == -1); conn->fd = net_connect_unix_with_retries(conn->path, 1000); if (conn->fd == -1) { i_error("connect(%s) failed: %m", conn->path); return -1; } conn->input = i_stream_create_fd(conn->fd, AUTH_CLIENT_MAX_LINE_LENGTH, FALSE); conn->output = o_stream_create_fd(conn->fd, (size_t)-1, FALSE); o_stream_set_no_error_handling(conn->output, TRUE); conn->io = io_add(conn->fd, IO_READ, auth_connection_input, conn); return 0; } void auth_connection_deinit(struct auth_connection **_conn) { struct auth_connection *conn = *_conn; *_conn = NULL; DLLIST_REMOVE(&auth_connections, conn); if (conn->fd != -1) { io_remove(&conn->io); i_stream_unref(&conn->input); o_stream_unref(&conn->output); if (close(conn->fd) < 0) i_error("close(auth connection) failed: %m"); } i_free(conn->path); i_free(conn); } static void auth_connection_disconnected(struct auth_connection **_conn) { struct auth_connection *conn = *_conn; *_conn = NULL; /* notify callback. it should deinit this connection */ conn->callback(NULL, conn->context); } void auth_connection_send(struct auth_connection *conn, const void *data, size_t size) { i_assert(conn->fd != -1); o_stream_nsend(conn->output, data, size); } void auth_connections_deinit(void) { while (auth_connections != NULL) { struct auth_connection *conn = auth_connections; auth_connection_disconnected(&conn); } }