Merge branch '1.3'
This commit is contained in:
commit
462fed556a
|
@ -18,14 +18,14 @@ fi
|
||||||
|
|
||||||
need_perl=5.14
|
need_perl=5.14
|
||||||
AC_CACHE_CHECK([whether perl is recent enough], ob_cv_perl_ver, [
|
AC_CACHE_CHECK([whether perl is recent enough], ob_cv_perl_ver, [
|
||||||
if $PERL -e "use v$need_perl;"; then
|
if $PERL -e "use v$need_perl;" 2> /dev/null; then
|
||||||
ob_cv_perl_ver=yes
|
ob_cv_perl_ver=yes
|
||||||
else
|
else
|
||||||
ob_cv_perl_ver=no
|
ob_cv_perl_ver=no
|
||||||
fi
|
fi
|
||||||
])
|
])
|
||||||
if test "x$ob_cv_perl_ver" = "xno"; then
|
if test "x$ob_cv_perl_ver" = "xno"; then
|
||||||
AC_MSG_ERROR([perl is too old])
|
AC_MSG_ERROR([perl is too old, need v$need_perl])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_CACHE_CHECK([whether strftime supports %z], ob_cv_strftime_z,
|
AC_CACHE_CHECK([whether strftime supports %z], ob_cv_strftime_z,
|
||||||
|
@ -94,7 +94,7 @@ if test "x$ob_cv_with_ssl" != xno; then
|
||||||
sav_LDFLAGS=$LDFLAGS
|
sav_LDFLAGS=$LDFLAGS
|
||||||
LDFLAGS="$LDFLAGS $SSL_LDFLAGS"
|
LDFLAGS="$LDFLAGS $SSL_LDFLAGS"
|
||||||
AC_CHECK_LIB(dl, dlopen, [LIBDL=-ldl])
|
AC_CHECK_LIB(dl, dlopen, [LIBDL=-ldl])
|
||||||
AC_CHECK_LIB(crypto, CRYPTO_lock, [LIBCRYPTO=-lcrypto])
|
AC_CHECK_LIB(crypto, X509_cmp, [LIBCRYPTO=-lcrypto])
|
||||||
AC_CHECK_LIB(ssl, SSL_connect,
|
AC_CHECK_LIB(ssl, SSL_connect,
|
||||||
[SSL_LIBS="-lssl $LIBCRYPTO $LIBDL" have_ssl_paths=yes])
|
[SSL_LIBS="-lssl $LIBCRYPTO $LIBDL" have_ssl_paths=yes])
|
||||||
LDFLAGS=$sav_LDFLAGS
|
LDFLAGS=$sav_LDFLAGS
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
typedef unsigned char uchar;
|
typedef unsigned char uchar;
|
||||||
typedef unsigned short ushort;
|
typedef unsigned short ushort;
|
||||||
typedef unsigned int uint;
|
typedef unsigned int uint;
|
||||||
|
typedef unsigned long ulong;
|
||||||
|
|
||||||
#define as(ar) (sizeof(ar)/sizeof(ar[0]))
|
#define as(ar) (sizeof(ar)/sizeof(ar[0]))
|
||||||
|
|
||||||
|
|
|
@ -953,7 +953,7 @@ parse_date( const char *str )
|
||||||
struct tm datetime;
|
struct tm datetime;
|
||||||
|
|
||||||
memset( &datetime, 0, sizeof(datetime) );
|
memset( &datetime, 0, sizeof(datetime) );
|
||||||
if (!(end = strptime( str, "%d-%b-%Y %H:%M:%S ", &datetime )))
|
if (!(end = strptime( str, "%e-%b-%Y %H:%M:%S ", &datetime )))
|
||||||
return -1;
|
return -1;
|
||||||
if ((date = timegm( &datetime )) == -1)
|
if ((date = timegm( &datetime )) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1203,17 +1203,16 @@ parse_response_code( imap_store_t *ctx, imap_cmd_t *cmd, char *s )
|
||||||
return RESP_OK;
|
return RESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int parse_list_rsp_p1( imap_store_t *, list_t *, char * );
|
||||||
static int parse_list_rsp_p2( imap_store_t *, list_t *, char * );
|
static int parse_list_rsp_p2( imap_store_t *, list_t *, char * );
|
||||||
|
|
||||||
static int
|
static int
|
||||||
parse_list_rsp( imap_store_t *ctx, list_t *list, char *cmd )
|
parse_list_rsp( imap_store_t *ctx, list_t *list, char *cmd )
|
||||||
{
|
{
|
||||||
char *arg;
|
|
||||||
list_t *lp;
|
list_t *lp;
|
||||||
|
|
||||||
if (!is_list( list )) {
|
if (!is_list( list )) {
|
||||||
free_list( list );
|
free_list( list );
|
||||||
bad_list:
|
|
||||||
error( "IMAP error: malformed LIST response\n" );
|
error( "IMAP error: malformed LIST response\n" );
|
||||||
return LIST_BAD;
|
return LIST_BAD;
|
||||||
}
|
}
|
||||||
|
@ -1223,10 +1222,19 @@ parse_list_rsp( imap_store_t *ctx, list_t *list, char *cmd )
|
||||||
return LIST_OK;
|
return LIST_OK;
|
||||||
}
|
}
|
||||||
free_list( list );
|
free_list( list );
|
||||||
if (!(arg = next_arg( &cmd )))
|
return parse_list( ctx, cmd, parse_list_rsp_p1 );
|
||||||
goto bad_list;
|
}
|
||||||
if (!ctx->delimiter[0])
|
|
||||||
ctx->delimiter[0] = arg[0];
|
static int
|
||||||
|
parse_list_rsp_p1( imap_store_t *ctx, list_t *list, char *cmd ATTR_UNUSED )
|
||||||
|
{
|
||||||
|
if (!is_opt_atom( list )) {
|
||||||
|
error( "IMAP error: malformed LIST response\n" );
|
||||||
|
free_list( list );
|
||||||
|
return LIST_BAD;
|
||||||
|
}
|
||||||
|
if (!ctx->delimiter[0] && is_atom( list ))
|
||||||
|
ctx->delimiter[0] = list->val[0];
|
||||||
return parse_list( ctx, cmd, parse_list_rsp_p2 );
|
return parse_list( ctx, cmd, parse_list_rsp_p2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1873,7 +1881,7 @@ ensure_password( imap_server_conf_t *srvc )
|
||||||
if (cmd) {
|
if (cmd) {
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int ret;
|
int ret;
|
||||||
char buffer[80];
|
char buffer[2048]; // Hopefully more than enough room for XOAUTH2, etc. tokens
|
||||||
|
|
||||||
if (*cmd == '+') {
|
if (*cmd == '+') {
|
||||||
flushn();
|
flushn();
|
||||||
|
@ -2079,7 +2087,7 @@ done_sasl_auth( imap_store_t *ctx, imap_cmd_t *cmd ATTR_UNUSED, int response )
|
||||||
int rc = sasl_client_step( ctx->sasl, NULL, 0, &interact, &out, &out_len );
|
int rc = sasl_client_step( ctx->sasl, NULL, 0, &interact, &out, &out_len );
|
||||||
if (process_sasl_step( ctx, rc, NULL, 0, interact, &out, &out_len ) < 0)
|
if (process_sasl_step( ctx, rc, NULL, 0, interact, &out, &out_len ) < 0)
|
||||||
warn( "Warning: SASL reported failure despite successful IMAP authentication. Ignoring...\n" );
|
warn( "Warning: SASL reported failure despite successful IMAP authentication. Ignoring...\n" );
|
||||||
else if (out)
|
else if (out_len > 0)
|
||||||
warn( "Warning: SASL wants more steps despite successful IMAP authentication. Ignoring...\n" );
|
warn( "Warning: SASL wants more steps despite successful IMAP authentication. Ignoring...\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2180,7 +2188,7 @@ imap_open_store_authenticate2( imap_store_t *ctx )
|
||||||
free( enc );
|
free( enc );
|
||||||
return;
|
return;
|
||||||
notsasl:
|
notsasl:
|
||||||
if (!ctx->sasl || sasl_listmech( ctx->sasl, NULL, "", "", "", &saslavail, NULL, NULL ) != SASL_OK)
|
if (!ctx->sasl || sasl_listmech( ctx->sasl, NULL, "", " ", "", &saslavail, NULL, NULL ) != SASL_OK)
|
||||||
saslavail = "(none)"; /* EXTERNAL is always there anyway. */
|
saslavail = "(none)"; /* EXTERNAL is always there anyway. */
|
||||||
if (!auth_login) {
|
if (!auth_login) {
|
||||||
error( "IMAP error: selected SASL mechanism(s) not available;\n"
|
error( "IMAP error: selected SASL mechanism(s) not available;\n"
|
||||||
|
|
|
@ -109,6 +109,7 @@ sub type_to_format($)
|
||||||
{
|
{
|
||||||
$_ = shift;
|
$_ = shift;
|
||||||
s/xint /\%\#x/g;
|
s/xint /\%\#x/g;
|
||||||
|
s/uint /\%u/g;
|
||||||
s/int /\%d/g;
|
s/int /\%d/g;
|
||||||
s/const char \*/\%s/g;
|
s/const char \*/\%s/g;
|
||||||
return $_;
|
return $_;
|
||||||
|
|
15
src/mbsync.1
15
src/mbsync.1
|
@ -267,7 +267,7 @@ with DOS/Windows file systems.
|
||||||
.TP
|
.TP
|
||||||
\fBSubFolders\fR \fBVerbatim\fR|\fBMaildir++\fR|\fBLegacy\fR
|
\fBSubFolders\fR \fBVerbatim\fR|\fBMaildir++\fR|\fBLegacy\fR
|
||||||
The on-disk folder naming style used for hierarchical mailboxes.
|
The on-disk folder naming style used for hierarchical mailboxes.
|
||||||
This has option has no effect when \fBFlatten\fR is used.
|
This option has no effect when \fBFlatten\fR is used.
|
||||||
.br
|
.br
|
||||||
Suppose mailboxes with the canonical paths \fBtop/sub/subsub\fR and
|
Suppose mailboxes with the canonical paths \fBtop/sub/subsub\fR and
|
||||||
\fBINBOX/sub/subsub\fR, the styles will yield the following on-disk paths:
|
\fBINBOX/sub/subsub\fR, the styles will yield the following on-disk paths:
|
||||||
|
@ -601,12 +601,13 @@ which in turn are overridden by command line switches.
|
||||||
..
|
..
|
||||||
.TP
|
.TP
|
||||||
\fBSyncState\fR {\fB*\fR|\fIpath\fR}
|
\fBSyncState\fR {\fB*\fR|\fIpath\fR}
|
||||||
Set the location of this Channel's synchronization state files. \fB*\fR means
|
Set the location of this Channel's synchronization state files.
|
||||||
that the state should be saved in a file named .mbsyncstate in the
|
\fB*\fR means that the state should be saved in a file named .mbsyncstate
|
||||||
Slave mailbox itself; this has the advantage that you needn't to care for the
|
in the Slave mailbox itself; this has the advantage that you do not need
|
||||||
state file if you delete the mailbox, but it works only with Maildir mailboxes,
|
to handle the state file separately if you delete the mailbox, but it works
|
||||||
obviously. Otherwise this is interpreted as a string to prepend to the Slave
|
only with Maildir mailboxes, obviously.
|
||||||
mailbox name to make up a complete path.
|
Otherwise this is interpreted as a string to prepend to the Slave mailbox
|
||||||
|
name to make up a complete path.
|
||||||
.br
|
.br
|
||||||
This option can be used outside any section for a global effect. In this case
|
This option can be used outside any section for a global effect. In this case
|
||||||
the appended string is made up according to the pattern
|
the appended string is made up according to the pattern
|
||||||
|
|
95
src/socket.c
95
src/socket.c
|
@ -63,6 +63,34 @@ socket_fail( conn_t *conn )
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LIBSSL
|
#ifdef HAVE_LIBSSL
|
||||||
|
static void ATTR_PRINTFLIKE(1, 2)
|
||||||
|
print_ssl_errors( const char *fmt, ... )
|
||||||
|
{
|
||||||
|
char *action;
|
||||||
|
va_list va;
|
||||||
|
ulong err;
|
||||||
|
|
||||||
|
va_start( va, fmt );
|
||||||
|
nfvasprintf( &action, fmt, va );
|
||||||
|
va_end( va );
|
||||||
|
while ((err = ERR_get_error()))
|
||||||
|
error( "Error while %s: %s\n", action, ERR_error_string( err, 0 ) );
|
||||||
|
free( action );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
print_ssl_socket_errors( const char *func, conn_t *conn )
|
||||||
|
{
|
||||||
|
ulong err;
|
||||||
|
int num = 0;
|
||||||
|
|
||||||
|
while ((err = ERR_get_error())) {
|
||||||
|
error( "Socket error: secure %s %s: %s\n", func, conn->name, ERR_error_string( err, 0 ) );
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ssl_return( const char *func, conn_t *conn, int ret )
|
ssl_return( const char *func, conn_t *conn, int ret )
|
||||||
{
|
{
|
||||||
|
@ -76,9 +104,12 @@ ssl_return( const char *func, conn_t *conn, int ret )
|
||||||
FALLTHROUGH
|
FALLTHROUGH
|
||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
return 0;
|
return 0;
|
||||||
case SSL_ERROR_SYSCALL:
|
|
||||||
case SSL_ERROR_SSL:
|
case SSL_ERROR_SSL:
|
||||||
if (!(err = ERR_get_error())) {
|
print_ssl_socket_errors( func, conn );
|
||||||
|
break;
|
||||||
|
case SSL_ERROR_SYSCALL:
|
||||||
|
if (print_ssl_socket_errors( func, conn ))
|
||||||
|
break;
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
case SSL_ERROR_ZERO_RETURN:
|
case SSL_ERROR_ZERO_RETURN:
|
||||||
/* Callers take the short path out, so signal higher layers from here. */
|
/* Callers take the short path out, so signal higher layers from here. */
|
||||||
|
@ -87,9 +118,6 @@ ssl_return( const char *func, conn_t *conn, int ret )
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
sys_error( "Socket error: secure %s %s", func, conn->name );
|
sys_error( "Socket error: secure %s %s", func, conn->name );
|
||||||
} else {
|
|
||||||
error( "Socket error: secure %s %s: %s\n", func, conn->name, ERR_error_string( err, 0 ) );
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error( "Socket error: secure %s %s: unhandled SSL error %d\n", func, conn->name, err );
|
error( "Socket error: secure %s %s: unhandled SSL error %d\n", func, conn->name, err );
|
||||||
|
@ -176,22 +204,29 @@ verify_cert_host( const server_conf_t *conf, conn_t *sock )
|
||||||
|
|
||||||
trusted = (STACK_OF(X509_OBJECT) *)sock->conf->trusted_certs;
|
trusted = (STACK_OF(X509_OBJECT) *)sock->conf->trusted_certs;
|
||||||
for (i = 0; i < sk_X509_OBJECT_num( trusted ); i++) {
|
for (i = 0; i < sk_X509_OBJECT_num( trusted ); i++) {
|
||||||
if (!X509_cmp( cert, X509_OBJECT_get0_X509( sk_X509_OBJECT_value( trusted, i ) ) ))
|
if (!X509_cmp( cert, X509_OBJECT_get0_X509( sk_X509_OBJECT_value( trusted, i ) ) )) {
|
||||||
|
X509_free( cert );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err = SSL_get_verify_result( sock->ssl );
|
err = SSL_get_verify_result( sock->ssl );
|
||||||
if (err != X509_V_OK) {
|
if (err != X509_V_OK) {
|
||||||
error( "SSL error connecting %s: %s\n", sock->name, X509_verify_cert_error_string( err ) );
|
error( "SSL error connecting %s: %s\n", sock->name, X509_verify_cert_error_string( err ) );
|
||||||
|
X509_free( cert );
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!conf->host) {
|
if (!conf->host) {
|
||||||
error( "SSL error connecting %s: Neither host nor matching certificate specified\n", sock->name );
|
error( "SSL error connecting %s: Neither host nor matching certificate specified\n", sock->name );
|
||||||
|
X509_free( cert );
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return verify_hostname( cert, conf->host );
|
int ret = verify_hostname( cert, conf->host );
|
||||||
|
|
||||||
|
X509_free( cert );
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -203,7 +238,15 @@ init_ssl_ctx( const server_conf_t *conf )
|
||||||
if (conf->SSLContext)
|
if (conf->SSLContext)
|
||||||
return conf->ssl_ctx_valid;
|
return conf->ssl_ctx_valid;
|
||||||
|
|
||||||
mconf->SSLContext = SSL_CTX_new( SSLv23_client_method() );
|
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||||
|
const SSL_METHOD *method = TLS_client_method();
|
||||||
|
#else
|
||||||
|
const SSL_METHOD *method = SSLv23_client_method();
|
||||||
|
#endif
|
||||||
|
if (!(mconf->SSLContext = SSL_CTX_new( method ))) {
|
||||||
|
print_ssl_errors( "initializing SSL context" );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(conf->ssl_versions & SSLv3))
|
if (!(conf->ssl_versions & SSLv3))
|
||||||
options |= SSL_OP_NO_SSLv3;
|
options |= SSL_OP_NO_SSLv3;
|
||||||
|
@ -221,25 +264,24 @@ init_ssl_ctx( const server_conf_t *conf )
|
||||||
SSL_CTX_set_options( mconf->SSLContext, options );
|
SSL_CTX_set_options( mconf->SSLContext, options );
|
||||||
|
|
||||||
if (conf->cert_file && !SSL_CTX_load_verify_locations( mconf->SSLContext, conf->cert_file, 0 )) {
|
if (conf->cert_file && !SSL_CTX_load_verify_locations( mconf->SSLContext, conf->cert_file, 0 )) {
|
||||||
error( "Error while loading certificate file '%s': %s\n",
|
print_ssl_errors( "loading certificate file '%s'", conf->cert_file );
|
||||||
conf->cert_file, ERR_error_string( ERR_get_error(), 0 ) );
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
mconf->trusted_certs = (_STACK *)sk_X509_OBJECT_dup( X509_STORE_get0_objects( SSL_CTX_get_cert_store( mconf->SSLContext ) ) );
|
mconf->trusted_certs = (_STACK *)sk_X509_OBJECT_dup( X509_STORE_get0_objects( SSL_CTX_get_cert_store( mconf->SSLContext ) ) );
|
||||||
if (mconf->system_certs && !SSL_CTX_set_default_verify_paths( mconf->SSLContext ))
|
if (mconf->system_certs && !SSL_CTX_set_default_verify_paths( mconf->SSLContext )) {
|
||||||
warn( "Warning: Unable to load default certificate files: %s\n",
|
ulong err;
|
||||||
ERR_error_string( ERR_get_error(), 0 ) );
|
while ((err = ERR_get_error()))
|
||||||
|
warn( "Warning: Unable to load default certificate files: %s\n", ERR_error_string( err, 0 ) );
|
||||||
|
}
|
||||||
|
|
||||||
SSL_CTX_set_verify( mconf->SSLContext, SSL_VERIFY_NONE, NULL );
|
SSL_CTX_set_verify( mconf->SSLContext, SSL_VERIFY_NONE, NULL );
|
||||||
|
|
||||||
if (conf->client_certfile && !SSL_CTX_use_certificate_chain_file( mconf->SSLContext, conf->client_certfile)) {
|
if (conf->client_certfile && !SSL_CTX_use_certificate_chain_file( mconf->SSLContext, conf->client_certfile)) {
|
||||||
error( "Error while loading client certificate file '%s': %s\n",
|
print_ssl_errors( "loading client certificate file '%s'", conf->client_certfile );
|
||||||
conf->client_certfile, ERR_error_string( ERR_get_error(), 0 ) );
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (conf->client_keyfile && !SSL_CTX_use_PrivateKey_file( mconf->SSLContext, conf->client_keyfile, SSL_FILETYPE_PEM)) {
|
if (conf->client_keyfile && !SSL_CTX_use_PrivateKey_file( mconf->SSLContext, conf->client_keyfile, SSL_FILETYPE_PEM)) {
|
||||||
error( "Error while loading client private key '%s': %s\n",
|
print_ssl_errors( "loading client private key '%s'", conf->client_keyfile );
|
||||||
conf->client_keyfile, ERR_error_string( ERR_get_error(), 0 ) );
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,10 +312,21 @@ socket_start_tls( conn_t *conn, void (*cb)( int ok, void *aux ) )
|
||||||
}
|
}
|
||||||
|
|
||||||
init_wakeup( &conn->ssl_fake, ssl_fake_cb, conn );
|
init_wakeup( &conn->ssl_fake, ssl_fake_cb, conn );
|
||||||
conn->ssl = SSL_new( ((server_conf_t *)conn->conf)->SSLContext );
|
if (!(conn->ssl = SSL_new( ((server_conf_t *)conn->conf)->SSLContext ))) {
|
||||||
if (ssl_return( "set server name", conn, SSL_set_tlsext_host_name( conn->ssl, conn->conf->host ) ) < 0)
|
print_ssl_errors( "initializing SSL connection" );
|
||||||
|
start_tls_p3( conn, 0 );
|
||||||
return;
|
return;
|
||||||
SSL_set_fd( conn->ssl, conn->fd );
|
}
|
||||||
|
if (!SSL_set_tlsext_host_name( conn->ssl, conn->conf->host )) {
|
||||||
|
print_ssl_errors( "setting SSL server host name" );
|
||||||
|
start_tls_p3( conn, 0 );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!SSL_set_fd( conn->ssl, conn->fd )) {
|
||||||
|
print_ssl_errors( "setting SSL socket fd" );
|
||||||
|
start_tls_p3( conn, 0 );
|
||||||
|
return;
|
||||||
|
}
|
||||||
SSL_set_mode( conn->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER );
|
SSL_set_mode( conn->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER );
|
||||||
socket_expect_read( conn, 1 );
|
socket_expect_read( conn, 1 );
|
||||||
conn->state = SCK_STARTTLS;
|
conn->state = SCK_STARTTLS;
|
||||||
|
@ -545,8 +598,10 @@ static void
|
||||||
socket_connected( conn_t *conn )
|
socket_connected( conn_t *conn )
|
||||||
{
|
{
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
|
if (conn->addrs) {
|
||||||
freeaddrinfo( conn->addrs );
|
freeaddrinfo( conn->addrs );
|
||||||
conn->addrs = 0;
|
conn->addrs = 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
conf_notifier( &conn->notify, 0, POLLIN );
|
conf_notifier( &conn->notify, 0, POLLIN );
|
||||||
socket_expect_read( conn, 0 );
|
socket_expect_read( conn, 0 );
|
||||||
|
|
Loading…
Reference in New Issue
Block a user