Added synchronous versions of connect and login.
authorfredrik <fredrik@959494ce-11ee-0310-bf91-de5d638817bd>
Tue, 8 May 2007 02:47:36 +0000 (02:47 +0000)
committerfredrik <fredrik@959494ce-11ee-0310-bf91-de5d638817bd>
Tue, 8 May 2007 02:47:36 +0000 (02:47 +0000)
git-svn-id: svn+ssh://svn.dolda2000.com/srv/svn/repos/src/doldaconnect@1026 959494ce-11ee-0310-bf91-de5d638817bd

include/doldaconnect/uilib.h
include/doldaconnect/uimisc.h
lib/uilib.c
lib/uimisc.c

index ad26394..dc726da 100644 (file)
@@ -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
index 8737070..f47dbd6 100644 (file)
@@ -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);
index f7a6b28..356e41e 100644 (file)
@@ -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);
+}
index 73684d3..c39ad76 100644 (file)
@@ -28,6 +28,7 @@
 #include <pwd.h>
 #include <string.h>
 #include <stdio.h>
+#include <sys/poll.h>
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -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;