X-Git-Url: http://dolda2000.com/gitweb/?a=blobdiff_plain;f=lib%2Fuimisc.c;h=e1ece1c3ae5178c482d2216849089c92a9067292;hb=c0d36fc531b148cfc8ceacc25e5e27d78cdd1906;hp=63c6fdb050efa3cf8f4dcafe12695bed47a0c985;hpb=d4c5deab29eaaab4b40df157b41d712caa8b2209;p=doldaconnect.git diff --git a/lib/uimisc.c b/lib/uimisc.c index 63c6fdb..e1ece1c 100644 --- a/lib/uimisc.c +++ b/lib/uimisc.c @@ -18,6 +18,7 @@ */ #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. */ @@ -26,7 +27,6 @@ #include #include #include -#include #include #ifdef HAVE_CONFIG_H @@ -34,7 +34,7 @@ #endif #include #include -#include +#include #ifdef HAVE_KRB5 #include @@ -79,6 +79,29 @@ struct fnetcbdata struct dc_fnetnode *dc_fnetnodes = NULL; struct dc_transfer *dc_transfers = NULL; +static void message(char *format, ...) +{ + static int on = -1; + char *v; + va_list args; + + if(on == -1) + { + on = 0; + if((v = getenv("LIBDCUI_MSG")) != NULL) + { + if(strtol(v, NULL, 0) & 1) + on = 1; + } + } + if(on == 1) + { + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + } +} + static void freelogindata(struct logindata *data) { if((data->mech != NULL) && (data->mech->release != NULL)) @@ -205,77 +228,6 @@ struct krb5data int valid, fwd, fwded; }; -static char *hexencode(char *data, size_t datalen) -{ - char *buf, this; - size_t bufsize, bufdata; - int dig; - - buf = NULL; - bufsize = bufdata = 0; - for(; datalen > 0; datalen--, data++) - { - dig = (*data & 0xF0) >> 4; - if(dig > 9) - this = 'A' + dig - 10; - else - this = dig + '0'; - addtobuf(buf, this); - dig = *data & 0x0F; - if(dig > 9) - this = 'A' + dig - 10; - else - this = dig + '0'; - addtobuf(buf, this); - } - addtobuf(buf, 0); - return(buf); -} - -static char *hexdecode(char *data, size_t *len) -{ - char *buf, this; - size_t bufsize, bufdata; - - buf = NULL; - bufsize = bufdata = 0; - for(; *data; data++) - { - if((*data >= 'A') && (*data <= 'F')) - { - this = (this & 0x0F) | ((*data - 'A' + 10) << 4); - } else if((*data >= '0') && (*data <= '9')) { - this = (this & 0x0F) | ((*data - '0') << 4); - } else { - if(buf != NULL) - free(buf); - return(NULL); - } - data++; - if(!*data) - { - if(buf != NULL) - free(buf); - return(NULL); - } - if((*data >= 'A') && (*data <= 'F')) - { - this = (this & 0xF0) | (*data - 'A' + 10); - } else if((*data >= '0') && (*data <= '9')) { - this = (this & 0xF0) | (*data - '0'); - } else { - if(buf != NULL) - free(buf); - return(NULL); - } - addtobuf(buf, this); - } - addtobuf(buf, 0); - if(len != NULL) - *len = bufdata - 1; - return(buf); -} - static void process_krb5(struct dc_response *resp, struct logindata *data) { int ret; @@ -324,7 +276,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) { - fprintf(stderr, "krb5_fwd_tgt_creds reported an error: %s\n", error_message(ret)); + message("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; @@ -376,28 +328,28 @@ static int init_krb5(struct logindata *data) data->mechdata = krb; if((ret = krb5_init_context(&krb->context)) != 0) { - fprintf(stderr, "krb5_init_context reported an error: %s\n", error_message(ret)); + message("krb5_init_context reported an error: %s\n", error_message(ret)); return(1); } if((ret = krb5_auth_con_init(krb->context, &krb->authcon)) != 0) { - fprintf(stderr, "krb5_auth_con_init reported an error: %s\n", error_message(ret)); + message("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) { - fprintf(stderr, "krb5_sname_to_principal reported an error: %s\n", error_message(ret)); + message("krb5_sname_to_principal reported an error: %s\n", error_message(ret)); return(1); } if((ret = krb5_cc_default(krb->context, &krb->ccache)) != 0) { - fprintf(stderr, "krb5_cc_default reported an error: %s\n", error_message(ret)); + message("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) { - fprintf(stderr, "krb5_cc_default reported an error: %s\n", error_message(ret)); + message("krb5_cc_default reported an error: %s\n", error_message(ret)); return(1); } memset(&creds, 0, sizeof(creds)); @@ -405,7 +357,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) { - fprintf(stderr, "krb5_get_credentials reported an error: %s\n", error_message(ret)); + message("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! */ @@ -413,7 +365,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) { - fprintf(stderr, "krb5_mk_req_extended reported an error: %s\n", error_message(ret)); + message("krb5_mk_req_extended reported an error: %s\n", error_message(ret)); return(1); } free(cksum.data); @@ -527,7 +479,7 @@ static int logincallback(struct dc_response *resp) if(authmechs[i].release != NULL) authmechs[i].release(data); data->mechdata = odata; - fprintf(stderr, "authentication mechanism %ls failed, trying further...\n", authmechs[i].name); + message("authentication mechanism %ls failed, trying further...\n", authmechs[i].name); } else { if((data->mech != NULL) && data->mech->release != NULL) { @@ -869,6 +821,9 @@ static int getfnlistcallback(struct dc_response *resp) fn->name = swcsdup(ires->argv[2].val.str); fn->numusers = ires->argv[3].val.num; fn->state = ires->argv[4].val.num; + if(fn->pubid != NULL) + free(fn->pubid); + fn->pubid = swcsdup(ires->argv[5].val.str); } else { fn = newfn(); fn->id = ires->argv[0].val.num; @@ -876,6 +831,7 @@ static int getfnlistcallback(struct dc_response *resp) fn->name = swcsdup(ires->argv[2].val.str); fn->numusers = ires->argv[3].val.num; fn->state = ires->argv[4].val.num; + fn->pubid = swcsdup(ires->argv[5].val.str); fn->found = 1; } dc_freeires(ires); @@ -985,13 +941,49 @@ static int gettrlistcallback(struct dc_response *resp) return(1); } +static int sortlist1(const struct dc_respline *l1, const struct dc_respline *l2) +{ + return(wcscmp(l1->argv[1], l2->argv[1])); +} + +static int sortlist2(const struct dc_fnetpeer **p1, const struct dc_fnetpeer **p2) +{ + return(wcscmp((*p1)->id, (*p2)->id)); +} + +static void fillpeer(struct dc_fnetpeer *peer, struct dc_respline *r) +{ + int i; + struct dc_fnetpeerdatum *datum; + + for(i = 3; i < r->argc; i += 2) + { + if((datum = finddatum(peer->fn, r->argv[i])) != NULL) + { + switch(datum->dt) + { + case DC_FNPD_INT: + peersetnum(peer, datum->id, wcstol(r->argv[i + 1], NULL, 10)); + break; + case DC_FNPD_LL: + peersetlnum(peer, datum->id, wcstoll(r->argv[i + 1], NULL, 10)); + break; + case DC_FNPD_STR: + peersetstr(peer, datum->id, r->argv[i + 1]); + break; + } + } + } +} + static int getpeerlistcallback(struct dc_response *resp) { - int i, o; + int i, o, c; struct dc_fnetnode *fn; struct fnetcbdata *data; - struct dc_fnetpeer *peer, *next; - struct dc_fnetpeerdatum *datum; + struct dc_fnetpeer *peer; + struct dc_fnetpeer **plist; + size_t plistsize, plistdata; data = resp->data; if((fn = dc_findfnetnode(data->fnid)) == NULL) @@ -1002,38 +994,43 @@ static int getpeerlistcallback(struct dc_response *resp) } if(resp->code == 200) { - for(peer = fn->peers; peer != NULL; peer = peer->next) - peer->found = 0; - for(i = 0; i < resp->numlines; i++) + qsort(resp->rlines, resp->numlines, sizeof(*resp->rlines), (int (*)(const void *, const void *))sortlist1); + plist = NULL; + plistsize = plistdata = 0; + for(i = 0, peer = fn->peers; peer != NULL; peer = peer->next) + addtobuf(plist, peer); + qsort(plist, plistdata, sizeof(*plist), (int (*)(const void *, const void *))sortlist2); + i = o = 0; + while(1) { - if((peer = dc_fnetfindpeer(fn, resp->rlines[i].argv[1])) == NULL) - peer = addpeer(fn, resp->rlines[i].argv[1], resp->rlines[i].argv[2]); - peer->found = 1; - for(o = 3; o < resp->rlines[i].argc; o += 2) + if((i < resp->numlines) && (o < plistdata)) { - if((datum = finddatum(fn, resp->rlines[i].argv[o])) != NULL) + c = wcscmp(resp->rlines[i].argv[1], plist[o]->id); + if(c < 0) { - switch(datum->dt) - { - case DC_FNPD_INT: - peersetnum(peer, datum->id, wcstol(resp->rlines[i].argv[o + 1], NULL, 10)); - break; - case DC_FNPD_LL: - peersetlnum(peer, datum->id, wcstoll(resp->rlines[i].argv[o + 1], NULL, 10)); - break; - case DC_FNPD_STR: - peersetstr(peer, datum->id, resp->rlines[i].argv[o + 1]); - break; - } + peer = addpeer(fn, resp->rlines[i].argv[1], resp->rlines[i].argv[2]); + fillpeer(peer, resp->rlines + i); + i++; + } else if(c > 0) { + delpeer(plist[o]); + o++; + } else { + fillpeer(plist[o], resp->rlines + i); + i++; + o++; } + } else if(i < resp->numlines) { + peer = addpeer(fn, resp->rlines[i].argv[1], resp->rlines[i].argv[2]); + fillpeer(peer, resp->rlines + i); + i++; + } else if(o < plistdata) { + delpeer(plist[o]); + o++; + } else { + break; } } - for(peer = fn->peers; peer != NULL; peer = next) - { - next = peer->next; - if(!peer->found) - delpeer(peer); - } + free(plist); } else if(resp->code == 201) { while(fn->peers != NULL) delpeer(fn->peers); @@ -1246,7 +1243,7 @@ void dc_uimisc_handlenotify(struct dc_response *resp) free(peer->nick); peer->nick = swcsdup(ires->argv[2].val.str); } - for(i = 3; i < resp->rlines[0].argc; i += 3) + for(i = 4; i < resp->rlines[0].argc; i += 3) { switch(wcstol(resp->rlines[0].argv[i + 1], NULL, 10)) {