| |
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 /* these aren't the most efficient things in the world, a hash optimized for tiny spaces would be far better */ |
| |
23 |
| |
24 ppdb _ppdb_new(pool p, jid id) |
| |
25 { |
| |
26 ppdb ret; |
| |
27 ret = pmalloc(p,sizeof(_ppdb)); |
| |
28 ret->p = p; |
| |
29 ret->pri = -1; |
| |
30 ret->next = NULL; |
| |
31 ret->user = NULL; |
| |
32 ret->x = NULL; |
| |
33 ret->id = jid_new(p,jid_full(id)); |
| |
34 |
| |
35 return ret; |
| |
36 } |
| |
37 |
| |
38 ppdb _ppdb_get(ppdb db, jid id) |
| |
39 { |
| |
40 ppdb cur; |
| |
41 |
| |
42 if(db == NULL || id == NULL) return NULL; |
| |
43 |
| |
44 for(cur = db->next; cur != NULL; cur = cur->next) |
| |
45 if(jid_cmp(cur->id,id) == 0) return cur; |
| |
46 |
| |
47 return NULL; |
| |
48 } |
| |
49 |
| |
50 ppdb ppdb_insert(ppdb db, jid id, xmlnode x) |
| |
51 { |
| |
52 char *res; |
| |
53 ppdb cur, curu; |
| |
54 pool p; |
| |
55 |
| |
56 if(id == NULL || id->server == NULL || x == NULL) |
| |
57 return db; |
| |
58 |
| |
59 /* new ppdb list dummy holder */ |
| |
60 if(db == NULL) |
| |
61 { |
| |
62 p = pool_heap(1024); |
| |
63 db = _ppdb_new(p,id); |
| |
64 } |
| |
65 |
| |
66 cur = _ppdb_get(db,id); |
| |
67 |
| |
68 /* just update it */ |
| |
69 if(cur != NULL) |
| |
70 { |
| |
71 xmlnode_free(cur->x); |
| |
72 cur->x = xmlnode_dup(x); |
| |
73 cur->pri = jutil_priority(x); |
| |
74 return db; |
| |
75 } |
| |
76 |
| |
77 /* make an entry for it */ |
| |
78 cur = _ppdb_new(db->p,id); |
| |
79 cur->x = xmlnode_dup(x); |
| |
80 cur->pri = jutil_priority(x); |
| |
81 cur->next = db->next; |
| |
82 db->next = cur; |
| |
83 |
| |
84 /* this is a presence from a resource, make an entry for just the user */ |
| |
85 if(id->user != NULL && id->resource != NULL) |
| |
86 { |
| |
87 /* modify the id to just user@host */ |
| |
88 res = id->resource; |
| |
89 jid_set(id,NULL,JID_RESOURCE); |
| |
90 curu = _ppdb_get(db,id); |
| |
91 |
| |
92 /* no user entry, make one */ |
| |
93 if(curu == NULL) |
| |
94 { |
| |
95 curu = _ppdb_new(db->p,id); |
| |
96 curu->next = db->next; |
| |
97 db->next = curu; |
| |
98 } |
| |
99 |
| |
100 /* restore the id */ |
| |
101 jid_set(id,res,JID_RESOURCE); |
| |
102 |
| |
103 /* insert this resource into the user list */ |
| |
104 cur->user = curu->user; |
| |
105 curu->user = cur; |
| |
106 } |
| |
107 |
| |
108 return db; |
| |
109 } |
| |
110 |
| |
111 xmlnode ppdb_primary(ppdb db, jid id) |
| |
112 { |
| |
113 ppdb cur, top; |
| |
114 |
| |
115 if(db == NULL || id == NULL) return NULL; |
| |
116 |
| |
117 cur = _ppdb_get(db,id); |
| |
118 |
| |
119 if(cur == NULL) return NULL; |
| |
120 |
| |
121 /* not user@host check, just return */ |
| |
122 if(id->user == NULL || id->resource != NULL) return cur->x; |
| |
123 |
| |
124 top = cur; |
| |
125 for(cur = cur->user; cur != NULL; cur = cur->user) |
| |
126 if(cur->pri >= top->pri) top = cur; |
| |
127 |
| |
128 if(top != NULL && top->pri >= 0) return top->x; |
| |
129 |
| |
130 return NULL; |
| |
131 } |
| |
132 |
| |
133 /* return the presence for the id, successive calls return all of the known resources for a user@host address */ |
| |
134 xmlnode ppdb_get(ppdb db, jid id) |
| |
135 { |
| |
136 static ppdb last = NULL; |
| |
137 ppdb cur; |
| |
138 |
| |
139 if(db == NULL || id == NULL) return NULL; |
| |
140 |
| |
141 /* MODE: if this is NOT just user@host addy, return just the single entry */ |
| |
142 if(id->user == NULL || id->resource != NULL) |
| |
143 { |
| |
144 /* we were just here, return now */ |
| |
145 if(last != NULL) |
| |
146 { |
| |
147 last = NULL; |
| |
148 return NULL; |
| |
149 } |
| |
150 |
| |
151 last = _ppdb_get(db,id); |
| |
152 if(last != NULL) |
| |
153 return last->x; |
| |
154 else |
| |
155 return NULL; |
| |
156 } |
| |
157 |
| |
158 /* handle looping for user@host */ |
| |
159 |
| |
160 /* we're already in the loop */ |
| |
161 if(last != NULL) |
| |
162 { |
| |
163 /* this is the last entry in the list */ |
| |
164 if(last->user == NULL) |
| |
165 { |
| |
166 last = NULL; |
| |
167 return NULL; |
| |
168 } |
| |
169 |
| |
170 last = last->user; |
| |
171 return last->x; |
| |
172 } |
| |
173 |
| |
174 /* start a new loop */ |
| |
175 cur = _ppdb_get(db,id); |
| |
176 |
| |
177 if(cur == NULL) return NULL; |
| |
178 |
| |
179 last = cur->user; |
| |
180 if(last != NULL) |
| |
181 return last->x; |
| |
182 else |
| |
183 return NULL; |
| |
184 } |
| |
185 |
| |
186 |
| |
187 void ppdb_free(ppdb db) |
| |
188 { |
| |
189 ppdb cur; |
| |
190 |
| |
191 if(db == NULL) return; |
| |
192 |
| |
193 for(cur = db; cur != NULL; cur = cur->next) |
| |
194 xmlnode_free(cur->x); |
| |
195 |
| |
196 pool_free(db->p); |
| |
197 } |
| |
198 |