Sat, 05 Jul 2003 21:54:19 +0000
[gaim-migrate @ 6485]
gaim_request_input() now takes a masked bool, which, if enabled, masks the
text on the entry field so that it cannot be seen. Good for password input
requests, and what do you know, that's why this is written!
| 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
754c63f29b77
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5681
diff
changeset
|
22 | #include "internal.h" |
| 3630 | 23 | |
|
5872
754c63f29b77
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5681
diff
changeset
|
24 | #include "debug.h" |
|
1092
9be1c9ea4d2c
[gaim-migrate @ 1102]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1088
diff
changeset
|
25 | #include "proxy.h" |
| 1 | 26 | |
|
5872
754c63f29b77
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5681
diff
changeset
|
27 | #include "gaim.h" |
|
3717
2fc0789e04e8
[gaim-migrate @ 3850]
Herman Bloggs <herman@bluedigits.com>
parents:
3630
diff
changeset
|
28 | |
|
4359
cf899ee07d1d
[gaim-migrate @ 4625]
Christian Hammond <chipx86@chipx86.com>
parents:
4335
diff
changeset
|
29 | gchar *strip_html(const gchar *text) |
| 1 | 30 | { |
| 1883 | 31 | int i, j, k; |
| 1 | 32 | int visible = 1; |
| 1883 | 33 | gchar *text2 = g_strdup(text); |
|
1250
46ac03911ab0
[gaim-migrate @ 1260]
Decklin Foster <decklin@red-bean.com>
parents:
1092
diff
changeset
|
34 | |
| 4757 | 35 | if(!text) |
| 36 | return NULL; | |
| 4503 | 37 | |
|
1250
46ac03911ab0
[gaim-migrate @ 1260]
Decklin Foster <decklin@red-bean.com>
parents:
1092
diff
changeset
|
38 | for (i = 0, j = 0; text2[i]; i++) { |
|
46ac03911ab0
[gaim-migrate @ 1260]
Decklin Foster <decklin@red-bean.com>
parents:
1092
diff
changeset
|
39 | if (text2[i] == '<') { |
| 1883 | 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 | 54 | } |
| 55 | } | |
| 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
46ac03911ab0
[gaim-migrate @ 1260]
Decklin Foster <decklin@red-bean.com>
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
145439fc3996
[gaim-migrate @ 5900]
Herman Bloggs <herman@bluedigits.com>
parents:
5211
diff
changeset
|
79 | char* turl; |
|
145439fc3996
[gaim-migrate @ 5900]
Herman Bloggs <herman@bluedigits.com>
parents:
5211
diff
changeset
|
80 | /* hyphen at end includes it in control set */ |
|
145439fc3996
[gaim-migrate @ 5900]
Herman Bloggs <herman@bluedigits.com>
parents:
5211
diff
changeset
|
81 | char addr_ctrl[] = "A-Za-z0-9.-"; |
|
145439fc3996
[gaim-migrate @ 5900]
Herman Bloggs <herman@bluedigits.com>
parents:
5211
diff
changeset
|
82 | char port_ctrl[] = "0-9"; |
|
145439fc3996
[gaim-migrate @ 5900]
Herman Bloggs <herman@bluedigits.com>
parents:
5211
diff
changeset
|
83 | char page_ctrl[] = "A-Za-z0-9.~_/&%%?=+^-"; |
| 1 | 84 | |
|
5501
145439fc3996
[gaim-migrate @ 5900]
Herman Bloggs <herman@bluedigits.com>
parents:
5211
diff
changeset
|
85 | if((turl=strstr(url, "http://")) || (turl=strstr(url, "HTTP://"))) |
|
145439fc3996
[gaim-migrate @ 5900]
Herman Bloggs <herman@bluedigits.com>
parents:
5211
diff
changeset
|
86 | url=turl+=7; |
|
145439fc3996
[gaim-migrate @ 5900]
Herman Bloggs <herman@bluedigits.com>
parents:
5211
diff
changeset
|
87 | |
|
145439fc3996
[gaim-migrate @ 5900]
Herman Bloggs <herman@bluedigits.com>
parents:
5211
diff
changeset
|
88 | snprintf(scan_info, sizeof(scan_info), |
|
145439fc3996
[gaim-migrate @ 5900]
Herman Bloggs <herman@bluedigits.com>
parents:
5211
diff
changeset
|
89 | "%%[%s]:%%[%s]/%%[%s]", |
|
145439fc3996
[gaim-migrate @ 5900]
Herman Bloggs <herman@bluedigits.com>
parents:
5211
diff
changeset
|
90 | addr_ctrl, port_ctrl, page_ctrl); |
|
145439fc3996
[gaim-migrate @ 5900]
Herman Bloggs <herman@bluedigits.com>
parents:
5211
diff
changeset
|
91 | |
|
2541
0afd3aaba327
[gaim-migrate @ 2554]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2417
diff
changeset
|
92 | f = sscanf(url, scan_info, test->address, port, test->page); |
| 1 | 93 | if (f == 1) { |
|
5501
145439fc3996
[gaim-migrate @ 5900]
Herman Bloggs <herman@bluedigits.com>
parents:
5211
diff
changeset
|
94 | snprintf(scan_info, sizeof(scan_info), |
|
145439fc3996
[gaim-migrate @ 5900]
Herman Bloggs <herman@bluedigits.com>
parents:
5211
diff
changeset
|
95 | "%%[%s]/%%[%s]", |
|
145439fc3996
[gaim-migrate @ 5900]
Herman Bloggs <herman@bluedigits.com>
parents:
5211
diff
changeset
|
96 | addr_ctrl, page_ctrl); |
|
2541
0afd3aaba327
[gaim-migrate @ 2554]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2417
diff
changeset
|
97 | f = sscanf(url, scan_info, test->address, test->page); |
|
5501
145439fc3996
[gaim-migrate @ 5900]
Herman Bloggs <herman@bluedigits.com>
parents:
5211
diff
changeset
|
98 | snprintf(port, sizeof(port), "80"); |
| 1 | 99 | } |
|
5501
145439fc3996
[gaim-migrate @ 5900]
Herman Bloggs <herman@bluedigits.com>
parents:
5211
diff
changeset
|
100 | if (f == 1) |
| 5512 | 101 | test->page[0] = '\0'; |
| 1 | 102 | |
|
2541
0afd3aaba327
[gaim-migrate @ 2554]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2417
diff
changeset
|
103 | sscanf(port, "%d", &test->port); |
| 1 | 104 | return test; |
| 105 | } | |
| 106 | ||
|
1840
770bc15f419c
[gaim-migrate @ 1850]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1250
diff
changeset
|
107 | struct grab_url_data { |
| 4322 | 108 | void (* callback)(gpointer, char *, unsigned long); |
|
1840
770bc15f419c
[gaim-migrate @ 1850]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1250
diff
changeset
|
109 | gpointer data; |
|
2541
0afd3aaba327
[gaim-migrate @ 2554]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2417
diff
changeset
|
110 | struct g_url *website; |
|
1840
770bc15f419c
[gaim-migrate @ 1850]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1250
diff
changeset
|
111 | char *url; |
|
2584
1d2c4de26640
[gaim-migrate @ 2597]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2541
diff
changeset
|
112 | gboolean full; |
|
2369
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
113 | |
|
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
114 | int inpa; |
|
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
115 | |
|
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
116 | gboolean sentreq; |
|
2584
1d2c4de26640
[gaim-migrate @ 2597]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2541
diff
changeset
|
117 | gboolean newline; |
|
1d2c4de26640
[gaim-migrate @ 2597]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2541
diff
changeset
|
118 | gboolean startsaving; |
|
2369
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
119 | char *webdata; |
| 4322 | 120 | unsigned long len; |
|
4331
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
121 | unsigned long data_len; |
|
1840
770bc15f419c
[gaim-migrate @ 1850]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1250
diff
changeset
|
122 | }; |
|
770bc15f419c
[gaim-migrate @ 1850]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1250
diff
changeset
|
123 | |
|
4331
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
124 | static gboolean |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
125 | parse_redirect(const char *data, size_t data_len, gint sock, |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
126 | struct grab_url_data *gunk) |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
127 | { |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
128 | gchar *s; |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
129 | |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
130 | if ((s = g_strstr_len(data, data_len, "Location: ")) != NULL) { |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
131 | gchar *new_url, *end; |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
132 | int len; |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
133 | |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
134 | s += strlen("Location: "); |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
135 | end = strchr(s, '\r'); |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
136 | |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
137 | /* Just in case :) */ |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
138 | if (end == NULL) |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
139 | end = strchr(s, '\n'); |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
140 | |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
141 | len = end - s; |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
142 | |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
143 | new_url = g_malloc(len + 1); |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
144 | strncpy(new_url, s, len); |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
145 | new_url[len] = '\0'; |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
146 | |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
147 | /* Close the existing stuff. */ |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
148 | gaim_input_remove(gunk->inpa); |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
149 | close(sock); |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
150 | |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
151 | /* Try again, with this new location. */ |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
152 | grab_url(new_url, gunk->full, gunk->callback, |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
153 | gunk->data); |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
154 | |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
155 | /* Free up. */ |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
156 | g_free(new_url); |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
157 | g_free(gunk->webdata); |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
158 | g_free(gunk->website); |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
159 | g_free(gunk->url); |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
160 | g_free(gunk); |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
161 | |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
162 | return TRUE; |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
163 | } |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
164 | |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
165 | return FALSE; |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
166 | } |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
167 | |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
168 | static size_t |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
169 | parse_content_len(const char *data, size_t data_len) |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
170 | { |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
171 | size_t content_len = 0; |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
172 | |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
173 | sscanf(data, "Content-Length: %d", &content_len); |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
174 | |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
175 | return content_len; |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
176 | } |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
177 | |
|
2369
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
178 | static void grab_url_callback(gpointer dat, gint sock, GaimInputCondition cond) |
|
1840
770bc15f419c
[gaim-migrate @ 1850]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1250
diff
changeset
|
179 | { |
|
770bc15f419c
[gaim-migrate @ 1850]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1250
diff
changeset
|
180 | struct grab_url_data *gunk = dat; |
| 1 | 181 | char data; |
| 182 | ||
|
1840
770bc15f419c
[gaim-migrate @ 1850]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1250
diff
changeset
|
183 | if (sock == -1) { |
| 4322 | 184 | gunk->callback(gunk->data, NULL, 0); |
|
2541
0afd3aaba327
[gaim-migrate @ 2554]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2417
diff
changeset
|
185 | g_free(gunk->website); |
|
1840
770bc15f419c
[gaim-migrate @ 1850]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1250
diff
changeset
|
186 | g_free(gunk->url); |
|
770bc15f419c
[gaim-migrate @ 1850]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1250
diff
changeset
|
187 | g_free(gunk); |
|
770bc15f419c
[gaim-migrate @ 1850]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1250
diff
changeset
|
188 | return; |
|
1087
bc9c6b635358
[gaim-migrate @ 1097]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
691
diff
changeset
|
189 | } |
| 1 | 190 | |
|
2369
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
191 | if (!gunk->sentreq) { |
|
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
192 | char buf[256]; |
|
3717
2fc0789e04e8
[gaim-migrate @ 3850]
Herman Bloggs <herman@bluedigits.com>
parents:
3630
diff
changeset
|
193 | |
|
2584
1d2c4de26640
[gaim-migrate @ 2597]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2541
diff
changeset
|
194 | g_snprintf(buf, sizeof(buf), "GET %s%s HTTP/1.0\r\n\r\n", gunk->full ? "" : "/", |
|
1d2c4de26640
[gaim-migrate @ 2597]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2541
diff
changeset
|
195 | gunk->full ? gunk->url : gunk->website->page); |
|
5211
94d9756c381f
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5176
diff
changeset
|
196 | |
|
94d9756c381f
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5176
diff
changeset
|
197 | gaim_debug(GAIM_DEBUG_MISC, "grab_url_callback", |
|
94d9756c381f
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5176
diff
changeset
|
198 | "Request: %s\n", buf); |
|
3717
2fc0789e04e8
[gaim-migrate @ 3850]
Herman Bloggs <herman@bluedigits.com>
parents:
3630
diff
changeset
|
199 | |
|
2369
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
200 | write(sock, buf, strlen(buf)); |
|
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
201 | fcntl(sock, F_SETFL, O_NONBLOCK); |
|
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
202 | gunk->sentreq = TRUE; |
|
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
203 | gunk->inpa = gaim_input_add(sock, GAIM_INPUT_READ, grab_url_callback, dat); |
|
4331
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
204 | gunk->data_len = 4096; |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
205 | gunk->webdata = g_malloc(gunk->data_len); |
|
2369
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
206 | return; |
|
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
207 | } |
| 1 | 208 | |
|
2369
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
209 | if (read(sock, &data, 1) > 0 || errno == EWOULDBLOCK) { |
|
278
4365a163c987
[gaim-migrate @ 288]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
268
diff
changeset
|
210 | if (errno == EWOULDBLOCK) { |
|
4365a163c987
[gaim-migrate @ 288]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
268
diff
changeset
|
211 | errno = 0; |
|
2369
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
212 | return; |
|
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
213 | } |
|
4331
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
214 | |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
215 | gunk->len++; |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
216 | |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
217 | if (gunk->len == gunk->data_len + 1) { |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
218 | gunk->data_len += (gunk->data_len) / 2; |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
219 | |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
220 | gunk->webdata = g_realloc(gunk->webdata, gunk->data_len); |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
221 | } |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
222 | |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
223 | gunk->webdata[gunk->len - 1] = data; |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
224 | |
|
2584
1d2c4de26640
[gaim-migrate @ 2597]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2541
diff
changeset
|
225 | if (!gunk->startsaving) { |
|
1d2c4de26640
[gaim-migrate @ 2597]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2541
diff
changeset
|
226 | if (data == '\r') |
|
1d2c4de26640
[gaim-migrate @ 2597]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2541
diff
changeset
|
227 | return; |
|
1d2c4de26640
[gaim-migrate @ 2597]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2541
diff
changeset
|
228 | if (data == '\n') { |
|
4331
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
229 | if (gunk->newline) { |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
230 | size_t content_len; |
|
2584
1d2c4de26640
[gaim-migrate @ 2597]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2541
diff
changeset
|
231 | gunk->startsaving = TRUE; |
|
4331
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
232 | |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
233 | /* See if we can find a redirect. */ |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
234 | if (parse_redirect(gunk->webdata, gunk->len, sock, gunk)) |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
235 | return; |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
236 | |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
237 | /* No redirect. See if we can find a content length. */ |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
238 | content_len = parse_content_len(gunk->webdata, gunk->len); |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
239 | |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
240 | if (content_len == 0) { |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
241 | /* We'll stick with an initial 8192 */ |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
242 | content_len = 8192; |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
243 | } |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
244 | |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
245 | /* Out with the old... */ |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
246 | gunk->len = 0; |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
247 | g_free(gunk->webdata); |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
248 | gunk->webdata = NULL; |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
249 | |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
250 | /* In with the new. */ |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
251 | gunk->data_len = content_len; |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
252 | gunk->webdata = g_malloc(gunk->data_len); |
|
5222a28cc31d
[gaim-migrate @ 4595]
Christian Hammond <chipx86@chipx86.com>
parents:
4322
diff
changeset
|
253 | } |
|
2584
1d2c4de26640
[gaim-migrate @ 2597]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2541
diff
changeset
|
254 | else |
|
1d2c4de26640
[gaim-migrate @ 2597]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2541
diff
changeset
|
255 | gunk->newline = TRUE; |
|
1d2c4de26640
[gaim-migrate @ 2597]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2541
diff
changeset
|
256 | return; |
|
1d2c4de26640
[gaim-migrate @ 2597]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2541
diff
changeset
|
257 | } |
|
1d2c4de26640
[gaim-migrate @ 2597]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2541
diff
changeset
|
258 | gunk->newline = FALSE; |
|
278
4365a163c987
[gaim-migrate @ 288]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
268
diff
changeset
|
259 | } |
|
2369
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
260 | } else if (errno != ETIMEDOUT) { |
|
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
261 | gunk->webdata = g_realloc(gunk->webdata, gunk->len + 1); |
|
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
262 | gunk->webdata[gunk->len] = 0; |
|
1250
46ac03911ab0
[gaim-migrate @ 1260]
Decklin Foster <decklin@red-bean.com>
parents:
1092
diff
changeset
|
263 | |
|
5211
94d9756c381f
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5176
diff
changeset
|
264 | gaim_debug(GAIM_DEBUG_MISC, "grab_url_callback", |
|
94d9756c381f
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5176
diff
changeset
|
265 | "Received: '%s'\n", gunk->webdata); |
|
1250
46ac03911ab0
[gaim-migrate @ 1260]
Decklin Foster <decklin@red-bean.com>
parents:
1092
diff
changeset
|
266 | |
|
2369
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
267 | gaim_input_remove(gunk->inpa); |
|
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
268 | close(sock); |
| 4322 | 269 | gunk->callback(gunk->data, gunk->webdata, gunk->len); |
|
2369
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
270 | if (gunk->webdata) |
|
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
271 | g_free(gunk->webdata); |
|
2541
0afd3aaba327
[gaim-migrate @ 2554]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2417
diff
changeset
|
272 | g_free(gunk->website); |
|
2369
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
273 | g_free(gunk->url); |
|
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
274 | g_free(gunk); |
|
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
275 | } else { |
|
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
276 | gaim_input_remove(gunk->inpa); |
|
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
277 | close(sock); |
| 4322 | 278 | gunk->callback(gunk->data, NULL, 0); |
|
2369
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
279 | if (gunk->webdata) |
|
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
280 | g_free(gunk->webdata); |
|
2541
0afd3aaba327
[gaim-migrate @ 2554]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2417
diff
changeset
|
281 | g_free(gunk->website); |
|
2369
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
282 | g_free(gunk->url); |
|
65cbc00bf992
[gaim-migrate @ 2382]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2090
diff
changeset
|
283 | g_free(gunk); |
| 1 | 284 | } |
| 285 | } | |
|
1840
770bc15f419c
[gaim-migrate @ 1850]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1250
diff
changeset
|
286 | |
| 4322 | 287 | void grab_url(char *url, gboolean full, void callback(gpointer, char *, unsigned long), gpointer data) |
|
1840
770bc15f419c
[gaim-migrate @ 1850]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1250
diff
changeset
|
288 | { |
|
770bc15f419c
[gaim-migrate @ 1850]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1250
diff
changeset
|
289 | int sock; |
|
770bc15f419c
[gaim-migrate @ 1850]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1250
diff
changeset
|
290 | struct grab_url_data *gunk = g_new0(struct grab_url_data, 1); |
|
770bc15f419c
[gaim-migrate @ 1850]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1250
diff
changeset
|
291 | |
|
770bc15f419c
[gaim-migrate @ 1850]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1250
diff
changeset
|
292 | gunk->callback = callback; |
|
770bc15f419c
[gaim-migrate @ 1850]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1250
diff
changeset
|
293 | gunk->data = data; |
|
770bc15f419c
[gaim-migrate @ 1850]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1250
diff
changeset
|
294 | gunk->url = g_strdup(url); |
|
770bc15f419c
[gaim-migrate @ 1850]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1250
diff
changeset
|
295 | gunk->website = parse_url(url); |
|
2584
1d2c4de26640
[gaim-migrate @ 2597]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2541
diff
changeset
|
296 | gunk->full = full; |
|
1840
770bc15f419c
[gaim-migrate @ 1850]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1250
diff
changeset
|
297 | |
|
5681
514fbc5374dc
[gaim-migrate @ 6100]
Christian Hammond <chipx86@chipx86.com>
parents:
5512
diff
changeset
|
298 | if ((sock = gaim_proxy_connect(NULL, gunk->website->address, |
|
514fbc5374dc
[gaim-migrate @ 6100]
Christian Hammond <chipx86@chipx86.com>
parents:
5512
diff
changeset
|
299 | gunk->website->port, grab_url_callback, |
|
514fbc5374dc
[gaim-migrate @ 6100]
Christian Hammond <chipx86@chipx86.com>
parents:
5512
diff
changeset
|
300 | gunk)) < 0) { |
|
2541
0afd3aaba327
[gaim-migrate @ 2554]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
2417
diff
changeset
|
301 | g_free(gunk->website); |
|
1881
bcd5d457cdbb
[gaim-migrate @ 1891]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1843
diff
changeset
|
302 | g_free(gunk->url); |
|
bcd5d457cdbb
[gaim-migrate @ 1891]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1843
diff
changeset
|
303 | g_free(gunk); |
| 4322 | 304 | callback(data, g_strdup(_("g003: Error opening connection.\n")), 0); |
|
1840
770bc15f419c
[gaim-migrate @ 1850]
Eric Warmenhoven <warmenhoven@yahoo.com>
parents:
1250
diff
changeset
|
305 | } |
|
770bc15f419c
[gaim-migrate @ 1850]
Eric Warmenhoven <warmenhoven@yahoo.com>
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 | } |