int sconnect(char *addr,int port,char *laddr,int doproc,PSHANDLER hf,void *ha) { int idx,opt; struct sockaddr_in rem,loc; #define FAIL0(m) { clwarnx(m); return -1; } #define FAIL1(m) { sockerrmsg(m,0); return -1; } #define FAIL2(m) { sockerrmsg(m,0); goto free_sock; } #define FAIL3(m) { sockerrmsg(m,0); goto free_event; } #define FAILD(m) { sockerrmsg(m,1); return -1; } #ifdef WIN32 if (initsockets()<0) return -1; #endif if (!hf) return -1; for (idx=0;idx<NSOCK;idx++) if (!sockets[idx].inuse) break; if (idx==NSOCK) { clwarnx("too many open sockets"); return -1; } sockets[idx].handler=hf; sockets[idx].data=ha; sockets[idx].ilen=sockets[idx].olen=0; sockets[idx].lp=1; sockets[idx].lpevent=-1; sockets[idx].state=sNORMAL; sockets[idx].attr=7; sockets[idx].mode=SM_NORM; sockets[idx].opmode=doproc ? SM_NORM : SM_HALF; sockets[idx].type=RT_SOCK; sockets[idx].zsp=NULL; sockets[idx].rawin=sockets[idx].rawout=sockets[idx].procin=0; window_flush(); /* flush output before a long blocking operation */ memset(&rem,0,sizeof(rem)); rem.sin_family=AF_INET; rem.sin_port=htons((short)port); if ((rem.sin_addr.s_addr=inet_addr(addr))==INADDR_NONE) { struct hostent *hp=gethostbyname(addr); if (!hp) FAILD("can't get remote address"); memcpy(&rem.sin_addr,hp->h_addr,sizeof(rem.sin_addr)); } memcpy(&sockets[idx].remote,&rem,sizeof(sockets[idx].remote)); if (laddr) { int slen; char *cp,*buf; memset(&loc,0,sizeof(loc)); loc.sin_family=AF_INET; slen=strlen(laddr); for (cp=laddr+slen;cp>laddr;--cp) if (*cp==':') break; if (*cp==':') { buf=malloc(cp-laddr+1); if (!buf) FAIL0("out of memory"); memcpy(buf,laddr,cp-laddr); buf[cp-laddr]='\0'; ++cp; loc.sin_port=htons((short)atoi(cp)); } else buf=laddr; if ((loc.sin_addr.s_addr=inet_addr(buf))==INADDR_NONE) { struct hostent *hp=gethostbyname(buf); if (!hp) FAILD("can't get local address"); memcpy(&loc.sin_addr,hp->h_addr,sizeof(loc.sin_addr)); } if (buf!=laddr) free(buf); } if ((sockets[idx].sock=socket(PF_INET,SOCK_STREAM,0))<0) FAIL1("can't create socket"); if (laddr) if (bind(sockets[idx].sock,(struct sockaddr *)&loc,sizeof(loc))<0) FAIL2("can't bind socket"); #ifdef WIN32 if ((sockets[idx].event=CreateEvent(NULL,FALSE,FALSE,NULL))==NULL) { clwarn("can't create event"); goto free_sock; } if (WSAEventSelect(sockets[idx].sock,sockets[idx].event,FD_READ|FD_CLOSE|FD_CONNECT)) FAIL3("can't bind event to socket"); #endif #ifndef WIN32 { int flags=fcntl(sockets[idx].sock,F_GETFL,0); if (flags<0) FAIL3("can't get fd flags"); if (fcntl(sockets[idx].sock,F_SETFL,flags|O_NONBLOCK)<0) FAIL3("can't set fd flags"); } #endif opt=KERN_SOCKBUFSIZE; setsockopt(sockets[idx].sock,SOL_SOCKET,SO_RCVBUF,(void*)&opt,sizeof(opt)); /* ignore result */ if (connect(sockets[idx].sock,(struct sockaddr *)&rem,sizeof(rem))<0) { #ifdef WIN32 if (WSAGetLastError()!=WSAEWOULDBLOCK) #else if (errno!=EINPROGRESS) #endif FAIL3("can't connect to remote host"); sockets[idx].mode=SM_CONN; sockets[idx].inuse=1; } else { sockets[idx].inuse=1; if (sockets[idx].handler) sockets[idx].handler(idx,SCONN,sockets[idx].data,NULL,0); } return idx; free_event: #ifdef WIN32 CloseHandle(sockets[idx].event); #endif free_sock: closesocket(sockets[idx].sock); return -1; #undef FAIL0 #undef FAIL1 #undef FAIL2 #undef FAIL3 }
int main(int argc, const char * argv[]) { if (nftw("/tmp/apitest", cb1, 10, FTW_DEPTH | FTW_PHYS) == 0) nftw("/tmp/apitest", cb2, 10, FTW_DEPTH | FTW_PHYS); atexit(cleanup); setvbuf(stdout, NULL, _IONBF, 0); printf("opening host... "); if ((host = la_host_open("/tmp/apitest")) == NULL) { FAIL0(); } OK(); //la_host_configure_compressor(host, zlib_compressor); la_host_configure_compressor(host, la_lz4_compressor); printf("opening db... "); if ((db = la_db_open(host, "apitest")) == NULL) { FAIL0(); } OK(); la_pull_params_t params; params.dbname = "library-53b825ecc2fd4f85afd2b93cc4da7739"; params.filter = NULL; params.host = "localhost"; params.port = 5984; params.options = 0; params.user = NULL; params.password = NULL; params.resolver = NULL; params.baton = NULL; puller = la_pull_create(db, ¶ms); printf("pulling changes... "); if (la_pull_run(puller) != 0) FAIL0(); la_pull_destroy(puller); OK(); la_view_iterator_t *it = la_db_view(db, NULL, NULL, NULL, NULL); la_view_iterator_result itresult; do { la_codec_value_t *value = NULL; la_codec_error_t error; itresult = la_view_iterator_next(it, &value, &error); if (itresult == LA_VIEW_ITERATOR_GOT_NEXT) printf("got object %s\n", la_codec_dumps(value, 0)); printf("%d %d\n", itresult, itresult == LA_VIEW_ITERATOR_GOT_NEXT); } while (itresult == LA_VIEW_ITERATOR_GOT_NEXT); if (itresult != LA_VIEW_ITERATOR_END) FAIL0(); OK(); printf("pulling again... "); puller = la_pull_create(db, ¶ms); if (la_pull_run(puller) != 0) FAIL0(); la_pull_destroy(puller); OK(); return 0; }