Blame src/st_list.c.crash

Packit 2900a8
Packit 2900a8
/*
Packit 2900a8
  Meanwhile - Unofficial Lotus Sametime Community Client Library
Packit 2900a8
  Copyright (C) 2004  Christopher (siege) O'Brien
Packit 2900a8
  
Packit 2900a8
  This library is free software; you can redistribute it and/or
Packit 2900a8
  modify it under the terms of the GNU Library General Public
Packit 2900a8
  License as published by the Free Software Foundation; either
Packit 2900a8
  version 2 of the License, or (at your option) any later version.
Packit 2900a8
  
Packit 2900a8
  This library is distributed in the hope that it will be useful,
Packit 2900a8
  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 2900a8
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 2900a8
  Library General Public License for more details.
Packit 2900a8
  
Packit 2900a8
  You should have received a copy of the GNU Library General Public
Packit 2900a8
  License along with this library; if not, write to the Free
Packit 2900a8
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Packit 2900a8
*/
Packit 2900a8
Packit 2900a8
#include <stdio.h>
Packit 2900a8
#include <string.h>
Packit 2900a8
#include <glib/gstring.h>
Packit 2900a8
Packit 2900a8
#include "mw_debug.h"
Packit 2900a8
#include "mw_util.h"
Packit 2900a8
#include "mw_st_list.h"
Packit 2900a8
Packit 2900a8
Packit 2900a8
struct mwSametimeList {
Packit 2900a8
  guint ver_major;
Packit 2900a8
  guint ver_minor;
Packit 2900a8
  guint ver_micro;
Packit 2900a8
Packit 2900a8
  GList *groups;
Packit 2900a8
};
Packit 2900a8
Packit 2900a8
Packit 2900a8
struct mwSametimeGroup {
Packit 2900a8
  struct mwSametimeList *list;
Packit 2900a8
Packit 2900a8
  enum mwSametimeGroupType type;
Packit 2900a8
  char *name;
Packit 2900a8
  char *alias;
Packit 2900a8
  gboolean open;
Packit 2900a8
Packit 2900a8
  GList *users;
Packit 2900a8
};
Packit 2900a8
Packit 2900a8
Packit 2900a8
struct mwSametimeUser {
Packit 2900a8
  struct mwSametimeGroup *group;
Packit 2900a8
Packit 2900a8
  enum mwSametimeUserType type;
Packit 2900a8
  struct mwIdBlock id;
Packit 2900a8
  char *name;
Packit 2900a8
  char *alias;
Packit 2900a8
};
Packit 2900a8
Packit 2900a8
Packit 2900a8
static void user_free(struct mwSametimeUser *u) {
Packit 2900a8
  struct mwSametimeGroup *g;
Packit 2900a8
Packit 2900a8
  g = u->group;
Packit 2900a8
  g->users = g_list_remove(g->users, u);
Packit 2900a8
Packit 2900a8
  mwIdBlock_clear(&u->id);
Packit 2900a8
  g_free(u->name);
Packit 2900a8
  g_free(u->alias);
Packit 2900a8
  g_free(u);
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
static void group_free(struct mwSametimeGroup *g) {
Packit 2900a8
  struct mwSametimeList *l;
Packit 2900a8
Packit 2900a8
  l = g->list;
Packit 2900a8
  l->groups = g_list_remove(l->groups, g);
Packit 2900a8
Packit 2900a8
  while(g->users)
Packit 2900a8
    mwSametimeUser_free(g->users->data);
Packit 2900a8
Packit 2900a8
  g_free(g->name);
Packit 2900a8
  g_free(g->alias);
Packit 2900a8
  g_free(g);
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
static void list_free(struct mwSametimeList *l) {
Packit 2900a8
  while(l->groups)
Packit 2900a8
    mwSametimeGroup_free(l->groups->data);
Packit 2900a8
Packit 2900a8
  g_free(l);
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
struct mwSametimeList *
Packit 2900a8
mwSametimeList_new() {
Packit 2900a8
Packit 2900a8
  struct mwSametimeList *stl;
Packit 2900a8
Packit 2900a8
  stl = g_new0(struct mwSametimeList, 1);
Packit 2900a8
  stl->ver_major = ST_LIST_MAJOR;
Packit 2900a8
  stl->ver_minor = ST_LIST_MINOR;
Packit 2900a8
  stl->ver_micro = ST_LIST_MICRO;
Packit 2900a8
Packit 2900a8
  return stl;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
void mwSametimeList_setMajor(struct mwSametimeList *l, guint v) {
Packit 2900a8
  g_return_if_fail(l != NULL);
Packit 2900a8
  l->ver_major = v;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
guint mwSametimeList_getMajor(struct mwSametimeList *l) {
Packit 2900a8
  g_return_val_if_fail(l != NULL, 0);
Packit 2900a8
  return l->ver_major;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
void mwSametimeList_setMinor(struct mwSametimeList *l, guint v) {
Packit 2900a8
  g_return_if_fail(l != NULL);
Packit 2900a8
  l->ver_minor = v;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
guint mwSametimeList_getMinor(struct mwSametimeList *l) {
Packit 2900a8
  g_return_val_if_fail(l != NULL, 0);
Packit 2900a8
  return l->ver_minor;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
void mwSametimeList_setMicro(struct mwSametimeList *l, guint v) {
Packit 2900a8
  g_return_if_fail(l != NULL);
Packit 2900a8
  l->ver_micro = v;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
guint mwSametimeList_getMicro(struct mwSametimeList *l) {
Packit 2900a8
  g_return_val_if_fail(l != NULL, 0);
Packit 2900a8
  return l->ver_micro;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
GList *mwSametimeList_getGroups(struct mwSametimeList *l) {
Packit 2900a8
  g_return_val_if_fail(l != NULL, NULL);
Packit 2900a8
  return g_list_copy(l->groups);
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
struct mwSametimeGroup *
Packit 2900a8
mwSametimeList_findGroup(struct mwSametimeList *l,
Packit 2900a8
			 const char *name) {
Packit 2900a8
  GList *s;
Packit 2900a8
Packit 2900a8
  g_return_val_if_fail(l != NULL, NULL);
Packit 2900a8
  g_return_val_if_fail(name != NULL, NULL);
Packit 2900a8
  g_return_val_if_fail(*name != '\0', NULL);
Packit 2900a8
Packit 2900a8
  for(s = l->groups; s; s = s->next) {
Packit 2900a8
    struct mwSametimeGroup *g = s->data;
Packit 2900a8
    if(! strcmp(g->name, name)) return g;
Packit 2900a8
  }
Packit 2900a8
Packit 2900a8
  return NULL;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
void mwSametimeList_free(struct mwSametimeList *l) {
Packit 2900a8
  g_return_if_fail(l != NULL);
Packit 2900a8
  list_free(l);
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
struct mwSametimeGroup *
Packit 2900a8
mwSametimeGroup_new(struct mwSametimeList *list,
Packit 2900a8
		    enum mwSametimeGroupType type,
Packit 2900a8
		    const char *name) {
Packit 2900a8
  
Packit 2900a8
  struct mwSametimeGroup *stg;
Packit 2900a8
Packit 2900a8
  g_return_val_if_fail(list != NULL, NULL);
Packit 2900a8
  g_return_val_if_fail(name != NULL, NULL);
Packit 2900a8
  g_return_val_if_fail(*name != '\0', NULL);
Packit 2900a8
Packit 2900a8
  stg = g_new0(struct mwSametimeGroup, 1);
Packit 2900a8
  stg->list = list;
Packit 2900a8
  stg->type = type;
Packit 2900a8
  stg->name = g_strdup(name);
Packit 2900a8
Packit 2900a8
  list->groups = g_list_append(list->groups, stg);
Packit 2900a8
Packit 2900a8
  return stg;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
enum mwSametimeGroupType mwSametimeGroup_getType(struct mwSametimeGroup *g) {
Packit 2900a8
  g_return_val_if_fail(g != NULL, mwSametimeGroup_UNKNOWN);
Packit 2900a8
  return g->type;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
const char *mwSametimeGroup_getName(struct mwSametimeGroup *g) {
Packit 2900a8
  g_return_val_if_fail(g != NULL, NULL);
Packit 2900a8
  return g->name;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
void mwSametimeGroup_setAlias(struct mwSametimeGroup *g,
Packit 2900a8
			      const char *alias) {
Packit 2900a8
  g_return_if_fail(g != NULL);
Packit 2900a8
Packit 2900a8
  g_free(g->alias);
Packit 2900a8
  g->alias = g_strdup(alias);
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
const char *mwSametimeGroup_getAlias(struct mwSametimeGroup *g) {
Packit 2900a8
  g_return_val_if_fail(g != NULL, NULL);
Packit 2900a8
  return g->alias;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
void mwSametimeGroup_setOpen(struct mwSametimeGroup *g, gboolean open) {
Packit 2900a8
  g_return_if_fail(g != NULL);
Packit 2900a8
  g->open = open;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
gboolean mwSametimeGroup_isOpen(struct mwSametimeGroup *g) {
Packit 2900a8
  g_return_val_if_fail(g != NULL, FALSE);
Packit 2900a8
  return g->open;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
struct mwSametimeList *mwSametimeGroup_getList(struct mwSametimeGroup *g) {
Packit 2900a8
  g_return_val_if_fail(g != NULL, NULL);
Packit 2900a8
  return g->list;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
GList *mwSametimeGroup_getUsers(struct mwSametimeGroup *g) {
Packit 2900a8
  g_return_val_if_fail(g != NULL, NULL);
Packit 2900a8
  return g_list_copy(g->users);
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
struct mwSametimeUser *
Packit 2900a8
mwSametimeGroup_findUser(struct mwSametimeGroup *g,
Packit 2900a8
			 struct mwIdBlock *user) {
Packit 2900a8
  GList *s;
Packit 2900a8
Packit 2900a8
  g_return_val_if_fail(g != NULL, NULL);
Packit 2900a8
  g_return_val_if_fail(user != NULL, NULL);
Packit 2900a8
Packit 2900a8
  for(s = g->users; s; s = s->next) {
Packit 2900a8
    struct mwSametimeUser *u = s->data;
Packit 2900a8
    if(mwIdBlock_equal(user, &u->id)) return u;
Packit 2900a8
  }
Packit 2900a8
Packit 2900a8
  return NULL;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
void mwSametimeGroup_free(struct mwSametimeGroup *g) {
Packit 2900a8
  g_return_if_fail(g != NULL);
Packit 2900a8
  g_return_if_fail(g->list != NULL);
Packit 2900a8
  group_free(g);
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
struct mwSametimeUser *
Packit 2900a8
mwSametimeUser_new(struct mwSametimeGroup *group,
Packit 2900a8
		   enum mwSametimeUserType type,
Packit 2900a8
		   struct mwIdBlock *id) {
Packit 2900a8
Packit 2900a8
  struct mwSametimeUser *stu;
Packit 2900a8
Packit 2900a8
  g_return_val_if_fail(group != NULL, NULL);
Packit 2900a8
  g_return_val_if_fail(id != NULL, NULL);
Packit 2900a8
  
Packit 2900a8
  stu = g_new0(struct mwSametimeUser, 1);
Packit 2900a8
  stu->group = group;
Packit 2900a8
  stu->type = type;
Packit 2900a8
  mwIdBlock_clone(&stu->id, id);
Packit 2900a8
Packit 2900a8
  group->users = g_list_append(group->users, stu);
Packit 2900a8
  
Packit 2900a8
  return stu;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
struct mwSametimeGroup *mwSametimeUser_getGroup(struct mwSametimeUser *u) {
Packit 2900a8
  g_return_val_if_fail(u != NULL, NULL);
Packit 2900a8
  return u->group;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
enum mwSametimeUserType mwSametimeUser_getType(struct mwSametimeUser *u) {
Packit 2900a8
  g_return_val_if_fail(u != NULL, mwSametimeUser_UNKNOWN);
Packit 2900a8
  return u->type;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
const char *mwSametimeUser_getUser(struct mwSametimeUser *u) {
Packit 2900a8
  g_return_val_if_fail(u != NULL, NULL);
Packit 2900a8
  return u->id.user;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
const char *mwSametimeUser_getCommunity(struct mwSametimeUser *u) {
Packit 2900a8
  g_return_val_if_fail(u != NULL, NULL);
Packit 2900a8
  return u->id.community;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
void mwSametimeUser_setShortName(struct mwSametimeUser *u, const char *name) {
Packit 2900a8
  g_return_if_fail(u != NULL);
Packit 2900a8
  g_free(u->name);
Packit 2900a8
  u->name = g_strdup(name);
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
const char *mwSametimeUser_getShortName(struct mwSametimeUser *u) {
Packit 2900a8
  g_return_val_if_fail(u != NULL, NULL);
Packit 2900a8
  return u->name;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
void mwSametimeUser_setAlias(struct mwSametimeUser *u, const char *alias) {
Packit 2900a8
  g_return_if_fail(u != NULL);
Packit 2900a8
  g_free(u->alias);
Packit 2900a8
  u->alias = g_strdup(alias);
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
const char *mwSametimeUser_getAlias(struct mwSametimeUser *u) {
Packit 2900a8
  g_return_val_if_fail(u != NULL, NULL);
Packit 2900a8
  return u->alias;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
void mwSametimeUser_free(struct mwSametimeUser *u) {
Packit 2900a8
  g_return_if_fail(u != NULL);
Packit 2900a8
  g_return_if_fail(u->group != NULL);
Packit 2900a8
  user_free(u);
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
static void str_replace(char *str, char from, char to) {
Packit 2900a8
  if(! str) return;
Packit 2900a8
  for(; *str; str++) if(*str == from) *str = to;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
static char user_type_to_char(enum mwSametimeUserType type) {
Packit 2900a8
  switch(type) {
Packit 2900a8
  case mwSametimeUser_NORMAL:    return '1';
Packit 2900a8
  case mwSametimeUser_EXTERNAL:  return '2';
Packit 2900a8
  case mwSametimeUser_UNKNOWN:
Packit 2900a8
  default:                       return '9';
Packit 2900a8
  }
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
static enum mwSametimeUserType user_char_to_type(char type) {
Packit 2900a8
  switch(type) {
Packit 2900a8
  case '1':  return mwSametimeUser_NORMAL;
Packit 2900a8
  case '2':  return mwSametimeUser_EXTERNAL;
Packit 2900a8
  default:   return mwSametimeUser_UNKNOWN;
Packit 2900a8
  }
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
static void user_put(GString *str, struct mwSametimeUser *u) {
Packit 2900a8
  char *id, *name, *alias;
Packit 2900a8
  char type;
Packit 2900a8
  
Packit 2900a8
  id = g_strdup(u->id.user);
Packit 2900a8
  name = g_strdup(u->name);
Packit 2900a8
  alias = g_strdup(u->alias);
Packit 2900a8
  type = user_type_to_char(u->type);
Packit 2900a8
Packit 2900a8
  if(id) str_replace(id, ' ', ';');
Packit 2900a8
  if(name) str_replace(name, ' ', ';');
Packit 2900a8
  if(alias) str_replace(alias, ' ', ';');
Packit 2900a8
Packit 2900a8
  if(!name && alias) {
Packit 2900a8
    name = alias;
Packit 2900a8
    alias = NULL;
Packit 2900a8
  }
Packit 2900a8
Packit 2900a8
  g_string_append_printf(str, "U %s%c:: %s,%s\r\n",
Packit 2900a8
			 id, type, (name? name: ""), (alias? alias: ""));
Packit 2900a8
Packit 2900a8
  g_free(id);
Packit 2900a8
  g_free(name);
Packit 2900a8
  g_free(alias);  
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
static char group_type_to_char(enum mwSametimeGroupType type) {
Packit 2900a8
  switch(type) {
Packit 2900a8
  case mwSametimeGroup_NORMAL:   return '2';
Packit 2900a8
  case mwSametimeGroup_DYNAMIC:  return '3';
Packit 2900a8
  case mwSametimeGroup_UNKNOWN:
Packit 2900a8
  default:                       return '9';
Packit 2900a8
  }
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
static enum mwSametimeGroupType group_char_to_type(char type) {
Packit 2900a8
  switch(type) {
Packit 2900a8
  case '2':  return mwSametimeGroup_NORMAL;
Packit 2900a8
  case '3':  return mwSametimeGroup_DYNAMIC;
Packit 2900a8
  default:   return mwSametimeGroup_UNKNOWN;
Packit 2900a8
  }
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
static void group_put(GString *str, struct mwSametimeGroup *g) {
Packit 2900a8
  char *name, *alias;
Packit 2900a8
  char type;
Packit 2900a8
  GList *gl;
Packit 2900a8
Packit 2900a8
  name = g_strdup(g->name);
Packit 2900a8
  alias = g_strdup((g->alias)? g->alias: name);
Packit 2900a8
  type = group_type_to_char(g->type);
Packit 2900a8
Packit 2900a8
  str_replace(name, ' ', ';');
Packit 2900a8
  str_replace(alias, ' ', ';');
Packit 2900a8
Packit 2900a8
  g_string_append_printf(str, "G %s%c %s %c\r\n",
Packit 2900a8
			 name, type, alias, (g->open? 'O':'C'));
Packit 2900a8
Packit 2900a8
  for(gl = g->users; gl; gl = gl->next) {
Packit 2900a8
    user_put(str, gl->data);
Packit 2900a8
  }
Packit 2900a8
Packit 2900a8
  g_free(name);
Packit 2900a8
  g_free(alias);
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
/** composes a GString with the written contents of a sametime list */
Packit 2900a8
static GString *list_store(struct mwSametimeList *l) {
Packit 2900a8
  GString *str;
Packit 2900a8
  GList *gl;
Packit 2900a8
Packit 2900a8
  g_return_val_if_fail(l != NULL, NULL);
Packit 2900a8
Packit 2900a8
  str = g_string_new(NULL);
Packit 2900a8
  g_string_append_printf(str, "Version=%u.%u.%u\r\n",
Packit 2900a8
			 l->ver_major, l->ver_minor, l->ver_micro);
Packit 2900a8
Packit 2900a8
  for(gl = l->groups; gl; gl = gl->next) {
Packit 2900a8
    group_put(str, gl->data);
Packit 2900a8
  }
Packit 2900a8
Packit 2900a8
  return str;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
char *mwSametimeList_store(struct mwSametimeList *l) {
Packit 2900a8
  GString *str;
Packit 2900a8
  char *s;
Packit 2900a8
Packit 2900a8
  g_return_val_if_fail(l != NULL, NULL);
Packit 2900a8
Packit 2900a8
  str = list_store(l);
Packit 2900a8
  s = str->str;
Packit 2900a8
  g_string_free(str, FALSE);
Packit 2900a8
  return s;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
void mwSametimeList_put(struct mwPutBuffer *b, struct mwSametimeList *l) {
Packit 2900a8
  GString *str;
Packit 2900a8
  guint16 len;
Packit 2900a8
Packit 2900a8
  g_return_if_fail(l != NULL);
Packit 2900a8
  g_return_if_fail(b != NULL);
Packit 2900a8
Packit 2900a8
  str = list_store(l);
Packit 2900a8
  len = (guint16) str->len;
Packit 2900a8
  guint16_put(b, len);
Packit 2900a8
  mwPutBuffer_write(b, str->str, len);
Packit 2900a8
Packit 2900a8
  g_string_free(str, TRUE);
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
static void get_version(const char *line, struct mwSametimeList *l) {
Packit 2900a8
  guint major = 0, minor = 0, micro = 0;
Packit 2900a8
  int ret;
Packit 2900a8
Packit 2900a8
  ret = sscanf(line, "Version=%u.%u.%u\n", &major, &minor, µ);
Packit 2900a8
  if(ret != 3) {
Packit 2900a8
    g_warning("strange sametime list version line:\n%s", line);
Packit 2900a8
  }
Packit 2900a8
Packit 2900a8
  l->ver_major = major;
Packit 2900a8
  l->ver_minor = minor;
Packit 2900a8
  l->ver_micro = micro;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
static struct mwSametimeGroup *get_group(const char *line,
Packit 2900a8
					 struct mwSametimeList *l) {
Packit 2900a8
  struct mwSametimeGroup *group;
Packit 2900a8
  char *name, *alias;
Packit 2900a8
  char type = '2', open = 'O';
Packit 2900a8
  int ret;
Packit 2900a8
Packit 2900a8
  ret = strlen(line);
Packit 2900a8
  name = g_malloc0(ret);
Packit 2900a8
  alias = g_malloc0(ret);
Packit 2900a8
Packit 2900a8
  ret = sscanf(line, "G %s %s %c\n",
Packit 2900a8
	       name, alias, &open;;
Packit 2900a8
Packit 2900a8
  if(ret < 3) {
Packit 2900a8
    g_warning("strange sametime list group line:\n%s", line);
Packit 2900a8
  }
Packit 2900a8
  
Packit 2900a8
  str_replace(name, ';', ' ');
Packit 2900a8
  str_replace(alias, ';', ' ');
Packit 2900a8
Packit 2900a8
  if(name && *name) {
Packit 2900a8
    int l = strlen(name)-1;
Packit 2900a8
    type = name[l];
Packit 2900a8
    name[l] = '\0';
Packit 2900a8
  }
Packit 2900a8
Packit 2900a8
  group = g_new0(struct mwSametimeGroup, 1);
Packit 2900a8
  group->list = l;
Packit 2900a8
  group->name = name;
Packit 2900a8
  group->type = group_char_to_type(type);
Packit 2900a8
  group->alias = alias;
Packit 2900a8
  group->open = (open == 'O');
Packit 2900a8
Packit 2900a8
  l->groups = g_list_append(l->groups, group);
Packit 2900a8
Packit 2900a8
  return group;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
static void get_user(const char *line, struct mwSametimeGroup *g) {
Packit 2900a8
  struct mwSametimeUser *user;
Packit 2900a8
  struct mwIdBlock idb = { 0, 0 };
Packit 2900a8
  char *name, *alias = NULL;
Packit 2900a8
  char type = '1';
Packit 2900a8
  int ret;
Packit 2900a8
  
Packit 2900a8
  ret = strlen(line);
Packit 2900a8
  idb.user = g_malloc0(ret);
Packit 2900a8
  name = g_malloc0(ret);
Packit 2900a8
Packit 2900a8
  ret = sscanf(line, "U %s %s",
Packit 2900a8
	       idb.user, name);
Packit 2900a8
Packit 2900a8
  if(ret < 2) {
Packit 2900a8
    g_warning("strange sametime list user line:\n%s", line);
Packit 2900a8
  }
Packit 2900a8
Packit 2900a8
  str_replace(idb.user, ';', ' ');
Packit 2900a8
  str_replace(name, ';', ' ');
Packit 2900a8
Packit 2900a8
  if(idb.user && *idb.user) {
Packit 2900a8
    char *tmp = strstr(idb.user, "::");
Packit 2900a8
    if(tmp--) {
Packit 2900a8
      type = *(tmp);
Packit 2900a8
      *tmp = '\0';
Packit 2900a8
    }
Packit 2900a8
  }
Packit 2900a8
Packit 2900a8
  if(name && *name) {
Packit 2900a8
    char *tmp = strrchr(name, ',');
Packit 2900a8
    if(tmp) {
Packit 2900a8
      *tmp++ = '\0';
Packit 2900a8
      if(*tmp) alias = tmp;
Packit 2900a8
    }
Packit 2900a8
  }
Packit 2900a8
Packit 2900a8
  user = g_new0(struct mwSametimeUser, 1);
Packit 2900a8
  user->group = g;
Packit 2900a8
  user->id.user = idb.user;
Packit 2900a8
  user->type = user_char_to_type(type);
Packit 2900a8
  user->name = name;
Packit 2900a8
  user->alias = g_strdup(alias);
Packit 2900a8
  
Packit 2900a8
  g->users = g_list_append(g->users, user);
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
/** returns a line from str, and advances str */
Packit 2900a8
static char *fetch_line(char **str) {
Packit 2900a8
  char *start = *str;
Packit 2900a8
  char *end;
Packit 2900a8
Packit 2900a8
  /* move to first non-whitespace character */
Packit 2900a8
  while(*start && g_ascii_isspace(*start)) start++;
Packit 2900a8
  if(! *start) return NULL;
Packit 2900a8
Packit 2900a8
  for(end = start + 1; *end; end++) {
Packit 2900a8
    if(*end == '\n' || *end == '\r') {
Packit 2900a8
      *(end++) = '\0';
Packit 2900a8
      break;
Packit 2900a8
    }
Packit 2900a8
  }
Packit 2900a8
Packit 2900a8
  *str = end;
Packit 2900a8
  return start;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
static void list_get(const char *lines, struct mwSametimeList *l) {
Packit 2900a8
  char *s = (char *) lines;
Packit 2900a8
  char *line;
Packit 2900a8
Packit 2900a8
  struct mwSametimeGroup *g = NULL;
Packit 2900a8
  
Packit 2900a8
  while( (line = fetch_line(&s)) ) {
Packit 2900a8
    switch(*line) {
Packit 2900a8
    case 'V':
Packit 2900a8
      get_version(line, l);
Packit 2900a8
      break;
Packit 2900a8
Packit 2900a8
    case 'G':
Packit 2900a8
      g = get_group(line, l);
Packit 2900a8
      break;
Packit 2900a8
Packit 2900a8
    case 'U':
Packit 2900a8
      get_user(line, g);
Packit 2900a8
      break;
Packit 2900a8
Packit 2900a8
    default:
Packit 2900a8
      g_warning("unknown sametime list data line:\n%s", line);
Packit 2900a8
    }
Packit 2900a8
  }  
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
struct mwSametimeList *mwSametimeList_load(const char *data) {
Packit 2900a8
  struct mwSametimeList *l;
Packit 2900a8
Packit 2900a8
  g_return_val_if_fail(data != NULL, NULL);
Packit 2900a8
  
Packit 2900a8
  l = mwSametimeList_new();
Packit 2900a8
  list_get(data, l);
Packit 2900a8
Packit 2900a8
  return l;
Packit 2900a8
}
Packit 2900a8
Packit 2900a8
Packit 2900a8
void mwSametimeList_get(struct mwGetBuffer *b, struct mwSametimeList *l) {
Packit 2900a8
  char *str = NULL;
Packit 2900a8
Packit 2900a8
  g_return_if_fail(l != NULL);
Packit 2900a8
  g_return_if_fail(b != NULL);
Packit 2900a8
Packit 2900a8
  mwString_get(b, &str);
Packit 2900a8
  list_get(str, l);
Packit 2900a8
  g_free(str);
Packit 2900a8
}
Packit 2900a8