Esempio 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);
}
Esempio n. 2
0
gpointer
ipmsg_tcp_recv_thread(gpointer data){
  ssize_t recv_len;
  size_t addr_len;
  int rc;
  tcp_con_t *con;
  char *recv_buf=NULL;
  int count=200;
  struct addrinfo *info;

  con=(tcp_con_t *)data;
  if (!con) {
    err_out("No connection recived\n");
    g_assert(con);
    return NULL;
  }
  if (!(con->peer_info)) {
    err_out("Invalid connection recived\n");
    g_assert(con->peer_info);
    return NULL;
  }
  
  rc=tcp_enable_keepalive(con);
  if (rc<0)
    return NULL;

  recv_buf=g_malloc(_MSG_BUF_SIZE);
  if (!recv_buf)
    return NULL;

  memset(recv_buf,0,_MSG_BUF_SIZE);

  while(1) {
    if (wait_socket(con->soc,WAIT_FOR_READ,TCP_SELECT_SEC)<0) {
      err_out("Can not send socket\n");
      destroy_tcp_connection(con);
      goto error_out;
    }else{
    read_retry:
      errno=0;
      memset(recv_buf, 0, sizeof(recv_buf));
      info=con->peer_info;
      recv_len=recv(con->soc,
		    recv_buf,
		    _MSG_BUF_SIZE,
		    MSG_PEEK);

      if (recv_len<=0) {
	if (errno==EINTR)
	  goto read_retry;
	if (errno)
	  err_out("Can not peek message %s(errno:%d)\n",strerror(errno),errno);
	destroy_tcp_connection(con);
	goto error_out;
      }

      dbg_out("tcp peek read:%d %s\n",recv_len,recv_buf);

      recv_len=recv(con->soc,
		    recv_buf,
		    recv_len,
		    MSG_PEEK);

      dbg_out("tcp read:%d %s\n",recv_len,recv_buf);
      if (recv_len>0) {
	msg_data_t msg;
	request_msg_t req;
	char *path;
	off_t size;
	unsigned long ipmsg_fattr;

	recv_buf[recv_len-1]='\0';
	memset(&req,0,sizeof(request_msg_t));

	init_message_data(&msg);
	parse_message(NULL,&msg,recv_buf,recv_len);
	parse_request(&req,msg.message);
	rc=refer_attach_file(req.pkt_no,req.fileid,&ipmsg_fattr,(const char **)&path,&size);
	if (rc<0) {
	  err_out("Can not find message:pktno %ld id : %d\n",
		  req.pkt_no,
		  req.fileid);
	  close(con->soc); /* エラーとしてクローズする  */
	}else{
	  dbg_out("transfer:%s (%d)\n",path,size);
	  switch(ipmsg_fattr) 
	    {
	    case IPMSG_FILE_REGULAR:
	      if (!tcp_transfer_file(con,path,size,0)) {
		tcp_ipmsg_finalize_connection(con);
		download_monitor_release_file(req.pkt_no,req.fileid);
	      }
	      break;
	    case IPMSG_FILE_DIR:
	      if (!tcp_transfer_dir(con,path)){
		download_monitor_release_file(req.pkt_no,req.fileid);
		tcp_ipmsg_finalize_connection(con);
	      }
	      break;
	    default:
	      break;
	    }
	  release_message_data(&msg);
	  g_free(path);
	  break;
	}
	release_message_data(&msg);
	break;
      }
    }
    --count;
    if (!count)
      break;
  }
  if (con->peer_info) /* closeは相手側で行うので, destroy_tcp_connectionは呼び出せない
		  * (Win版ipmsgの仕様).  
		  */
    freeaddrinfo(con->peer_info); 
 error_out:
  g_free(con);
  if (recv_buf)
    g_free(recv_buf);

  return NULL;
}
Esempio n. 3
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;
}