Mercurial > pidgin
annotate src/html.c @ 5638:0bdfa28c678e
[gaim-migrate @ 6047]
We're slowly killing off multi.h. The proto_user_split and proto_user_opt
have been replaced with GaimAccountOption and GaimAccountUserSplit
structures, which of course have an API. The account dialog is being
rewritten as well, and will soon allow you to add and modify accounts again.
committer: Tailor Script <tailor@pidgin.im>
author | Christian Hammond <chipx86@chipx86.com> |
---|---|
date | Sun, 01 Jun 2003 17:40:20 +0000 |
parents | e41b04bb4afe |
children | 46d7ad0dfa26 |
rev | line source |
---|---|
1 | 1 /* |
2 * gaim | |
3 * | |
4 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net> | |
5176 | 5 * 2003, Nathan Walp <faceprint@faceprint.com> |
1 | 6 * |
7 * This program is free software; you can redistribute it and/or modify | |
8 * it under the terms of the GNU General Public License as published by | |
9 * the Free Software Foundation; either version 2 of the License, or | |
10 * (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 * GNU General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU General Public License | |
18 * along with this program; if not, write to the Free Software | |
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
20 * | |
21 */ | |
22 | |
349
b402a23f35df
[gaim-migrate @ 359]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
278
diff
changeset
|
23 #ifdef HAVE_CONFIG_H |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2060
diff
changeset
|
24 #include <config.h> |
349
b402a23f35df
[gaim-migrate @ 359]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
278
diff
changeset
|
25 #endif |
1 | 26 #include <string.h> |
27 #include <stdio.h> | |
28 #include <stdlib.h> | |
3630 | 29 |
30 #ifndef _WIN32 | |
1 | 31 #include <sys/time.h> |
32 #include <unistd.h> | |
33 #include <sys/socket.h> | |
34 #include <netdb.h> | |
35 #include <netinet/in.h> | |
3630 | 36 #endif |
37 | |
38 #include <sys/types.h> | |
278
29e1669b006b
[gaim-migrate @ 288]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
268
diff
changeset
|
39 #include <fcntl.h> |
29e1669b006b
[gaim-migrate @ 288]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
268
diff
changeset
|
40 #include <errno.h> |
3630 | 41 #include "gaim.h" |
1092
a930439f29b1
[gaim-migrate @ 1102]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1088
diff
changeset
|
42 #include "proxy.h" |
1 | 43 |
3717
988485669631
[gaim-migrate @ 3850]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
3630
diff
changeset
|
44 #ifdef _WIN32 |
988485669631
[gaim-migrate @ 3850]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
3630
diff
changeset
|
45 #include "win32dep.h" |
988485669631
[gaim-migrate @ 3850]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
3630
diff
changeset
|
46 #endif |
988485669631
[gaim-migrate @ 3850]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
3630
diff
changeset
|
47 |
4359
5fb47ec9bfe4
[gaim-migrate @ 4625]
Christian Hammond <chipx86@chipx86.com>
parents:
4335
diff
changeset
|
48 gchar *strip_html(const gchar *text) |
1 | 49 { |
1883
060161a5d5f8
[gaim-migrate @ 1893]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1881
diff
changeset
|
50 int i, j, k; |
1 | 51 int visible = 1; |
1883
060161a5d5f8
[gaim-migrate @ 1893]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1881
diff
changeset
|
52 gchar *text2 = g_strdup(text); |
1250
b5783215b245
[gaim-migrate @ 1260]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1092
diff
changeset
|
53 |
4757 | 54 if(!text) |
55 return NULL; | |
4503 | 56 |
1250
b5783215b245
[gaim-migrate @ 1260]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1092
diff
changeset
|
57 for (i = 0, j = 0; text2[i]; i++) { |
b5783215b245
[gaim-migrate @ 1260]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1092
diff
changeset
|
58 if (text2[i] == '<') { |
1883
060161a5d5f8
[gaim-migrate @ 1893]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1881
diff
changeset
|
59 k = i + 1; |
4777 | 60 if(g_ascii_isspace(text2[k])) { |
61 visible = 1; | |
62 } else { | |
63 while (text2[k]) { | |
64 if (text2[k] == '<') { | |
65 visible = 1; | |
66 break; | |
67 } | |
68 if (text2[k] == '>') { | |
69 visible = 0; | |
70 break; | |
71 } | |
72 k++; | |
1883
060161a5d5f8
[gaim-migrate @ 1893]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1881
diff
changeset
|
73 } |
060161a5d5f8
[gaim-migrate @ 1893]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1881
diff
changeset
|
74 } |
060161a5d5f8
[gaim-migrate @ 1893]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1881
diff
changeset
|
75 } else if (text2[i] == '>' && !visible) { |
1 | 76 visible = 1; |
77 continue; | |
78 } | |
4473 | 79 if (text2[i] == '&' && strncasecmp(text2+i,""",6) == 0) { |
80 text2[j++] = '\"'; | |
81 i = i+5; | |
82 continue; | |
83 } | |
1250
b5783215b245
[gaim-migrate @ 1260]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1092
diff
changeset
|
84 if (visible) { |
1 | 85 text2[j++] = text2[i]; |
86 } | |
87 } | |
88 text2[j] = '\0'; | |
89 return text2; | |
90 } | |
91 | |
3630 | 92 struct g_url *parse_url(char *url) |
1 | 93 { |
5512 | 94 struct g_url *test = g_new0(struct g_url, 1); |
1 | 95 char scan_info[255]; |
96 char port[5]; | |
97 int f; | |
5501
36d2c875a822
[gaim-migrate @ 5900]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
5211
diff
changeset
|
98 char* turl; |
36d2c875a822
[gaim-migrate @ 5900]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
5211
diff
changeset
|
99 /* hyphen at end includes it in control set */ |
36d2c875a822
[gaim-migrate @ 5900]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
5211
diff
changeset
|
100 char addr_ctrl[] = "A-Za-z0-9.-"; |
36d2c875a822
[gaim-migrate @ 5900]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
5211
diff
changeset
|
101 char port_ctrl[] = "0-9"; |
36d2c875a822
[gaim-migrate @ 5900]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
5211
diff
changeset
|
102 char page_ctrl[] = "A-Za-z0-9.~_/&%%?=+^-"; |
1 | 103 |
5501
36d2c875a822
[gaim-migrate @ 5900]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
5211
diff
changeset
|
104 if((turl=strstr(url, "http://")) || (turl=strstr(url, "HTTP://"))) |
36d2c875a822
[gaim-migrate @ 5900]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
5211
diff
changeset
|
105 url=turl+=7; |
36d2c875a822
[gaim-migrate @ 5900]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
5211
diff
changeset
|
106 |
36d2c875a822
[gaim-migrate @ 5900]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
5211
diff
changeset
|
107 snprintf(scan_info, sizeof(scan_info), |
36d2c875a822
[gaim-migrate @ 5900]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
5211
diff
changeset
|
108 "%%[%s]:%%[%s]/%%[%s]", |
36d2c875a822
[gaim-migrate @ 5900]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
5211
diff
changeset
|
109 addr_ctrl, port_ctrl, page_ctrl); |
36d2c875a822
[gaim-migrate @ 5900]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
5211
diff
changeset
|
110 |
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2417
diff
changeset
|
111 f = sscanf(url, scan_info, test->address, port, test->page); |
1 | 112 if (f == 1) { |
5501
36d2c875a822
[gaim-migrate @ 5900]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
5211
diff
changeset
|
113 snprintf(scan_info, sizeof(scan_info), |
36d2c875a822
[gaim-migrate @ 5900]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
5211
diff
changeset
|
114 "%%[%s]/%%[%s]", |
36d2c875a822
[gaim-migrate @ 5900]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
5211
diff
changeset
|
115 addr_ctrl, page_ctrl); |
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2417
diff
changeset
|
116 f = sscanf(url, scan_info, test->address, test->page); |
5501
36d2c875a822
[gaim-migrate @ 5900]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
5211
diff
changeset
|
117 snprintf(port, sizeof(port), "80"); |
1 | 118 } |
5501
36d2c875a822
[gaim-migrate @ 5900]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
5211
diff
changeset
|
119 if (f == 1) |
5512 | 120 test->page[0] = '\0'; |
1 | 121 |
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2417
diff
changeset
|
122 sscanf(port, "%d", &test->port); |
1 | 123 return test; |
124 } | |
125 | |
1840
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
126 struct grab_url_data { |
4322 | 127 void (* callback)(gpointer, char *, unsigned long); |
1840
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
128 gpointer data; |
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2417
diff
changeset
|
129 struct g_url *website; |
1840
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
130 char *url; |
2584
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
131 gboolean full; |
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
132 |
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
133 int inpa; |
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
134 |
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
135 gboolean sentreq; |
2584
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
136 gboolean newline; |
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
137 gboolean startsaving; |
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
138 char *webdata; |
4322 | 139 unsigned long len; |
4331
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
140 unsigned long data_len; |
1840
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
141 }; |
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
142 |
4331
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
143 static gboolean |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
144 parse_redirect(const char *data, size_t data_len, gint sock, |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
145 struct grab_url_data *gunk) |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
146 { |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
147 gchar *s; |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
148 |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
149 if ((s = g_strstr_len(data, data_len, "Location: ")) != NULL) { |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
150 gchar *new_url, *end; |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
151 int len; |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
152 |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
153 s += strlen("Location: "); |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
154 end = strchr(s, '\r'); |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
155 |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
156 /* Just in case :) */ |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
157 if (end == NULL) |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
158 end = strchr(s, '\n'); |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
159 |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
160 len = end - s; |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
161 |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
162 new_url = g_malloc(len + 1); |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
163 strncpy(new_url, s, len); |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
164 new_url[len] = '\0'; |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
165 |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
166 /* Close the existing stuff. */ |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
167 gaim_input_remove(gunk->inpa); |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
168 close(sock); |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
169 |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
170 /* Try again, with this new location. */ |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
171 grab_url(new_url, gunk->full, gunk->callback, |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
172 gunk->data); |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
173 |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
174 /* Free up. */ |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
175 g_free(new_url); |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
176 g_free(gunk->webdata); |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
177 g_free(gunk->website); |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
178 g_free(gunk->url); |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
179 g_free(gunk); |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
180 |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
181 return TRUE; |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
182 } |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
183 |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
184 return FALSE; |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
185 } |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
186 |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
187 static size_t |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
188 parse_content_len(const char *data, size_t data_len) |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
189 { |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
190 size_t content_len = 0; |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
191 |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
192 sscanf(data, "Content-Length: %d", &content_len); |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
193 |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
194 return content_len; |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
195 } |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
196 |
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
197 static void grab_url_callback(gpointer dat, gint sock, GaimInputCondition cond) |
1840
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
198 { |
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
199 struct grab_url_data *gunk = dat; |
1 | 200 char data; |
201 | |
1840
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
202 if (sock == -1) { |
4322 | 203 gunk->callback(gunk->data, NULL, 0); |
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2417
diff
changeset
|
204 g_free(gunk->website); |
1840
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
205 g_free(gunk->url); |
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
206 g_free(gunk); |
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
207 return; |
1087
56c7ceb986a8
[gaim-migrate @ 1097]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
691
diff
changeset
|
208 } |
1 | 209 |
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
210 if (!gunk->sentreq) { |
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
211 char buf[256]; |
3717
988485669631
[gaim-migrate @ 3850]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
3630
diff
changeset
|
212 |
2584
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
213 g_snprintf(buf, sizeof(buf), "GET %s%s HTTP/1.0\r\n\r\n", gunk->full ? "" : "/", |
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
214 gunk->full ? gunk->url : gunk->website->page); |
5211
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5176
diff
changeset
|
215 |
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5176
diff
changeset
|
216 gaim_debug(GAIM_DEBUG_MISC, "grab_url_callback", |
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5176
diff
changeset
|
217 "Request: %s\n", buf); |
3717
988485669631
[gaim-migrate @ 3850]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
3630
diff
changeset
|
218 |
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
219 write(sock, buf, strlen(buf)); |
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
220 fcntl(sock, F_SETFL, O_NONBLOCK); |
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
221 gunk->sentreq = TRUE; |
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
222 gunk->inpa = gaim_input_add(sock, GAIM_INPUT_READ, grab_url_callback, dat); |
4331
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
223 gunk->data_len = 4096; |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
224 gunk->webdata = g_malloc(gunk->data_len); |
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
225 return; |
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
226 } |
1 | 227 |
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
228 if (read(sock, &data, 1) > 0 || errno == EWOULDBLOCK) { |
278
29e1669b006b
[gaim-migrate @ 288]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
268
diff
changeset
|
229 if (errno == EWOULDBLOCK) { |
29e1669b006b
[gaim-migrate @ 288]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
268
diff
changeset
|
230 errno = 0; |
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
231 return; |
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
232 } |
4331
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
233 |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
234 gunk->len++; |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
235 |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
236 if (gunk->len == gunk->data_len + 1) { |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
237 gunk->data_len += (gunk->data_len) / 2; |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
238 |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
239 gunk->webdata = g_realloc(gunk->webdata, gunk->data_len); |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
240 } |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
241 |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
242 gunk->webdata[gunk->len - 1] = data; |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
243 |
2584
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
244 if (!gunk->startsaving) { |
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
245 if (data == '\r') |
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
246 return; |
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
247 if (data == '\n') { |
4331
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
248 if (gunk->newline) { |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
249 size_t content_len; |
2584
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
250 gunk->startsaving = TRUE; |
4331
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
251 |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
252 /* See if we can find a redirect. */ |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
253 if (parse_redirect(gunk->webdata, gunk->len, sock, gunk)) |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
254 return; |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
255 |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
256 /* No redirect. See if we can find a content length. */ |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
257 content_len = parse_content_len(gunk->webdata, gunk->len); |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
258 |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
259 if (content_len == 0) { |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
260 /* We'll stick with an initial 8192 */ |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
261 content_len = 8192; |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
262 } |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
263 |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
264 /* Out with the old... */ |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
265 gunk->len = 0; |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
266 g_free(gunk->webdata); |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
267 gunk->webdata = NULL; |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
268 |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
269 /* In with the new. */ |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
270 gunk->data_len = content_len; |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
271 gunk->webdata = g_malloc(gunk->data_len); |
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
272 } |
2584
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
273 else |
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
274 gunk->newline = TRUE; |
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
275 return; |
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
276 } |
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
277 gunk->newline = FALSE; |
278
29e1669b006b
[gaim-migrate @ 288]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
268
diff
changeset
|
278 } |
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
279 } else if (errno != ETIMEDOUT) { |
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
280 gunk->webdata = g_realloc(gunk->webdata, gunk->len + 1); |
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
281 gunk->webdata[gunk->len] = 0; |
1250
b5783215b245
[gaim-migrate @ 1260]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1092
diff
changeset
|
282 |
5211
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5176
diff
changeset
|
283 gaim_debug(GAIM_DEBUG_MISC, "grab_url_callback", |
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5176
diff
changeset
|
284 "Received: '%s'\n", gunk->webdata); |
1250
b5783215b245
[gaim-migrate @ 1260]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1092
diff
changeset
|
285 |
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
286 gaim_input_remove(gunk->inpa); |
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
287 close(sock); |
4322 | 288 gunk->callback(gunk->data, gunk->webdata, gunk->len); |
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
289 if (gunk->webdata) |
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
290 g_free(gunk->webdata); |
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2417
diff
changeset
|
291 g_free(gunk->website); |
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
292 g_free(gunk->url); |
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
293 g_free(gunk); |
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
294 } else { |
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
295 gaim_input_remove(gunk->inpa); |
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
296 close(sock); |
4322 | 297 gunk->callback(gunk->data, NULL, 0); |
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
298 if (gunk->webdata) |
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
299 g_free(gunk->webdata); |
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2417
diff
changeset
|
300 g_free(gunk->website); |
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
301 g_free(gunk->url); |
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
302 g_free(gunk); |
1 | 303 } |
304 } | |
1840
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
305 |
4322 | 306 void grab_url(char *url, gboolean full, void callback(gpointer, char *, unsigned long), gpointer data) |
1840
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
307 { |
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
308 int sock; |
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
309 struct grab_url_data *gunk = g_new0(struct grab_url_data, 1); |
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
310 |
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
311 gunk->callback = callback; |
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
312 gunk->data = data; |
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
313 gunk->url = g_strdup(url); |
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
314 gunk->website = parse_url(url); |
2584
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
315 gunk->full = full; |
1840
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
316 |
4634 | 317 if ((sock = proxy_connect(NULL, gunk->website->address, gunk->website->port, |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2369
diff
changeset
|
318 grab_url_callback, gunk)) < 0) { |
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2417
diff
changeset
|
319 g_free(gunk->website); |
1881
a02584b98823
[gaim-migrate @ 1891]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1843
diff
changeset
|
320 g_free(gunk->url); |
a02584b98823
[gaim-migrate @ 1891]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1843
diff
changeset
|
321 g_free(gunk); |
4322 | 322 callback(data, g_strdup(_("g003: Error opening connection.\n")), 0); |
1840
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
323 } |
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
324 } |
5093 | 325 |
5104 | 326 struct gaim_parse_tag { |
327 char *src_tag; | |
328 char *dest_tag; | |
329 }; | |
330 | |
5093 | 331 #define ALLOW_TAG_ALT(x, y) if(!g_ascii_strncasecmp(c, "<" x " ", strlen("<" x " "))) { \ |
5176 | 332 const char *o = c + strlen("<" x); \ |
5141 | 333 const char *p = NULL, *q = NULL, *r = NULL; \ |
5176 | 334 GString *innards = g_string_new(""); \ |
335 while(o && *o) { \ | |
5141 | 336 if(!q && (*o == '\"' || *o == '\'') ) { \ |
337 q = o; \ | |
338 } else if(q) { \ | |
339 if(*o == *q) { \ | |
5176 | 340 char *unescaped = g_strndup(q+1, o-q-1); \ |
341 char *escaped = g_markup_escape_text(unescaped, -1); \ | |
342 g_string_append_printf(innards, "%c%s%c", *q, escaped, *q); \ | |
5141 | 343 q = NULL; \ |
344 } else if(*c == '\\') { \ | |
345 o++; \ | |
346 } \ | |
347 } else if(*o == '<') { \ | |
348 r = o; \ | |
349 } else if(*o == '>') { \ | |
350 p = o; \ | |
351 break; \ | |
5176 | 352 } else { \ |
353 innards = g_string_append_c(innards, *o); \ | |
5141 | 354 } \ |
355 o++; \ | |
356 } \ | |
357 if(p && !r) { \ | |
5104 | 358 if(*(p-1) != '/') { \ |
359 struct gaim_parse_tag *pt = g_new0(struct gaim_parse_tag, 1); \ | |
360 pt->src_tag = x; \ | |
361 pt->dest_tag = y; \ | |
362 tags = g_list_prepend(tags, pt); \ | |
363 } \ | |
5093 | 364 xhtml = g_string_append(xhtml, "<" y); \ |
365 c += strlen("<" x ); \ | |
5176 | 366 xhtml = g_string_append(xhtml, innards->str); \ |
367 xhtml = g_string_append_c(xhtml, '>'); \ | |
5093 | 368 c = p + 1; \ |
369 } else { \ | |
370 xhtml = g_string_append(xhtml, "<"); \ | |
5110 | 371 plain = g_string_append_c(plain, '<'); \ |
5176 | 372 c++; \ |
5093 | 373 } \ |
5176 | 374 g_string_free(innards, TRUE); \ |
5093 | 375 continue; \ |
376 } \ | |
377 if(!g_ascii_strncasecmp(c, "<" x, strlen("<" x)) && \ | |
378 (*(c+strlen("<" x)) == '>' || \ | |
379 !g_ascii_strncasecmp(c+strlen("<" x), "/>", 2))) { \ | |
380 xhtml = g_string_append(xhtml, "<" y); \ | |
381 c += strlen("<" x); \ | |
5104 | 382 if(*c != '/') { \ |
383 struct gaim_parse_tag *pt = g_new0(struct gaim_parse_tag, 1); \ | |
384 pt->src_tag = x; \ | |
385 pt->dest_tag = y; \ | |
386 tags = g_list_prepend(tags, pt); \ | |
5110 | 387 xhtml = g_string_append_c(xhtml, '>'); \ |
388 } else { \ | |
389 xhtml = g_string_append(xhtml, "/>");\ | |
5104 | 390 } \ |
5110 | 391 c = strchr(c, '>') + 1; \ |
5093 | 392 continue; \ |
393 } | |
394 #define ALLOW_TAG(x) ALLOW_TAG_ALT(x, x) | |
395 | |
5110 | 396 void html_to_xhtml(const char *html, char **xhtml_out, char **plain_out) { |
5093 | 397 GString *xhtml = g_string_new(""); |
5110 | 398 GString *plain = g_string_new(""); |
5093 | 399 GList *tags = NULL, *tag; |
5141 | 400 const char *c = html; |
5176 | 401 |
402 while(c && *c) { | |
5141 | 403 if(*c == '<') { |
5093 | 404 if(*(c+1) == '/') { /* closing tag */ |
405 tag = tags; | |
406 while(tag) { | |
5104 | 407 struct gaim_parse_tag *pt = tag->data; |
408 if(!g_ascii_strncasecmp((c+2), pt->src_tag, strlen(pt->src_tag)) && *(c+strlen(pt->src_tag)+2) == '>') { | |
409 c += strlen(pt->src_tag) + 3; | |
5093 | 410 break; |
411 } | |
412 tag = tag->next; | |
413 } | |
414 if(tag) { | |
415 while(tags) { | |
5104 | 416 struct gaim_parse_tag *pt = tags->data; |
417 g_string_append_printf(xhtml, "</%s>", pt->dest_tag); | |
5093 | 418 if(tags == tag) |
419 break; | |
5104 | 420 tags = g_list_remove(tags, pt); |
421 g_free(pt); | |
5093 | 422 } |
5104 | 423 g_free(tag->data); |
5093 | 424 tags = g_list_remove(tags, tag->data); |
425 } else { | |
426 /* we tried to close a tag we never opened! escape it | |
427 * and move on */ | |
428 xhtml = g_string_append(xhtml, "<"); | |
5110 | 429 plain = g_string_append_c(plain, '<'); |
5093 | 430 c++; |
431 } | |
432 } else { /* opening tag */ | |
433 ALLOW_TAG("a"); | |
5101 | 434 ALLOW_TAG_ALT("b", "strong"); |
5093 | 435 ALLOW_TAG("blockquote"); |
5101 | 436 ALLOW_TAG_ALT("bold", "strong"); |
5093 | 437 ALLOW_TAG("cite"); |
438 ALLOW_TAG("div"); | |
439 ALLOW_TAG("em"); | |
440 ALLOW_TAG("h1"); | |
441 ALLOW_TAG("h2"); | |
442 ALLOW_TAG("h3"); | |
443 ALLOW_TAG("h4"); | |
444 ALLOW_TAG("h5"); | |
445 ALLOW_TAG("h6"); | |
446 ALLOW_TAG("html"); | |
5101 | 447 ALLOW_TAG_ALT("i", "em"); |
448 ALLOW_TAG_ALT("italic", "em"); | |
5093 | 449 ALLOW_TAG("li"); |
450 ALLOW_TAG("ol"); | |
451 ALLOW_TAG("p"); | |
452 ALLOW_TAG("pre"); | |
453 ALLOW_TAG("q"); | |
454 ALLOW_TAG("span"); | |
455 ALLOW_TAG("strong"); | |
456 ALLOW_TAG("ul"); | |
457 | |
5174 | 458 /* we skip <HR> because it's not legal in XHTML-IM. However, |
459 * we still want to send something sensible, so we put a | |
460 * linebreak in its place. <BR> also needs special handling | |
461 * because putting a </BR> to close it would just be dumb. */ | |
462 if((!g_ascii_strncasecmp(c, "<br", 3) | |
463 || !g_ascii_strncasecmp(c, "<hr", 3)) | |
464 && (*(c+3) == '>' || | |
465 !g_ascii_strncasecmp(c+3, "/>", 2) || | |
466 !g_ascii_strncasecmp(c+3, " />", 3))) { | |
467 c = strchr(c, '>') + 1; | |
468 xhtml = g_string_append(xhtml, "<br/>"); | |
469 if(*c != '\n') | |
470 plain = g_string_append_c(plain, '\n'); | |
471 continue; | |
472 } | |
473 if(!g_ascii_strncasecmp(c, "<u>", 3) || !g_ascii_strncasecmp(c, "<underline>", strlen("<underline>"))) { | |
5104 | 474 struct gaim_parse_tag *pt = g_new0(struct gaim_parse_tag, 1); |
475 pt->src_tag = *(c+2) == '>' ? "u" : "underline"; | |
476 pt->dest_tag = "span"; | |
477 tags = g_list_prepend(tags, pt); | |
478 c = strchr(c, '>') + 1; | |
479 xhtml = g_string_append(xhtml, "<span style='text-decoration: underline;'>"); | |
480 continue; | |
481 } | |
5174 | 482 if(!g_ascii_strncasecmp(c, "<s>", 3) || !g_ascii_strncasecmp(c, "<strike>", strlen("<strike>"))) { |
5104 | 483 struct gaim_parse_tag *pt = g_new0(struct gaim_parse_tag, 1); |
484 pt->src_tag = *(c+2) == '>' ? "s" : "strike"; | |
485 pt->dest_tag = "span"; | |
486 tags = g_list_prepend(tags, pt); | |
487 c = strchr(c, '>') + 1; | |
488 xhtml = g_string_append(xhtml, "<span style='text-decoration: line-through;'>"); | |
489 continue; | |
490 } | |
491 if(!g_ascii_strncasecmp(c, "<sub>", 5)) { | |
492 struct gaim_parse_tag *pt = g_new0(struct gaim_parse_tag, 1); | |
493 pt->src_tag = "sub"; | |
494 pt->dest_tag = "span"; | |
495 tags = g_list_prepend(tags, pt); | |
496 c = strchr(c, '>') + 1; | |
497 xhtml = g_string_append(xhtml, "<span style='vertical-align:sub;'>"); | |
498 continue; | |
499 } | |
500 if(!g_ascii_strncasecmp(c, "<sup>", 5)) { | |
501 struct gaim_parse_tag *pt = g_new0(struct gaim_parse_tag, 1); | |
502 pt->src_tag = "sup"; | |
503 pt->dest_tag = "span"; | |
504 tags = g_list_prepend(tags, pt); | |
505 c = strchr(c, '>') + 1; | |
506 xhtml = g_string_append(xhtml, "<span style='vertical-align:super;'>"); | |
507 continue; | |
508 } | |
5107 | 509 if(!g_ascii_strncasecmp(c, "<font", 5) && (*(c+5) == '>' || *(c+5) == ' ')) { |
510 const char *p = c; | |
511 GString *style = g_string_new(""); | |
512 struct gaim_parse_tag *pt; | |
513 while(*p && *p != '>') { | |
514 if(!g_ascii_strncasecmp(p, "color=", strlen("color="))) { | |
515 const char *q = p + strlen("color="); | |
516 GString *color = g_string_new(""); | |
517 if(*q == '\'' || *q == '\"') | |
518 q++; | |
519 while(*q && *q != '\"' && *q != '\'' && *q != ' ') { | |
520 color = g_string_append_c(color, *q); | |
521 q++; | |
522 } | |
523 g_string_append_printf(style, "color: %s; ", color->str); | |
524 g_string_free(color, TRUE); | |
525 p = q; | |
526 } else if(!g_ascii_strncasecmp(p, "face=", strlen("face="))) { | |
527 const char *q = p + strlen("face="); | |
528 gboolean space_allowed = FALSE; | |
529 GString *face = g_string_new(""); | |
530 if(*q == '\'' || *q == '\"') { | |
531 space_allowed = TRUE; | |
532 q++; | |
533 } | |
534 while(*q && *q != '\"' && *q != '\'' && (space_allowed || *q != ' ')) { | |
535 face = g_string_append_c(face, *q); | |
536 q++; | |
537 } | |
538 g_string_append_printf(style, "font-family: %s; ", face->str); | |
539 g_string_free(face, TRUE); | |
540 p = q; | |
541 } else if(!g_ascii_strncasecmp(p, "size=", strlen("size="))) { | |
542 const char *q = p + strlen("size="); | |
543 int sz; | |
544 const char *size = "medium"; | |
545 if(*q == '\'' || *q == '\"') | |
546 q++; | |
547 sz = atoi(q); | |
548 if(sz < 3) | |
549 size = "smaller"; | |
550 else if(sz > 3) | |
551 size = "larger"; | |
552 g_string_append_printf(style, "font-size: %s; ", size); | |
553 p = q; | |
554 } | |
555 p++; | |
556 } | |
557 c = strchr(c, '>') + 1; | |
558 pt = g_new0(struct gaim_parse_tag, 1); | |
559 pt->src_tag = "font"; | |
560 pt->dest_tag = "span"; | |
561 tags = g_list_prepend(tags, pt); | |
562 xhtml = g_string_append(xhtml, "<span"); | |
563 if(style->len) | |
564 g_string_append_printf(xhtml, " style='%s'", style->str); | |
565 xhtml = g_string_append_c(xhtml, '>'); | |
566 g_string_free(style, TRUE); | |
567 continue; | |
568 } | |
569 if(!g_ascii_strncasecmp(c, "<body ", 6)) { | |
570 const char *p = c; | |
571 gboolean did_something = FALSE; | |
572 while(*p && *p != '>') { | |
573 if(!g_ascii_strncasecmp(p, "bgcolor=", strlen("bgcolor="))) { | |
574 const char *q = p + strlen("bgcolor="); | |
575 struct gaim_parse_tag *pt = g_new0(struct gaim_parse_tag, 1); | |
576 GString *color = g_string_new(""); | |
577 if(*q == '\'' || *q == '\"') | |
578 q++; | |
579 while(*q && *q != '\"' && *q != '\'' && *q != ' ') { | |
580 color = g_string_append_c(color, *q); | |
581 q++; | |
582 } | |
583 g_string_append_printf(xhtml, "<span style='background: %s;'>", color->str); | |
584 g_string_free(color, TRUE); | |
585 c = strchr(c, '>') + 1; | |
586 pt->src_tag = "body"; | |
587 pt->dest_tag = "span"; | |
588 tags = g_list_prepend(tags, pt); | |
589 did_something = TRUE; | |
590 break; | |
591 } | |
592 p++; | |
593 } | |
594 if(did_something) continue; | |
595 } | |
596 /* this has to come after the special case for bgcolor */ | |
597 ALLOW_TAG("body"); | |
5093 | 598 if(!g_ascii_strncasecmp(c, "<!--", strlen("<!--"))) { |
599 char *p = strstr(c + strlen("<!--"), "-->"); | |
600 if(p) { | |
601 xhtml = g_string_append(xhtml, "<!--"); | |
602 c += strlen("<!--"); | |
603 continue; | |
604 } | |
605 } | |
606 | |
607 xhtml = g_string_append(xhtml, "<"); | |
5110 | 608 plain = g_string_append_c(plain, '<'); |
5093 | 609 c++; |
610 } | |
611 } else { | |
612 xhtml = g_string_append_c(xhtml, *c); | |
5110 | 613 plain = g_string_append_c(plain, *c); |
5093 | 614 c++; |
615 } | |
616 } | |
617 tag = tags; | |
618 while(tag) { | |
619 g_string_append_printf(xhtml, "</%s>", (char *)tag->data); | |
620 tag = tag->next; | |
621 } | |
622 g_list_free(tags); | |
5110 | 623 if(xhtml_out) |
624 *xhtml_out = g_strdup(xhtml->str); | |
625 if(plain_out) | |
626 *plain_out = g_strdup(plain->str); | |
5093 | 627 g_string_free(xhtml, TRUE); |
5110 | 628 g_string_free(plain, TRUE); |
5093 | 629 } |