imap-client-hibernate.c revision 8c1199cac76762101a2ca3ae66443b6b0dc28683
/* Copyright (c) 2014-2017 Dovecot authors, see the included COPYING file */
#include "imap-common.h"
#include "fdpass.h"
#include "net.h"
#include "ostream.h"
#include "write-full.h"
#include "base64.h"
#include "str.h"
#include "strescape.h"
#include "master-service.h"
#include "mailbox-watch.h"
#include "imap-state.h"
#include "imap-client.h"
#define IMAP_HIBERNATE_SOCKET_NAME "imap-hibernate"
#define IMAP_HIBERNATE_SEND_TIMEOUT_SECS 10
#define IMAP_HIBERNATE_HANDSHAKE "VERSION\timap-hibernate\t1\t0\n"
{
char buf[1024];
strlen(IMAP_HIBERNATE_HANDSHAKE)) < 0) {
return -1;
return -1;
return 0;
}
return -1;
}
{
const char *tag;
}
}
if (user->session_create_time != 0) {
}
unsigned int i;
if (i > 0)
}
}
if (fd_notify != -1)
}
static int
{
return -1;
return -1;
}
return -1;
}
return 0;
}
{
char buf[1024];
return -1;
} else if (ret == 0) {
return -1;
} else if (buf[0] != '+') {
return -1;
} else {
return 0;
}
}
static int
{
const char *path;
int fd;
*fd_r = -1;
if (fd == -1) {
return -1;
}
ret = -1;
else if (fd_notify != -1) {
else
}
alarm(0);
if (ret < 0) {
return -1;
}
return 0;
}
{
const char *error;
/* we won't try to hibernate stdio clients */
return FALSE;
}
/* wait until we've sent the pending output to client */
return FALSE;
}
if (ret < 0) {
i_error("Couldn't hibernate imap client: "
"Couldn't export state: %s (mailbox=%s)", error,
i_debug("Couldn't hibernate imap client: "
"Couldn't export state: %s (mailbox=%s)", error,
}
&error);
if (fd_notify == -1) {
i_debug("Couldn't hibernate imap client: "
"Couldn't extract notifications fd: %s",
error);
}
ret = -1;
}
}
if (ret > 0) {
ret = -1;
}
if (ret > 0) {
/* hide the disconnect log message, because the client didn't
actually log out */
i_debug("Successfully hibernated imap client in mailbox %s",
}
}
/* notify imap-hibernate that we're done by closing the connection.
do this only after client is destroyed. this way imap-hibernate
won't try to launch another imap process too early and cause
problems (like sending duplicate session ID to stats process) */
if (fd_hibernate != -1)
buffer_free(&state);
return ret > 0;
}