From e4b88cc0edd9e56806aa68b6c47a7b4782f97dc1 Mon Sep 17 00:00:00 2001 From: fredrik Date: Tue, 8 May 2007 02:47:36 +0000 Subject: [PATCH] Added synchronous versions of connect and login. git-svn-id: svn+ssh://svn.dolda2000.com/srv/svn/repos/src/doldaconnect@1026 959494ce-11ee-0310-bf91-de5d638817bd --- include/doldaconnect/uilib.h | 6 +++- include/doldaconnect/uimisc.h | 3 ++ lib/uilib.c | 78 +++++++++++++++++++++++++++++++++++-------- lib/uimisc.c | 69 ++++++++++++++++++++++++++++++++++++-- 4 files changed, 140 insertions(+), 16 deletions(-) diff --git a/include/doldaconnect/uilib.h b/include/doldaconnect/uilib.h index ad26394..dc726da 100644 --- a/include/doldaconnect/uilib.h +++ b/include/doldaconnect/uilib.h @@ -38,6 +38,8 @@ struct dc_intresp } *argv; }; +char *dc_srv_local; + int dc_init(void); void dc_cleanup(void); void dc_disconnect(void); @@ -51,10 +53,12 @@ int dc_queuecmd(int (*callback)(struct dc_response *), void *data, ...); int dc_handleread(void); int dc_handlewrite(void); int dc_connect(char *host); -int dc_connectlocal(void); +int dc_connectsync(char *host, struct dc_response **respbuf); +int dc_connectsync2(char *host, int rev); struct dc_intresp *dc_interpret(struct dc_response *resp); void dc_freeires(struct dc_intresp *ires); int dc_checkprotocol(struct dc_response *resp, int revision); const char *dc_gethostname(void); +int dc_getfd(void); #endif diff --git a/include/doldaconnect/uimisc.h b/include/doldaconnect/uimisc.h index 8737070..f47dbd6 100644 --- a/include/doldaconnect/uimisc.h +++ b/include/doldaconnect/uimisc.h @@ -102,7 +102,10 @@ struct dc_transfer void *udata; }; +int dc_convtty(int type, wchar_t *text, char **resp, void *data); +int dc_convnone(int type, wchar_t *text, char **resp, void *data); void dc_loginasync(char *username, int useauthless, int (*conv)(int, wchar_t *, char **, void *), void (*callback)(int, wchar_t *, void *), void *udata); +int dc_login(char *username, int useauthless, int (*conv)(int, wchar_t *, char **, void *), wchar_t **reason); struct dc_fnetnode *dc_findfnetnode(int id); void dc_getfnlistasync(void (*callback)(int, void *), void *udata); void dc_uimisc_handlenotify(struct dc_response *resp); diff --git a/lib/uilib.c b/lib/uilib.c index f7a6b28..356e41e 100644 --- a/lib/uilib.c +++ b/lib/uilib.c @@ -102,6 +102,7 @@ struct { int family; int sentcreds; } servinfo; +char *dc_srv_local; static struct dc_response *makeresp(void) { @@ -258,6 +259,7 @@ int dc_init(void) { if((ichandle = iconv_open("wchar_t", "utf-8")) == (iconv_t)-1) return(-1); + dc_srv_local = sstrdup(""); initcmds(); return(0); } @@ -1128,7 +1130,7 @@ static struct addrinfo *defaulthost(void) return(ret); } -static int dc_connectai(struct addrinfo *hosts) +static int dc_connectai(struct addrinfo *hosts, struct qcmd **cnctcmd) { struct qcmd *qcmd; int errnobak; @@ -1144,6 +1146,8 @@ static int dc_connectai(struct addrinfo *hosts) if((fd = socket(curhost->ai_family, curhost->ai_socktype, curhost->ai_protocol)) < 0) { errnobak = errno; + freeaddrinfo(hostlist); + hostlist = NULL; errno = errnobak; return(-1); } @@ -1165,35 +1169,78 @@ static int dc_connectai(struct addrinfo *hosts) break; } } - qcmd = makeqcmd(NULL); - resetreader = 1; + if(state != -1) + { + qcmd = makeqcmd(NULL); + if(cnctcmd != NULL) + *cnctcmd = qcmd; + resetreader = 1; + } else { + free(hostlist); + hostlist = NULL; + } return(fd); } -int dc_connect(char *host) +static int dc_connect2(char *host, struct qcmd **cnctcmd) { struct addrinfo *ai; + struct qcmd *qcmd; int ret; - if(!host || !*host) + if(host == dc_srv_local) + ai = getlocalai(); + else if(!host || !*host) ai = defaulthost(); else ai = resolvhost(host); if(ai == NULL) return(-1); - if((ret = dc_connectai(ai)) != 0) - freeaddrinfo(ai); + ret = dc_connectai(ai, &qcmd); + if((ret >= 0) && (cnctcmd != NULL)) + *cnctcmd = qcmd; return(ret); } -int dc_connectlocal(void) +int dc_connect(char *host) +{ + return(dc_connect2(host, NULL)); +} + +int dc_connectsync(char *host, struct dc_response **respbuf) { - struct addrinfo *ai; int ret; + struct qcmd *cc; + struct dc_response *resp; - ai = getlocalai(); - if((ret = dc_connectai(ai)) != 0) - freeaddrinfo(ai); + if((ret = dc_connect2(host, &cc)) < 0) + return(-1); + resp = dc_gettaggedrespsync(cc->tag); + if(resp == NULL) { + dc_disconnect(); + return(-1); + } + if(respbuf == NULL) + dc_freeresp(resp); + else + *respbuf = resp; + return(ret); +} + +int dc_connectsync2(char *host, int rev) +{ + int ret; + struct dc_response *resp; + + if((ret = dc_connectsync(host, &resp)) < 0) + return(-1); + if(dc_checkprotocol(resp, rev)) + { + dc_freeresp(resp); + dc_disconnect(); + return(-1); + } + dc_freeresp(resp); return(ret); } @@ -1278,7 +1325,7 @@ int dc_checkprotocol(struct dc_response *resp, int revision) if((ires = dc_interpret(resp)) == NULL) return(-1); low = ires->argv[0].val.num; - high = ires->argv[0].val.num; + high = ires->argv[1].val.num; dc_freeires(ires); if((revision < low) || (revision > high)) return(-1); @@ -1289,3 +1336,8 @@ const char *dc_gethostname(void) { return(servinfo.hostname); } + +int dc_getfd(void) +{ + return(fd); +} diff --git a/lib/uimisc.c b/lib/uimisc.c index 73684d3..c39ad76 100644 --- a/lib/uimisc.c +++ b/lib/uimisc.c @@ -28,6 +28,7 @@ #include #include #include +#include #ifdef HAVE_CONFIG_H #include @@ -63,6 +64,13 @@ struct logindata struct authmech *mech; }; +struct synclogindata +{ + int aborted; + int err; + wchar_t *reason; +}; + struct gencbdata { void (*callback)(int resp, void *data); @@ -436,7 +444,7 @@ static struct authmech authmechs[] = } }; -static int builtinconv(int type, wchar_t *text, char **resp, void *data) +int dc_convtty(int type, wchar_t *text, char **resp, void *data) { char *buf, *pass; @@ -453,6 +461,11 @@ static int builtinconv(int type, wchar_t *text, char **resp, void *data) return(1); } +int dc_convnone(int type, wchar_t *text, char **resp, void *data) +{ + return(1); +} + static int logincallback(struct dc_response *resp) { int i; @@ -537,7 +550,7 @@ void dc_loginasync(char *username, int useauthless, int (*conv)(int, wchar_t *, data = smalloc(sizeof(*data)); if(conv == NULL) - conv = builtinconv; + conv = dc_convtty; data->conv = conv; data->mech = NULL; data->data = udata; @@ -555,6 +568,58 @@ void dc_loginasync(char *username, int useauthless, int (*conv)(int, wchar_t *, dc_queuecmd(logincallback, data, L"lsauth", NULL); } +static void synclogincb(int err, wchar_t *reason, struct synclogindata *data) +{ + if(data->aborted) + { + free(data); + return; + } + data->err = err; + if(reason == NULL) + data->reason = NULL; + else + data->reason = swcsdup(reason); +} + +int dc_login(char *username, int useauthless, int (*conv)(int, wchar_t *, char **, void *), wchar_t **reason) +{ + int ret, abort; + struct synclogindata *dbuf; + struct pollfd pfd; + + dbuf = smalloc(sizeof(*dbuf)); + memset(dbuf, 0, sizeof(*dbuf)); + dbuf->err = -1; + dc_loginasync(username, useauthless, conv, (void (*)(int, wchar_t *, void *))synclogincb, dbuf); + while(dbuf->err == -1) + { + pfd.fd = dc_getfd(); + pfd.events = POLLIN; + if(dc_wantwrite()) + pfd.events |= POLLOUT; + abort = 0; + if(poll(&pfd, 1, -1) < 0) + abort = 1; + if(!abort && (pfd.revents & POLLIN) && dc_handleread()) + abort = 1; + if(!abort && (pfd.revents & POLLOUT) && dc_handlewrite()) + abort = 1; + if(abort) + { + dbuf->aborted = 1; + return(-1); + } + } + if(reason != NULL) + *reason = dbuf->reason; + else if(dbuf->reason != NULL) + free(dbuf->reason); + ret = dbuf->err; + free(dbuf); + return(ret); +} + static struct dc_fnetpeerdatum *finddatum(struct dc_fnetnode *fn, wchar_t *id) { struct dc_fnetpeerdatum *datum; -- 2.11.0