Mercurial > pidgin.yaz
comparison libpurple/protocols/jabber/jutil.c @ 15374:5fe8042783c1
Rename gtk/ and libgaim/ to pidgin/ and libpurple/
author | Sean Egan <seanegan@gmail.com> |
---|---|
date | Sat, 20 Jan 2007 02:32:10 +0000 |
parents | |
children | 32c366eeeb99 |
comparison
equal
deleted
inserted
replaced
15373:f79e0f4df793 | 15374:5fe8042783c1 |
---|---|
1 /* | |
2 * gaim - Jabber Protocol Plugin | |
3 * | |
4 * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com> | |
5 * | |
6 * This program is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program; if not, write to the Free Software | |
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 * | |
20 */ | |
21 #include "internal.h" | |
22 #include "server.h" | |
23 #include "util.h" | |
24 | |
25 #include "chat.h" | |
26 #include "presence.h" | |
27 #include "jutil.h" | |
28 | |
29 gboolean jabber_nodeprep_validate(const char *str) | |
30 { | |
31 const char *c; | |
32 | |
33 if(!str) | |
34 return TRUE; | |
35 | |
36 if(strlen(str) > 1023) | |
37 return FALSE; | |
38 | |
39 c = str; | |
40 while(c && *c) { | |
41 gunichar ch = g_utf8_get_char(c); | |
42 if(ch == '\"' || ch == '&' || ch == '\'' || ch == '/' || ch == ':' || | |
43 ch == '<' || ch == '>' || ch == '@' || !g_unichar_isgraph(ch)) { | |
44 return FALSE; | |
45 } | |
46 c = g_utf8_next_char(c); | |
47 } | |
48 | |
49 return TRUE; | |
50 } | |
51 | |
52 gboolean jabber_nameprep_validate(const char *str) | |
53 { | |
54 const char *c; | |
55 | |
56 if(!str) | |
57 return TRUE; | |
58 | |
59 if(strlen(str) > 1023) | |
60 return FALSE; | |
61 | |
62 c = str; | |
63 while(c && *c) { | |
64 gunichar ch = g_utf8_get_char(c); | |
65 if(!g_unichar_isgraph(ch)) | |
66 return FALSE; | |
67 | |
68 c = g_utf8_next_char(c); | |
69 } | |
70 | |
71 | |
72 return TRUE; | |
73 } | |
74 | |
75 gboolean jabber_resourceprep_validate(const char *str) | |
76 { | |
77 const char *c; | |
78 | |
79 if(!str) | |
80 return TRUE; | |
81 | |
82 if(strlen(str) > 1023) | |
83 return FALSE; | |
84 | |
85 c = str; | |
86 while(c && *c) { | |
87 gunichar ch = g_utf8_get_char(c); | |
88 if(!g_unichar_isgraph(ch) && ch != ' ') | |
89 return FALSE; | |
90 | |
91 c = g_utf8_next_char(c); | |
92 } | |
93 | |
94 return TRUE; | |
95 } | |
96 | |
97 | |
98 JabberID* | |
99 jabber_id_new(const char *str) | |
100 { | |
101 char *at; | |
102 char *slash; | |
103 JabberID *jid; | |
104 | |
105 if(!str || !g_utf8_validate(str, -1, NULL)) | |
106 return NULL; | |
107 | |
108 jid = g_new0(JabberID, 1); | |
109 | |
110 at = g_utf8_strchr(str, -1, '@'); | |
111 slash = g_utf8_strchr(str, -1, '/'); | |
112 | |
113 if(at) { | |
114 jid->node = g_utf8_normalize(str, at-str, G_NORMALIZE_NFKC); | |
115 if(slash) { | |
116 jid->domain = g_utf8_normalize(at+1, slash-(at+1), G_NORMALIZE_NFKC); | |
117 jid->resource = g_utf8_normalize(slash+1, -1, G_NORMALIZE_NFKC); | |
118 } else { | |
119 jid->domain = g_utf8_normalize(at+1, -1, G_NORMALIZE_NFKC); | |
120 } | |
121 } else { | |
122 if(slash) { | |
123 jid->domain = g_utf8_normalize(str, slash-str, G_NORMALIZE_NFKC); | |
124 jid->resource = g_utf8_normalize(slash+1, -1, G_NORMALIZE_NFKC); | |
125 } else { | |
126 jid->domain = g_utf8_normalize(str, -1, G_NORMALIZE_NFKC); | |
127 } | |
128 } | |
129 | |
130 | |
131 if(!jabber_nodeprep_validate(jid->node) || | |
132 !jabber_nameprep_validate(jid->domain) || | |
133 !jabber_resourceprep_validate(jid->resource)) { | |
134 jabber_id_free(jid); | |
135 return NULL; | |
136 } | |
137 | |
138 return jid; | |
139 } | |
140 | |
141 void | |
142 jabber_id_free(JabberID *jid) | |
143 { | |
144 if(jid) { | |
145 if(jid->node) | |
146 g_free(jid->node); | |
147 if(jid->domain) | |
148 g_free(jid->domain); | |
149 if(jid->resource) | |
150 g_free(jid->resource); | |
151 g_free(jid); | |
152 } | |
153 } | |
154 | |
155 | |
156 char *jabber_get_resource(const char *in) | |
157 { | |
158 JabberID *jid = jabber_id_new(in); | |
159 char *out; | |
160 | |
161 if(!jid) | |
162 return NULL; | |
163 | |
164 out = g_strdup(jid->resource); | |
165 jabber_id_free(jid); | |
166 | |
167 return out; | |
168 } | |
169 | |
170 char *jabber_get_bare_jid(const char *in) | |
171 { | |
172 JabberID *jid = jabber_id_new(in); | |
173 char *out; | |
174 | |
175 if(!jid) | |
176 return NULL; | |
177 | |
178 out = g_strdup_printf("%s%s%s", jid->node ? jid->node : "", | |
179 jid->node ? "@" : "", jid->domain); | |
180 jabber_id_free(jid); | |
181 | |
182 return out; | |
183 } | |
184 | |
185 const char *jabber_normalize(const GaimAccount *account, const char *in) | |
186 { | |
187 GaimConnection *gc = account ? account->gc : NULL; | |
188 JabberStream *js = gc ? gc->proto_data : NULL; | |
189 static char buf[3072]; /* maximum legal length of a jabber jid */ | |
190 JabberID *jid; | |
191 char *node, *domain; | |
192 | |
193 jid = jabber_id_new(in); | |
194 | |
195 if(!jid) | |
196 return NULL; | |
197 | |
198 node = jid->node ? g_utf8_strdown(jid->node, -1) : NULL; | |
199 domain = g_utf8_strdown(jid->domain, -1); | |
200 | |
201 | |
202 if(js && node && jid->resource && | |
203 jabber_chat_find(js, node, domain)) | |
204 g_snprintf(buf, sizeof(buf), "%s@%s/%s", node, domain, | |
205 jid->resource); | |
206 else | |
207 g_snprintf(buf, sizeof(buf), "%s%s%s", node ? node : "", | |
208 node ? "@" : "", domain); | |
209 | |
210 jabber_id_free(jid); | |
211 g_free(node); | |
212 g_free(domain); | |
213 | |
214 return buf; | |
215 } | |
216 | |
217 GaimConversation * | |
218 jabber_find_unnormalized_conv(const char *name, GaimAccount *account) | |
219 { | |
220 GaimConversation *c = NULL; | |
221 GList *cnv; | |
222 | |
223 g_return_val_if_fail(name != NULL, NULL); | |
224 | |
225 for(cnv = gaim_get_conversations(); cnv; cnv = cnv->next) { | |
226 c = (GaimConversation*)cnv->data; | |
227 if(gaim_conversation_get_type(c) == GAIM_CONV_TYPE_IM && | |
228 !gaim_utf8_strcasecmp(name, gaim_conversation_get_name(c)) && | |
229 account == gaim_conversation_get_account(c)) | |
230 return c; | |
231 } | |
232 | |
233 return NULL; | |
234 } | |
235 |