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); }
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; }
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; }