Blame src/common.c

Packit Service 37472d
Packit Service 37472d
/*
Packit Service 37472d
  Meanwhile - Unofficial Lotus Sametime Community Client Library
Packit Service 37472d
  Copyright (C) 2004  Christopher (siege) O'Brien
Packit Service 37472d
  
Packit Service 37472d
  This library is free software; you can redistribute it and/or
Packit Service 37472d
  modify it under the terms of the GNU Library General Public
Packit Service 37472d
  License as published by the Free Software Foundation; either
Packit Service 37472d
  version 2 of the License, or (at your option) any later version.
Packit Service 37472d
  
Packit Service 37472d
  This library is distributed in the hope that it will be useful,
Packit Service 37472d
  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 37472d
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 37472d
  Library General Public License for more details.
Packit Service 37472d
  
Packit Service 37472d
  You should have received a copy of the GNU Library General Public
Packit Service 37472d
  License along with this library; if not, write to the Free
Packit Service 37472d
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Packit Service 37472d
*/
Packit Service 37472d
Packit Service 37472d
#include <glib.h>
Packit Service 37472d
#include <string.h>
Packit Service 37472d
Packit Service 37472d
#include "mw_common.h"
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** @todo the *_get functions should make sure to clear their
Packit Service 37472d
    structures in the event of failure, to prevent memory leaks */
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
#define MW16_PUT(b, val) \
Packit Service 37472d
  *(b)++ = ((val) >> 0x08) & 0xff; \
Packit Service 37472d
  *(b)++ = (val) & 0xff;
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
#define MW16_GET(b, val) \
Packit Service 37472d
  val = (*(b)++ & 0xff) << 8; \
Packit Service 37472d
  val = val | (*(b)++ & 0xff);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
#define MW32_PUT(b, val) \
Packit Service 37472d
  *(b)++ = ((val) >> 0x18) & 0xff; \
Packit Service 37472d
  *(b)++ = ((val) >> 0x10) & 0xff; \
Packit Service 37472d
  *(b)++ = ((val) >> 0x08) & 0xff; \
Packit Service 37472d
  *(b)++ = (val) & 0xff;
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
#define MW32_GET(b, val) \
Packit Service 37472d
  val = (*(b)++ & 0xff) << 0x18; \
Packit Service 37472d
  val = val | (*(b)++ & 0xff) << 0x10; \
Packit Service 37472d
  val = val | (*(b)++ & 0xff) << 0x08; \
Packit Service 37472d
  val = val | (*(b)++ & 0xff);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwPutBuffer {
Packit Service 37472d
  guchar *buf;  /**< head of buffer */
Packit Service 37472d
  gsize len;    /**< length of buffer */
Packit Service 37472d
Packit Service 37472d
  guchar *ptr;  /**< offset to first unused byte */
Packit Service 37472d
  gsize rem;    /**< count of unused bytes remaining */
Packit Service 37472d
};
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwGetBuffer {
Packit Service 37472d
  guchar *buf;  /**< head of buffer */
Packit Service 37472d
  gsize len;    /**< length of buffer */
Packit Service 37472d
Packit Service 37472d
  guchar *ptr;  /**< offset to first unused byte */
Packit Service 37472d
  gsize rem;    /**< count of unused bytes remaining */
Packit Service 37472d
Packit Service 37472d
  gboolean wrap;   /**< TRUE to indicate buf shouldn't be freed */
Packit Service 37472d
  gboolean error;  /**< TRUE to indicate an error */
Packit Service 37472d
};
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
#define BUFFER_USED(buffer) \
Packit Service 37472d
  ((buffer)->len - (buffer)->rem)
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** ensure that there's at least enough space remaining in the put
Packit Service 37472d
    buffer to fit needed. */
Packit Service 37472d
static void ensure_buffer(struct mwPutBuffer *b, gsize needed) {
Packit Service 37472d
  if(b->rem < needed) {
Packit Service 37472d
    gsize len = b->len, use = BUFFER_USED(b);
Packit Service 37472d
    guchar *buf;
Packit Service 37472d
Packit Service 37472d
    /* newly created buffers are empty until written to, and then they
Packit Service 37472d
       have 1024 available */
Packit Service 37472d
    if(! len) len = 1024;
Packit Service 37472d
Packit Service 37472d
    /* double len until it's large enough to fit needed */
Packit Service 37472d
    while( (len - use) < needed ) len = len << 1;
Packit Service 37472d
Packit Service 37472d
    /* create the new buffer. if there was anything in the old buffer,
Packit Service 37472d
       copy it into the new buffer and free the old copy */
Packit Service 37472d
    buf = g_malloc(len);
Packit Service 37472d
    if(b->buf) {
Packit Service 37472d
      memcpy(buf, b->buf, use);
Packit Service 37472d
      g_free(b->buf);
Packit Service 37472d
    }
Packit Service 37472d
Packit Service 37472d
    /* put the new buffer into b */
Packit Service 37472d
    b->buf = buf;
Packit Service 37472d
    b->len = len;
Packit Service 37472d
    b->ptr = buf + use;
Packit Service 37472d
    b->rem = len - use;
Packit Service 37472d
  }
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** determine if there are at least needed bytes available in the
Packit Service 37472d
    buffer. sets the error flag if there's not at least needed bytes
Packit Service 37472d
    left in the buffer
Packit Service 37472d
Packit Service 37472d
    @returns true if there's enough data, false if not */
Packit Service 37472d
static gboolean check_buffer(struct mwGetBuffer *b, gsize needed) {
Packit Service 37472d
  if(! b->error)  b->error = (b->rem < needed);
Packit Service 37472d
  return ! b->error;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwPutBuffer *mwPutBuffer_new() {
Packit Service 37472d
  return g_new0(struct mwPutBuffer, 1);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwPutBuffer_write(struct mwPutBuffer *b, gpointer data, gsize len) {
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
  g_return_if_fail(data != NULL);
Packit Service 37472d
Packit Service 37472d
  if(! len) return;
Packit Service 37472d
Packit Service 37472d
  ensure_buffer(b, len);
Packit Service 37472d
  memcpy(b->ptr, data, len);
Packit Service 37472d
  b->ptr += len;
Packit Service 37472d
  b->rem -= len;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwPutBuffer_free(struct mwPutBuffer *b) {
Packit Service 37472d
  if(! b) return;
Packit Service 37472d
  g_free(b->buf);
Packit Service 37472d
  g_free(b);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwPutBuffer_finalize(struct mwOpaque *to, struct mwPutBuffer *from) {
Packit Service 37472d
  g_return_if_fail(to != NULL);
Packit Service 37472d
  g_return_if_fail(from != NULL);
Packit Service 37472d
Packit Service 37472d
  to->len = BUFFER_USED(from);
Packit Service 37472d
  to->data = from->buf;
Packit Service 37472d
Packit Service 37472d
  g_free(from);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwGetBuffer *mwGetBuffer_new(struct mwOpaque *o) {
Packit Service 37472d
  struct mwGetBuffer *b = g_new0(struct mwGetBuffer, 1);
Packit Service 37472d
Packit Service 37472d
  if(o && o->len) {
Packit Service 37472d
    b->buf = b->ptr = g_memdup(o->data, o->len);
Packit Service 37472d
    b->len = b->rem = o->len;
Packit Service 37472d
  }
Packit Service 37472d
Packit Service 37472d
  return b;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwGetBuffer *mwGetBuffer_wrap(const struct mwOpaque *o) {
Packit Service 37472d
  struct mwGetBuffer *b = g_new0(struct mwGetBuffer, 1);
Packit Service 37472d
Packit Service 37472d
  if(o && o->len) {
Packit Service 37472d
    b->buf = b->ptr = o->data;
Packit Service 37472d
    b->len = b->rem = o->len;
Packit Service 37472d
  }
Packit Service 37472d
  b->wrap = TRUE;
Packit Service 37472d
Packit Service 37472d
  return b;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
gsize mwGetBuffer_read(struct mwGetBuffer *b, gpointer data, gsize len) {
Packit Service 37472d
  g_return_val_if_fail(b != NULL, 0);
Packit Service 37472d
  g_return_val_if_fail(data != NULL, 0);
Packit Service 37472d
Packit Service 37472d
  if(b->error) return 0;
Packit Service 37472d
  if(! len) return 0;
Packit Service 37472d
Packit Service 37472d
  if(b->rem < len)
Packit Service 37472d
    len = b->rem;
Packit Service 37472d
Packit Service 37472d
  memcpy(data, b->ptr, len);
Packit Service 37472d
  b->ptr += len;
Packit Service 37472d
  b->rem -= len;
Packit Service 37472d
Packit Service 37472d
  return len;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
gsize mwGetBuffer_advance(struct mwGetBuffer *b, gsize len) {
Packit Service 37472d
  g_return_val_if_fail(b != NULL, 0);
Packit Service 37472d
Packit Service 37472d
  if(b->error) return 0;
Packit Service 37472d
  if(! len) return 0;
Packit Service 37472d
Packit Service 37472d
  if(b->rem < len)
Packit Service 37472d
    len = b->rem;
Packit Service 37472d
Packit Service 37472d
  b->ptr += len;
Packit Service 37472d
  b->rem -= len;
Packit Service 37472d
Packit Service 37472d
  return len;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwGetBuffer_reset(struct mwGetBuffer *b) {
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
Packit Service 37472d
  b->rem = b->len;
Packit Service 37472d
  b->ptr = b->buf;
Packit Service 37472d
  b->error = FALSE;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
gsize mwGetBuffer_remaining(struct mwGetBuffer *b) {
Packit Service 37472d
  g_return_val_if_fail(b != NULL, 0);
Packit Service 37472d
  return b->rem;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
gboolean mwGetBuffer_error(struct mwGetBuffer *b) {
Packit Service 37472d
  g_return_val_if_fail(b != NULL, TRUE);
Packit Service 37472d
  return b->error;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwGetBuffer_free(struct mwGetBuffer *b) {
Packit Service 37472d
  if(! b) return;
Packit Service 37472d
  if(! b->wrap) g_free(b->buf);
Packit Service 37472d
  g_free(b);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
#define guint16_buflen()  2
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void guint16_put(struct mwPutBuffer *b, guint16 val) {
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
Packit Service 37472d
  ensure_buffer(b, guint16_buflen());
Packit Service 37472d
  MW16_PUT(b->ptr, val);
Packit Service 37472d
  b->rem -= guint16_buflen();
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void guint16_get(struct mwGetBuffer *b, guint16 *val) {
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
Packit Service 37472d
  if(b->error) return;
Packit Service 37472d
  g_return_if_fail(check_buffer(b, guint16_buflen()));
Packit Service 37472d
Packit Service 37472d
  MW16_GET(b->ptr, *val);
Packit Service 37472d
  b->rem -= guint16_buflen();
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
guint16 guint16_peek(struct mwGetBuffer *b) {
Packit Service 37472d
  guchar *buf = b->buf;
Packit Service 37472d
  guint16 r = 0;
Packit Service 37472d
  
Packit Service 37472d
  if(b->rem >= guint16_buflen())
Packit Service 37472d
    MW16_GET(buf, r);
Packit Service 37472d
Packit Service 37472d
  return r;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
#define guint32_buflen()  4
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void guint32_put(struct mwPutBuffer *b, guint32 val) {
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
Packit Service 37472d
  ensure_buffer(b, guint32_buflen());
Packit Service 37472d
  MW32_PUT(b->ptr, val);
Packit Service 37472d
  b->rem -= guint32_buflen();
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void guint32_get(struct mwGetBuffer *b, guint32 *val) {
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
Packit Service 37472d
  if(b->error) return;
Packit Service 37472d
  g_return_if_fail(check_buffer(b, guint32_buflen()));
Packit Service 37472d
Packit Service 37472d
  MW32_GET(b->ptr, *val);
Packit Service 37472d
  b->rem -= guint32_buflen();
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
guint32 guint32_peek(struct mwGetBuffer *b) {
Packit Service 37472d
  guchar *buf = b->buf;
Packit Service 37472d
  guint32 r = 0;
Packit Service 37472d
Packit Service 37472d
  if(b->rem >= guint32_buflen())
Packit Service 37472d
    MW32_GET(buf, r);
Packit Service 37472d
Packit Service 37472d
  return r;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
#define gboolean_buflen()  1
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void gboolean_put(struct mwPutBuffer *b, gboolean val) {
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
Packit Service 37472d
  ensure_buffer(b, gboolean_buflen());
Packit Service 37472d
  *(b->ptr) = !! val;
Packit Service 37472d
  b->ptr++;
Packit Service 37472d
  b->rem--;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void gboolean_get(struct mwGetBuffer *b, gboolean *val) {
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
Packit Service 37472d
  if(b->error) return;
Packit Service 37472d
  g_return_if_fail(check_buffer(b, gboolean_buflen()));
Packit Service 37472d
Packit Service 37472d
  *val = !! *(b->ptr);
Packit Service 37472d
  b->ptr++;
Packit Service 37472d
  b->rem--;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
gboolean gboolean_peek(struct mwGetBuffer *b) {
Packit Service 37472d
  gboolean v = FALSE;
Packit Service 37472d
Packit Service 37472d
  if(b->rem >= gboolean_buflen())
Packit Service 37472d
    v = !! *(b->ptr);
Packit Service 37472d
Packit Service 37472d
  return v;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static gboolean mw_streq(const char *a, const char *b) {
Packit Service 37472d
  return (a == b) || (a && b && !strcmp(a, b));
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwString_put(struct mwPutBuffer *b, const char *val) {
Packit Service 37472d
  gsize len = 0;
Packit Service 37472d
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
Packit Service 37472d
  if(val) len = strlen(val);
Packit Service 37472d
Packit Service 37472d
  guint16_put(b, (guint16) len);
Packit Service 37472d
Packit Service 37472d
  if(len) {
Packit Service 37472d
    ensure_buffer(b, len);
Packit Service 37472d
    memcpy(b->ptr, val, len);
Packit Service 37472d
    b->ptr += len;
Packit Service 37472d
    b->rem -= len;
Packit Service 37472d
  }
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwString_get(struct mwGetBuffer *b, char **val) {
Packit Service 37472d
  guint16 len = 0;
Packit Service 37472d
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
  g_return_if_fail(val != NULL);
Packit Service 37472d
Packit Service 37472d
  *val = NULL;
Packit Service 37472d
Packit Service 37472d
  if(b->error) return;
Packit Service 37472d
  guint16_get(b, &len;;
Packit Service 37472d
Packit Service 37472d
  g_return_if_fail(check_buffer(b, (gsize) len));
Packit Service 37472d
Packit Service 37472d
  if(len) {
Packit Service 37472d
    *val = g_malloc0(len + 1);
Packit Service 37472d
    memcpy(*val, b->ptr, len);
Packit Service 37472d
    b->ptr += len;
Packit Service 37472d
    b->rem -= len;
Packit Service 37472d
  }
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwOpaque_put(struct mwPutBuffer *b, const struct mwOpaque *o) {
Packit Service 37472d
  gsize len;
Packit Service 37472d
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
Packit Service 37472d
  if(! o) {
Packit Service 37472d
    guint32_put(b, 0x00);
Packit Service 37472d
    return;
Packit Service 37472d
  }
Packit Service 37472d
Packit Service 37472d
  len = o->len;
Packit Service 37472d
  if(len)
Packit Service 37472d
    g_return_if_fail(o->data != NULL);
Packit Service 37472d
  
Packit Service 37472d
  guint32_put(b, (guint32) len);
Packit Service 37472d
Packit Service 37472d
  if(len) {
Packit Service 37472d
    ensure_buffer(b, len);
Packit Service 37472d
    memcpy(b->ptr, o->data, len);
Packit Service 37472d
    b->ptr += len;
Packit Service 37472d
    b->rem -= len;
Packit Service 37472d
  }
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwOpaque_get(struct mwGetBuffer *b, struct mwOpaque *o) {
Packit Service 37472d
  guint32 tmp = 0;
Packit Service 37472d
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
  g_return_if_fail(o != NULL);
Packit Service 37472d
Packit Service 37472d
  o->len = 0;
Packit Service 37472d
  o->data = NULL;
Packit Service 37472d
  
Packit Service 37472d
  if(b->error) return;
Packit Service 37472d
  guint32_get(b, &tmp);
Packit Service 37472d
Packit Service 37472d
  g_return_if_fail(check_buffer(b, (gsize) tmp));
Packit Service 37472d
Packit Service 37472d
  o->len = (gsize) tmp;
Packit Service 37472d
  if(tmp > 0) {
Packit Service 37472d
    o->data = g_memdup(b->ptr, tmp);
Packit Service 37472d
    b->ptr += tmp;
Packit Service 37472d
    b->rem -= tmp;
Packit Service 37472d
  }
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwOpaque_clear(struct mwOpaque *o) {
Packit Service 37472d
  if(! o) return;
Packit Service 37472d
  g_free(o->data);
Packit Service 37472d
  o->data = NULL;
Packit Service 37472d
  o->len = 0;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwOpaque_free(struct mwOpaque *o) {
Packit Service 37472d
  if(! o) return;
Packit Service 37472d
  g_free(o->data);
Packit Service 37472d
  g_free(o);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwOpaque_clone(struct mwOpaque *to, const struct mwOpaque *from) {
Packit Service 37472d
  g_return_if_fail(to != NULL);
Packit Service 37472d
Packit Service 37472d
  to->len = 0;
Packit Service 37472d
  to->data = NULL;
Packit Service 37472d
Packit Service 37472d
  if(from) {
Packit Service 37472d
    to->len = from->len;
Packit Service 37472d
    if(to->len)
Packit Service 37472d
      to->data = g_memdup(from->data, to->len);
Packit Service 37472d
  }
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/* 8.2 Common Structures */
Packit Service 37472d
/* 8.2.1 Login Info block */
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwLoginInfo_put(struct mwPutBuffer *b, const struct mwLoginInfo *login) {
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
  g_return_if_fail(login != NULL);
Packit Service 37472d
Packit Service 37472d
  mwString_put(b, login->login_id);
Packit Service 37472d
  guint16_put(b, login->type);
Packit Service 37472d
  mwString_put(b, login->user_id);
Packit Service 37472d
  mwString_put(b, login->user_name);
Packit Service 37472d
  mwString_put(b, login->community);
Packit Service 37472d
  gboolean_put(b, login->full);
Packit Service 37472d
Packit Service 37472d
  if(login->full) {
Packit Service 37472d
    mwString_put(b, login->desc);
Packit Service 37472d
    guint32_put(b, login->ip_addr);
Packit Service 37472d
    mwString_put(b, login->server_id);
Packit Service 37472d
  }
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwLoginInfo_get(struct mwGetBuffer *b, struct mwLoginInfo *login) {
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
  g_return_if_fail(login != NULL);
Packit Service 37472d
Packit Service 37472d
  if(b->error) return;
Packit Service 37472d
Packit Service 37472d
  mwString_get(b, &login->login_id);
Packit Service 37472d
  guint16_get(b, &login->type);
Packit Service 37472d
  mwString_get(b, &login->user_id);
Packit Service 37472d
  mwString_get(b, &login->user_name);
Packit Service 37472d
  mwString_get(b, &login->community);
Packit Service 37472d
  gboolean_get(b, &login->full);
Packit Service 37472d
  
Packit Service 37472d
  if(login->full) {
Packit Service 37472d
    mwString_get(b, &login->desc);
Packit Service 37472d
    guint32_get(b, &login->ip_addr);
Packit Service 37472d
    mwString_get(b, &login->server_id);
Packit Service 37472d
  }
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwLoginInfo_clear(struct mwLoginInfo *login) {
Packit Service 37472d
  if(! login) return;
Packit Service 37472d
Packit Service 37472d
  g_free(login->login_id);
Packit Service 37472d
  g_free(login->user_id);
Packit Service 37472d
  g_free(login->user_name);
Packit Service 37472d
  g_free(login->community);
Packit Service 37472d
  g_free(login->desc);
Packit Service 37472d
  g_free(login->server_id);
Packit Service 37472d
Packit Service 37472d
  memset(login, 0x00, sizeof(struct mwLoginInfo));
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwLoginInfo_clone(struct mwLoginInfo *to,
Packit Service 37472d
		       const struct mwLoginInfo *from) {
Packit Service 37472d
Packit Service 37472d
  g_return_if_fail(to != NULL);
Packit Service 37472d
  g_return_if_fail(from != NULL);
Packit Service 37472d
Packit Service 37472d
  to->login_id= g_strdup(from->login_id);
Packit Service 37472d
  to->type = from->type;
Packit Service 37472d
  to->user_id = g_strdup(from->user_id);
Packit Service 37472d
  to->user_name = g_strdup(from->user_name);
Packit Service 37472d
  to->community = g_strdup(from->community);
Packit Service 37472d
Packit Service 37472d
  if( (to->full = from->full) ) {
Packit Service 37472d
    to->desc = g_strdup(from->desc);
Packit Service 37472d
    to->ip_addr = from->ip_addr;
Packit Service 37472d
    to->server_id = g_strdup(from->server_id);
Packit Service 37472d
  }
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/* 8.2.2 Private Info Block */
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwUserItem_put(struct mwPutBuffer *b, const struct mwUserItem *user) {
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
  g_return_if_fail(user != NULL);
Packit Service 37472d
Packit Service 37472d
  gboolean_put(b, user->full);
Packit Service 37472d
  mwString_put(b, user->id);
Packit Service 37472d
  mwString_put(b, user->community);
Packit Service 37472d
  
Packit Service 37472d
  if(user->full)
Packit Service 37472d
    mwString_put(b, user->name);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwUserItem_get(struct mwGetBuffer *b, struct mwUserItem *user) {
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
  g_return_if_fail(user != NULL);
Packit Service 37472d
Packit Service 37472d
  if(b->error) return;
Packit Service 37472d
Packit Service 37472d
  gboolean_get(b, &user->full);
Packit Service 37472d
  mwString_get(b, &user->id);
Packit Service 37472d
  mwString_get(b, &user->community);
Packit Service 37472d
Packit Service 37472d
  if(user->full)
Packit Service 37472d
    mwString_get(b, &user->name);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwUserItem_clear(struct mwUserItem *user) {
Packit Service 37472d
  if(! user) return;
Packit Service 37472d
Packit Service 37472d
  g_free(user->id);
Packit Service 37472d
  g_free(user->community);
Packit Service 37472d
  g_free(user->name);
Packit Service 37472d
Packit Service 37472d
  memset(user, 0x00, sizeof(struct mwUserItem));
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwUserItem_clone(struct mwUserItem *to,
Packit Service 37472d
		      const struct mwUserItem *from) {
Packit Service 37472d
Packit Service 37472d
  g_return_if_fail(to != NULL);
Packit Service 37472d
  g_return_if_fail(from != NULL);
Packit Service 37472d
Packit Service 37472d
  to->full = from->full;
Packit Service 37472d
  to->id = g_strdup(from->id);
Packit Service 37472d
  to->community = g_strdup(from->community);
Packit Service 37472d
  to->name = (to->full)? g_strdup(from->name): NULL;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwPrivacyInfo_put(struct mwPutBuffer *b,
Packit Service 37472d
		       const struct mwPrivacyInfo *info) {
Packit Service 37472d
  guint32 c;
Packit Service 37472d
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
  g_return_if_fail(info != NULL);
Packit Service 37472d
Packit Service 37472d
  gboolean_put(b, info->deny);
Packit Service 37472d
  guint32_put(b, info->count);
Packit Service 37472d
Packit Service 37472d
  for(c = info->count; c--; ) mwUserItem_put(b, info->users + c);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwPrivacyInfo_get(struct mwGetBuffer *b, struct mwPrivacyInfo *info) {
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
  g_return_if_fail(info != NULL);
Packit Service 37472d
Packit Service 37472d
  if(b->error) return;
Packit Service 37472d
Packit Service 37472d
  gboolean_get(b, &info->deny);
Packit Service 37472d
  guint32_get(b, &info->count);
Packit Service 37472d
Packit Service 37472d
  if(info->count) {
Packit Service 37472d
    guint32 c = info->count;
Packit Service 37472d
    info->users = g_new0(struct mwUserItem, c);
Packit Service 37472d
    while(c--) mwUserItem_get(b, info->users + c);
Packit Service 37472d
  }
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwPrivacyInfo_clone(struct mwPrivacyInfo *to,
Packit Service 37472d
			 const struct mwPrivacyInfo *from) {
Packit Service 37472d
Packit Service 37472d
  guint32 c;
Packit Service 37472d
Packit Service 37472d
  g_return_if_fail(to != NULL);
Packit Service 37472d
  g_return_if_fail(from != NULL);
Packit Service 37472d
Packit Service 37472d
  to->deny = from->deny;
Packit Service 37472d
  c = to->count = from->count;
Packit Service 37472d
Packit Service 37472d
  to->users = g_new0(struct mwUserItem, c);
Packit Service 37472d
  while(c--) mwUserItem_clone(to->users+c, from->users+c);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwPrivacyInfo_clear(struct mwPrivacyInfo *info) {
Packit Service 37472d
  struct mwUserItem *u;
Packit Service 37472d
  guint32 c;
Packit Service 37472d
Packit Service 37472d
  g_return_if_fail(info != NULL);
Packit Service 37472d
Packit Service 37472d
  u = info->users;
Packit Service 37472d
  c = info->count;
Packit Service 37472d
Packit Service 37472d
  while(c--) mwUserItem_clear(u + c);
Packit Service 37472d
  g_free(u);
Packit Service 37472d
Packit Service 37472d
  info->count = 0;
Packit Service 37472d
  info->users = NULL;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/* 8.2.3 User Status Block */
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwUserStatus_put(struct mwPutBuffer *b,
Packit Service 37472d
		      const struct mwUserStatus *stat) {
Packit Service 37472d
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
  g_return_if_fail(stat != NULL);
Packit Service 37472d
Packit Service 37472d
  guint16_put(b, stat->status);
Packit Service 37472d
  guint32_put(b, stat->time);
Packit Service 37472d
  mwString_put(b, stat->desc);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwUserStatus_get(struct mwGetBuffer *b, struct mwUserStatus *stat) {
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
  g_return_if_fail(stat != NULL);
Packit Service 37472d
Packit Service 37472d
  if(b->error) return;
Packit Service 37472d
Packit Service 37472d
  guint16_get(b, &stat->status);
Packit Service 37472d
  guint32_get(b, &stat->time);
Packit Service 37472d
  mwString_get(b, &stat->desc);
Packit Service 008821
Packit Service 008821
  // Quick'n ugly hack for recent Sametime clients
Packit Service 008821
  stat->time = 0;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwUserStatus_clear(struct mwUserStatus *stat) {
Packit Service 37472d
  if(! stat) return;
Packit Service 37472d
  g_free(stat->desc);
Packit Service 37472d
  memset(stat, 0x00, sizeof(struct mwUserStatus));
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwUserStatus_clone(struct mwUserStatus *to,
Packit Service 37472d
			const struct mwUserStatus *from) {
Packit Service 37472d
Packit Service 37472d
  g_return_if_fail(to != NULL);
Packit Service 37472d
  g_return_if_fail(from != NULL);
Packit Service 37472d
Packit Service 37472d
  to->status = from->status;
Packit Service 37472d
  to->time = from->time;
Packit Service 37472d
  to->desc = g_strdup(from->desc);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/* 8.2.4 ID Block */
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwIdBlock_put(struct mwPutBuffer *b, const struct mwIdBlock *id) {
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
  g_return_if_fail(id != NULL);
Packit Service 37472d
Packit Service 37472d
  mwString_put(b, id->user);
Packit Service 37472d
  mwString_put(b, id->community);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwIdBlock_get(struct mwGetBuffer *b, struct mwIdBlock *id) {
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
  g_return_if_fail(id != NULL);
Packit Service 37472d
Packit Service 37472d
  if(b->error) return;
Packit Service 37472d
Packit Service 37472d
  mwString_get(b, &id->user);
Packit Service 37472d
  mwString_get(b, &id->community);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwIdBlock_clear(struct mwIdBlock *id) {
Packit Service 37472d
  if(! id) return;
Packit Service 37472d
Packit Service 37472d
  g_free(id->user);
Packit Service 37472d
  id->user = NULL;
Packit Service 37472d
Packit Service 37472d
  g_free(id->community);
Packit Service 37472d
  id->community = NULL;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwIdBlock_clone(struct mwIdBlock *to, const struct mwIdBlock *from) {
Packit Service 37472d
  g_return_if_fail(to != NULL);
Packit Service 37472d
  g_return_if_fail(from != NULL);
Packit Service 37472d
Packit Service 37472d
  to->user = g_strdup(from->user);
Packit Service 37472d
  to->community = g_strdup(from->community);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
guint mwIdBlock_hash(const struct mwIdBlock *idb) {
Packit Service 37472d
  return (idb)? g_str_hash(idb->user): 0;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
gboolean mwIdBlock_equal(const struct mwIdBlock *a,
Packit Service 37472d
			 const struct mwIdBlock *b) {
Packit Service 37472d
Packit Service 37472d
  g_return_val_if_fail(a != NULL, FALSE);
Packit Service 37472d
  g_return_val_if_fail(b != NULL, FALSE);
Packit Service 37472d
Packit Service 37472d
  return ( mw_streq(a->user, b->user) &&
Packit Service 37472d
	   mw_streq(a->community, b->community) );
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/* 8.2.5 Encryption Block */
Packit Service 37472d
Packit Service 37472d
/** @todo I think this can be put into cipher */
Packit Service 37472d
Packit Service 37472d
void mwEncryptItem_put(struct mwPutBuffer *b,
Packit Service 37472d
		       const struct mwEncryptItem *ei) {
Packit Service 37472d
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
  g_return_if_fail(ei != NULL);
Packit Service 37472d
  
Packit Service 37472d
  guint16_put(b, ei->id);
Packit Service 37472d
  mwOpaque_put(b, &ei->info);
Packit Service 37472d
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwEncryptItem_get(struct mwGetBuffer *b, struct mwEncryptItem *ei) {
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
  g_return_if_fail(ei != NULL);
Packit Service 37472d
Packit Service 37472d
  if(b->error) return;
Packit Service 37472d
Packit Service 37472d
  guint16_get(b, &ei->id);
Packit Service 37472d
  mwOpaque_get(b, &ei->info);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwEncryptItem_clear(struct mwEncryptItem *ei) {
Packit Service 37472d
  if(! ei) return;
Packit Service 37472d
  ei->id = 0x0000;
Packit Service 37472d
  mwOpaque_clear(&ei->info);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwEncryptItem_free(struct mwEncryptItem *ei) {
Packit Service 37472d
  mwEncryptItem_clear(ei);
Packit Service 37472d
  g_free(ei);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/* 8.4.2.1 Awareness ID Block */
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** @todo move this into srvc_aware */
Packit Service 37472d
Packit Service 37472d
void mwAwareIdBlock_put(struct mwPutBuffer *b,
Packit Service 37472d
			const struct mwAwareIdBlock *idb) {
Packit Service 37472d
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
  g_return_if_fail(idb != NULL);
Packit Service 37472d
Packit Service 37472d
  guint16_put(b, idb->type);
Packit Service 37472d
  mwString_put(b, idb->user);
Packit Service 37472d
  mwString_put(b, idb->community);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwAwareIdBlock_get(struct mwGetBuffer *b, struct mwAwareIdBlock *idb) {
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
  g_return_if_fail(idb != NULL);
Packit Service 37472d
Packit Service 37472d
  if(b->error) return;
Packit Service 37472d
Packit Service 37472d
  guint16_get(b, &idb->type);
Packit Service 37472d
  mwString_get(b, &idb->user);
Packit Service 37472d
  mwString_get(b, &idb->community);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwAwareIdBlock_clone(struct mwAwareIdBlock *to,
Packit Service 37472d
			  const struct mwAwareIdBlock *from) {
Packit Service 37472d
Packit Service 37472d
  g_return_if_fail(to != NULL);
Packit Service 37472d
  g_return_if_fail(from != NULL);
Packit Service 37472d
Packit Service 37472d
  to->type = from->type;
Packit Service 37472d
  to->user = g_strdup(from->user);
Packit Service 37472d
  to->community = g_strdup(from->community);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwAwareIdBlock_clear(struct mwAwareIdBlock *idb) {
Packit Service 37472d
  if(! idb) return;
Packit Service 37472d
  g_free(idb->user);
Packit Service 37472d
  g_free(idb->community);
Packit Service 37472d
  memset(idb, 0x00, sizeof(struct mwAwareIdBlock));
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
guint mwAwareIdBlock_hash(const struct mwAwareIdBlock *a) {
Packit Service 37472d
  return (a)? g_str_hash(a->user): 0;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
gboolean mwAwareIdBlock_equal(const struct mwAwareIdBlock *a,
Packit Service 37472d
			      const struct mwAwareIdBlock *b) {
Packit Service 37472d
Packit Service 37472d
  g_return_val_if_fail(a != NULL, FALSE);
Packit Service 37472d
  g_return_val_if_fail(b != NULL, FALSE);
Packit Service 37472d
  
Packit Service 37472d
  return ( (a->type == b->type) &&
Packit Service 37472d
	   mw_streq(a->user, b->user) &&
Packit Service 37472d
	   mw_streq(a->community, b->community) );
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/* 8.4.2.4 Snapshot */
Packit Service 37472d
Packit Service 37472d
void mwAwareSnapshot_get(struct mwGetBuffer *b, struct mwAwareSnapshot *idb) {
Packit Service 37472d
  guint32 end_of_block;
Packit Service 37472d
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
  g_return_if_fail(idb != NULL);
Packit Service 37472d
Packit Service 37472d
  guint32_get(b, &end_of_block);
Packit Service 37472d
  mwAwareIdBlock_get(b, &idb->id);
Packit Service 37472d
  mwString_get(b, &idb->group);
Packit Service 37472d
  gboolean_get(b, &idb->online);
Packit Service 37472d
Packit Service 37472d
  if(idb->online) {
Packit Service 37472d
    mwString_get(b, &idb->alt_id);
Packit Service 37472d
    mwUserStatus_get(b, &idb->status);
Packit Service 37472d
    mwString_get(b, &idb->name);
Packit Service 37472d
  }
Packit Service 37472d
Packit Service 37472d
  if(b->ptr < b->buf + end_of_block) {
Packit Service 37472d
    mwGetBuffer_advance(b, b->buf + end_of_block - b->ptr);
Packit Service 37472d
  }
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwAwareSnapshot_clone(struct mwAwareSnapshot *to,
Packit Service 37472d
			   const struct mwAwareSnapshot *from) {
Packit Service 37472d
Packit Service 37472d
  g_return_if_fail(to != NULL);
Packit Service 37472d
  g_return_if_fail(from != NULL);
Packit Service 37472d
Packit Service 37472d
  mwAwareIdBlock_clone(&to->id, &from->id);
Packit Service 37472d
  if( (to->online = from->online) ) {
Packit Service 37472d
    to->alt_id = g_strdup(from->alt_id);
Packit Service 37472d
    mwUserStatus_clone(&to->status, &from->status);
Packit Service 37472d
    to->name = g_strdup(from->name);
Packit Service 37472d
    to->group = g_strdup(from->group);
Packit Service 37472d
  }
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwAwareSnapshot_clear(struct mwAwareSnapshot *idb) {
Packit Service 37472d
  if(! idb) return;
Packit Service 37472d
  mwAwareIdBlock_clear(&idb->id);
Packit Service 37472d
  mwUserStatus_clear(&idb->status);
Packit Service 37472d
  g_free(idb->alt_id);
Packit Service 37472d
  g_free(idb->name);
Packit Service 37472d
  g_free(idb->group);
Packit Service 37472d
  memset(idb, 0x00, sizeof(struct mwAwareSnapshot));
Packit Service 37472d
}
Packit Service 37472d