3127
|
1 /* --------------------------------------------------------------------------
|
|
2 *
|
|
3 * License
|
|
4 *
|
|
5 * The contents of this file are subject to the Jabber Open Source License
|
|
6 * Version 1.0 (the "JOSL"). You may not copy or use this file, in either
|
|
7 * source code or executable form, except in compliance with the JOSL. You
|
|
8 * may obtain a copy of the JOSL at http://www.jabber.org/ or at
|
|
9 * http://www.opensource.org/.
|
|
10 *
|
|
11 * Software distributed under the JOSL is distributed on an "AS IS" basis,
|
|
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the JOSL
|
|
13 * for the specific language governing rights and limitations under the
|
|
14 * JOSL.
|
|
15 *
|
|
16 * Copyrights
|
|
17 *
|
|
18 * Portions created by or assigned to Jabber.com, Inc. are
|
|
19 * Copyright (c) 1999-2002 Jabber.com, Inc. All Rights Reserved. Contact
|
|
20 * information for Jabber.com, Inc. is available at http://www.jabber.com/.
|
2086
|
21 *
|
3127
|
22 * Portions Copyright (c) 1998-1999 Jeremie Miller.
|
|
23 *
|
|
24 * Acknowledgements
|
|
25 *
|
|
26 * Special thanks to the Jabber Open Source Contributors for their
|
|
27 * suggestions and support of Jabber.
|
|
28 *
|
|
29 * Alternatively, the contents of this file may be used under the terms of the
|
|
30 * GNU General Public License Version 2 or later (the "GPL"), in which case
|
|
31 * the provisions of the GPL are applicable instead of those above. If you
|
|
32 * wish to allow use of your version of this file only under the terms of the
|
|
33 * GPL and not to allow others to use your version of this file under the JOSL,
|
|
34 * indicate your decision by deleting the provisions above and replace them
|
|
35 * with the notice and other provisions required by the GPL. If you do not
|
|
36 * delete the provisions above, a recipient may use your version of this file
|
|
37 * under either the JOSL or the GPL.
|
|
38 *
|
|
39 *
|
|
40 * --------------------------------------------------------------------------*/
|
2086
|
41
|
3127
|
42 #include "lib.h"
|
2086
|
43
|
|
44 /* these aren't the most efficient things in the world, a hash optimized for tiny spaces would be far better */
|
|
45
|
|
46 ppdb _ppdb_new(pool p, jid id)
|
|
47 {
|
|
48 ppdb ret;
|
|
49 ret = pmalloc(p,sizeof(_ppdb));
|
|
50 ret->p = p;
|
|
51 ret->pri = -1;
|
|
52 ret->next = NULL;
|
|
53 ret->user = NULL;
|
|
54 ret->x = NULL;
|
|
55 ret->id = jid_new(p,jid_full(id));
|
|
56
|
|
57 return ret;
|
|
58 }
|
|
59
|
|
60 ppdb _ppdb_get(ppdb db, jid id)
|
|
61 {
|
|
62 ppdb cur;
|
|
63
|
|
64 if(db == NULL || id == NULL) return NULL;
|
|
65
|
|
66 for(cur = db->next; cur != NULL; cur = cur->next)
|
|
67 if(jid_cmp(cur->id,id) == 0) return cur;
|
|
68
|
|
69 return NULL;
|
|
70 }
|
|
71
|
|
72 ppdb ppdb_insert(ppdb db, jid id, xmlnode x)
|
|
73 {
|
|
74 ppdb cur, curu;
|
|
75 pool p;
|
|
76
|
|
77 if(id == NULL || id->server == NULL || x == NULL)
|
|
78 return db;
|
|
79
|
|
80 /* new ppdb list dummy holder */
|
|
81 if(db == NULL)
|
|
82 {
|
|
83 p = pool_heap(1024);
|
3127
|
84 db = _ppdb_new(p,NULL);
|
2086
|
85 }
|
|
86
|
|
87 cur = _ppdb_get(db,id);
|
|
88
|
|
89 /* just update it */
|
|
90 if(cur != NULL)
|
|
91 {
|
|
92 xmlnode_free(cur->x);
|
|
93 cur->x = xmlnode_dup(x);
|
|
94 cur->pri = jutil_priority(x);
|
|
95 return db;
|
|
96 }
|
|
97
|
|
98 /* make an entry for it */
|
|
99 cur = _ppdb_new(db->p,id);
|
|
100 cur->x = xmlnode_dup(x);
|
|
101 cur->pri = jutil_priority(x);
|
|
102 cur->next = db->next;
|
|
103 db->next = cur;
|
|
104
|
3127
|
105 /* if this is a user's resource presence, get the the user entry */
|
|
106 if(id->user != NULL && (curu = _ppdb_get(db,jid_user(id))) != cur)
|
2086
|
107 {
|
|
108 /* no user entry, make one */
|
|
109 if(curu == NULL)
|
|
110 {
|
3127
|
111 curu = _ppdb_new(db->p,jid_user(id));
|
2086
|
112 curu->next = db->next;
|
|
113 db->next = curu;
|
|
114 }
|
|
115
|
|
116 /* insert this resource into the user list */
|
|
117 cur->user = curu->user;
|
|
118 curu->user = cur;
|
|
119 }
|
|
120
|
|
121 return db;
|
|
122 }
|
|
123
|
|
124 xmlnode ppdb_primary(ppdb db, jid id)
|
|
125 {
|
|
126 ppdb cur, top;
|
|
127
|
|
128 if(db == NULL || id == NULL) return NULL;
|
|
129
|
|
130 cur = _ppdb_get(db,id);
|
|
131
|
|
132 if(cur == NULL) return NULL;
|
|
133
|
|
134 /* not user@host check, just return */
|
|
135 if(id->user == NULL || id->resource != NULL) return cur->x;
|
|
136
|
|
137 top = cur;
|
|
138 for(cur = cur->user; cur != NULL; cur = cur->user)
|
|
139 if(cur->pri >= top->pri) top = cur;
|
|
140
|
|
141 if(top != NULL && top->pri >= 0) return top->x;
|
|
142
|
|
143 return NULL;
|
|
144 }
|
|
145
|
|
146 /* return the presence for the id, successive calls return all of the known resources for a user@host address */
|
|
147 xmlnode ppdb_get(ppdb db, jid id)
|
|
148 {
|
|
149 static ppdb last = NULL;
|
|
150 ppdb cur;
|
|
151
|
|
152 if(db == NULL || id == NULL) return NULL;
|
|
153
|
|
154 /* MODE: if this is NOT just user@host addy, return just the single entry */
|
|
155 if(id->user == NULL || id->resource != NULL)
|
|
156 {
|
|
157 /* we were just here, return now */
|
|
158 if(last != NULL)
|
|
159 {
|
|
160 last = NULL;
|
|
161 return NULL;
|
|
162 }
|
|
163
|
|
164 last = _ppdb_get(db,id);
|
|
165 if(last != NULL)
|
|
166 return last->x;
|
|
167 else
|
|
168 return NULL;
|
|
169 }
|
|
170
|
|
171 /* handle looping for user@host */
|
|
172
|
|
173 /* we're already in the loop */
|
|
174 if(last != NULL)
|
|
175 {
|
|
176 /* this is the last entry in the list */
|
|
177 if(last->user == NULL)
|
|
178 {
|
|
179 last = NULL;
|
|
180 return NULL;
|
|
181 }
|
|
182
|
|
183 last = last->user;
|
|
184 return last->x;
|
|
185 }
|
|
186
|
|
187 /* start a new loop */
|
|
188 cur = _ppdb_get(db,id);
|
|
189
|
|
190 if(cur == NULL) return NULL;
|
|
191
|
|
192 last = cur->user;
|
|
193 if(last != NULL)
|
|
194 return last->x;
|
|
195 else
|
|
196 return NULL;
|
|
197 }
|
|
198
|
|
199
|
|
200 void ppdb_free(ppdb db)
|
|
201 {
|
|
202 ppdb cur;
|
|
203
|
|
204 if(db == NULL) return;
|
|
205
|
|
206 for(cur = db; cur != NULL; cur = cur->next)
|
|
207 xmlnode_free(cur->x);
|
|
208
|
|
209 pool_free(db->p);
|
|
210 }
|
|
211
|