X-Git-Url: http://dolda2000.com/gitweb/?a=blobdiff_plain;f=lib%2Fuimisc.c;h=2aa6fd3598162c1c8ddb2f63d0d56c90b56c4684;hb=HEAD;hp=8252a7e46bf1f1ac6b36cd1ada8086e400c06a8f;hpb=3616b334bc6426e973e08b612a5e8fd30ad80a5f;p=doldaconnect.git diff --git a/lib/uimisc.c b/lib/uimisc.c index 8252a7e..2aa6fd3 100644 --- a/lib/uimisc.c +++ b/lib/uimisc.c @@ -1,6 +1,6 @@ /* * Dolda Connect - Modular multiuser Direct Connect-style client - * Copyright (C) 2004 Fredrik Tolf (fredrik@dolda2000.com) + * Copyright (C) 2004 Fredrik Tolf * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,15 +19,12 @@ #include #include -/* I'm very unsure about this, but for now it defines wcstoll (which - * should be defined anyway) and doesn't break anything... let's keep - * two eyes wide open, though. */ -#define __USE_ISOC99 #include #include #include #include #include +#include #ifdef HAVE_CONFIG_H #include @@ -63,6 +60,13 @@ struct logindata struct authmech *mech; }; +struct synclogindata +{ + int aborted; + int err; + wchar_t *reason; +}; + struct gencbdata { void (*callback)(int resp, void *data); @@ -79,22 +83,19 @@ struct fnetcbdata struct dc_fnetnode *dc_fnetnodes = NULL; struct dc_transfer *dc_transfers = NULL; -static void message(char *format, ...) +static void message(int bits, char *format, ...) { - static int on = -1; + static int hb = -1; char *v; va_list args; - if(on == -1) + if(hb == -1) { - on = 0; + hb = 0; if((v = getenv("LIBDCUI_MSG")) != NULL) - { - if(strtol(v, NULL, 0) & 1) - on = 1; - } + hb = strtol(v, NULL, 0) & 65535; } - if(on == 1) + if(hb & bits) { va_start(args, format); vfprintf(stderr, format, args); @@ -190,7 +191,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) { @@ -236,6 +237,7 @@ static void process_krb5(struct dc_response *resp, struct logindata *data) krb5_data k5d; krb5_ap_rep_enc_part *repl; char *buf; + size_t kdl; krb = data->mechdata; switch(resp->code) @@ -249,14 +251,15 @@ 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; case 1: if((ires = dc_interpret(resp)) != NULL) { - k5d.data = hexdecode(icswcstombs(ires->argv[0].val.str, NULL, NULL), &k5d.length); + k5d.data = hexdecode(icswcstombs(ires->argv[0].val.str, NULL, NULL), &kdl); + k5d.length = kdl; if(!krb->valid) { if((ret = krb5_rd_rep(krb->context, krb->authcon, &k5d, &repl)) != 0) @@ -276,7 +279,7 @@ static void process_krb5(struct dc_response *resp, struct logindata *data) krb->reqbuf.data = NULL; if((ret = krb5_fwd_tgt_creds(krb->context, krb->authcon, NULL, krb->servcreds->client, krb->servcreds->server, 0, 1, &krb->reqbuf)) != 0) { - message("krb5_fwd_tgt_creds reported an error: %s\n", error_message(ret)); + message(1, "krb5_fwd_tgt_creds reported an error: %s\n", error_message(ret)); dc_queuecmd(logincallback, data, L"pass", L"31", NULL); krb->fwd = 0; krb->state = 2; @@ -323,7 +326,7 @@ static int init_krb5(struct logindata *data) if(dc_gethostname() == NULL) { - message("cannot use krb5 without a host name"); + message(1, "cannot use krb5 without a host name\n"); return(1); } krb = smalloc(sizeof(*krb)); @@ -333,28 +336,28 @@ static int init_krb5(struct logindata *data) data->mechdata = krb; if((ret = krb5_init_context(&krb->context)) != 0) { - message("krb5_init_context reported an error: %s\n", error_message(ret)); + message(1, "krb5_init_context reported an error: %s\n", error_message(ret)); return(1); } if((ret = krb5_auth_con_init(krb->context, &krb->authcon)) != 0) { - message("krb5_auth_con_init reported an error: %s\n", error_message(ret)); + message(1, "krb5_auth_con_init reported an error: %s\n", error_message(ret)); return(1); } krb5_auth_con_setflags(krb->context, krb->authcon, KRB5_AUTH_CONTEXT_DO_SEQUENCE); if((ret = krb5_sname_to_principal(krb->context, dc_gethostname(), "doldacond", KRB5_NT_SRV_HST, &krb->sprinc)) != 0) { - message("krb5_sname_to_principal reported an error: %s\n", error_message(ret)); + message(1, "krb5_sname_to_principal reported an error: %s\n", error_message(ret)); return(1); } if((ret = krb5_cc_default(krb->context, &krb->ccache)) != 0) { - message("krb5_cc_default reported an error: %s\n", error_message(ret)); + message(1, "krb5_cc_default reported an error: %s\n", error_message(ret)); return(1); } if((ret = krb5_cc_get_principal(krb->context, krb->ccache, &krb->myprinc)) != 0) { - message("krb5_cc_default reported an error: %s\n", error_message(ret)); + message(1, "krb5_cc_default reported an error: %s\n", error_message(ret)); return(1); } memset(&creds, 0, sizeof(creds)); @@ -362,7 +365,7 @@ static int init_krb5(struct logindata *data) creds.server = krb->sprinc; if((ret = krb5_get_credentials(krb->context, 0, krb->ccache, &creds, &krb->servcreds)) != 0) { - message("krb5_get_credentials reported an error: %s\n", error_message(ret)); + message(1, "krb5_get_credentials reported an error: %s\n", error_message(ret)); return(1); } /* WTF is this checksum stuff?! The Krb docs don't say a word about it! */ @@ -370,7 +373,7 @@ static int init_krb5(struct logindata *data) cksum.length = strlen(cksum.data); if((ret = krb5_mk_req_extended(krb->context, &krb->authcon, AP_OPTS_MUTUAL_REQUIRED, &cksum, krb->servcreds, &krb->reqbuf)) != 0) { - message("krb5_mk_req_extended reported an error: %s\n", error_message(ret)); + message(1, "krb5_mk_req_extended reported an error: %s\n", error_message(ret)); return(1); } free(cksum.data); @@ -436,7 +439,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 +456,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; @@ -485,12 +493,13 @@ static int logincallback(struct dc_response *resp) { odata = data->mechdata; data->mechdata = NULL; + message(4, "trying auth mech %ls\n", authmechs[i].name); if((authmechs[i].init != NULL) && authmechs[i].init(data)) { if(authmechs[i].release != NULL) authmechs[i].release(data); data->mechdata = odata; - message("authentication mechanism %ls failed, trying further...\n", authmechs[i].name); + message(2, "authentication mechanism %ls failed, trying further...\n", authmechs[i].name); } else { if((data->mech != NULL) && data->mech->release != NULL) { @@ -522,7 +531,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 +546,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 +564,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 +757,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); } @@ -905,8 +967,8 @@ static int gettrlistcallback(struct dc_response *resp) } transfer->dir = ires->argv[1].val.num; transfer->state = ires->argv[2].val.num; - transfer->size = ires->argv[6].val.num; - transfer->curpos = ires->argv[7].val.num; + transfer->size = ires->argv[6].val.lnum; + transfer->curpos = ires->argv[7].val.lnum; if(transfer->hash != NULL) { free(transfer->hash); @@ -922,8 +984,8 @@ static int gettrlistcallback(struct dc_response *resp) transfer->peerid = swcsdup(ires->argv[3].val.str); transfer->peernick = swcsdup(ires->argv[4].val.str); transfer->path = swcsdup(ires->argv[5].val.str); - transfer->size = ires->argv[6].val.num; - transfer->curpos = ires->argv[7].val.num; + transfer->size = ires->argv[6].val.lnum; + transfer->curpos = ires->argv[7].val.lnum; if(wcslen(ires->argv[8].val.str) > 0) transfer->hash = swcsdup(ires->argv[8].val.str); transfer->found = 1; @@ -1071,9 +1133,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 +1171,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) @@ -1185,7 +1247,7 @@ void dc_uimisc_handlenotify(struct dc_response *resp) break; case 613: if((transfer = dc_findtransfer(ires->argv[0].val.num)) != NULL) - transfer->size = ires->argv[1].val.num; + transfer->size = ires->argv[1].val.lnum; break; case 614: if((transfer = dc_findtransfer(ires->argv[0].val.num)) != NULL) @@ -1196,7 +1258,7 @@ void dc_uimisc_handlenotify(struct dc_response *resp) break; case 615: if((transfer = dc_findtransfer(ires->argv[0].val.num)) != NULL) - transfer->curpos = ires->argv[1].val.num; + transfer->curpos = ires->argv[1].val.lnum; break; case 616: if((transfer = dc_findtransfer(ires->argv[0].val.num)) != NULL)