Ejemplo n.º 1
0
static void replica_connect(const char *channel)
{
    int wait;
    sasl_callback_t *cb;
    int timeout;
    const char *port, *auth_status = NULL;

    cb = mysasl_callbacks(NULL,
                          get_config(channel, "sync_authname"),
                          get_config(channel, "sync_realm"),
                          get_config(channel, "sync_password"));

    /* get the right port */
    port = get_config(channel, "sync_port");
    if (port) {
        imap_csync_protocol.service = port;
        csync_protocol.service = port;
    }

    for (wait = 15;; wait *= 2) {
        sync_backend = backend_connect(sync_backend, servername,
                                       &imap_csync_protocol, "", cb, &auth_status,
                                       (verbose > 1 ? fileno(stderr) : -1));

        if (sync_backend) {
            if (sync_backend->capability & CAPA_REPLICATION) {
                /* attach our IMAP tag buffer to our protstreams as userdata */
                sync_backend->in->userdata = sync_backend->out->userdata = &tagbuf;
                break;
            }
            else {
                backend_disconnect(sync_backend);
                sync_backend = NULL;
            }
        }

        sync_backend = backend_connect(sync_backend, servername,
                                       &csync_protocol, "", cb, NULL,
                                       (verbose > 1 ? fileno(stderr) : -1));

        if (sync_backend || auth_status || connect_once || wait > 1000) break;

        fprintf(stderr,
                "Can not connect to server '%s', retrying in %d seconds\n",
                servername, wait);
        sleep(wait);
    }

    free_callbacks(cb);
    cb = NULL;

    if (!sync_backend) {
        fprintf(stderr, "Can not connect to server '%s'\n",
                servername);
        syslog(LOG_ERR, "Can not connect to server '%s'", servername);
        _exit(1);
    }

    if (servername[0] != '/' && sync_backend->sock >= 0) {
        tcp_disable_nagle(sync_backend->sock);
        tcp_enable_keepalive(sync_backend->sock);
    }

#ifdef HAVE_ZLIB
    /* Does the backend support compression? */
    if (CAPA(sync_backend, CAPA_COMPRESS)) {
        prot_printf(sync_backend->out, "%s\r\n",
                    sync_backend->prot->u.std.compress_cmd.cmd);
        prot_flush(sync_backend->out);

        if (sync_parse_response("COMPRESS", sync_backend->in, NULL)) {
            if (do_compress) fatal("Failed to enable compression, aborting", EC_SOFTWARE);
            syslog(LOG_NOTICE, "Failed to enable compression, continuing uncompressed");
        }
        else {
            prot_setcompress(sync_backend->in);
            prot_setcompress(sync_backend->out);
        }
    }
    else if (do_compress) fatal("Backend does not support compression, aborting", EC_SOFTWARE);
#endif

    /* links to sockets */
    sync_in = sync_backend->in;
    sync_out = sync_backend->out;

    if (verbose > 1) {
        prot_setlog(sync_in, fileno(stderr));
        prot_setlog(sync_out, fileno(stderr));
    }

    /* Set inactivity timer */
    timeout = config_getint(IMAPOPT_SYNC_TIMEOUT);
    if (timeout < 3) timeout = 3;
    prot_settimeout(sync_in, timeout);

    /* Force use of LITERAL+ so we don't need two way communications */
    prot_setisclient(sync_in, 1);
    prot_setisclient(sync_out, 1);
}
Ejemplo n.º 2
0
static struct backend *restore_connect(const char *servername,
                                       struct buf *tagbuf,
                                       const struct restore_options *options)
{
    struct backend *backend = NULL;
    sasl_callback_t *cb;
    int timeout;
    const char *auth_status = NULL;

    cb = mysasl_callbacks(NULL,
                          config_getstring(IMAPOPT_RESTORE_AUTHNAME),
                          config_getstring(IMAPOPT_RESTORE_REALM),
                          config_getstring(IMAPOPT_RESTORE_PASSWORD));

    /* try to connect over IMAP */
    backend = backend_connect(backend, servername,
                              &imap_csync_protocol, "", cb, &auth_status,
                              (options->verbose > 1 ? fileno(stderr) : -1));

    if (backend) {
        if (backend->capability & CAPA_REPLICATION) {
            /* attach our IMAP tag buffer to our protstreams as userdata */
            backend->in->userdata = backend->out->userdata = tagbuf;
        }
        else {
            backend_disconnect(backend);
            backend = NULL;
        }
    }

    /* if that didn't work, fall back to csync */
    if (!backend) {
        backend = backend_connect(backend, servername,
                                  &csync_protocol, "", cb, NULL,
                                  (options->verbose > 1 ? fileno(stderr) : -1));
    }

    free_callbacks(cb);
    cb = NULL;

    if (!backend) {
        fprintf(stderr, "Can not connect to server '%s'\n", servername);
        syslog(LOG_ERR, "Can not connect to server '%s'", servername);
        return NULL;
    }

    if (servername[0] != '/' && backend->sock >= 0) {
        tcp_disable_nagle(backend->sock);
        tcp_enable_keepalive(backend->sock);
    }

#ifdef HAVE_ZLIB
    /* Does the backend support compression? */
    if (CAPA(backend, CAPA_COMPRESS)) {
        prot_printf(backend->out, "%s\r\n",
                    backend->prot->u.std.compress_cmd.cmd);
        prot_flush(backend->out);

        if (sync_parse_response("COMPRESS", backend->in, NULL)) {
            if (options->require_compression)
                fatal("Failed to enable compression, aborting", EX_SOFTWARE);
            syslog(LOG_NOTICE, "Failed to enable compression, continuing uncompressed");
        }
        else {
            prot_setcompress(backend->in);
            prot_setcompress(backend->out);
        }
    }
    else if (options->require_compression) {
        fatal("Backend does not support compression, aborting", EX_SOFTWARE);
    }
#endif

    if (options->verbose > 1) {
        /* XXX did we do this during backend_connect already? */
        prot_setlog(backend->in, fileno(stderr));
        prot_setlog(backend->out, fileno(stderr));
    }

    /* Set inactivity timer */
    timeout = config_getint(IMAPOPT_SYNC_TIMEOUT);
    if (timeout < 3) timeout = 3;
    prot_settimeout(backend->in, timeout);

    /* Force use of LITERAL+ so we don't need two way communications */
    prot_setisclient(backend->in, 1);
    prot_setisclient(backend->out, 1);

    return backend;
}