Continued data model docs.
[doldaconnect.git] / lib / uimisc.c
index 8252a7e..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);
@@ -190,7 +198,7 @@ static void process_pam(struct dc_response *resp, struct logindata *data)
                data->callback(DC_LOGIN_ERR_CONV, NULL, data->data);
                freelogindata(data);
            } else {
-               dc_queuecmd(logincallback, data, L"pass", L"%%s", buf, NULL);
+               dc_queuecmd(logincallback, data, L"pass", L"%s", buf, NULL);
            }
            if(buf != NULL)
            {
@@ -249,7 +257,7 @@ static void process_krb5(struct dc_response *resp, struct logindata *data)
        {
        case 0:
            buf = hexencode(krb->reqbuf.data, krb->reqbuf.length);
-           dc_queuecmd(logincallback, data, L"pass", L"%%s", buf, NULL);
+           dc_queuecmd(logincallback, data, L"pass", L"%s", buf, NULL);
            free(buf);
            krb->state = 1;
            break;
@@ -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;
@@ -522,7 +535,7 @@ static int logincallback(struct dc_response *resp)
                    }
                    username = pwent->pw_name;
                }
-               dc_queuecmd(logincallback, data, L"login", data->mech->name, L"%%s", username, NULL);
+               dc_queuecmd(logincallback, data, L"login", data->mech->name, L"%s", username, NULL);
            }
        }
     } else if(!wcscmp(resp->cmdname, L"login") || !wcscmp(resp->cmdname, L"pass")) {
@@ -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;
@@ -696,6 +761,7 @@ static void delpeer(struct dc_fnetpeer *peer)
            free(peer->di[i].d.str);
        putdatum(peer->fn, peer->di[i].datum);
     }
+    free(peer->di);
     free(peer);
 }
 
@@ -1071,9 +1137,9 @@ static int getpalistcallback(struct dc_response *resp)
            adddatum(fn, ires->argv[0].val.str, ires->argv[1].val.num);
            dc_freeires(ires);
        }
-       dc_queuecmd(getpeerlistcallback, data, L"lspeers", L"%%i", fn->id, NULL);
+       dc_queuecmd(getpeerlistcallback, data, L"lspeers", L"%i", fn->id, NULL);
     } else if(resp->code == 201) {
-       dc_queuecmd(getpeerlistcallback, data, L"lspeers", L"%%i", fn->id, NULL);
+       dc_queuecmd(getpeerlistcallback, data, L"lspeers", L"%i", fn->id, NULL);
     } else {
        data->callback(fn, resp->code, data->data);
        free(data);
@@ -1109,7 +1175,7 @@ void dc_getpeerlistasync(struct dc_fnetnode *fn, void (*callback)(struct dc_fnet
     data->callback = callback;
     data->fnid = fn->id;
     data->data = udata;
-    dc_queuecmd(getpalistcallback, data, L"lspa", L"%%i", fn->id, NULL);
+    dc_queuecmd(getpalistcallback, data, L"lspa", L"%i", fn->id, NULL);
 }
 
 void dc_uimisc_disconnected(void)