| 112 struct grab_url_data { |
109 struct grab_url_data { |
| 113 void (*callback)(gpointer, char *); |
110 void (*callback)(gpointer, char *); |
| 114 gpointer data; |
111 gpointer data; |
| 115 struct g_url website; |
112 struct g_url website; |
| 116 char *url; |
113 char *url; |
| |
114 |
| |
115 int inpa; |
| |
116 |
| |
117 gboolean sentreq; |
| |
118 char *webdata; |
| |
119 int len; |
| |
120 gboolean startsaving; |
| 117 }; |
121 }; |
| 118 |
122 |
| 119 static void grab_url_callback(gpointer dat, gint sock, GdkInputCondition cond) |
123 static void grab_url_callback(gpointer dat, gint sock, GaimInputCondition cond) |
| 120 { |
124 { |
| 121 struct grab_url_data *gunk = dat; |
125 struct grab_url_data *gunk = dat; |
| 122 char *webdata = NULL; |
|
| 123 int len; |
|
| 124 int read_rv; |
|
| 125 int datalen = 0; |
|
| 126 char buf[256]; |
|
| 127 char data; |
126 char data; |
| 128 int startsaving = 0; |
|
| 129 GtkWidget *pw = NULL, *pbar = NULL, *label; |
|
| 130 |
127 |
| 131 if (sock == -1) { |
128 if (sock == -1) { |
| 132 gunk->callback(gunk->data, NULL); |
129 gunk->callback(gunk->data, NULL); |
| 133 g_free(gunk->url); |
130 g_free(gunk->url); |
| 134 g_free(gunk); |
131 g_free(gunk); |
| 135 return; |
132 return; |
| 136 } |
133 } |
| 137 |
134 |
| 138 g_snprintf(buf, sizeof(buf), "GET /%s HTTP/1.0\r\n\r\n", gunk->website.page); |
135 if (!gunk->sentreq) { |
| 139 debug_printf("Request: %s\n", buf); |
136 char buf[256]; |
| 140 write(sock, buf, strlen(buf)); |
137 g_snprintf(buf, sizeof(buf), "GET /%s HTTP/1.0\r\n\r\n", gunk->website.page); |
| 141 fcntl(sock, F_SETFL, O_NONBLOCK); |
138 debug_printf("Request: %s\n", buf); |
| 142 |
139 write(sock, buf, strlen(buf)); |
| 143 webdata = NULL; |
140 fcntl(sock, F_SETFL, O_NONBLOCK); |
| 144 len = 0; |
141 gunk->sentreq = TRUE; |
| 145 |
142 gunk->inpa = gaim_input_add(sock, GAIM_INPUT_READ, grab_url_callback, dat); |
| 146 /* |
143 return; |
| 147 * avoid fgetc(), it causes problems on solaris |
144 } |
| 148 while ((data = fgetc(sockfile)) != EOF) { |
145 |
| 149 */ |
146 if (read(sock, &data, 1) > 0 || errno == EWOULDBLOCK) { |
| 150 /* read_rv will be 0 on EOF and < 0 on error, so this should be fine */ |
|
| 151 while ((read_rv = read(sock, &data, 1)) > 0 || errno == EWOULDBLOCK) { |
|
| 152 if (errno == EWOULDBLOCK) { |
147 if (errno == EWOULDBLOCK) { |
| 153 errno = 0; |
148 errno = 0; |
| 154 continue; |
149 return; |
| 155 } |
150 } |
| 156 |
151 |
| 157 if (!data) |
152 if (!gunk->startsaving && data == '<') { |
| 158 continue; |
153 if (gunk->webdata) |
| 159 |
154 g_free(gunk->webdata); |
| 160 if (!startsaving && data == '<') { |
155 gunk->webdata = NULL; |
| 161 #ifdef HAVE_STRSTR |
156 gunk->len = 0; |
| 162 char *cs = strstr(webdata, "Content-Length"); |
157 gunk->startsaving = 1; |
| 163 if (cs) { |
158 } |
| 164 char tmpbuf[1024]; |
159 |
| 165 sscanf(cs, "Content-Length: %d", &datalen); |
160 gunk->len++; |
| 166 |
161 gunk->webdata = g_realloc(gunk->webdata, gunk->len); |
| 167 g_snprintf(tmpbuf, 1024, _("Getting %d bytes from %s"), |
162 gunk->webdata[gunk->len - 1] = data; |
| 168 datalen, gunk->url); |
163 } else if (errno != ETIMEDOUT) { |
| 169 pw = gtk_dialog_new(); |
164 |
| 170 |
165 gunk->webdata = g_realloc(gunk->webdata, gunk->len + 1); |
| 171 label = gtk_label_new(tmpbuf); |
166 gunk->webdata[gunk->len] = 0; |
| 172 gtk_widget_show(label); |
167 |
| 173 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(pw)->vbox), |
168 debug_printf(_("Receieved: '%s'\n"), gunk->webdata); |
| 174 label, FALSE, FALSE, 5); |
169 |
| 175 |
170 gaim_input_remove(gunk->inpa); |
| 176 pbar = gtk_progress_bar_new(); |
171 close(sock); |
| 177 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(pw)->action_area), |
172 gunk->callback(gunk->data, gunk->webdata); |
| 178 pbar, FALSE, FALSE, 5); |
173 if (gunk->webdata) |
| 179 gtk_widget_show(pbar); |
174 g_free(gunk->webdata); |
| 180 |
175 g_free(gunk->url); |
| 181 gtk_window_set_title(GTK_WINDOW(pw), _("Getting Data")); |
176 g_free(gunk); |
| 182 |
177 } else { |
| 183 gtk_widget_realize(pw); |
178 gaim_input_remove(gunk->inpa); |
| 184 aol_icon(pw->window); |
179 close(sock); |
| 185 |
180 gunk->callback(gunk->data, NULL); |
| 186 gtk_widget_show(pw); |
181 if (gunk->webdata) |
| 187 } else |
182 g_free(gunk->webdata); |
| 188 datalen = 0; |
183 g_free(gunk->url); |
| 189 #else |
184 g_free(gunk); |
| 190 datalen = 0; |
185 } |
| 191 #endif |
|
| 192 g_free(webdata); |
|
| 193 webdata = NULL; |
|
| 194 len = 0; |
|
| 195 startsaving = 1; |
|
| 196 } |
|
| 197 |
|
| 198 len++; |
|
| 199 webdata = g_realloc(webdata, len); |
|
| 200 webdata[len - 1] = data; |
|
| 201 |
|
| 202 if (pbar) |
|
| 203 gtk_progress_bar_update(GTK_PROGRESS_BAR(pbar), ((100 * len) / datalen) / 100.0); |
|
| 204 |
|
| 205 while (gtk_events_pending()) |
|
| 206 gtk_main_iteration(); |
|
| 207 } |
|
| 208 |
|
| 209 webdata = g_realloc(webdata, len + 1); |
|
| 210 webdata[len] = 0; |
|
| 211 |
|
| 212 |
|
| 213 debug_printf(_("Receieved: '%s'\n"), webdata); |
|
| 214 |
|
| 215 if (pw) |
|
| 216 gtk_widget_destroy(pw); |
|
| 217 |
|
| 218 close(sock); |
|
| 219 gunk->callback(gunk->data, webdata); |
|
| 220 g_free(gunk->url); |
|
| 221 g_free(gunk); |
|
| 222 } |
186 } |
| 223 |
187 |
| 224 void grab_url(char *url, void (*callback)(gpointer, char *), gpointer data) |
188 void grab_url(char *url, void (*callback)(gpointer, char *), gpointer data) |
| 225 { |
189 { |
| 226 int sock; |
190 int sock; |