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.
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.
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.
17 * Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
26 if(strlen(id
->server
) == 0 || strlen(id
->server
) > 255)
29 /* lowercase the hostname, make sure it's valid characters */
30 for(str
= id
->server
; *str
!= '\0'; str
++)
33 if(!(isalnum(*str
) || *str
== '.' || *str
== '-' || *str
== '_')) return NULL
;
36 /* cut off the user */
37 if(id
->user
!= NULL
&& strlen(id
->user
) > 64)
40 /* check for low and invalid ascii characters in the username */
42 for(str
= id
->user
; *str
!= '\0'; str
++)
43 if(*str
<= 32 || *str
== ':' || *str
== '@' || *str
== '<' || *str
== '>' || *str
== '\'' || *str
== '"' || *str
== '&') return NULL
;
48 jid
jid_new(pool p
, char *idstr
)
50 char *server
, *resource
, *type
, *str
;
53 if(p
== NULL
|| idstr
== NULL
|| strlen(idstr
) == 0)
56 /* user@server/resource */
58 str
= pstrdup(p
, idstr
);
60 id
= pmalloc(p
,sizeof(struct jid_struct
));
61 id
->full
= id
->server
= id
->user
= id
->resource
= NULL
;
65 resource
= strstr(str
,"/");
70 if(strlen(resource
) > 0)
71 id
->resource
= resource
;
73 resource
= str
+ strlen(str
); /* point to end */
76 type
= strstr(str
,":");
77 if(type
!= NULL
&& type
< resource
)
81 str
= type
; /* ignore the type: prefix */
84 server
= strstr(str
,"@");
85 if(server
== NULL
|| server
> resource
)
86 { /* if there's no @, it's just the server address */
99 void jid_set(jid id
, char *str
, int item
)
106 /* invalidate the cached copy */
112 if(str
!= NULL
&& strlen(str
) != 0)
113 id
->resource
= pstrdup(id
->p
, str
);
119 if(str
!= NULL
&& strlen(str
) != 0)
120 id
->user
= pstrdup(id
->p
, str
);
123 if(jid_safe(id
) == NULL
)
124 id
->user
= old
; /* revert if invalid */
128 id
->server
= pstrdup(id
->p
, str
);
129 if(jid_safe(id
) == NULL
)
130 id
->server
= old
; /* revert if invalid */
136 char *jid_full(jid id
)
143 /* use cached copy */
147 s
= spool_new(id
->p
);
150 spooler(s
, id
->user
,"@",s
);
152 spool_add(s
, id
->server
);
154 if(id
->resource
!= NULL
)
155 spooler(s
, "/",id
->resource
,s
);
157 id
->full
= spool_print(s
);
161 /* parses a /resource?name=value&foo=bar into an xmlnode representing <resource name="value" foo="bar"/> */
162 xmlnode
jid_xres(jid id
)
164 char *cur
, *qmark
, *amp
, *eq
;
167 if(id
== NULL
|| id
->resource
== NULL
) return NULL
;
169 cur
= pstrdup(id
->p
, id
->resource
);
170 qmark
= strstr(cur
, "?");
171 if(qmark
== NULL
) return NULL
;
175 x
= _xmlnode_new(id
->p
, cur
, NTYPE_TAG
);
180 eq
= strstr(cur
, "=");
181 if(eq
== NULL
) break;
185 amp
= strstr(eq
, "&");
192 xmlnode_put_attrib(x
,cur
,eq
);
204 int _jid_nullstrcmp(char *a
, char *b
)
206 if(a
== NULL
&& b
== NULL
) return 0;
207 if(a
== NULL
|| b
== NULL
) return -1;
210 int _jid_nullstrcasecmp(char *a
, char *b
)
212 if(a
== NULL
&& b
== NULL
) return 0;
213 if(a
== NULL
|| b
== NULL
) return -1;
214 return strcasecmp(a
,b
);
217 int jid_cmp(jid a
, jid b
)
219 if(a
== NULL
|| b
== NULL
)
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;
229 /* suggested by Anders Qvist <quest@valdez.netg.se> */
230 int jid_cmpx(jid a
, jid b
, int parts
)
232 if(a
== NULL
|| b
== NULL
)
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;
242 /* makes a copy of b in a's pool, requires a valid a first! */
243 jid
jid_append(jid a
, jid b
)
257 if(jid_cmp(next
,b
) == 0)
259 if(next
->next
== NULL
)
260 next
->next
= jid_new(a
->p
,jid_full(b
));
266 xmlnode
jid_nodescan(jid id
, xmlnode x
)
272 if(id
== NULL
|| xmlnode_get_firstchild(x
) == NULL
) return NULL
;
275 for(cur
= xmlnode_get_firstchild(x
); cur
!= NULL
; cur
= xmlnode_get_nextsibling(cur
))
277 if(xmlnode_get_type(cur
) != NTYPE_TAG
) continue;
279 tmp
= jid_new(p
,xmlnode_get_attrib(cur
,"jid"));
280 if(tmp
== NULL
) continue;
282 if(jid_cmp(tmp
,id
) == 0) break;