Fixed segv bug in aborthublist.
[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);
affc65d8 72 bzs = NULL;
7989fee6 73 }
0d04e87e
FT
74 if(filter != NULL) {
75 regfree(filter);
76 free(filter);
77 filter = NULL;
78 }
79 if(handler != NULL) {
80 handler(PHO_FINI, NULL, 0);
81 handler = NULL;
82 }
83 }
84}
85
86int validhub(char *field, ...)
87{
88 int match;
89 va_list args;
90
91 if(filter == NULL)
92 return(1);
93 match = 0;
94 va_start(args, field);
95 do {
96 if(!regexec(filter, field, 0, NULL, 0)) {
97 match = 1;
98 break;
99 }
100 } while((field = va_arg(args, char *)) != NULL);
101 va_end(args);
102 return(match);
103}
104
7989fee6 105static void fdcb(gpointer data, gint source, GdkInputCondition cond)
0d04e87e 106{
7989fee6 107 int ret, bzret, hret;
0d04e87e 108
7989fee6
FT
109 if(itag != -1)
110 gdk_input_remove(itag);
111 if(otag != -1)
112 gdk_input_remove(otag);
113 itag = otag = -1;
114 ret = htprocess(hc, ((cond & GDK_INPUT_READ)?POLLIN:0) | ((cond & GDK_INPUT_WRITE)?POLLOUT:0));
115 if(ret < 0) {
116 msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Could not read hublist from server: %s"), strerror(errno));
117 aborthublist();
0d04e87e 118 return;
7989fee6
FT
119 }
120 if(state == 0) {
121 if(hc->rescode != 0) {
122 if(hc->rescode != 200) {
123 msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("The hublist server returned an error: \"%i %s\""), hc->rescode, hc->resstr);
124 aborthublist();
125 return;
126 }
127 state = 1;
b0d389ac 128 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(main_pubhubbar), _("Getting list..."));
7989fee6
FT
129 }
130 }
131 if(state == 1) {
b0d389ac
FT
132 if(hc->tlen > 0) {
133 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(main_pubhubbar), ((double)hc->rxd) / ((double)hc->tlen));
134 } else {
135 gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR(main_pubhubbar), ((double)hc->databufdata) / 10000.0);
136 gtk_progress_bar_pulse(GTK_PROGRESS_BAR(main_pubhubbar));
137 }
7989fee6
FT
138 if(hc->databufdata > 0) {
139 if(bzs == NULL) {
140 bufcat(mybuf, hc->databuf, hc->databufdata);
141 hc->databufdata = 0;
142 } else {
143 bzs->next_in = hc->databuf;
144 bzs->avail_in = hc->databufdata;
145 do {
146 sizebuf2(mybuf, mybufdata + 1024, 1);
147 bzs->next_out = mybuf + mybufdata;
148 bzs->avail_out = mybufsize - mybufdata;
149 bzret = BZ2_bzDecompress(bzs);
150 if((bzret != BZ_OK) && (bzret != BZ_STREAM_END)) {
151 msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Could not decompress hublist (%i)"), hret);
152 aborthublist();
153 return;
154 }
155 mybufdata = mybufsize - bzs->avail_out;
156 if(bzret == BZ_STREAM_END) {
157 ret = 1;
158 break;
159 }
160 } while(bzs->avail_out == 0);
161 memmove(hc->databuf, bzs->next_in, hc->databufdata -= (bzs->next_in - hc->databuf));
162 }
163 if((hret = handler(PHO_DATA, mybuf, mybufdata)) < 0)
164 aborthublist();
165 else
166 memmove(mybuf, mybuf + hret, mybufdata -= hret);
167 }
168 if(ret) {
b0d389ac
FT
169 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(main_pubhubbar), 1);
170 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(main_pubhubbar), _("Finalizing list..."));
171 gdk_window_process_updates(main_pubhubbar->window, FALSE);
0d04e87e 172 handler(PHO_EOF, NULL, 0);
0d04e87e 173 aborthublist();
7989fee6 174 }
0d04e87e 175 }
7989fee6
FT
176 if(hc != NULL)
177 settags();
178}
179
180static void settags(void)
181{
182 if(htpollflags(hc) & POLLIN)
183 itag = gdk_input_add(hc->fd, GDK_INPUT_READ, fdcb, NULL);
184 if(htpollflags(hc) & POLLOUT)
185 otag = gdk_input_add(hc->fd, GDK_INPUT_WRITE, fdcb, NULL);
0d04e87e
FT
186}
187
188void fetchhublist(char *url, regex_t *flt)
189{
0d04e87e
FT
190 int len;
191 char *p;
7989fee6 192 struct hturlinfo *u;
0d04e87e
FT
193
194 aborthublist();
195 filter = flt;
7989fee6
FT
196 u = parseurl(url);
197 hc = htconnect(u);
198 freeurl(u);
199 state = 0;
200 settags();
b0d389ac
FT
201 gtk_widget_show(main_pubhubbarbox);
202 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(main_pubhubbar), _("Connecting..."));
203 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(main_pubhubbar), 0);
204 gdk_window_process_updates(main_pubhubbarbox->window, TRUE);
7989fee6 205
0d04e87e
FT
206 len = strlen(url);
207 p = url + len;
208 if((len > 4) && !strncmp(p - 4, ".bz2", 4)) {
209 p -= 4;
210 len -= 4;
7989fee6
FT
211 bzs = memset(smalloc(sizeof(*bzs)), 0, sizeof(*bzs));
212 if(BZ2_bzDecompressInit(bzs, 0, 0) != BZ_OK) {
213 msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Could not initialize decompression library"));
214 free(bzs);
215 bzs = NULL;
216 aborthublist();
217 return;
0d04e87e 218 }
0d04e87e
FT
219 }
220 if((len > 4) && !strncmp(p - 4, ".xml", 4)) {
221 p -= 4;
222 len -= 4;
223 handler = pubhubxmlhandler;
224 } else {
225 handler = pubhuboldhandler;
226 }
0d04e87e 227 handler(PHO_INIT, NULL, 0);
0d04e87e 228}