Bugfixes in the old-style hublist decoder.
[doldaconnect.git] / clients / gtk2 / hublist.c
CommitLineData
0d04e87e
FT
1/*
2 * Dolda Connect - Modular multiuser Direct Connect-style client
3 * Copyright (C) 2007 Fredrik Tolf (fredrik@dolda2000.com)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18*/
19
20#include <stdlib.h>
21#include <stdio.h>
22#include <unistd.h>
23#include <regex.h>
24#include <signal.h>
25#include <string.h>
26#include <stdarg.h>
27#include <gtk/gtk.h>
7989fee6 28#include <bzlib.h>
0d04e87e 29#include <errno.h>
7989fee6 30#include <sys/poll.h>
0d04e87e
FT
31
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35#include "dolcon.h"
36#include "hublist.h"
7989fee6
FT
37#include <http.h>
38
39static void settags(void);
0d04e87e
FT
40
41static regex_t *filter = NULL;
7989fee6 42static int itag = -1, otag = -1;
0d04e87e 43static int (*handler)(int, char *, size_t) = NULL;
7989fee6
FT
44static int state;
45static struct htconn *hc;
46static bz_stream *bzs;
47/* Only needed because of bzlib: */
48static char *mybuf;
49static size_t mybufsize, mybufdata;
0d04e87e 50
b0d389ac
FT
51#include "mainwnd.gtkh"
52
0d04e87e
FT
53void aborthublist(void)
54{
7989fee6
FT
55 if(mybuf != NULL) {
56 free(mybuf);
57 mybuf = NULL;
58 mybufsize = mybufdata = 0;
59 }
60 if(hc != NULL) {
b0d389ac 61 gtk_widget_hide(main_pubhubbarbox);
7989fee6
FT
62 if(itag != -1)
63 gdk_input_remove(itag);
64 if(otag != -1)
65 gdk_input_remove(otag);
66 itag = otag = -1;
67 freehtconn(hc);
68 hc = NULL;
69 if(bzs != NULL) {
70 BZ2_bzDecompressEnd(bzs);
71 free(bzs);
72 }
0d04e87e
FT
73 if(filter != NULL) {
74 regfree(filter);
75 free(filter);
76 filter = NULL;
77 }
78 if(handler != NULL) {
79 handler(PHO_FINI, NULL, 0);
80 handler = NULL;
81 }
82 }
83}
84
85int validhub(char *field, ...)
86{
87 int match;
88 va_list args;
89
90 if(filter == NULL)
91 return(1);
92 match = 0;
93 va_start(args, field);
94 do {
95 if(!regexec(filter, field, 0, NULL, 0)) {
96 match = 1;
97 break;
98 }
99 } while((field = va_arg(args, char *)) != NULL);
100 va_end(args);
101 return(match);
102}
103
7989fee6 104static void fdcb(gpointer data, gint source, GdkInputCondition cond)
0d04e87e 105{
7989fee6 106 int ret, bzret, hret;
0d04e87e 107
7989fee6
FT
108 if(itag != -1)
109 gdk_input_remove(itag);
110 if(otag != -1)
111 gdk_input_remove(otag);
112 itag = otag = -1;
113 ret = htprocess(hc, ((cond & GDK_INPUT_READ)?POLLIN:0) | ((cond & GDK_INPUT_WRITE)?POLLOUT:0));
114 if(ret < 0) {
115 msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Could not read hublist from server: %s"), strerror(errno));
116 aborthublist();
0d04e87e 117 return;
7989fee6
FT
118 }
119 if(state == 0) {
120 if(hc->rescode != 0) {
121 if(hc->rescode != 200) {
122 msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("The hublist server returned an error: \"%i %s\""), hc->rescode, hc->resstr);
123 aborthublist();
124 return;
125 }
126 state = 1;
b0d389ac 127 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(main_pubhubbar), _("Getting list..."));
7989fee6
FT
128 }
129 }
130 if(state == 1) {
b0d389ac
FT
131 if(hc->tlen > 0) {
132 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(main_pubhubbar), ((double)hc->rxd) / ((double)hc->tlen));
133 } else {
134 gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR(main_pubhubbar), ((double)hc->databufdata) / 10000.0);
135 gtk_progress_bar_pulse(GTK_PROGRESS_BAR(main_pubhubbar));
136 }
7989fee6
FT
137 if(hc->databufdata > 0) {
138 if(bzs == NULL) {
139 bufcat(mybuf, hc->databuf, hc->databufdata);
140 hc->databufdata = 0;
141 } else {
142 bzs->next_in = hc->databuf;
143 bzs->avail_in = hc->databufdata;
144 do {
145 sizebuf2(mybuf, mybufdata + 1024, 1);
146 bzs->next_out = mybuf + mybufdata;
147 bzs->avail_out = mybufsize - mybufdata;
148 bzret = BZ2_bzDecompress(bzs);
149 if((bzret != BZ_OK) && (bzret != BZ_STREAM_END)) {
150 msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Could not decompress hublist (%i)"), hret);
151 aborthublist();
152 return;
153 }
154 mybufdata = mybufsize - bzs->avail_out;
155 if(bzret == BZ_STREAM_END) {
156 ret = 1;
157 break;
158 }
159 } while(bzs->avail_out == 0);
160 memmove(hc->databuf, bzs->next_in, hc->databufdata -= (bzs->next_in - hc->databuf));
161 }
162 if((hret = handler(PHO_DATA, mybuf, mybufdata)) < 0)
163 aborthublist();
164 else
165 memmove(mybuf, mybuf + hret, mybufdata -= hret);
166 }
167 if(ret) {
b0d389ac
FT
168 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(main_pubhubbar), 1);
169 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(main_pubhubbar), _("Finalizing list..."));
170 gdk_window_process_updates(main_pubhubbar->window, FALSE);
0d04e87e 171 handler(PHO_EOF, NULL, 0);
0d04e87e 172 aborthublist();
7989fee6 173 }
0d04e87e 174 }
7989fee6
FT
175 if(hc != NULL)
176 settags();
177}
178
179static void settags(void)
180{
181 if(htpollflags(hc) & POLLIN)
182 itag = gdk_input_add(hc->fd, GDK_INPUT_READ, fdcb, NULL);
183 if(htpollflags(hc) & POLLOUT)
184 otag = gdk_input_add(hc->fd, GDK_INPUT_WRITE, fdcb, NULL);
0d04e87e
FT
185}
186
187void fetchhublist(char *url, regex_t *flt)
188{
0d04e87e
FT
189 int len;
190 char *p;
7989fee6 191 struct hturlinfo *u;
0d04e87e
FT
192
193 aborthublist();
194 filter = flt;
7989fee6
FT
195 u = parseurl(url);
196 hc = htconnect(u);
197 freeurl(u);
198 state = 0;
199 settags();
b0d389ac
FT
200 gtk_widget_show(main_pubhubbarbox);
201 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(main_pubhubbar), _("Connecting..."));
202 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(main_pubhubbar), 0);
203 gdk_window_process_updates(main_pubhubbarbox->window, TRUE);
7989fee6 204
0d04e87e
FT
205 len = strlen(url);
206 p = url + len;
207 if((len > 4) && !strncmp(p - 4, ".bz2", 4)) {
208 p -= 4;
209 len -= 4;
7989fee6
FT
210 bzs = memset(smalloc(sizeof(*bzs)), 0, sizeof(*bzs));
211 if(BZ2_bzDecompressInit(bzs, 0, 0) != BZ_OK) {
212 msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Could not initialize decompression library"));
213 free(bzs);
214 bzs = NULL;
215 aborthublist();
216 return;
0d04e87e 217 }
0d04e87e
FT
218 }
219 if((len > 4) && !strncmp(p - 4, ".xml", 4)) {
220 p -= 4;
221 len -= 4;
222 handler = pubhubxmlhandler;
223 } else {
224 handler = pubhuboldhandler;
225 }
0d04e87e 226 handler(PHO_INIT, NULL, 0);
0d04e87e 227}