Mercurial > ~mikael > mcabber > hg
comparison mcabber/libjabber/jutil.c @ 417:c3ae9251c197
Sync libjabber with upstream
Sync with jabberd-1.4.4.
author | Mikael Berthe <mikael@lilotux.net> |
---|---|
date | Thu, 01 Sep 2005 23:29:21 +0200 |
parents | bf3d6e241714 |
children | f791f5f0cfce |
comparison
equal
deleted
inserted
replaced
416:48e7808c4191 | 417:c3ae9251c197 |
---|---|
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 * 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/. | |
21 * | |
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 */ | |
30 | |
31 /** | |
32 * @file jutil.c | |
33 * @brief various utilities mainly for handling xmlnodes containing stanzas | |
34 */ | |
35 | |
1 #include "jabber.h" | 36 #include "jabber.h" |
2 | 37 |
3 /* util for making presence packets */ | 38 /** |
39 * utility for making presence stanzas | |
40 * | |
41 * @param type the type of the presence (one of the JPACKET__* contants) | |
42 * @param to to whom the presence should be sent, NULL for a broadcast presence | |
43 * @param status optional status (CDATA for the <status/> element, NULL for now <status/> element) | |
44 * @return the xmlnode containing the created presence stanza | |
45 */ | |
4 xmlnode jutil_presnew(int type, char *to, char *status) | 46 xmlnode jutil_presnew(int type, char *to, char *status) |
5 { | 47 { |
6 xmlnode pres; | 48 xmlnode pres; |
7 | 49 |
8 pres = xmlnode_new_tag("presence"); | 50 pres = xmlnode_new_tag("presence"); |
9 switch(type) | 51 switch(type) |
10 { | 52 { |
11 case JPACKET__SUBSCRIBE: | 53 case JPACKET__SUBSCRIBE: |
12 xmlnode_put_attrib(pres,"type","subscribe"); | 54 xmlnode_put_attrib(pres,"type","subscribe"); |
13 break; | 55 break; |
14 case JPACKET__UNSUBSCRIBE: | 56 case JPACKET__UNSUBSCRIBE: |
15 xmlnode_put_attrib(pres,"type","unsubscribe"); | 57 xmlnode_put_attrib(pres,"type","unsubscribe"); |
16 break; | 58 break; |
17 case JPACKET__SUBSCRIBED: | 59 case JPACKET__SUBSCRIBED: |
18 xmlnode_put_attrib(pres,"type","subscribed"); | 60 xmlnode_put_attrib(pres,"type","subscribed"); |
19 break; | 61 break; |
20 case JPACKET__UNSUBSCRIBED: | 62 case JPACKET__UNSUBSCRIBED: |
21 xmlnode_put_attrib(pres,"type","unsubscribed"); | 63 xmlnode_put_attrib(pres,"type","unsubscribed"); |
22 break; | 64 break; |
23 case JPACKET__PROBE: | 65 case JPACKET__PROBE: |
24 xmlnode_put_attrib(pres,"type","probe"); | 66 xmlnode_put_attrib(pres,"type","probe"); |
25 break; | 67 break; |
26 case JPACKET__UNAVAILABLE: | 68 case JPACKET__UNAVAILABLE: |
27 xmlnode_put_attrib(pres,"type","unavailable"); | 69 xmlnode_put_attrib(pres,"type","unavailable"); |
28 break; | 70 break; |
71 case JPACKET__INVISIBLE: | |
72 xmlnode_put_attrib(pres,"type","invisible"); | |
73 break; | |
29 } | 74 } |
30 if(to != NULL) | 75 if(to != NULL) |
31 xmlnode_put_attrib(pres,"to",to); | 76 xmlnode_put_attrib(pres,"to",to); |
32 if(status != NULL) | 77 if(status != NULL) |
33 xmlnode_insert_cdata(xmlnode_insert_tag(pres,"status"),status,strlen(status)); | 78 xmlnode_insert_cdata(xmlnode_insert_tag(pres,"status"),status,strlen(status)); |
34 | 79 |
35 return pres; | 80 return pres; |
36 } | 81 } |
37 | 82 |
38 /* util for making IQ packets */ | 83 /** |
84 * utility for making IQ stanzas, that contain a <query/> element in a different namespace | |
85 * | |
86 * @note In traditional Jabber protocols the element inside an iq element has the name "query". | |
87 * This util is not able to create IQ stanzas that contain a query which a element that does | |
88 * not have the name "query" | |
89 * | |
90 * @param type the type of the iq stanza (one of JPACKET__GET, JPACKET__SET, JPACKET__RESULT, JPACKET__ERROR) | |
91 * @param ns the namespace of the <query/> element | |
92 * @return the created xmlnode | |
93 */ | |
39 xmlnode jutil_iqnew(int type, char *ns) | 94 xmlnode jutil_iqnew(int type, char *ns) |
40 { | 95 { |
41 xmlnode iq; | 96 xmlnode iq; |
42 | 97 |
43 iq = xmlnode_new_tag("iq"); | 98 iq = xmlnode_new_tag("iq"); |
44 switch(type) | 99 switch(type) |
45 { | 100 { |
46 case JPACKET__GET: | 101 case JPACKET__GET: |
47 xmlnode_put_attrib(iq,"type","get"); | 102 xmlnode_put_attrib(iq,"type","get"); |
48 break; | 103 break; |
49 case JPACKET__SET: | 104 case JPACKET__SET: |
50 xmlnode_put_attrib(iq,"type","set"); | 105 xmlnode_put_attrib(iq,"type","set"); |
51 break; | 106 break; |
52 case JPACKET__RESULT: | 107 case JPACKET__RESULT: |
53 xmlnode_put_attrib(iq,"type","result"); | 108 xmlnode_put_attrib(iq,"type","result"); |
54 break; | 109 break; |
55 case JPACKET__ERROR: | 110 case JPACKET__ERROR: |
56 xmlnode_put_attrib(iq,"type","error"); | 111 xmlnode_put_attrib(iq,"type","error"); |
57 break; | 112 break; |
58 } | 113 } |
59 xmlnode_put_attrib(xmlnode_insert_tag(iq,"query"),"xmlns",ns); | 114 xmlnode_put_attrib(xmlnode_insert_tag(iq,"query"),"xmlns",ns); |
60 | 115 |
61 return iq; | 116 return iq; |
62 } | 117 } |
63 | 118 |
64 /* util for making message packets */ | 119 /** |
120 * utility for making message stanzas | |
121 * | |
122 * @param type the type of the message (as a string!) | |
123 * @param to the recipient of the message | |
124 * @param subj the subject of the message (NULL for no subject element) | |
125 * @param body the body of the message | |
126 * @return the xmlnode containing the new message stanza | |
127 */ | |
65 xmlnode jutil_msgnew(char *type, char *to, char *subj, char *body) | 128 xmlnode jutil_msgnew(char *type, char *to, char *subj, char *body) |
66 { | 129 { |
67 xmlnode msg; | 130 xmlnode msg; |
68 | 131 |
69 msg = xmlnode_new_tag("message"); | 132 msg = xmlnode_new_tag("message"); |
70 xmlnode_put_attrib (msg, "type", type); | 133 |
71 xmlnode_put_attrib (msg, "to", to); | 134 if (type != NULL) { |
72 | 135 xmlnode_put_attrib (msg, "type", type); |
73 if (subj) | 136 } |
74 { | 137 |
75 xmlnode_insert_cdata (xmlnode_insert_tag (msg, "subject"), subj, strlen (subj)); | 138 if (to != NULL) { |
76 } | 139 xmlnode_put_attrib (msg, "to", to); |
77 | 140 } |
78 xmlnode_insert_cdata (xmlnode_insert_tag (msg, "body"), body, strlen (body)); | 141 |
142 if (subj != NULL) { | |
143 xmlnode_insert_cdata(xmlnode_insert_tag(msg, "subject"), subj, strlen(subj)); | |
144 } | |
145 | |
146 if (body != NULL) { | |
147 xmlnode_insert_cdata(xmlnode_insert_tag(msg, "body"), body, strlen(body)); | |
148 } | |
79 | 149 |
80 return msg; | 150 return msg; |
81 } | 151 } |
82 | 152 |
83 /* util for making stream packets */ | 153 /** |
154 * utility for making stream packets (containing the stream header element) | |
155 * | |
156 * @param xmlns the default namespace of the stream (e.g. jabber:client or jabber:server) | |
157 * @param server the domain of the server | |
158 * @return the xmlnode containing the root element of the stream | |
159 */ | |
84 xmlnode jutil_header(char* xmlns, char* server) | 160 xmlnode jutil_header(char* xmlns, char* server) |
85 { | 161 { |
86 xmlnode result; | 162 xmlnode result; |
87 if ((xmlns == NULL)||(server == NULL)) | 163 if ((xmlns == NULL)||(server == NULL)) |
88 return NULL; | 164 return NULL; |
92 xmlnode_put_attrib(result, "to", server); | 168 xmlnode_put_attrib(result, "to", server); |
93 | 169 |
94 return result; | 170 return result; |
95 } | 171 } |
96 | 172 |
97 /* returns the priority on a presence packet */ | 173 /** |
174 * returns the priority on an available presence packet | |
175 * | |
176 * @param xmlnode the xmlnode containing the presence packet | |
177 * @return the presence priority, -129 for unavailable presences and errors | |
178 */ | |
98 int jutil_priority(xmlnode x) | 179 int jutil_priority(xmlnode x) |
99 { | 180 { |
100 char *str; | 181 char *str; |
101 int p; | 182 int p; |
102 | 183 |
103 if(x == NULL) | 184 if(x == NULL) |
104 return -1; | 185 return -129; |
105 | 186 |
106 if(xmlnode_get_attrib(x,"type") != NULL) | 187 if(xmlnode_get_attrib(x,"type") != NULL) |
107 return -1; | 188 return -129; |
108 | 189 |
109 x = xmlnode_get_tag(x,"priority"); | 190 x = xmlnode_get_tag(x,"priority"); |
110 if(x == NULL) | 191 if(x == NULL) |
111 return 0; | 192 return 0; |
112 | 193 |
113 str = xmlnode_get_data((x)); | 194 str = xmlnode_get_data((x)); |
114 if(str == NULL) | 195 if(str == NULL) |
115 return 0; | 196 return 0; |
116 | 197 |
117 p = atoi(str); | 198 p = atoi(str); |
118 if(p >= 0) | 199 /* xmpp-im section 2.2.2.3 */ |
119 return p; | 200 return p<-128 ? -128 : p>127 ? 127 : p; |
120 else | 201 } |
121 return 0; | 202 |
122 } | 203 /** |
123 | 204 * reverse sender and destination of a packet |
205 * | |
206 * @param x the xmlnode where sender and receiver should be exchanged | |
207 */ | |
124 void jutil_tofrom(xmlnode x) | 208 void jutil_tofrom(xmlnode x) |
125 { | 209 { |
126 char *to, *from; | 210 char *to, *from; |
127 | 211 |
128 to = xmlnode_get_attrib(x,"to"); | 212 to = xmlnode_get_attrib(x,"to"); |
129 from = xmlnode_get_attrib(x,"from"); | 213 from = xmlnode_get_attrib(x,"from"); |
130 xmlnode_put_attrib(x,"from",to); | 214 xmlnode_put_attrib(x,"from",to); |
131 xmlnode_put_attrib(x,"to",from); | 215 xmlnode_put_attrib(x,"to",from); |
132 } | 216 } |
133 | 217 |
218 /** | |
219 * change and xmlnode to be the result xmlnode for the original iq query | |
220 * | |
221 * @param x the xmlnode that should become the result for itself | |
222 * @return the result xmlnode (same as given as parameter x) | |
223 */ | |
134 xmlnode jutil_iqresult(xmlnode x) | 224 xmlnode jutil_iqresult(xmlnode x) |
135 { | 225 { |
136 xmlnode cur; | 226 xmlnode cur; |
137 | 227 |
138 jutil_tofrom(x); | 228 jutil_tofrom(x); |
139 | 229 |
140 xmlnode_put_attrib(x,"type","result"); | 230 xmlnode_put_attrib(x,"type","result"); |
141 | 231 |
142 /* hide all children of the iq, they go back empty */ | 232 /* hide all children of the iq, they go back empty */ |
143 for(cur = xmlnode_get_firstchild(x); cur != NULL; cur = xmlnode_get_nextsibling(cur)) | 233 for(cur = xmlnode_get_firstchild(x); cur != NULL; cur = xmlnode_get_nextsibling(cur)) |
144 xmlnode_hide(cur); | 234 xmlnode_hide(cur); |
145 | 235 |
146 return x; | 236 return x; |
147 } | 237 } |
148 | 238 |
239 /** | |
240 * get the present time as a textual timestamp in the format YYYYMMDDTHH:MM:SS | |
241 * | |
242 * @note this function is not thread safe | |
243 * | |
244 * @return pointer to a static (!) buffer containing the timestamp (or NULL on failure) | |
245 */ | |
149 char *jutil_timestamp(void) | 246 char *jutil_timestamp(void) |
150 { | 247 { |
151 time_t t; | 248 time_t t; |
152 struct tm *new_time; | 249 struct tm *new_time; |
153 static char timestamp[18]; | 250 static char timestamp[18]; |
154 int ret; | 251 int ret; |
155 | 252 |
156 t = time(NULL); | 253 t = time(NULL); |
157 | 254 |
158 if(t == (time_t)-1) | 255 if(t == (time_t)-1) |
159 return NULL; | 256 return NULL; |
160 new_time = gmtime(&t); | 257 new_time = gmtime(&t); |
161 | 258 |
162 ret = snprintf(timestamp, 18, "%d%02d%02dT%02d:%02d:%02d", 1900+new_time->tm_year, | 259 ret = snprintf(timestamp, 18, "%d%02d%02dT%02d:%02d:%02d", 1900+new_time->tm_year, |
163 new_time->tm_mon+1, new_time->tm_mday, new_time->tm_hour, | 260 new_time->tm_mon+1, new_time->tm_mday, new_time->tm_hour, |
164 new_time->tm_min, new_time->tm_sec); | 261 new_time->tm_min, new_time->tm_sec); |
165 | 262 |
166 if(ret == -1) | 263 if(ret == -1) |
167 return NULL; | 264 return NULL; |
168 | 265 |
169 return timestamp; | 266 return timestamp; |
170 } | 267 } |
171 | 268 |
172 void jutil_error(xmlnode x, terror E) | 269 /** |
270 * map a terror structure to a xterror structure | |
271 * | |
272 * terror structures have been used in jabberd14 up to version 1.4.3 but | |
273 * are not able to hold XMPP compliant stanza errors. The xterror | |
274 * structure has been introduced to be XMPP compliant. This function | |
275 * is to ease writting wrappers that accept terror structures and call | |
276 * the real functions that require now xterror structures | |
277 * | |
278 * @param old the terror struct that should be converted | |
279 * @param mapped pointer to the xterror struct that should be filled with the converted error | |
280 */ | |
281 void jutil_error_map(terror old, xterror *mapped) | |
282 { | |
283 mapped->code = old.code; | |
284 if (old.msg == NULL) | |
285 mapped->msg[0] = 0; | |
286 else | |
287 strncpy(mapped->msg, old.msg, sizeof(mapped->msg)); | |
288 | |
289 switch (old.code) | |
290 { | |
291 case 302: | |
292 strcpy(mapped->type, "modify"); | |
293 strcpy(mapped->condition, "redirect"); | |
294 break; | |
295 case 400: | |
296 strcpy(mapped->type, "modify"); | |
297 strcpy(mapped->condition, "bad-request"); | |
298 break; | |
299 case 401: | |
300 strcpy(mapped->type, "auth"); | |
301 strcpy(mapped->condition, "not-authorized"); | |
302 break; | |
303 case 402: | |
304 strcpy(mapped->type, "auth"); | |
305 strcpy(mapped->condition, "payment-required"); | |
306 break; | |
307 case 403: | |
308 strcpy(mapped->type, "auth"); | |
309 strcpy(mapped->condition, "forbidden"); | |
310 break; | |
311 case 404: | |
312 strcpy(mapped->type, "cancel"); | |
313 strcpy(mapped->condition, "item-not-found"); | |
314 break; | |
315 case 405: | |
316 strcpy(mapped->type, "cancel"); | |
317 strcpy(mapped->condition, "not-allowed"); | |
318 break; | |
319 case 406: | |
320 strcpy(mapped->type, "modify"); | |
321 strcpy(mapped->condition, "not-acceptable"); | |
322 break; | |
323 case 407: | |
324 strcpy(mapped->type, "auth"); | |
325 strcpy(mapped->condition, "registration-requited"); | |
326 break; | |
327 case 408: | |
328 strcpy(mapped->type, "wait"); | |
329 strcpy(mapped->condition, "remote-server-timeout"); | |
330 break; | |
331 case 409: | |
332 strcpy(mapped->type, "cancel"); | |
333 strcpy(mapped->condition, "conflict"); | |
334 break; | |
335 case 500: | |
336 strcpy(mapped->type, "wait"); | |
337 strcpy(mapped->condition, "internal-server-error"); | |
338 break; | |
339 case 501: | |
340 strcpy(mapped->type, "cancel"); | |
341 strcpy(mapped->condition, "feature-not-implemented"); | |
342 break; | |
343 case 502: | |
344 strcpy(mapped->type, "wait"); | |
345 strcpy(mapped->condition, "service-unavailable"); | |
346 break; | |
347 case 503: | |
348 strcpy(mapped->type, "cancel"); | |
349 strcpy(mapped->condition, "service-unavailable"); | |
350 break; | |
351 case 504: | |
352 strcpy(mapped->type, "wait"); | |
353 strcpy(mapped->condition, "remote-server-timeout"); | |
354 break; | |
355 case 510: | |
356 strcpy(mapped->type, "cancel"); | |
357 strcpy(mapped->condition, "service-unavailable"); | |
358 break; | |
359 default: | |
360 strcpy(mapped->type, "wait"); | |
361 strcpy(mapped->condition, "undefined-condition"); | |
362 } | |
363 } | |
364 | |
365 /** | |
366 * update an xmlnode to be the error stanza for itself | |
367 * | |
368 * @param x the xmlnode that should become an stanza error message | |
369 * @param E the structure that holds the error information | |
370 */ | |
371 void jutil_error_xmpp(xmlnode x, xterror E) | |
173 { | 372 { |
174 xmlnode err; | 373 xmlnode err; |
175 char code[4]; | 374 char code[4]; |
176 | 375 |
177 xmlnode_put_attrib(x,"type","error"); | 376 xmlnode_put_attrib(x, "type", "error"); |
178 err = xmlnode_insert_tag(x,"error"); | 377 err = xmlnode_insert_tag(x, "error"); |
179 | 378 |
180 snprintf(code,4,"%d",E.code); | 379 snprintf(code, sizeof(code), "%d", E.code); |
181 xmlnode_put_attrib(err,"code",code); | 380 xmlnode_put_attrib(err, "code", code); |
182 if(E.msg != NULL) | 381 if (E.type != NULL) |
183 xmlnode_insert_cdata(err,E.msg,strlen(E.msg)); | 382 xmlnode_put_attrib(err, "type", E.type); |
383 if (E.condition != NULL) | |
384 xmlnode_put_attrib(xmlnode_insert_tag(err, E.condition), "xmlns", NS_XMPP_STANZAS); | |
385 if (E.msg != NULL) | |
386 { | |
387 xmlnode text; | |
388 text = xmlnode_insert_tag(err, "text"); | |
389 xmlnode_put_attrib(text, "xmlns", NS_XMPP_STANZAS); | |
390 xmlnode_insert_cdata(text, E.msg, strlen(E.msg)); | |
391 } | |
184 | 392 |
185 jutil_tofrom(x); | 393 jutil_tofrom(x); |
186 } | 394 } |
187 | 395 |
396 /** | |
397 * wrapper around jutil_error_xmpp for compatibility with modules for jabberd up to version 1.4.3 | |
398 * | |
399 * @deprecated use jutil_error_xmpp instead! | |
400 * | |
401 * @param x the xmlnode that should become an stanza error message | |
402 * @param E the strucutre that holds the error information | |
403 */ | |
404 void jutil_error(xmlnode x, terror E) | |
405 { | |
406 xterror xE; | |
407 jutil_error_map(E, &xE); | |
408 jutil_error_xmpp(x, xE); | |
409 } | |
410 | |
411 /** | |
412 * add a delayed delivery (JEP-0091) element to a message using the | |
413 * present timestamp. | |
414 * If a reason is given, this reason will be added as CDATA to the | |
415 * inserted element | |
416 * | |
417 * @param msg the message where the element should be added | |
418 * @param reason plain text information why the delayed delivery information has been added | |
419 */ | |
188 void jutil_delay(xmlnode msg, char *reason) | 420 void jutil_delay(xmlnode msg, char *reason) |
189 { | 421 { |
190 xmlnode delay; | 422 xmlnode delay; |
191 | 423 |
192 delay = xmlnode_insert_tag(msg,"x"); | 424 delay = xmlnode_insert_tag(msg,"x"); |
193 xmlnode_put_attrib(delay,"xmlns",NS_DELAY); | 425 xmlnode_put_attrib(delay,"xmlns",NS_DELAY); |
194 xmlnode_put_attrib(delay,"from",xmlnode_get_attrib(msg,"to")); | 426 xmlnode_put_attrib(delay,"from",xmlnode_get_attrib(msg,"to")); |
195 xmlnode_put_attrib(delay,"stamp",jutil_timestamp()); | 427 xmlnode_put_attrib(delay,"stamp",jutil_timestamp()); |
196 if(reason != NULL) | 428 if(reason != NULL) |
197 xmlnode_insert_cdata(delay,reason,strlen(reason)); | 429 xmlnode_insert_cdata(delay,reason,strlen(reason)); |
198 } | 430 } |
199 | 431 |
200 #define KEYBUF 100 | 432 #define KEYBUF 100 |
201 | 433 |
434 /** | |
435 * create or validate a key value for stone-age jabber protocols | |
436 * | |
437 * Before dialback had been introduced for s2s (and therefore only in jabberd 1.0), | |
438 * Jabber used these keys to protect some iq requests. A client first had to | |
439 * request a key with a IQ get and use it inside the IQ set request. By being able | |
440 * to receive the key in the IQ get response, the client (more or less) proved to be | |
441 * who he claimed to be. | |
442 * | |
443 * The implementation of this function uses a static array with KEYBUF entries (default | |
444 * value of KEYBUF is 100). Therefore a key gets invalid at the 100th key that is created | |
445 * afterwards. It is also invalidated after it has been validated once. | |
446 * | |
447 * @deprecated This function is not really used anymore. jabberd14 does not check any | |
448 * keys anymore and only creates them in the jsm's mod_register.c for compatibility. This | |
449 * function is also used in mod_groups.c and the key is even checked there, but I do not | |
450 * know if mod_groups.c still works at all. | |
451 * | |
452 * @param key for validation the key the client sent, for generation of a new key NULL | |
453 * @param seed the seed for generating the key, must stay the same for the same user | |
454 * @return the new key when created, the key if the key has been validated, NULL if the key is invalid | |
455 */ | |
202 char *jutil_regkey(char *key, char *seed) | 456 char *jutil_regkey(char *key, char *seed) |
203 { | 457 { |
204 static char keydb[KEYBUF][41]; | 458 static char keydb[KEYBUF][41]; |
205 static char seeddb[KEYBUF][41]; | 459 static char seeddb[KEYBUF][41]; |
206 static int last = -1; | 460 static int last = -1; |
208 int i; | 462 int i; |
209 | 463 |
210 /* blanket the keydb first time */ | 464 /* blanket the keydb first time */ |
211 if(last == -1) | 465 if(last == -1) |
212 { | 466 { |
213 last = 0; | 467 last = 0; |
214 memset(&keydb,0,KEYBUF*41); | 468 memset(&keydb,0,KEYBUF*41); |
215 memset(&seeddb,0,KEYBUF*41); | 469 memset(&seeddb,0,KEYBUF*41); |
216 srand(time(NULL)); | 470 srand(time(NULL)); |
217 } | 471 } |
218 | 472 |
219 /* creation phase */ | 473 /* creation phase */ |
220 if(key == NULL && seed != NULL) | 474 if(key == NULL && seed != NULL) |
221 { | 475 { |
222 /* create a random key hash and store it */ | 476 /* create a random key hash and store it */ |
223 sprintf(strint,"%d",rand()); | 477 sprintf(strint,"%d",rand()); |
224 strcpy(keydb[last],shahash(strint)); | 478 strcpy(keydb[last],shahash(strint)); |
225 | 479 |
226 /* store a hash for the seed associated w/ this key */ | 480 /* store a hash for the seed associated w/ this key */ |
227 strcpy(seeddb[last],shahash(seed)); | 481 strcpy(seeddb[last],shahash(seed)); |
228 | 482 |
229 /* return it all */ | 483 /* return it all */ |
230 str = keydb[last]; | 484 str = keydb[last]; |
231 last++; | 485 last++; |
232 if(last == KEYBUF) last = 0; | 486 if(last == KEYBUF) last = 0; |
233 return str; | 487 return str; |
234 } | 488 } |
235 | 489 |
236 /* validation phase */ | 490 /* validation phase */ |
237 str = shahash(seed); | 491 str = shahash(seed); |
238 for(i=0;i<KEYBUF;i++) | 492 for(i=0;i<KEYBUF;i++) |
239 if(j_strcmp(keydb[i],key) == 0 && j_strcmp(seeddb[i],str) == 0) | 493 if(j_strcmp(keydb[i],key) == 0 && j_strcmp(seeddb[i],str) == 0) |
240 { | 494 { |
241 seeddb[i][0] = '\0'; /* invalidate this key */ | 495 seeddb[i][0] = '\0'; /* invalidate this key */ |
242 return keydb[i]; | 496 return keydb[i]; |
243 } | 497 } |
244 | 498 |
245 return NULL; | 499 return NULL; |
246 } | 500 } |
247 | 501 |