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