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