Mercurial > pidgin
annotate src/html.c @ 5205:fefad67de2c7
[gaim-migrate @ 5573]
I had a damn good commit message, but it was eaten. Let's try it again.
Announcing, Gaim Plugin API version 2.0, or GPAPIV2.0 for short.
There are lots'a cool thingies here.
Okay now, this isn't as cool as the previous message, but:
1) There's now a single entry function for all plugin types. It returns a
detailed information structure on the plugin. This removes a lot of the
ugliness from old plugins. Oh yeah, libicq wasn't converted to this, so
if you use it, well, you shouldn't have used it anyway, but now you
can't! bwahahaha. Use AIM/ICQ.
2) There are now 3 types of plugins: Standard, Loader, and Protocol
plugins.
Standard plugins are, well, standard, compiled plugins.
Loader plugins load other plugins. For example, the perl support is now
a loader plugin. It loads perl scripts. In the future, we'll have
Ruby and Python loader plugins.
Protocol plugins are, well, protocol plugins... yeah...
3) Plugins have unique IDs, so they can be referred to or automatically
updated from a plugin database in the future. Neat, huh?
4) Plugins will have dependency support in the future, and can be hidden,
so if you have, say, a logging core plugin, it won't have to show up,
but then you load the GTK+ logging plugin and it'll auto-load the core
plugin. Core/UI split plugins!
5) There will eventually be custom plugin signals and RPC of some sort, for
the core/ui split plugins.
So, okay, back up .gaimrc.
I'd like to thank my parents for their support, javabsp for helping convert
a bunch of protocol plugins, and Etan for helping convert a bunch of
standard plugins.
Have fun. If you have any problems, please let me know, but you probably
won't have anything major happen. You will have to convert your plugins,
though, and I'm not guaranteeing that all perl scripts will still work.
I'll end up changing the perl script API eventually, so I know they won't
down the road. Don't worry, though. It'll be mass cool.
faceprint wants me to just commit the damn code already. So, here we go!!!
..
..
I need a massage. From a young, cute girl. Are there any young, cute girls
in the audience? IM me plz k thx.
committer: Tailor Script <tailor@pidgin.im>
| author | Christian Hammond <chipx86@chipx86.com> |
|---|---|
| date | Fri, 25 Apr 2003 06:47:33 +0000 |
| parents | 6911a84cbab1 |
| children | 0241d6b6702d |
| 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 { |
|
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2417
diff
changeset
|
94 struct g_url *test = g_new0(struct g_url, 1); |
| 1 | 95 char scan_info[255]; |
| 96 char port[5]; | |
| 97 int f; | |
| 98 | |
| 99 if (strstr(url, "http://")) | |
|
1250
b5783215b245
[gaim-migrate @ 1260]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1092
diff
changeset
|
100 g_snprintf(scan_info, sizeof(scan_info), |
| 2060 | 101 "http://%%[A-Za-z0-9.]:%%[0-9]/%%[A-Za-z0-9.~_-/&%%?=+]"); |
| 1 | 102 else |
|
1250
b5783215b245
[gaim-migrate @ 1260]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1092
diff
changeset
|
103 g_snprintf(scan_info, sizeof(scan_info), |
| 2060 | 104 "%%[A-Za-z0-9.]:%%[0-9]/%%[A-Za-z0-9.~_-/&%%?=+^]"); |
|
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2417
diff
changeset
|
105 f = sscanf(url, scan_info, test->address, port, test->page); |
| 1 | 106 if (f == 1) { |
| 107 if (strstr(url, "http://")) | |
|
1250
b5783215b245
[gaim-migrate @ 1260]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1092
diff
changeset
|
108 g_snprintf(scan_info, sizeof(scan_info), |
| 2060 | 109 "http://%%[A-Za-z0-9.]/%%[A-Za-z0-9.~_-/&%%?=+^]"); |
| 1 | 110 else |
|
1250
b5783215b245
[gaim-migrate @ 1260]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1092
diff
changeset
|
111 g_snprintf(scan_info, sizeof(scan_info), |
| 2060 | 112 "%%[A-Za-z0-9.]/%%[A-Za-z0-9.~_-/&%%?=+^]"); |
|
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2417
diff
changeset
|
113 f = sscanf(url, scan_info, test->address, test->page); |
|
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2417
diff
changeset
|
114 g_snprintf(port, sizeof(test->port), "80"); |
|
1250
b5783215b245
[gaim-migrate @ 1260]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1092
diff
changeset
|
115 port[2] = 0; |
| 1 | 116 } |
| 117 if (f == 1) { | |
| 118 if (strstr(url, "http://")) | |
| 119 g_snprintf(scan_info, sizeof(scan_info), "http://%%[A-Za-z0-9.]"); | |
|
1250
b5783215b245
[gaim-migrate @ 1260]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1092
diff
changeset
|
120 else |
|
b5783215b245
[gaim-migrate @ 1260]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1092
diff
changeset
|
121 g_snprintf(scan_info, sizeof(scan_info), "%%[A-Za-z0-9.]"); |
|
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2417
diff
changeset
|
122 f = sscanf(url, scan_info, test->address); |
|
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2417
diff
changeset
|
123 g_snprintf(test->page, sizeof(test->page), "%c", '\0'); |
| 1 | 124 } |
| 125 | |
|
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2417
diff
changeset
|
126 sscanf(port, "%d", &test->port); |
| 1 | 127 return test; |
| 128 } | |
| 129 | |
|
1840
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
130 struct grab_url_data { |
| 4322 | 131 void (* callback)(gpointer, char *, unsigned long); |
|
1840
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
132 gpointer data; |
|
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2417
diff
changeset
|
133 struct g_url *website; |
|
1840
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
134 char *url; |
|
2584
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
135 gboolean full; |
|
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
136 |
|
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
137 int inpa; |
|
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
138 |
|
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
139 gboolean sentreq; |
|
2584
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
140 gboolean newline; |
|
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
141 gboolean startsaving; |
|
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
142 char *webdata; |
| 4322 | 143 unsigned long len; |
|
4331
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
144 unsigned long data_len; |
|
1840
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
145 }; |
|
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
146 |
|
4331
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
147 static gboolean |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
148 parse_redirect(const char *data, size_t data_len, gint sock, |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
149 struct grab_url_data *gunk) |
|
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 gchar *s; |
|
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 if ((s = g_strstr_len(data, data_len, "Location: ")) != NULL) { |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
154 gchar *new_url, *end; |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
155 int len; |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
156 |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
157 s += strlen("Location: "); |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
158 end = strchr(s, '\r'); |
|
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 /* Just in case :) */ |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
161 if (end == NULL) |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
162 end = strchr(s, '\n'); |
|
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 len = end - s; |
|
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 new_url = g_malloc(len + 1); |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
167 strncpy(new_url, s, len); |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
168 new_url[len] = '\0'; |
|
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 /* Close the existing stuff. */ |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
171 gaim_input_remove(gunk->inpa); |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
172 close(sock); |
|
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 /* Try again, with this new location. */ |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
175 grab_url(new_url, gunk->full, gunk->callback, |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
176 gunk->data); |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
177 |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
178 /* Free up. */ |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
179 g_free(new_url); |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
180 g_free(gunk->webdata); |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
181 g_free(gunk->website); |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
182 g_free(gunk->url); |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
183 g_free(gunk); |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
184 |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
185 return TRUE; |
|
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 |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
188 return FALSE; |
|
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 |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
191 static size_t |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
192 parse_content_len(const char *data, size_t data_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 size_t content_len = 0; |
|
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 sscanf(data, "Content-Length: %d", &content_len); |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
197 |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
198 return content_len; |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
199 } |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
200 |
|
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
201 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
|
202 { |
|
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
203 struct grab_url_data *gunk = dat; |
| 1 | 204 char data; |
| 205 | |
|
1840
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
206 if (sock == -1) { |
| 4322 | 207 gunk->callback(gunk->data, NULL, 0); |
|
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2417
diff
changeset
|
208 g_free(gunk->website); |
|
1840
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
209 g_free(gunk->url); |
|
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
210 g_free(gunk); |
|
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
211 return; |
|
1087
56c7ceb986a8
[gaim-migrate @ 1097]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
691
diff
changeset
|
212 } |
| 1 | 213 |
|
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
214 if (!gunk->sentreq) { |
|
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
215 char buf[256]; |
|
3717
988485669631
[gaim-migrate @ 3850]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
3630
diff
changeset
|
216 |
|
2584
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
217 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
|
218 gunk->full ? gunk->url : gunk->website->page); |
|
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
219 debug_printf("Request: %s\n", buf); |
|
3717
988485669631
[gaim-migrate @ 3850]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
3630
diff
changeset
|
220 |
|
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
221 write(sock, buf, strlen(buf)); |
|
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
222 fcntl(sock, F_SETFL, O_NONBLOCK); |
|
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
223 gunk->sentreq = TRUE; |
|
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
224 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
|
225 gunk->data_len = 4096; |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
226 gunk->webdata = g_malloc(gunk->data_len); |
|
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
227 return; |
|
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
228 } |
| 1 | 229 |
|
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
230 if (read(sock, &data, 1) > 0 || errno == EWOULDBLOCK) { |
|
278
29e1669b006b
[gaim-migrate @ 288]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
268
diff
changeset
|
231 if (errno == EWOULDBLOCK) { |
|
29e1669b006b
[gaim-migrate @ 288]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
268
diff
changeset
|
232 errno = 0; |
|
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
233 return; |
|
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
234 } |
|
4331
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 gunk->len++; |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
237 |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
238 if (gunk->len == gunk->data_len + 1) { |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
239 gunk->data_len += (gunk->data_len) / 2; |
|
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 gunk->webdata = g_realloc(gunk->webdata, gunk->data_len); |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
242 } |
|
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 gunk->webdata[gunk->len - 1] = data; |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
245 |
|
2584
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
246 if (!gunk->startsaving) { |
|
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
247 if (data == '\r') |
|
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
248 return; |
|
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
249 if (data == '\n') { |
|
4331
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
250 if (gunk->newline) { |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
251 size_t content_len; |
|
2584
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
252 gunk->startsaving = TRUE; |
|
4331
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
253 |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
254 /* See if we can find a redirect. */ |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
255 if (parse_redirect(gunk->webdata, gunk->len, sock, gunk)) |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
256 return; |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
257 |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
258 /* No redirect. See if we can find a content length. */ |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
259 content_len = parse_content_len(gunk->webdata, gunk->len); |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
260 |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
261 if (content_len == 0) { |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
262 /* We'll stick with an initial 8192 */ |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
263 content_len = 8192; |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
264 } |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
265 |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
266 /* Out with the old... */ |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
267 gunk->len = 0; |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
268 g_free(gunk->webdata); |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
269 gunk->webdata = NULL; |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
270 |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
271 /* In with the new. */ |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
272 gunk->data_len = content_len; |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
273 gunk->webdata = g_malloc(gunk->data_len); |
|
bbd7b12986a8
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
274 } |
|
2584
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
275 else |
|
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
276 gunk->newline = TRUE; |
|
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
277 return; |
|
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
278 } |
|
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
279 gunk->newline = FALSE; |
|
278
29e1669b006b
[gaim-migrate @ 288]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
268
diff
changeset
|
280 } |
|
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
281 } else if (errno != ETIMEDOUT) { |
|
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
282 gunk->webdata = g_realloc(gunk->webdata, gunk->len + 1); |
|
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
283 gunk->webdata[gunk->len] = 0; |
|
1250
b5783215b245
[gaim-migrate @ 1260]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1092
diff
changeset
|
284 |
| 3100 | 285 debug_printf(_("Received: '%s'\n"), gunk->webdata); |
|
1250
b5783215b245
[gaim-migrate @ 1260]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1092
diff
changeset
|
286 |
|
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
287 gaim_input_remove(gunk->inpa); |
|
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
288 close(sock); |
| 4322 | 289 gunk->callback(gunk->data, gunk->webdata, gunk->len); |
|
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
290 if (gunk->webdata) |
|
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
291 g_free(gunk->webdata); |
|
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2417
diff
changeset
|
292 g_free(gunk->website); |
|
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
293 g_free(gunk->url); |
|
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
294 g_free(gunk); |
|
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
295 } else { |
|
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
296 gaim_input_remove(gunk->inpa); |
|
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
297 close(sock); |
| 4322 | 298 gunk->callback(gunk->data, NULL, 0); |
|
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
299 if (gunk->webdata) |
|
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
300 g_free(gunk->webdata); |
|
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2417
diff
changeset
|
301 g_free(gunk->website); |
|
2369
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
302 g_free(gunk->url); |
|
117e9f0950b6
[gaim-migrate @ 2382]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
303 g_free(gunk); |
| 1 | 304 } |
| 305 } | |
|
1840
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
306 |
| 4322 | 307 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
|
308 { |
|
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
309 int sock; |
|
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
310 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
|
311 |
|
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
312 gunk->callback = callback; |
|
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
313 gunk->data = data; |
|
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
314 gunk->url = g_strdup(url); |
|
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
315 gunk->website = parse_url(url); |
|
2584
34812d648f72
[gaim-migrate @ 2597]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2541
diff
changeset
|
316 gunk->full = full; |
|
1840
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
317 |
| 4634 | 318 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
|
319 grab_url_callback, gunk)) < 0) { |
|
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2417
diff
changeset
|
320 g_free(gunk->website); |
|
1881
a02584b98823
[gaim-migrate @ 1891]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1843
diff
changeset
|
321 g_free(gunk->url); |
|
a02584b98823
[gaim-migrate @ 1891]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1843
diff
changeset
|
322 g_free(gunk); |
| 4322 | 323 callback(data, g_strdup(_("g003: Error opening connection.\n")), 0); |
|
1840
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
324 } |
|
00aef397a1fe
[gaim-migrate @ 1850]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1250
diff
changeset
|
325 } |
| 5093 | 326 |
| 5104 | 327 struct gaim_parse_tag { |
| 328 char *src_tag; | |
| 329 char *dest_tag; | |
| 330 }; | |
| 331 | |
| 5093 | 332 #define ALLOW_TAG_ALT(x, y) if(!g_ascii_strncasecmp(c, "<" x " ", strlen("<" x " "))) { \ |
| 5176 | 333 const char *o = c + strlen("<" x); \ |
| 5141 | 334 const char *p = NULL, *q = NULL, *r = NULL; \ |
| 5176 | 335 GString *innards = g_string_new(""); \ |
| 336 while(o && *o) { \ | |
| 5141 | 337 if(!q && (*o == '\"' || *o == '\'') ) { \ |
| 338 q = o; \ | |
| 339 } else if(q) { \ | |
| 340 if(*o == *q) { \ | |
| 5176 | 341 char *unescaped = g_strndup(q+1, o-q-1); \ |
| 342 char *escaped = g_markup_escape_text(unescaped, -1); \ | |
| 343 g_string_append_printf(innards, "%c%s%c", *q, escaped, *q); \ | |
| 5141 | 344 q = NULL; \ |
| 345 } else if(*c == '\\') { \ | |
| 346 o++; \ | |
| 347 } \ | |
| 348 } else if(*o == '<') { \ | |
| 349 r = o; \ | |
| 350 } else if(*o == '>') { \ | |
| 351 p = o; \ | |
| 352 break; \ | |
| 5176 | 353 } else { \ |
| 354 innards = g_string_append_c(innards, *o); \ | |
| 5141 | 355 } \ |
| 356 o++; \ | |
| 357 } \ | |
| 358 if(p && !r) { \ | |
| 5104 | 359 if(*(p-1) != '/') { \ |
| 360 struct gaim_parse_tag *pt = g_new0(struct gaim_parse_tag, 1); \ | |
| 361 pt->src_tag = x; \ | |
| 362 pt->dest_tag = y; \ | |
| 363 tags = g_list_prepend(tags, pt); \ | |
| 364 } \ | |
| 5093 | 365 xhtml = g_string_append(xhtml, "<" y); \ |
| 366 c += strlen("<" x ); \ | |
| 5176 | 367 xhtml = g_string_append(xhtml, innards->str); \ |
| 368 xhtml = g_string_append_c(xhtml, '>'); \ | |
| 5093 | 369 c = p + 1; \ |
| 370 } else { \ | |
| 371 xhtml = g_string_append(xhtml, "<"); \ | |
| 5110 | 372 plain = g_string_append_c(plain, '<'); \ |
| 5176 | 373 c++; \ |
| 5093 | 374 } \ |
| 5176 | 375 g_string_free(innards, TRUE); \ |
| 5093 | 376 continue; \ |
| 377 } \ | |
| 378 if(!g_ascii_strncasecmp(c, "<" x, strlen("<" x)) && \ | |
| 379 (*(c+strlen("<" x)) == '>' || \ | |
| 380 !g_ascii_strncasecmp(c+strlen("<" x), "/>", 2))) { \ | |
| 381 xhtml = g_string_append(xhtml, "<" y); \ | |
| 382 c += strlen("<" x); \ | |
| 5104 | 383 if(*c != '/') { \ |
| 384 struct gaim_parse_tag *pt = g_new0(struct gaim_parse_tag, 1); \ | |
| 385 pt->src_tag = x; \ | |
| 386 pt->dest_tag = y; \ | |
| 387 tags = g_list_prepend(tags, pt); \ | |
| 5110 | 388 xhtml = g_string_append_c(xhtml, '>'); \ |
| 389 } else { \ | |
| 390 xhtml = g_string_append(xhtml, "/>");\ | |
| 5104 | 391 } \ |
| 5110 | 392 c = strchr(c, '>') + 1; \ |
| 5093 | 393 continue; \ |
| 394 } | |
| 395 #define ALLOW_TAG(x) ALLOW_TAG_ALT(x, x) | |
| 396 | |
| 5110 | 397 void html_to_xhtml(const char *html, char **xhtml_out, char **plain_out) { |
| 5093 | 398 GString *xhtml = g_string_new(""); |
| 5110 | 399 GString *plain = g_string_new(""); |
| 5093 | 400 GList *tags = NULL, *tag; |
| 5141 | 401 const char *c = html; |
| 5176 | 402 |
| 403 while(c && *c) { | |
| 5141 | 404 if(*c == '<') { |
| 5093 | 405 if(*(c+1) == '/') { /* closing tag */ |
| 406 tag = tags; | |
| 407 while(tag) { | |
| 5104 | 408 struct gaim_parse_tag *pt = tag->data; |
| 409 if(!g_ascii_strncasecmp((c+2), pt->src_tag, strlen(pt->src_tag)) && *(c+strlen(pt->src_tag)+2) == '>') { | |
| 410 c += strlen(pt->src_tag) + 3; | |
| 5093 | 411 break; |
| 412 } | |
| 413 tag = tag->next; | |
| 414 } | |
| 415 if(tag) { | |
| 416 while(tags) { | |
| 5104 | 417 struct gaim_parse_tag *pt = tags->data; |
| 418 g_string_append_printf(xhtml, "</%s>", pt->dest_tag); | |
| 5093 | 419 if(tags == tag) |
| 420 break; | |
| 5104 | 421 tags = g_list_remove(tags, pt); |
| 422 g_free(pt); | |
| 5093 | 423 } |
| 5104 | 424 g_free(tag->data); |
| 5093 | 425 tags = g_list_remove(tags, tag->data); |
| 426 } else { | |
| 427 /* we tried to close a tag we never opened! escape it | |
| 428 * and move on */ | |
| 429 xhtml = g_string_append(xhtml, "<"); | |
| 5110 | 430 plain = g_string_append_c(plain, '<'); |
| 5093 | 431 c++; |
| 432 } | |
| 433 } else { /* opening tag */ | |
| 434 ALLOW_TAG("a"); | |
| 5101 | 435 ALLOW_TAG_ALT("b", "strong"); |
| 5093 | 436 ALLOW_TAG("blockquote"); |
| 5101 | 437 ALLOW_TAG_ALT("bold", "strong"); |
| 5093 | 438 ALLOW_TAG("cite"); |
| 439 ALLOW_TAG("div"); | |
| 440 ALLOW_TAG("em"); | |
| 441 ALLOW_TAG("h1"); | |
| 442 ALLOW_TAG("h2"); | |
| 443 ALLOW_TAG("h3"); | |
| 444 ALLOW_TAG("h4"); | |
| 445 ALLOW_TAG("h5"); | |
| 446 ALLOW_TAG("h6"); | |
| 447 ALLOW_TAG("html"); | |
| 5101 | 448 ALLOW_TAG_ALT("i", "em"); |
| 449 ALLOW_TAG_ALT("italic", "em"); | |
| 5093 | 450 ALLOW_TAG("li"); |
| 451 ALLOW_TAG("ol"); | |
| 452 ALLOW_TAG("p"); | |
| 453 ALLOW_TAG("pre"); | |
| 454 ALLOW_TAG("q"); | |
| 455 ALLOW_TAG("span"); | |
| 456 ALLOW_TAG("strong"); | |
| 457 ALLOW_TAG("ul"); | |
| 458 | |
| 5174 | 459 /* we skip <HR> because it's not legal in XHTML-IM. However, |
| 460 * we still want to send something sensible, so we put a | |
| 461 * linebreak in its place. <BR> also needs special handling | |
| 462 * because putting a </BR> to close it would just be dumb. */ | |
| 463 if((!g_ascii_strncasecmp(c, "<br", 3) | |
| 464 || !g_ascii_strncasecmp(c, "<hr", 3)) | |
| 465 && (*(c+3) == '>' || | |
| 466 !g_ascii_strncasecmp(c+3, "/>", 2) || | |
| 467 !g_ascii_strncasecmp(c+3, " />", 3))) { | |
| 468 c = strchr(c, '>') + 1; | |
| 469 xhtml = g_string_append(xhtml, "<br/>"); | |
| 470 if(*c != '\n') | |
| 471 plain = g_string_append_c(plain, '\n'); | |
| 472 continue; | |
| 473 } | |
| 474 if(!g_ascii_strncasecmp(c, "<u>", 3) || !g_ascii_strncasecmp(c, "<underline>", strlen("<underline>"))) { | |
| 5104 | 475 struct gaim_parse_tag *pt = g_new0(struct gaim_parse_tag, 1); |
| 476 pt->src_tag = *(c+2) == '>' ? "u" : "underline"; | |
| 477 pt->dest_tag = "span"; | |
| 478 tags = g_list_prepend(tags, pt); | |
| 479 c = strchr(c, '>') + 1; | |
| 480 xhtml = g_string_append(xhtml, "<span style='text-decoration: underline;'>"); | |
| 481 continue; | |
| 482 } | |
| 5174 | 483 if(!g_ascii_strncasecmp(c, "<s>", 3) || !g_ascii_strncasecmp(c, "<strike>", strlen("<strike>"))) { |
| 5104 | 484 struct gaim_parse_tag *pt = g_new0(struct gaim_parse_tag, 1); |
| 485 pt->src_tag = *(c+2) == '>' ? "s" : "strike"; | |
| 486 pt->dest_tag = "span"; | |
| 487 tags = g_list_prepend(tags, pt); | |
| 488 c = strchr(c, '>') + 1; | |
| 489 xhtml = g_string_append(xhtml, "<span style='text-decoration: line-through;'>"); | |
| 490 continue; | |
| 491 } | |
| 492 if(!g_ascii_strncasecmp(c, "<sub>", 5)) { | |
| 493 struct gaim_parse_tag *pt = g_new0(struct gaim_parse_tag, 1); | |
| 494 pt->src_tag = "sub"; | |
| 495 pt->dest_tag = "span"; | |
| 496 tags = g_list_prepend(tags, pt); | |
| 497 c = strchr(c, '>') + 1; | |
| 498 xhtml = g_string_append(xhtml, "<span style='vertical-align:sub;'>"); | |
| 499 continue; | |
| 500 } | |
| 501 if(!g_ascii_strncasecmp(c, "<sup>", 5)) { | |
| 502 struct gaim_parse_tag *pt = g_new0(struct gaim_parse_tag, 1); | |
| 503 pt->src_tag = "sup"; | |
| 504 pt->dest_tag = "span"; | |
| 505 tags = g_list_prepend(tags, pt); | |
| 506 c = strchr(c, '>') + 1; | |
| 507 xhtml = g_string_append(xhtml, "<span style='vertical-align:super;'>"); | |
| 508 continue; | |
| 509 } | |
| 5107 | 510 if(!g_ascii_strncasecmp(c, "<font", 5) && (*(c+5) == '>' || *(c+5) == ' ')) { |
| 511 const char *p = c; | |
| 512 GString *style = g_string_new(""); | |
| 513 struct gaim_parse_tag *pt; | |
| 514 while(*p && *p != '>') { | |
| 515 if(!g_ascii_strncasecmp(p, "color=", strlen("color="))) { | |
| 516 const char *q = p + strlen("color="); | |
| 517 GString *color = g_string_new(""); | |
| 518 if(*q == '\'' || *q == '\"') | |
| 519 q++; | |
| 520 while(*q && *q != '\"' && *q != '\'' && *q != ' ') { | |
| 521 color = g_string_append_c(color, *q); | |
| 522 q++; | |
| 523 } | |
| 524 g_string_append_printf(style, "color: %s; ", color->str); | |
| 525 g_string_free(color, TRUE); | |
| 526 p = q; | |
| 527 } else if(!g_ascii_strncasecmp(p, "face=", strlen("face="))) { | |
| 528 const char *q = p + strlen("face="); | |
| 529 gboolean space_allowed = FALSE; | |
| 530 GString *face = g_string_new(""); | |
| 531 if(*q == '\'' || *q == '\"') { | |
| 532 space_allowed = TRUE; | |
| 533 q++; | |
| 534 } | |
| 535 while(*q && *q != '\"' && *q != '\'' && (space_allowed || *q != ' ')) { | |
| 536 face = g_string_append_c(face, *q); | |
| 537 q++; | |
| 538 } | |
| 539 g_string_append_printf(style, "font-family: %s; ", face->str); | |
| 540 g_string_free(face, TRUE); | |
| 541 p = q; | |
| 542 } else if(!g_ascii_strncasecmp(p, "size=", strlen("size="))) { | |
| 543 const char *q = p + strlen("size="); | |
| 544 int sz; | |
| 545 const char *size = "medium"; | |
| 546 if(*q == '\'' || *q == '\"') | |
| 547 q++; | |
| 548 sz = atoi(q); | |
| 549 if(sz < 3) | |
| 550 size = "smaller"; | |
| 551 else if(sz > 3) | |
| 552 size = "larger"; | |
| 553 g_string_append_printf(style, "font-size: %s; ", size); | |
| 554 p = q; | |
| 555 } | |
| 556 p++; | |
| 557 } | |
| 558 c = strchr(c, '>') + 1; | |
| 559 pt = g_new0(struct gaim_parse_tag, 1); | |
| 560 pt->src_tag = "font"; | |
| 561 pt->dest_tag = "span"; | |
| 562 tags = g_list_prepend(tags, pt); | |
| 563 xhtml = g_string_append(xhtml, "<span"); | |
| 564 if(style->len) | |
| 565 g_string_append_printf(xhtml, " style='%s'", style->str); | |
| 566 xhtml = g_string_append_c(xhtml, '>'); | |
| 567 g_string_free(style, TRUE); | |
| 568 continue; | |
| 569 } | |
| 570 if(!g_ascii_strncasecmp(c, "<body ", 6)) { | |
| 571 const char *p = c; | |
| 572 gboolean did_something = FALSE; | |
| 573 while(*p && *p != '>') { | |
| 574 if(!g_ascii_strncasecmp(p, "bgcolor=", strlen("bgcolor="))) { | |
| 575 const char *q = p + strlen("bgcolor="); | |
| 576 struct gaim_parse_tag *pt = g_new0(struct gaim_parse_tag, 1); | |
| 577 GString *color = g_string_new(""); | |
| 578 if(*q == '\'' || *q == '\"') | |
| 579 q++; | |
| 580 while(*q && *q != '\"' && *q != '\'' && *q != ' ') { | |
| 581 color = g_string_append_c(color, *q); | |
| 582 q++; | |
| 583 } | |
| 584 g_string_append_printf(xhtml, "<span style='background: %s;'>", color->str); | |
| 585 g_string_free(color, TRUE); | |
| 586 c = strchr(c, '>') + 1; | |
| 587 pt->src_tag = "body"; | |
| 588 pt->dest_tag = "span"; | |
| 589 tags = g_list_prepend(tags, pt); | |
| 590 did_something = TRUE; | |
| 591 break; | |
| 592 } | |
| 593 p++; | |
| 594 } | |
| 595 if(did_something) continue; | |
| 596 } | |
| 597 /* this has to come after the special case for bgcolor */ | |
| 598 ALLOW_TAG("body"); | |
| 5093 | 599 if(!g_ascii_strncasecmp(c, "<!--", strlen("<!--"))) { |
| 600 char *p = strstr(c + strlen("<!--"), "-->"); | |
| 601 if(p) { | |
| 602 xhtml = g_string_append(xhtml, "<!--"); | |
| 603 c += strlen("<!--"); | |
| 604 continue; | |
| 605 } | |
| 606 } | |
| 607 | |
| 608 xhtml = g_string_append(xhtml, "<"); | |
| 5110 | 609 plain = g_string_append_c(plain, '<'); |
| 5093 | 610 c++; |
| 611 } | |
| 612 } else { | |
| 613 xhtml = g_string_append_c(xhtml, *c); | |
| 5110 | 614 plain = g_string_append_c(plain, *c); |
| 5093 | 615 c++; |
| 616 } | |
| 617 } | |
| 618 tag = tags; | |
| 619 while(tag) { | |
| 620 g_string_append_printf(xhtml, "</%s>", (char *)tag->data); | |
| 621 tag = tag->next; | |
| 622 } | |
| 623 g_list_free(tags); | |
| 5110 | 624 if(xhtml_out) |
| 625 *xhtml_out = g_strdup(xhtml->str); | |
| 626 if(plain_out) | |
| 627 *plain_out = g_strdup(plain->str); | |
| 5093 | 628 g_string_free(xhtml, TRUE); |
| 5110 | 629 g_string_free(plain, TRUE); |
| 5093 | 630 } |
