Commit | Line | Data |
---|---|---|
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> | |
28 | #include <errno.h> | |
29 | ||
30 | #ifdef HAVE_CONFIG_H | |
31 | #include <config.h> | |
32 | #endif | |
33 | #include "dolcon.h" | |
34 | #include "hublist.h" | |
35 | ||
36 | static regex_t *filter = NULL; | |
37 | static pid_t fetchpid = 0; | |
38 | static int listfd = -1; | |
39 | static int iotag = -1; | |
40 | static int (*handler)(int, char *, size_t) = NULL; | |
41 | static char readbuf[65536]; | |
42 | static off_t bufpos = 0; | |
43 | ||
44 | void aborthublist(void) | |
45 | { | |
46 | if(fetchpid > 0) { | |
47 | gdk_input_remove(iotag); | |
48 | iotag = -1; | |
49 | close(listfd); | |
50 | listfd = -1; | |
51 | kill(fetchpid, SIGINT); | |
52 | fetchpid = 0; | |
53 | if(filter != NULL) { | |
54 | regfree(filter); | |
55 | free(filter); | |
56 | filter = NULL; | |
57 | } | |
58 | if(handler != NULL) { | |
59 | handler(PHO_FINI, NULL, 0); | |
60 | handler = NULL; | |
61 | } | |
62 | } | |
63 | } | |
64 | ||
65 | int validhub(char *field, ...) | |
66 | { | |
67 | int match; | |
68 | va_list args; | |
69 | ||
70 | if(filter == NULL) | |
71 | return(1); | |
72 | match = 0; | |
73 | va_start(args, field); | |
74 | do { | |
75 | if(!regexec(filter, field, 0, NULL, 0)) { | |
76 | match = 1; | |
77 | break; | |
78 | } | |
79 | } while((field = va_arg(args, char *)) != NULL); | |
80 | va_end(args); | |
81 | return(match); | |
82 | } | |
83 | ||
84 | static void readcb(gpointer data, gint source, GdkInputCondition cond) | |
85 | { | |
86 | int ret; | |
87 | ||
88 | if(!(cond & GDK_INPUT_READ)) | |
89 | return; | |
90 | if(bufpos == sizeof(readbuf)) | |
91 | bufpos = 0; | |
92 | ret = read(listfd, readbuf + bufpos, sizeof(readbuf) - bufpos); | |
93 | if(ret <= 0) { | |
94 | if(ret < 0) | |
95 | msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Could not read from public hub listing process: %s"), strerror(errno)); | |
96 | else | |
97 | handler(PHO_EOF, NULL, 0); | |
98 | aborthublist(); | |
99 | } else { | |
100 | bufpos += ret; | |
101 | if((ret = handler(PHO_DATA, readbuf, (size_t)bufpos)) < 0) | |
102 | aborthublist(); | |
103 | else | |
104 | memmove(readbuf, readbuf + ret, bufpos -= ret); | |
105 | } | |
106 | } | |
107 | ||
108 | void fetchhublist(char *url, regex_t *flt) | |
109 | { | |
110 | int pfd[2]; | |
111 | int len; | |
112 | char *p; | |
113 | ||
114 | aborthublist(); | |
115 | filter = flt; | |
116 | pipe(pfd); | |
117 | if((fetchpid = fork()) == 0) { | |
118 | dup2(pfd[1], 1); | |
119 | close(pfd[0]); | |
120 | close(pfd[1]); | |
121 | execlp("wget", "wget", "-qO", "-", url, NULL); | |
122 | perror("wget"); | |
123 | exit(127); | |
124 | } | |
125 | close(pfd[1]); | |
126 | listfd = pfd[0]; | |
127 | len = strlen(url); | |
128 | p = url + len; | |
129 | if((len > 4) && !strncmp(p - 4, ".bz2", 4)) { | |
130 | p -= 4; | |
131 | len -= 4; | |
132 | pipe(pfd); | |
133 | if(fork() == 0) { | |
134 | dup2(listfd, 0); | |
135 | dup2(pfd[1], 1); | |
136 | close(listfd); | |
137 | close(pfd[0]); | |
138 | close(pfd[1]); | |
139 | execlp("bzcat", "bzcat", NULL); | |
140 | perror("bzcat"); | |
141 | exit(127); | |
142 | } | |
143 | close(listfd); | |
144 | close(pfd[1]); | |
145 | listfd = pfd[0]; | |
146 | } | |
147 | if((len > 4) && !strncmp(p - 4, ".xml", 4)) { | |
148 | p -= 4; | |
149 | len -= 4; | |
150 | handler = pubhubxmlhandler; | |
151 | } else { | |
152 | handler = pubhuboldhandler; | |
153 | } | |
154 | bufpos = 0; | |
155 | handler(PHO_INIT, NULL, 0); | |
156 | iotag = gdk_input_add(listfd, GDK_INPUT_READ, readcb, NULL); | |
157 | } |