Mercurial > pidgin.yaz
comparison src/protocols/jabber/jid.c @ 2086:424a40f12a6c
[gaim-migrate @ 2096]
moving protocols from plugins/ to src/protocols. making it so that you can select which protocols are compiled statically.
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Tue, 31 Jul 2001 01:00:39 +0000 |
parents | |
children | 4e7cefc55971 |
comparison
equal
deleted
inserted
replaced
2085:7ebb4322f89b | 2086:424a40f12a6c |
---|---|
1 /* | |
2 * This program is free software; you can redistribute it and/or modify | |
3 * it under the terms of the GNU General Public License as published by | |
4 * the Free Software Foundation; either version 2 of the License, or | |
5 * (at your option) any later version. | |
6 * | |
7 * This program is distributed in the hope that it will be useful, | |
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
10 * GNU General Public License for more details. | |
11 * | |
12 * You should have received a copy of the GNU General Public License | |
13 * along with this program; if not, write to the Free Software | |
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
15 * | |
16 * Jabber | |
17 * Copyright (C) 1998-1999 The Jabber Team http://jabber.org/ | |
18 */ | |
19 | |
20 #include "jabber.h" | |
21 | |
22 jid jid_safe(jid id) | |
23 { | |
24 char *str; | |
25 | |
26 if(strlen(id->server) == 0 || strlen(id->server) > 255) | |
27 return NULL; | |
28 | |
29 /* lowercase the hostname, make sure it's valid characters */ | |
30 for(str = id->server; *str != '\0'; str++) | |
31 { | |
32 *str = tolower(*str); | |
33 if(!(isalnum(*str) || *str == '.' || *str == '-' || *str == '_')) return NULL; | |
34 } | |
35 | |
36 /* cut off the user */ | |
37 if(id->user != NULL && strlen(id->user) > 64) | |
38 id->user[64] = '\0'; | |
39 | |
40 /* check for low and invalid ascii characters in the username */ | |
41 if(id->user != NULL) | |
42 for(str = id->user; *str != '\0'; str++) | |
43 if(*str <= 32 || *str == ':' || *str == '@' || *str == '<' || *str == '>' || *str == '\'' || *str == '"' || *str == '&') return NULL; | |
44 | |
45 return id; | |
46 } | |
47 | |
48 jid jid_new(pool p, char *idstr) | |
49 { | |
50 char *server, *resource, *type, *str; | |
51 jid id; | |
52 | |
53 if(p == NULL || idstr == NULL || strlen(idstr) == 0) | |
54 return NULL; | |
55 | |
56 /* user@server/resource */ | |
57 | |
58 str = pstrdup(p, idstr); | |
59 | |
60 id = pmalloc(p,sizeof(struct jid_struct)); | |
61 id->full = id->server = id->user = id->resource = NULL; | |
62 id->p = p; | |
63 id->next = NULL; | |
64 | |
65 resource = strstr(str,"/"); | |
66 if(resource != NULL) | |
67 { | |
68 *resource = '\0'; | |
69 ++resource; | |
70 if(strlen(resource) > 0) | |
71 id->resource = resource; | |
72 }else{ | |
73 resource = str + strlen(str); /* point to end */ | |
74 } | |
75 | |
76 type = strstr(str,":"); | |
77 if(type != NULL && type < resource) | |
78 { | |
79 *type = '\0'; | |
80 ++type; | |
81 str = type; /* ignore the type: prefix */ | |
82 } | |
83 | |
84 server = strstr(str,"@"); | |
85 if(server == NULL || server > resource) | |
86 { /* if there's no @, it's just the server address */ | |
87 id->server = str; | |
88 }else{ | |
89 *server = '\0'; | |
90 ++server; | |
91 id->server = server; | |
92 if(strlen(str) > 0) | |
93 id->user = str; | |
94 } | |
95 | |
96 return jid_safe(id); | |
97 } | |
98 | |
99 void jid_set(jid id, char *str, int item) | |
100 { | |
101 char *old; | |
102 | |
103 if(id == NULL) | |
104 return; | |
105 | |
106 /* invalidate the cached copy */ | |
107 id->full = NULL; | |
108 | |
109 switch(item) | |
110 { | |
111 case JID_RESOURCE: | |
112 if(str != NULL && strlen(str) != 0) | |
113 id->resource = pstrdup(id->p, str); | |
114 else | |
115 id->resource = NULL; | |
116 break; | |
117 case JID_USER: | |
118 old = id->user; | |
119 if(str != NULL && strlen(str) != 0) | |
120 id->user = pstrdup(id->p, str); | |
121 else | |
122 id->user = NULL; | |
123 if(jid_safe(id) == NULL) | |
124 id->user = old; /* revert if invalid */ | |
125 break; | |
126 case JID_SERVER: | |
127 old = id->server; | |
128 id->server = pstrdup(id->p, str); | |
129 if(jid_safe(id) == NULL) | |
130 id->server = old; /* revert if invalid */ | |
131 break; | |
132 } | |
133 | |
134 } | |
135 | |
136 char *jid_full(jid id) | |
137 { | |
138 spool s; | |
139 | |
140 if(id == NULL) | |
141 return NULL; | |
142 | |
143 /* use cached copy */ | |
144 if(id->full != NULL) | |
145 return id->full; | |
146 | |
147 s = spool_new(id->p); | |
148 | |
149 if(id->user != NULL) | |
150 spooler(s, id->user,"@",s); | |
151 | |
152 spool_add(s, id->server); | |
153 | |
154 if(id->resource != NULL) | |
155 spooler(s, "/",id->resource,s); | |
156 | |
157 id->full = spool_print(s); | |
158 return id->full; | |
159 } | |
160 | |
161 /* parses a /resource?name=value&foo=bar into an xmlnode representing <resource name="value" foo="bar"/> */ | |
162 xmlnode jid_xres(jid id) | |
163 { | |
164 char *cur, *qmark, *amp, *eq; | |
165 xmlnode x; | |
166 | |
167 if(id == NULL || id->resource == NULL) return NULL; | |
168 | |
169 cur = pstrdup(id->p, id->resource); | |
170 qmark = strstr(cur, "?"); | |
171 if(qmark == NULL) return NULL; | |
172 *qmark = '\0'; | |
173 qmark++; | |
174 | |
175 x = _xmlnode_new(id->p, cur, NTYPE_TAG); | |
176 | |
177 cur = qmark; | |
178 while(cur != '\0') | |
179 { | |
180 eq = strstr(cur, "="); | |
181 if(eq == NULL) break; | |
182 *eq = '\0'; | |
183 eq++; | |
184 | |
185 amp = strstr(eq, "&"); | |
186 if(amp != NULL) | |
187 { | |
188 *amp = '\0'; | |
189 amp++; | |
190 } | |
191 | |
192 xmlnode_put_attrib(x,cur,eq); | |
193 | |
194 if(amp != NULL) | |
195 cur = amp; | |
196 else | |
197 break; | |
198 } | |
199 | |
200 return x; | |
201 } | |
202 | |
203 /* local utils */ | |
204 int _jid_nullstrcmp(char *a, char *b) | |
205 { | |
206 if(a == NULL && b == NULL) return 0; | |
207 if(a == NULL || b == NULL) return -1; | |
208 return strcmp(a,b); | |
209 } | |
210 int _jid_nullstrcasecmp(char *a, char *b) | |
211 { | |
212 if(a == NULL && b == NULL) return 0; | |
213 if(a == NULL || b == NULL) return -1; | |
214 return strcasecmp(a,b); | |
215 } | |
216 | |
217 int jid_cmp(jid a, jid b) | |
218 { | |
219 if(a == NULL || b == NULL) | |
220 return -1; | |
221 | |
222 if(_jid_nullstrcmp(a->resource, b->resource) != 0) return -1; | |
223 if(_jid_nullstrcasecmp(a->user, b->user) != 0) return -1; | |
224 if(_jid_nullstrcmp(a->server, b->server) != 0) return -1; | |
225 | |
226 return 0; | |
227 } | |
228 | |
229 /* suggested by Anders Qvist <quest@valdez.netg.se> */ | |
230 int jid_cmpx(jid a, jid b, int parts) | |
231 { | |
232 if(a == NULL || b == NULL) | |
233 return -1; | |
234 | |
235 if(parts & JID_RESOURCE && _jid_nullstrcmp(a->resource, b->resource) != 0) return -1; | |
236 if(parts & JID_USER && _jid_nullstrcasecmp(a->user, b->user) != 0) return -1; | |
237 if(parts & JID_SERVER && _jid_nullstrcmp(a->server, b->server) != 0) return -1; | |
238 | |
239 return 0; | |
240 } | |
241 | |
242 /* makes a copy of b in a's pool, requires a valid a first! */ | |
243 jid jid_append(jid a, jid b) | |
244 { | |
245 jid next; | |
246 | |
247 if(a == NULL) | |
248 return NULL; | |
249 | |
250 if(b == NULL) | |
251 return a; | |
252 | |
253 next = a; | |
254 while(next != NULL) | |
255 { | |
256 /* check for dups */ | |
257 if(jid_cmp(next,b) == 0) | |
258 break; | |
259 if(next->next == NULL) | |
260 next->next = jid_new(a->p,jid_full(b)); | |
261 next = next->next; | |
262 } | |
263 return a; | |
264 } | |
265 | |
266 xmlnode jid_nodescan(jid id, xmlnode x) | |
267 { | |
268 xmlnode cur; | |
269 pool p; | |
270 jid tmp; | |
271 | |
272 if(id == NULL || xmlnode_get_firstchild(x) == NULL) return NULL; | |
273 | |
274 p = pool_new(); | |
275 for(cur = xmlnode_get_firstchild(x); cur != NULL; cur = xmlnode_get_nextsibling(cur)) | |
276 { | |
277 if(xmlnode_get_type(cur) != NTYPE_TAG) continue; | |
278 | |
279 tmp = jid_new(p,xmlnode_get_attrib(cur,"jid")); | |
280 if(tmp == NULL) continue; | |
281 | |
282 if(jid_cmp(tmp,id) == 0) break; | |
283 } | |
284 pool_free(p); | |
285 | |
286 return cur; | |
287 } |