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   guchar *buf;  /**< head of buffer */
57   gsize len;    /**< length of buffer */
58 
59   guchar *ptr;  /**< offset to first unused byte */
60   gsize rem;    /**< count of unused bytes remaining */
61 };
62 
63 
64 struct mwGetBuffer {
65   guchar *buf;  /**< head of buffer */
66   gsize len;    /**< length of buffer */
67 
68   guchar *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. */
ensure_buffer(struct mwPutBuffer * b,gsize 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     guchar *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 */
check_buffer(struct mwGetBuffer * b,gsize needed)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 
mwPutBuffer_new()122 struct mwPutBuffer *mwPutBuffer_new() {
123   return g_new0(struct mwPutBuffer, 1);
124 }
125 
126 
mwPutBuffer_write(struct mwPutBuffer * b,gpointer data,gsize len)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 
mwPutBuffer_free(struct mwPutBuffer * b)140 void mwPutBuffer_free(struct mwPutBuffer *b) {
141   if(! b) return;
142   g_free(b->buf);
143   g_free(b);
144 }
145 
146 
mwPutBuffer_finalize(struct mwOpaque * to,struct mwPutBuffer * from)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 
mwGetBuffer_new(struct mwOpaque * o)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 
mwGetBuffer_wrap(const struct mwOpaque * o)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 = o->data;
175     b->len = b->rem = o->len;
176   }
177   b->wrap = TRUE;
178 
179   return b;
180 }
181 
182 
mwGetBuffer_read(struct mwGetBuffer * b,gpointer data,gsize len)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 
mwGetBuffer_advance(struct mwGetBuffer * b,gsize len)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 
mwGetBuffer_reset(struct mwGetBuffer * b)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 
mwGetBuffer_remaining(struct mwGetBuffer * b)226 gsize mwGetBuffer_remaining(struct mwGetBuffer *b) {
227   g_return_val_if_fail(b != NULL, 0);
228   return b->rem;
229 }
230 
231 
mwGetBuffer_error(struct mwGetBuffer * b)232 gboolean mwGetBuffer_error(struct mwGetBuffer *b) {
233   g_return_val_if_fail(b != NULL, TRUE);
234   return b->error;
235 }
236 
237 
mwGetBuffer_free(struct mwGetBuffer * b)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 
guint16_put(struct mwPutBuffer * b,guint16 val)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 
guint16_get(struct mwGetBuffer * b,guint16 * val)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 
guint16_peek(struct mwGetBuffer * b)268 guint16 guint16_peek(struct mwGetBuffer *b) {
269   guchar *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 
guint32_put(struct mwPutBuffer * b,guint32 val)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 
guint32_get(struct mwGetBuffer * b,guint32 * val)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 
guint32_peek(struct mwGetBuffer * b)302 guint32 guint32_peek(struct mwGetBuffer *b) {
303   guchar *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 
gboolean_put(struct mwPutBuffer * b,gboolean val)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 
gboolean_get(struct mwGetBuffer * b,gboolean * val)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 
gboolean_peek(struct mwGetBuffer * b)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 
mw_streq(const char * a,const char * b)348 static gboolean mw_streq(const char *a, const char *b) {
349   return (a == b) || (a && b && !strcmp(a, b));
350 }
351 
352 
mwString_put(struct mwPutBuffer * b,const char * val)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 
mwString_get(struct mwGetBuffer * b,char ** val)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 
mwOpaque_put(struct mwPutBuffer * b,const struct mwOpaque * o)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 
mwOpaque_get(struct mwGetBuffer * b,struct mwOpaque * o)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 
mwOpaque_clear(struct mwOpaque * o)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 
mwOpaque_free(struct mwOpaque * o)449 void mwOpaque_free(struct mwOpaque *o) {
450   if(! o) return;
451   g_free(o->data);
452   g_free(o);
453 }
454 
455 
mwOpaque_clone(struct mwOpaque * to,const struct mwOpaque * from)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 
mwLoginInfo_put(struct mwPutBuffer * b,const struct mwLoginInfo * login)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 
mwLoginInfo_get(struct mwGetBuffer * b,struct mwLoginInfo * login)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 
mwLoginInfo_clear(struct mwLoginInfo * login)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 
mwLoginInfo_clone(struct mwLoginInfo * to,const struct mwLoginInfo * from)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 
mwUserItem_put(struct mwPutBuffer * b,const struct mwUserItem * user)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 
mwUserItem_get(struct mwGetBuffer * b,struct mwUserItem * user)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 
mwUserItem_clear(struct mwUserItem * user)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 
mwUserItem_clone(struct mwUserItem * to,const struct mwUserItem * from)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 
mwPrivacyInfo_put(struct mwPutBuffer * b,const struct mwPrivacyInfo * info)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 
mwPrivacyInfo_get(struct mwGetBuffer * b,struct mwPrivacyInfo * info)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 
mwPrivacyInfo_clone(struct mwPrivacyInfo * to,const struct mwPrivacyInfo * from)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 
mwPrivacyInfo_clear(struct mwPrivacyInfo * info)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 
mwUserStatus_put(struct mwPutBuffer * b,const struct mwUserStatus * stat)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 
mwUserStatus_get(struct mwGetBuffer * b,struct mwUserStatus * stat)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 
mwUserStatus_clear(struct mwUserStatus * stat)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 
mwUserStatus_clone(struct mwUserStatus * to,const struct mwUserStatus * from)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 
mwIdBlock_put(struct mwPutBuffer * b,const struct mwIdBlock * id)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 
mwIdBlock_get(struct mwGetBuffer * b,struct mwIdBlock * id)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 
mwIdBlock_clear(struct mwIdBlock * id)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 
mwIdBlock_clone(struct mwIdBlock * to,const struct mwIdBlock * from)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 
mwIdBlock_hash(const struct mwIdBlock * idb)756 guint mwIdBlock_hash(const struct mwIdBlock *idb) {
757   return (idb)? g_str_hash(idb->user): 0;
758 }
759 
760 
mwIdBlock_equal(const struct mwIdBlock * a,const struct mwIdBlock * b)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 
mwEncryptItem_put(struct mwPutBuffer * b,const struct mwEncryptItem * ei)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 
mwEncryptItem_get(struct mwGetBuffer * b,struct mwEncryptItem * ei)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 
mwEncryptItem_clear(struct mwEncryptItem * ei)799 void mwEncryptItem_clear(struct mwEncryptItem *ei) {
800   if(! ei) return;
801   ei->id = 0x0000;
802   mwOpaque_clear(&ei->info);
803 }
804 
805 
mwEncryptItem_free(struct mwEncryptItem * ei)806 void mwEncryptItem_free(struct mwEncryptItem *ei) {
807   mwEncryptItem_clear(ei);
808   g_free(ei);
809 }
810 
811 
812 /* 8.4.2.1 Awareness ID Block */
813 
814 
815 /** @todo move this into srvc_aware */
816 
mwAwareIdBlock_put(struct mwPutBuffer * b,const struct mwAwareIdBlock * idb)817 void mwAwareIdBlock_put(struct mwPutBuffer *b,
818 			const struct mwAwareIdBlock *idb) {
819 
820   g_return_if_fail(b != NULL);
821   g_return_if_fail(idb != NULL);
822 
823   guint16_put(b, idb->type);
824   mwString_put(b, idb->user);
825   mwString_put(b, idb->community);
826 }
827 
828 
mwAwareIdBlock_get(struct mwGetBuffer * b,struct mwAwareIdBlock * idb)829 void mwAwareIdBlock_get(struct mwGetBuffer *b, struct mwAwareIdBlock *idb) {
830   g_return_if_fail(b != NULL);
831   g_return_if_fail(idb != NULL);
832 
833   if(b->error) return;
834 
835   guint16_get(b, &idb->type);
836   mwString_get(b, &idb->user);
837   mwString_get(b, &idb->community);
838 }
839 
840 
mwAwareIdBlock_clone(struct mwAwareIdBlock * to,const struct mwAwareIdBlock * from)841 void mwAwareIdBlock_clone(struct mwAwareIdBlock *to,
842 			  const struct mwAwareIdBlock *from) {
843 
844   g_return_if_fail(to != NULL);
845   g_return_if_fail(from != NULL);
846 
847   to->type = from->type;
848   to->user = g_strdup(from->user);
849   to->community = g_strdup(from->community);
850 }
851 
852 
mwAwareIdBlock_clear(struct mwAwareIdBlock * idb)853 void mwAwareIdBlock_clear(struct mwAwareIdBlock *idb) {
854   if(! idb) return;
855   g_free(idb->user);
856   g_free(idb->community);
857   memset(idb, 0x00, sizeof(struct mwAwareIdBlock));
858 }
859 
860 
mwAwareIdBlock_hash(const struct mwAwareIdBlock * a)861 guint mwAwareIdBlock_hash(const struct mwAwareIdBlock *a) {
862   return (a)? g_str_hash(a->user): 0;
863 }
864 
865 
mwAwareIdBlock_equal(const struct mwAwareIdBlock * a,const struct mwAwareIdBlock * b)866 gboolean mwAwareIdBlock_equal(const struct mwAwareIdBlock *a,
867 			      const struct mwAwareIdBlock *b) {
868 
869   g_return_val_if_fail(a != NULL, FALSE);
870   g_return_val_if_fail(b != NULL, FALSE);
871 
872   return ( (a->type == b->type) &&
873 	   mw_streq(a->user, b->user) &&
874 	   mw_streq(a->community, b->community) );
875 }
876 
877 
878 /* 8.4.2.4 Snapshot */
879 
mwAwareSnapshot_get(struct mwGetBuffer * b,struct mwAwareSnapshot * idb)880 void mwAwareSnapshot_get(struct mwGetBuffer *b, struct mwAwareSnapshot *idb) {
881   guint32 junk;
882   char *empty = NULL;
883 
884   g_return_if_fail(b != NULL);
885   g_return_if_fail(idb != NULL);
886 
887   guint32_get(b, &junk);
888   mwAwareIdBlock_get(b, &idb->id);
889   mwString_get(b, &idb->group);
890   gboolean_get(b, &idb->online);
891 
892   g_free(empty);
893 
894   if(idb->online) {
895     mwString_get(b, &idb->alt_id);
896     mwUserStatus_get(b, &idb->status);
897     mwString_get(b, &idb->name);
898   }
899 }
900 
901 
mwAwareSnapshot_clone(struct mwAwareSnapshot * to,const struct mwAwareSnapshot * from)902 void mwAwareSnapshot_clone(struct mwAwareSnapshot *to,
903 			   const struct mwAwareSnapshot *from) {
904 
905   g_return_if_fail(to != NULL);
906   g_return_if_fail(from != NULL);
907 
908   mwAwareIdBlock_clone(&to->id, &from->id);
909   if( (to->online = from->online) ) {
910     to->alt_id = g_strdup(from->alt_id);
911     mwUserStatus_clone(&to->status, &from->status);
912     to->name = g_strdup(from->name);
913     to->group = g_strdup(from->group);
914   }
915 }
916 
917 
mwAwareSnapshot_clear(struct mwAwareSnapshot * idb)918 void mwAwareSnapshot_clear(struct mwAwareSnapshot *idb) {
919   if(! idb) return;
920   mwAwareIdBlock_clear(&idb->id);
921   mwUserStatus_clear(&idb->status);
922   g_free(idb->alt_id);
923   g_free(idb->name);
924   g_free(idb->group);
925   memset(idb, 0x00, sizeof(struct mwAwareSnapshot));
926 }
927 
928