| |
1 |
| |
2 /* |
| |
3 Meanwhile - Unofficial Lotus Sametime Community Client Library |
| |
4 Copyright (C) 2004 Christopher (siege) O'Brien |
| |
5 |
| |
6 This library is free software; you can redistribute it and/or |
| |
7 modify it under the terms of the GNU Library General Public |
| |
8 License as published by the Free Software Foundation; either |
| |
9 version 2 of the License, or (at your option) any later version. |
| |
10 |
| |
11 This library is distributed in the hope that it will be useful, |
| |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of |
| |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| |
14 Library General Public License for more details. |
| |
15 |
| |
16 You should have received a copy of the GNU Library General Public |
| |
17 License along with this library; if not, write to the Free |
| |
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| |
19 */ |
| |
20 |
| |
21 #include <glib.h> |
| |
22 #include <string.h> |
| |
23 |
| |
24 #include "mw_common.h" |
| |
25 |
| |
26 |
| |
27 /** @todo the *_get functions should make sure to clear their |
| |
28 structures in the event of failure, to prevent memory leaks */ |
| |
29 |
| |
30 |
| |
31 #define MW16_PUT(b, val) \ |
| |
32 *(b)++ = ((val) >> 0x08) & 0xff; \ |
| |
33 *(b)++ = (val) & 0xff; |
| |
34 |
| |
35 |
| |
36 #define MW16_GET(b, val) \ |
| |
37 val = (*(b)++ & 0xff) << 8; \ |
| |
38 val = val | (*(b)++ & 0xff); |
| |
39 |
| |
40 |
| |
41 #define MW32_PUT(b, val) \ |
| |
42 *(b)++ = ((val) >> 0x18) & 0xff; \ |
| |
43 *(b)++ = ((val) >> 0x10) & 0xff; \ |
| |
44 *(b)++ = ((val) >> 0x08) & 0xff; \ |
| |
45 *(b)++ = (val) & 0xff; |
| |
46 |
| |
47 |
| |
48 #define MW32_GET(b, val) \ |
| |
49 val = (*(b)++ & 0xff) << 0x18; \ |
| |
50 val = val | (*(b)++ & 0xff) << 0x10; \ |
| |
51 val = val | (*(b)++ & 0xff) << 0x08; \ |
| |
52 val = val | (*(b)++ & 0xff); |
| |
53 |
| |
54 |
| |
55 struct mwPutBuffer { |
| |
56 char *buf; /**< head of buffer */ |
| |
57 gsize len; /**< length of buffer */ |
| |
58 |
| |
59 char *ptr; /**< offset to first unused byte */ |
| |
60 gsize rem; /**< count of unused bytes remaining */ |
| |
61 }; |
| |
62 |
| |
63 |
| |
64 struct mwGetBuffer { |
| |
65 char *buf; /**< head of buffer */ |
| |
66 gsize len; /**< length of buffer */ |
| |
67 |
| |
68 char *ptr; /**< offset to first unused byte */ |
| |
69 gsize rem; /**< count of unused bytes remaining */ |
| |
70 |
| |
71 gboolean wrap; /**< TRUE to indicate buf shouldn't be freed */ |
| |
72 gboolean error; /**< TRUE to indicate an error */ |
| |
73 }; |
| |
74 |
| |
75 |
| |
76 #define BUFFER_USED(buffer) \ |
| |
77 ((buffer)->len - (buffer)->rem) |
| |
78 |
| |
79 |
| |
80 /** ensure that there's at least enough space remaining in the put |
| |
81 buffer to fit needed. */ |
| |
82 static void ensure_buffer(struct mwPutBuffer *b, gsize needed) { |
| |
83 if(b->rem < needed) { |
| |
84 gsize len = b->len, use = BUFFER_USED(b); |
| |
85 char *buf; |
| |
86 |
| |
87 /* newly created buffers are empty until written to, and then they |
| |
88 have 1024 available */ |
| |
89 if(! len) len = 1024; |
| |
90 |
| |
91 /* double len until it's large enough to fit needed */ |
| |
92 while( (len - use) < needed ) len = len << 1; |
| |
93 |
| |
94 /* create the new buffer. if there was anything in the old buffer, |
| |
95 copy it into the new buffer and free the old copy */ |
| |
96 buf = g_malloc(len); |
| |
97 if(b->buf) { |
| |
98 memcpy(buf, b->buf, use); |
| |
99 g_free(b->buf); |
| |
100 } |
| |
101 |
| |
102 /* put the new buffer into b */ |
| |
103 b->buf = buf; |
| |
104 b->len = len; |
| |
105 b->ptr = buf + use; |
| |
106 b->rem = len - use; |
| |
107 } |
| |
108 } |
| |
109 |
| |
110 |
| |
111 /** determine if there are at least needed bytes available in the |
| |
112 buffer. sets the error flag if there's not at least needed bytes |
| |
113 left in the buffer |
| |
114 |
| |
115 @returns true if there's enough data, false if not */ |
| |
116 static gboolean check_buffer(struct mwGetBuffer *b, gsize needed) { |
| |
117 if(! b->error) b->error = (b->rem < needed); |
| |
118 return ! b->error; |
| |
119 } |
| |
120 |
| |
121 |
| |
122 struct mwPutBuffer *mwPutBuffer_new() { |
| |
123 return g_new0(struct mwPutBuffer, 1); |
| |
124 } |
| |
125 |
| |
126 |
| |
127 void mwPutBuffer_write(struct mwPutBuffer *b, gpointer data, gsize len) { |
| |
128 g_return_if_fail(b != NULL); |
| |
129 g_return_if_fail(data != NULL); |
| |
130 |
| |
131 if(! len) return; |
| |
132 |
| |
133 ensure_buffer(b, len); |
| |
134 memcpy(b->ptr, data, len); |
| |
135 b->ptr += len; |
| |
136 b->rem -= len; |
| |
137 } |
| |
138 |
| |
139 |
| |
140 void mwPutBuffer_free(struct mwPutBuffer *b) { |
| |
141 if(! b) return; |
| |
142 g_free(b->buf); |
| |
143 g_free(b); |
| |
144 } |
| |
145 |
| |
146 |
| |
147 void mwPutBuffer_finalize(struct mwOpaque *to, struct mwPutBuffer *from) { |
| |
148 g_return_if_fail(to != NULL); |
| |
149 g_return_if_fail(from != NULL); |
| |
150 |
| |
151 to->len = BUFFER_USED(from); |
| |
152 to->data = from->buf; |
| |
153 |
| |
154 g_free(from); |
| |
155 } |
| |
156 |
| |
157 |
| |
158 struct mwGetBuffer *mwGetBuffer_new(struct mwOpaque *o) { |
| |
159 struct mwGetBuffer *b = g_new0(struct mwGetBuffer, 1); |
| |
160 |
| |
161 if(o && o->len) { |
| |
162 b->buf = b->ptr = g_memdup(o->data, o->len); |
| |
163 b->len = b->rem = o->len; |
| |
164 } |
| |
165 |
| |
166 return b; |
| |
167 } |
| |
168 |
| |
169 |
| |
170 struct mwGetBuffer *mwGetBuffer_wrap(const struct mwOpaque *o) { |
| |
171 struct mwGetBuffer *b = g_new0(struct mwGetBuffer, 1); |
| |
172 |
| |
173 if(o && o->len) { |
| |
174 b->buf = b->ptr = (char *) o->data; |
| |
175 b->len = b->rem = o->len; |
| |
176 } |
| |
177 b->wrap = TRUE; |
| |
178 |
| |
179 return b; |
| |
180 } |
| |
181 |
| |
182 |
| |
183 gsize mwGetBuffer_read(struct mwGetBuffer *b, gpointer data, gsize len) { |
| |
184 g_return_val_if_fail(b != NULL, 0); |
| |
185 g_return_val_if_fail(data != NULL, 0); |
| |
186 |
| |
187 if(b->error) return 0; |
| |
188 if(! len) return 0; |
| |
189 |
| |
190 if(b->rem < len) |
| |
191 len = b->rem; |
| |
192 |
| |
193 memcpy(data, b->ptr, len); |
| |
194 b->ptr += len; |
| |
195 b->rem -= len; |
| |
196 |
| |
197 return len; |
| |
198 } |
| |
199 |
| |
200 |
| |
201 gsize mwGetBuffer_advance(struct mwGetBuffer *b, gsize len) { |
| |
202 g_return_val_if_fail(b != NULL, 0); |
| |
203 |
| |
204 if(b->error) return 0; |
| |
205 if(! len) return 0; |
| |
206 |
| |
207 if(b->rem < len) |
| |
208 len = b->rem; |
| |
209 |
| |
210 b->ptr += len; |
| |
211 b->rem -= len; |
| |
212 |
| |
213 return len; |
| |
214 } |
| |
215 |
| |
216 |
| |
217 void mwGetBuffer_reset(struct mwGetBuffer *b) { |
| |
218 g_return_if_fail(b != NULL); |
| |
219 |
| |
220 b->rem = b->len; |
| |
221 b->ptr = b->buf; |
| |
222 b->error = FALSE; |
| |
223 } |
| |
224 |
| |
225 |
| |
226 gsize mwGetBuffer_remaining(struct mwGetBuffer *b) { |
| |
227 g_return_val_if_fail(b != NULL, 0); |
| |
228 return b->rem; |
| |
229 } |
| |
230 |
| |
231 |
| |
232 gboolean mwGetBuffer_error(struct mwGetBuffer *b) { |
| |
233 g_return_val_if_fail(b != NULL, TRUE); |
| |
234 return b->error; |
| |
235 } |
| |
236 |
| |
237 |
| |
238 void mwGetBuffer_free(struct mwGetBuffer *b) { |
| |
239 if(! b) return; |
| |
240 if(! b->wrap) g_free(b->buf); |
| |
241 g_free(b); |
| |
242 } |
| |
243 |
| |
244 |
| |
245 #define guint16_buflen() 2 |
| |
246 |
| |
247 |
| |
248 void guint16_put(struct mwPutBuffer *b, guint16 val) { |
| |
249 g_return_if_fail(b != NULL); |
| |
250 |
| |
251 ensure_buffer(b, guint16_buflen()); |
| |
252 MW16_PUT(b->ptr, val); |
| |
253 b->rem -= guint16_buflen(); |
| |
254 } |
| |
255 |
| |
256 |
| |
257 void guint16_get(struct mwGetBuffer *b, guint16 *val) { |
| |
258 g_return_if_fail(b != NULL); |
| |
259 |
| |
260 if(b->error) return; |
| |
261 g_return_if_fail(check_buffer(b, guint16_buflen())); |
| |
262 |
| |
263 MW16_GET(b->ptr, *val); |
| |
264 b->rem -= guint16_buflen(); |
| |
265 } |
| |
266 |
| |
267 |
| |
268 guint16 guint16_peek(struct mwGetBuffer *b) { |
| |
269 char *buf = b->buf; |
| |
270 guint16 r = 0; |
| |
271 |
| |
272 if(b->rem >= guint16_buflen()) |
| |
273 MW16_GET(buf, r); |
| |
274 |
| |
275 return r; |
| |
276 } |
| |
277 |
| |
278 |
| |
279 #define guint32_buflen() 4 |
| |
280 |
| |
281 |
| |
282 void guint32_put(struct mwPutBuffer *b, guint32 val) { |
| |
283 g_return_if_fail(b != NULL); |
| |
284 |
| |
285 ensure_buffer(b, guint32_buflen()); |
| |
286 MW32_PUT(b->ptr, val); |
| |
287 b->rem -= guint32_buflen(); |
| |
288 } |
| |
289 |
| |
290 |
| |
291 void guint32_get(struct mwGetBuffer *b, guint32 *val) { |
| |
292 g_return_if_fail(b != NULL); |
| |
293 |
| |
294 if(b->error) return; |
| |
295 g_return_if_fail(check_buffer(b, guint32_buflen())); |
| |
296 |
| |
297 MW32_GET(b->ptr, *val); |
| |
298 b->rem -= guint32_buflen(); |
| |
299 } |
| |
300 |
| |
301 |
| |
302 guint32 guint32_peek(struct mwGetBuffer *b) { |
| |
303 char *buf = b->buf; |
| |
304 guint32 r = 0; |
| |
305 |
| |
306 if(b->rem >= guint32_buflen()) |
| |
307 MW32_GET(buf, r); |
| |
308 |
| |
309 return r; |
| |
310 } |
| |
311 |
| |
312 |
| |
313 #define gboolean_buflen() 1 |
| |
314 |
| |
315 |
| |
316 void gboolean_put(struct mwPutBuffer *b, gboolean val) { |
| |
317 g_return_if_fail(b != NULL); |
| |
318 |
| |
319 ensure_buffer(b, gboolean_buflen()); |
| |
320 *(b->ptr) = !! val; |
| |
321 b->ptr++; |
| |
322 b->rem--; |
| |
323 } |
| |
324 |
| |
325 |
| |
326 void gboolean_get(struct mwGetBuffer *b, gboolean *val) { |
| |
327 g_return_if_fail(b != NULL); |
| |
328 |
| |
329 if(b->error) return; |
| |
330 g_return_if_fail(check_buffer(b, gboolean_buflen())); |
| |
331 |
| |
332 *val = !! *(b->ptr); |
| |
333 b->ptr++; |
| |
334 b->rem--; |
| |
335 } |
| |
336 |
| |
337 |
| |
338 gboolean gboolean_peek(struct mwGetBuffer *b) { |
| |
339 gboolean v = FALSE; |
| |
340 |
| |
341 if(b->rem >= gboolean_buflen()) |
| |
342 v = !! *(b->ptr); |
| |
343 |
| |
344 return v; |
| |
345 } |
| |
346 |
| |
347 |
| |
348 gboolean mw_streq(const char *a, const char *b) { |
| |
349 return (a == b) || (a && b && !strcmp(a, b)); |
| |
350 } |
| |
351 |
| |
352 |
| |
353 void mwString_put(struct mwPutBuffer *b, const char *val) { |
| |
354 gsize len = 0; |
| |
355 |
| |
356 g_return_if_fail(b != NULL); |
| |
357 |
| |
358 if(val) len = strlen(val); |
| |
359 |
| |
360 guint16_put(b, (guint16) len); |
| |
361 |
| |
362 if(len) { |
| |
363 ensure_buffer(b, len); |
| |
364 memcpy(b->ptr, val, len); |
| |
365 b->ptr += len; |
| |
366 b->rem -= len; |
| |
367 } |
| |
368 } |
| |
369 |
| |
370 |
| |
371 void mwString_get(struct mwGetBuffer *b, char **val) { |
| |
372 guint16 len = 0; |
| |
373 |
| |
374 g_return_if_fail(b != NULL); |
| |
375 g_return_if_fail(val != NULL); |
| |
376 |
| |
377 *val = NULL; |
| |
378 |
| |
379 if(b->error) return; |
| |
380 guint16_get(b, &len); |
| |
381 |
| |
382 g_return_if_fail(check_buffer(b, (gsize) len)); |
| |
383 |
| |
384 if(len) { |
| |
385 *val = g_malloc0(len + 1); |
| |
386 memcpy(*val, b->ptr, len); |
| |
387 b->ptr += len; |
| |
388 b->rem -= len; |
| |
389 } |
| |
390 } |
| |
391 |
| |
392 |
| |
393 void mwOpaque_put(struct mwPutBuffer *b, const struct mwOpaque *o) { |
| |
394 gsize len; |
| |
395 |
| |
396 g_return_if_fail(b != NULL); |
| |
397 |
| |
398 if(! o) { |
| |
399 guint32_put(b, 0x00); |
| |
400 return; |
| |
401 } |
| |
402 |
| |
403 len = o->len; |
| |
404 if(len) |
| |
405 g_return_if_fail(o->data != NULL); |
| |
406 |
| |
407 guint32_put(b, (guint32) len); |
| |
408 |
| |
409 if(len) { |
| |
410 ensure_buffer(b, len); |
| |
411 memcpy(b->ptr, o->data, len); |
| |
412 b->ptr += len; |
| |
413 b->rem -= len; |
| |
414 } |
| |
415 } |
| |
416 |
| |
417 |
| |
418 void mwOpaque_get(struct mwGetBuffer *b, struct mwOpaque *o) { |
| |
419 guint32 tmp = 0; |
| |
420 |
| |
421 g_return_if_fail(b != NULL); |
| |
422 g_return_if_fail(o != NULL); |
| |
423 |
| |
424 o->len = 0; |
| |
425 o->data = NULL; |
| |
426 |
| |
427 if(b->error) return; |
| |
428 guint32_get(b, &tmp); |
| |
429 |
| |
430 g_return_if_fail(check_buffer(b, (gsize) tmp)); |
| |
431 |
| |
432 o->len = (gsize) tmp; |
| |
433 if(tmp > 0) { |
| |
434 o->data = g_memdup(b->ptr, tmp); |
| |
435 b->ptr += tmp; |
| |
436 b->rem -= tmp; |
| |
437 } |
| |
438 } |
| |
439 |
| |
440 |
| |
441 void mwOpaque_clear(struct mwOpaque *o) { |
| |
442 if(! o) return; |
| |
443 g_free(o->data); |
| |
444 o->data = NULL; |
| |
445 o->len = 0; |
| |
446 } |
| |
447 |
| |
448 |
| |
449 void mwOpaque_free(struct mwOpaque *o) { |
| |
450 if(! o) return; |
| |
451 g_free(o->data); |
| |
452 g_free(o); |
| |
453 } |
| |
454 |
| |
455 |
| |
456 void mwOpaque_clone(struct mwOpaque *to, const struct mwOpaque *from) { |
| |
457 g_return_if_fail(to != NULL); |
| |
458 |
| |
459 to->len = 0; |
| |
460 to->data = NULL; |
| |
461 |
| |
462 if(from) { |
| |
463 to->len = from->len; |
| |
464 if(to->len) |
| |
465 to->data = g_memdup(from->data, to->len); |
| |
466 } |
| |
467 } |
| |
468 |
| |
469 |
| |
470 /* 8.2 Common Structures */ |
| |
471 /* 8.2.1 Login Info block */ |
| |
472 |
| |
473 |
| |
474 void mwLoginInfo_put(struct mwPutBuffer *b, const struct mwLoginInfo *login) { |
| |
475 g_return_if_fail(b != NULL); |
| |
476 g_return_if_fail(login != NULL); |
| |
477 |
| |
478 mwString_put(b, login->login_id); |
| |
479 guint16_put(b, login->type); |
| |
480 mwString_put(b, login->user_id); |
| |
481 mwString_put(b, login->user_name); |
| |
482 mwString_put(b, login->community); |
| |
483 gboolean_put(b, login->full); |
| |
484 |
| |
485 if(login->full) { |
| |
486 mwString_put(b, login->desc); |
| |
487 guint32_put(b, login->ip_addr); |
| |
488 mwString_put(b, login->server_id); |
| |
489 } |
| |
490 } |
| |
491 |
| |
492 |
| |
493 void mwLoginInfo_get(struct mwGetBuffer *b, struct mwLoginInfo *login) { |
| |
494 g_return_if_fail(b != NULL); |
| |
495 g_return_if_fail(login != NULL); |
| |
496 |
| |
497 if(b->error) return; |
| |
498 |
| |
499 mwString_get(b, &login->login_id); |
| |
500 guint16_get(b, &login->type); |
| |
501 mwString_get(b, &login->user_id); |
| |
502 mwString_get(b, &login->user_name); |
| |
503 mwString_get(b, &login->community); |
| |
504 gboolean_get(b, &login->full); |
| |
505 |
| |
506 if(login->full) { |
| |
507 mwString_get(b, &login->desc); |
| |
508 guint32_get(b, &login->ip_addr); |
| |
509 mwString_get(b, &login->server_id); |
| |
510 } |
| |
511 } |
| |
512 |
| |
513 |
| |
514 void mwLoginInfo_clear(struct mwLoginInfo *login) { |
| |
515 if(! login) return; |
| |
516 |
| |
517 g_free(login->login_id); |
| |
518 g_free(login->user_id); |
| |
519 g_free(login->user_name); |
| |
520 g_free(login->community); |
| |
521 g_free(login->desc); |
| |
522 g_free(login->server_id); |
| |
523 |
| |
524 memset(login, 0x00, sizeof(struct mwLoginInfo)); |
| |
525 } |
| |
526 |
| |
527 |
| |
528 void mwLoginInfo_clone(struct mwLoginInfo *to, |
| |
529 const struct mwLoginInfo *from) { |
| |
530 |
| |
531 g_return_if_fail(to != NULL); |
| |
532 g_return_if_fail(from != NULL); |
| |
533 |
| |
534 to->login_id= g_strdup(from->login_id); |
| |
535 to->type = from->type; |
| |
536 to->user_id = g_strdup(from->user_id); |
| |
537 to->user_name = g_strdup(from->user_name); |
| |
538 to->community = g_strdup(from->community); |
| |
539 |
| |
540 if( (to->full = from->full) ) { |
| |
541 to->desc = g_strdup(from->desc); |
| |
542 to->ip_addr = from->ip_addr; |
| |
543 to->server_id = g_strdup(from->server_id); |
| |
544 } |
| |
545 } |
| |
546 |
| |
547 |
| |
548 /* 8.2.2 Private Info Block */ |
| |
549 |
| |
550 |
| |
551 void mwUserItem_put(struct mwPutBuffer *b, const struct mwUserItem *user) { |
| |
552 g_return_if_fail(b != NULL); |
| |
553 g_return_if_fail(user != NULL); |
| |
554 |
| |
555 gboolean_put(b, user->full); |
| |
556 mwString_put(b, user->id); |
| |
557 mwString_put(b, user->community); |
| |
558 |
| |
559 if(user->full) |
| |
560 mwString_put(b, user->name); |
| |
561 } |
| |
562 |
| |
563 |
| |
564 void mwUserItem_get(struct mwGetBuffer *b, struct mwUserItem *user) { |
| |
565 g_return_if_fail(b != NULL); |
| |
566 g_return_if_fail(user != NULL); |
| |
567 |
| |
568 if(b->error) return; |
| |
569 |
| |
570 gboolean_get(b, &user->full); |
| |
571 mwString_get(b, &user->id); |
| |
572 mwString_get(b, &user->community); |
| |
573 |
| |
574 if(user->full) |
| |
575 mwString_get(b, &user->name); |
| |
576 } |
| |
577 |
| |
578 |
| |
579 void mwUserItem_clear(struct mwUserItem *user) { |
| |
580 if(! user) return; |
| |
581 |
| |
582 g_free(user->id); |
| |
583 g_free(user->community); |
| |
584 g_free(user->name); |
| |
585 |
| |
586 memset(user, 0x00, sizeof(struct mwUserItem)); |
| |
587 } |
| |
588 |
| |
589 |
| |
590 void mwUserItem_clone(struct mwUserItem *to, |
| |
591 const struct mwUserItem *from) { |
| |
592 |
| |
593 g_return_if_fail(to != NULL); |
| |
594 g_return_if_fail(from != NULL); |
| |
595 |
| |
596 to->full = from->full; |
| |
597 to->id = g_strdup(from->id); |
| |
598 to->community = g_strdup(from->community); |
| |
599 to->name = (to->full)? g_strdup(from->name): NULL; |
| |
600 } |
| |
601 |
| |
602 |
| |
603 void mwPrivacyInfo_put(struct mwPutBuffer *b, |
| |
604 const struct mwPrivacyInfo *info) { |
| |
605 guint32 c; |
| |
606 |
| |
607 g_return_if_fail(b != NULL); |
| |
608 g_return_if_fail(info != NULL); |
| |
609 |
| |
610 gboolean_put(b, info->deny); |
| |
611 guint32_put(b, info->count); |
| |
612 |
| |
613 for(c = info->count; c--; ) mwUserItem_put(b, info->users + c); |
| |
614 } |
| |
615 |
| |
616 |
| |
617 void mwPrivacyInfo_get(struct mwGetBuffer *b, struct mwPrivacyInfo *info) { |
| |
618 g_return_if_fail(b != NULL); |
| |
619 g_return_if_fail(info != NULL); |
| |
620 |
| |
621 if(b->error) return; |
| |
622 |
| |
623 gboolean_get(b, &info->deny); |
| |
624 guint32_get(b, &info->count); |
| |
625 |
| |
626 if(info->count) { |
| |
627 guint32 c = info->count; |
| |
628 info->users = g_new0(struct mwUserItem, c); |
| |
629 while(c--) mwUserItem_get(b, info->users + c); |
| |
630 } |
| |
631 } |
| |
632 |
| |
633 |
| |
634 void mwPrivacyInfo_clone(struct mwPrivacyInfo *to, |
| |
635 const struct mwPrivacyInfo *from) { |
| |
636 |
| |
637 guint32 c; |
| |
638 |
| |
639 g_return_if_fail(to != NULL); |
| |
640 g_return_if_fail(from != NULL); |
| |
641 |
| |
642 to->deny = from->deny; |
| |
643 c = to->count = from->count; |
| |
644 |
| |
645 to->users = g_new0(struct mwUserItem, c); |
| |
646 while(c--) mwUserItem_clone(to->users+c, from->users+c); |
| |
647 } |
| |
648 |
| |
649 |
| |
650 void mwPrivacyInfo_clear(struct mwPrivacyInfo *info) { |
| |
651 struct mwUserItem *u; |
| |
652 guint32 c; |
| |
653 |
| |
654 g_return_if_fail(info != NULL); |
| |
655 |
| |
656 u = info->users; |
| |
657 c = info->count; |
| |
658 |
| |
659 while(c--) mwUserItem_clear(u + c); |
| |
660 g_free(u); |
| |
661 |
| |
662 info->count = 0; |
| |
663 info->users = NULL; |
| |
664 } |
| |
665 |
| |
666 |
| |
667 /* 8.2.3 User Status Block */ |
| |
668 |
| |
669 |
| |
670 void mwUserStatus_put(struct mwPutBuffer *b, |
| |
671 const struct mwUserStatus *stat) { |
| |
672 |
| |
673 g_return_if_fail(b != NULL); |
| |
674 g_return_if_fail(stat != NULL); |
| |
675 |
| |
676 guint16_put(b, stat->status); |
| |
677 guint32_put(b, stat->time); |
| |
678 mwString_put(b, stat->desc); |
| |
679 } |
| |
680 |
| |
681 |
| |
682 void mwUserStatus_get(struct mwGetBuffer *b, struct mwUserStatus *stat) { |
| |
683 g_return_if_fail(b != NULL); |
| |
684 g_return_if_fail(stat != NULL); |
| |
685 |
| |
686 if(b->error) return; |
| |
687 |
| |
688 guint16_get(b, &stat->status); |
| |
689 guint32_get(b, &stat->time); |
| |
690 mwString_get(b, &stat->desc); |
| |
691 } |
| |
692 |
| |
693 |
| |
694 void mwUserStatus_clear(struct mwUserStatus *stat) { |
| |
695 if(! stat) return; |
| |
696 g_free(stat->desc); |
| |
697 memset(stat, 0x00, sizeof(struct mwUserStatus)); |
| |
698 } |
| |
699 |
| |
700 |
| |
701 void mwUserStatus_clone(struct mwUserStatus *to, |
| |
702 const struct mwUserStatus *from) { |
| |
703 |
| |
704 g_return_if_fail(to != NULL); |
| |
705 g_return_if_fail(from != NULL); |
| |
706 |
| |
707 to->status = from->status; |
| |
708 to->time = from->time; |
| |
709 to->desc = g_strdup(from->desc); |
| |
710 } |
| |
711 |
| |
712 |
| |
713 /* 8.2.4 ID Block */ |
| |
714 |
| |
715 |
| |
716 void mwIdBlock_put(struct mwPutBuffer *b, const struct mwIdBlock *id) { |
| |
717 g_return_if_fail(b != NULL); |
| |
718 g_return_if_fail(id != NULL); |
| |
719 |
| |
720 mwString_put(b, id->user); |
| |
721 mwString_put(b, id->community); |
| |
722 } |
| |
723 |
| |
724 |
| |
725 void mwIdBlock_get(struct mwGetBuffer *b, struct mwIdBlock *id) { |
| |
726 g_return_if_fail(b != NULL); |
| |
727 g_return_if_fail(id != NULL); |
| |
728 |
| |
729 if(b->error) return; |
| |
730 |
| |
731 mwString_get(b, &id->user); |
| |
732 mwString_get(b, &id->community); |
| |
733 } |
| |
734 |
| |
735 |
| |
736 void mwIdBlock_clear(struct mwIdBlock *id) { |
| |
737 if(! id) return; |
| |
738 |
| |
739 g_free(id->user); |
| |
740 id->user = NULL; |
| |
741 |
| |
742 g_free(id->community); |
| |
743 id->community = NULL; |
| |
744 } |
| |
745 |
| |
746 |
| |
747 void mwIdBlock_clone(struct mwIdBlock *to, const struct mwIdBlock *from) { |
| |
748 g_return_if_fail(to != NULL); |
| |
749 g_return_if_fail(from != NULL); |
| |
750 |
| |
751 to->user = g_strdup(from->user); |
| |
752 to->community = g_strdup(from->community); |
| |
753 } |
| |
754 |
| |
755 |
| |
756 guint mwIdBlock_hash(const struct mwIdBlock *idb) { |
| |
757 return (idb)? g_str_hash(idb->user): 0; |
| |
758 } |
| |
759 |
| |
760 |
| |
761 gboolean mwIdBlock_equal(const struct mwIdBlock *a, |
| |
762 const struct mwIdBlock *b) { |
| |
763 |
| |
764 g_return_val_if_fail(a != NULL, FALSE); |
| |
765 g_return_val_if_fail(b != NULL, FALSE); |
| |
766 |
| |
767 return ( mw_streq(a->user, b->user) && |
| |
768 mw_streq(a->community, b->community) ); |
| |
769 } |
| |
770 |
| |
771 |
| |
772 /* 8.2.5 Encryption Block */ |
| |
773 |
| |
774 /** @todo I think this can be put into cipher */ |
| |
775 |
| |
776 void mwEncryptItem_put(struct mwPutBuffer *b, |
| |
777 const struct mwEncryptItem *ei) { |
| |
778 |
| |
779 g_return_if_fail(b != NULL); |
| |
780 g_return_if_fail(ei != NULL); |
| |
781 |
| |
782 guint16_put(b, ei->id); |
| |
783 mwOpaque_put(b, &ei->info); |
| |
784 |
| |
785 } |
| |
786 |
| |
787 |
| |
788 void mwEncryptItem_get(struct mwGetBuffer *b, struct mwEncryptItem *ei) { |
| |
789 g_return_if_fail(b != NULL); |
| |
790 g_return_if_fail(ei != NULL); |
| |
791 |
| |
792 if(b->error) return; |
| |
793 |
| |
794 guint16_get(b, &ei->id); |
| |
795 mwOpaque_get(b, &ei->info); |
| |
796 } |
| |
797 |
| |
798 |
| |
799 void mwEncryptItem_clear(struct mwEncryptItem *ei) { |
| |
800 if(! ei) return; |
| |
801 ei->id = 0x0000; |
| |
802 mwOpaque_clear(&ei->info); |
| |
803 } |
| |
804 |
| |
805 |
| |
806 /* 8.4.2.1 Awareness ID Block */ |
| |
807 |
| |
808 |
| |
809 /** @todo move this into srvc_aware */ |
| |
810 |
| |
811 void mwAwareIdBlock_put(struct mwPutBuffer *b, |
| |
812 const struct mwAwareIdBlock *idb) { |
| |
813 |
| |
814 g_return_if_fail(b != NULL); |
| |
815 g_return_if_fail(idb != NULL); |
| |
816 |
| |
817 guint16_put(b, idb->type); |
| |
818 mwString_put(b, idb->user); |
| |
819 mwString_put(b, idb->community); |
| |
820 } |
| |
821 |
| |
822 |
| |
823 void mwAwareIdBlock_get(struct mwGetBuffer *b, struct mwAwareIdBlock *idb) { |
| |
824 g_return_if_fail(b != NULL); |
| |
825 g_return_if_fail(idb != NULL); |
| |
826 |
| |
827 if(b->error) return; |
| |
828 |
| |
829 guint16_get(b, &idb->type); |
| |
830 mwString_get(b, &idb->user); |
| |
831 mwString_get(b, &idb->community); |
| |
832 } |
| |
833 |
| |
834 |
| |
835 void mwAwareIdBlock_clone(struct mwAwareIdBlock *to, |
| |
836 const struct mwAwareIdBlock *from) { |
| |
837 |
| |
838 g_return_if_fail(to != NULL); |
| |
839 g_return_if_fail(from != NULL); |
| |
840 |
| |
841 to->type = from->type; |
| |
842 to->user = g_strdup(from->user); |
| |
843 to->community = g_strdup(from->community); |
| |
844 } |
| |
845 |
| |
846 |
| |
847 void mwAwareIdBlock_clear(struct mwAwareIdBlock *idb) { |
| |
848 if(! idb) return; |
| |
849 g_free(idb->user); |
| |
850 g_free(idb->community); |
| |
851 memset(idb, 0x00, sizeof(struct mwAwareIdBlock)); |
| |
852 } |
| |
853 |
| |
854 |
| |
855 guint mwAwareIdBlock_hash(const struct mwAwareIdBlock *a) { |
| |
856 return (a)? g_str_hash(a->user): 0; |
| |
857 } |
| |
858 |
| |
859 |
| |
860 gboolean mwAwareIdBlock_equal(const struct mwAwareIdBlock *a, |
| |
861 const struct mwAwareIdBlock *b) { |
| |
862 |
| |
863 g_return_val_if_fail(a != NULL, FALSE); |
| |
864 g_return_val_if_fail(b != NULL, FALSE); |
| |
865 |
| |
866 return ( (a->type == b->type) && |
| |
867 mw_streq(a->user, b->user) && |
| |
868 mw_streq(a->community, b->community) ); |
| |
869 } |
| |
870 |
| |
871 |
| |
872 /* 8.4.2.4 Snapshot */ |
| |
873 |
| |
874 void mwAwareSnapshot_get(struct mwGetBuffer *b, struct mwAwareSnapshot *idb) { |
| |
875 guint32 junk; |
| |
876 char *empty = NULL; |
| |
877 |
| |
878 g_return_if_fail(b != NULL); |
| |
879 g_return_if_fail(idb != NULL); |
| |
880 |
| |
881 guint32_get(b, &junk); |
| |
882 mwAwareIdBlock_get(b, &idb->id); |
| |
883 mwString_get(b, &idb->group); |
| |
884 gboolean_get(b, &idb->online); |
| |
885 |
| |
886 g_free(empty); |
| |
887 |
| |
888 if(idb->online) { |
| |
889 mwString_get(b, &idb->alt_id); |
| |
890 mwUserStatus_get(b, &idb->status); |
| |
891 mwString_get(b, &idb->name); |
| |
892 } |
| |
893 } |
| |
894 |
| |
895 |
| |
896 void mwAwareSnapshot_clone(struct mwAwareSnapshot *to, |
| |
897 const struct mwAwareSnapshot *from) { |
| |
898 |
| |
899 g_return_if_fail(to != NULL); |
| |
900 g_return_if_fail(from != NULL); |
| |
901 |
| |
902 mwAwareIdBlock_clone(&to->id, &from->id); |
| |
903 if( (to->online = from->online) ) { |
| |
904 to->alt_id = g_strdup(from->alt_id); |
| |
905 mwUserStatus_clone(&to->status, &from->status); |
| |
906 to->name = g_strdup(from->name); |
| |
907 to->group = g_strdup(from->group); |
| |
908 } |
| |
909 } |
| |
910 |
| |
911 |
| |
912 void mwAwareSnapshot_clear(struct mwAwareSnapshot *idb) { |
| |
913 if(! idb) return; |
| |
914 mwAwareIdBlock_clear(&idb->id); |
| |
915 mwUserStatus_clear(&idb->status); |
| |
916 g_free(idb->alt_id); |
| |
917 g_free(idb->name); |
| |
918 g_free(idb->group); |
| |
919 memset(idb, 0x00, sizeof(struct mwAwareSnapshot)); |
| |
920 } |
| |
921 |
| |
922 |
| |
923 const char *mwLoginType_getName(enum mwLoginType type) { |
| |
924 switch(type) { |
| |
925 case mwLogin_LIB: |
| |
926 return "Lotus Binary Library"; |
| |
927 |
| |
928 case mwLogin_JAVA_WEB: |
| |
929 return "Lotus Java Client Applet"; |
| |
930 |
| |
931 case mwLogin_BINARY: |
| |
932 return "Lotus Sametime"; |
| |
933 |
| |
934 case mwLogin_JAVA_APP: |
| |
935 return "Lotus Java Client Application"; |
| |
936 |
| |
937 case mwLogin_NOTES_6_5: |
| |
938 return "Lotus Notes Client 6.5.2+"; |
| |
939 |
| |
940 case mwLogin_NOTES_7_0: |
| |
941 return "Lotus Notes Client 7"; |
| |
942 |
| |
943 case mwLogin_ICT: |
| |
944 return "IBM Community Tools (ICT)"; |
| |
945 |
| |
946 case mwLogin_NOTESBUDDY: |
| |
947 case mwLogin_NOTESBUDDY_4_15: |
| |
948 return "Alphaworks NotesBuddy"; |
| |
949 |
| |
950 case mwLogin_SANITY: |
| |
951 return "Sanity"; |
| |
952 |
| |
953 case mwLogin_ST_PERL: |
| |
954 return "ST-Send-Message"; |
| |
955 |
| |
956 case mwLogin_PMR_ALERT: |
| |
957 return "PMR Alert"; |
| |
958 |
| |
959 case mwLogin_TRILLIAN: |
| |
960 case mwLogin_TRILLIAN_IBM: |
| |
961 return "Trillian"; |
| |
962 |
| |
963 case mwLogin_MEANWHILE: |
| |
964 return "Meanwhile"; |
| |
965 |
| |
966 case mwLogin_MW_PYTHON: |
| |
967 return "Meanwhile Python"; |
| |
968 |
| |
969 case mwLogin_MW_GAIM: |
| |
970 return "Meanwhile Gaim"; |
| |
971 |
| |
972 case mwLogin_MW_ADIUM: |
| |
973 return "Meanwhile Adium"; |
| |
974 |
| |
975 case mwLogin_MW_KOPETE: |
| |
976 return "Meanwhile Kopete"; |
| |
977 |
| |
978 default: |
| |
979 return NULL; |
| |
980 } |
| |
981 } |
| |
982 |