X-Git-Url: http://dolda2000.com/gitweb/?p=doldaconnect.git;a=blobdiff_plain;f=clients%2Fgtk2%2Fhublist.c;h=2420ff89e93cec134ce265110e765a6f6784b5c2;hp=72121468024deb3f2735ff4f2c3875c8c9328155;hb=0bdaf034bbe27cb94ab32847afe683cb11a000eb;hpb=d05758f6eda21695e6215d60d28b9747d0b8aaa3 diff --git a/clients/gtk2/hublist.c b/clients/gtk2/hublist.c index 7212146..2420ff8 100644 --- a/clients/gtk2/hublist.c +++ b/clients/gtk2/hublist.c @@ -1,6 +1,6 @@ /* * Dolda Connect - Modular multiuser Direct Connect-style client - * Copyright (C) 2007 Fredrik Tolf (fredrik@dolda2000.com) + * Copyright (C) 2007 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 @@ -25,31 +25,52 @@ #include #include #include +#include #include +#include #ifdef HAVE_CONFIG_H #include #endif #include "dolcon.h" #include "hublist.h" +#include + +static void settags(void); static regex_t *filter = NULL; -static pid_t fetchpid = 0; -static int listfd = -1; -static int iotag = -1; +static int itag = -1, otag = -1; static int (*handler)(int, char *, size_t) = NULL; -static char readbuf[65536]; -static off_t bufpos = 0; +static int state; +static struct htconn *hc; +static bz_stream *bzs; +/* Only needed because of bzlib: */ +static char *mybuf; +static size_t mybufsize, mybufdata; + +#include "mainwnd.gtkh" void aborthublist(void) { - if(fetchpid > 0) { - gdk_input_remove(iotag); - iotag = -1; - close(listfd); - listfd = -1; - kill(fetchpid, SIGINT); - fetchpid = 0; + if(mybuf != NULL) { + free(mybuf); + mybuf = NULL; + mybufsize = mybufdata = 0; + } + if(hc != NULL) { + gtk_widget_hide(main_pubhubbarbox); + if(itag != -1) + gdk_input_remove(itag); + if(otag != -1) + gdk_input_remove(otag); + itag = otag = -1; + freehtconn(hc); + hc = NULL; + if(bzs != NULL) { + BZ2_bzDecompressEnd(bzs); + free(bzs); + bzs = NULL; + } if(filter != NULL) { regfree(filter); free(filter); @@ -81,77 +102,134 @@ int validhub(char *field, ...) return(match); } -static void readcb(gpointer data, gint source, GdkInputCondition cond) +static void fdcb(gpointer data, gint source, GdkInputCondition cond) { - int ret; + int ret, bzret, hret; - if(!(cond & GDK_INPUT_READ)) + if(itag != -1) + gdk_input_remove(itag); + if(otag != -1) + gdk_input_remove(otag); + itag = otag = -1; + ret = htprocess(hc, ((cond & GDK_INPUT_READ)?POLLIN:0) | ((cond & GDK_INPUT_WRITE)?POLLOUT:0)); + if(ret < 0) { + msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Could not read hublist from server: %s"), strerror(errno)); + aborthublist(); return; - if(bufpos == sizeof(readbuf)) - bufpos = 0; - ret = read(listfd, readbuf + bufpos, sizeof(readbuf) - bufpos); - if(ret <= 0) { - if(ret < 0) - msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Could not read from public hub listing process: %s"), strerror(errno)); - else + } + if(state == 0) { + if(hc->rescode != 0) { + if(hc->rescode != 200) { + msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("The hublist server returned an error: \"%i %s\""), hc->rescode, hc->resstr); + aborthublist(); + return; + } + state = 1; + gtk_progress_bar_set_text(GTK_PROGRESS_BAR(main_pubhubbar), _("Getting list...")); + } + } + if(state == 1) { + if(hc->tlen > 0) { + gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(main_pubhubbar), ((double)hc->rxd) / ((double)hc->tlen)); + } else { + gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR(main_pubhubbar), ((double)hc->databufdata) / 10000.0); + gtk_progress_bar_pulse(GTK_PROGRESS_BAR(main_pubhubbar)); + } + if(hc->databufdata > 0) { + if(bzs == NULL) { + bufcat(mybuf, hc->databuf, hc->databufdata); + hc->databufdata = 0; + } else { + bzs->next_in = hc->databuf; + bzs->avail_in = hc->databufdata; + do { + sizebuf2(mybuf, mybufdata + 1024, 1); + bzs->next_out = mybuf + mybufdata; + bzs->avail_out = mybufsize - mybufdata; + bzret = BZ2_bzDecompress(bzs); + if((bzret != BZ_OK) && (bzret != BZ_STREAM_END)) { + msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Could not decompress hublist (%i)"), bzret); + aborthublist(); + return; + } + mybufdata = mybufsize - bzs->avail_out; + if(bzret == BZ_STREAM_END) { + ret = 1; + break; + } + } while(bzs->avail_out == 0); + memmove(hc->databuf, bzs->next_in, hc->databufdata -= (bzs->next_in - hc->databuf)); + } + if((hret = handler(PHO_DATA, mybuf, mybufdata)) < 0) + aborthublist(); + else + memmove(mybuf, mybuf + hret, mybufdata -= hret); + } + if(ret) { + gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(main_pubhubbar), 1); + gtk_progress_bar_set_text(GTK_PROGRESS_BAR(main_pubhubbar), _("Finalizing list...")); + gdk_window_process_updates(main_pubhubbar->window, FALSE); handler(PHO_EOF, NULL, 0); - aborthublist(); - } else { - bufpos += ret; - if((ret = handler(PHO_DATA, readbuf, (size_t)bufpos)) < 0) aborthublist(); - else - memmove(readbuf, readbuf + ret, bufpos -= ret); + } } + if(hc != NULL) + settags(); +} + +static void settags(void) +{ + if(htpollflags(hc) & POLLIN) + itag = gdk_input_add(hc->fd, GDK_INPUT_READ, fdcb, NULL); + if(htpollflags(hc) & POLLOUT) + otag = gdk_input_add(hc->fd, GDK_INPUT_WRITE, fdcb, NULL); } void fetchhublist(char *url, regex_t *flt) { - int pfd[2]; int len; char *p; + struct hturlinfo *u; aborthublist(); filter = flt; - pipe(pfd); - if((fetchpid = fork()) == 0) { - dup2(pfd[1], 1); - close(pfd[0]); - close(pfd[1]); - execlp("wget", "wget", "-qO", "-", url, NULL); - perror("wget"); - exit(127); + u = parseurl(url); + hc = htconnect(u); + freeurl(u); + if(hc == NULL) { + msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Could not read hublist from server: %s"), strerror(errno)); + return; } - close(pfd[1]); - listfd = pfd[0]; + hc->autoredir = 1; + state = 0; + settags(); + gtk_widget_show(main_pubhubbarbox); + gtk_progress_bar_set_text(GTK_PROGRESS_BAR(main_pubhubbar), _("Connecting...")); + gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(main_pubhubbar), 0); + gdk_window_process_updates(main_pubhubbarbox->window, TRUE); + len = strlen(url); p = url + len; if((len > 4) && !strncmp(p - 4, ".bz2", 4)) { + /* Because using Transfer-Encoding would just be too good! */ p -= 4; len -= 4; - pipe(pfd); - if(fork() == 0) { - dup2(listfd, 0); - dup2(pfd[1], 1); - close(listfd); - close(pfd[0]); - close(pfd[1]); - execlp("bzcat", "bzcat", NULL); - perror("bzcat"); - exit(127); + bzs = memset(smalloc(sizeof(*bzs)), 0, sizeof(*bzs)); + if(BZ2_bzDecompressInit(bzs, 0, 0) != BZ_OK) { + msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Could not initialize decompression library")); + free(bzs); + bzs = NULL; + aborthublist(); + return; } - close(listfd); - close(pfd[1]); - listfd = pfd[0]; } if((len > 4) && !strncmp(p - 4, ".xml", 4)) { + /* Because using Content-Type would just be too good! */ p -= 4; len -= 4; handler = pubhubxmlhandler; } else { handler = pubhuboldhandler; } - bufpos = 0; handler(PHO_INIT, NULL, 0); - iotag = gdk_input_add(listfd, GDK_INPUT_READ, readcb, NULL); }