Blame src/st_list.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 <stdio.h>
Packit Service 37472d
#include <string.h>
Packit Service 1bfe49
#include <glib.h>
Packit Service 37472d
Packit Service 37472d
#include "mw_debug.h"
Packit Service 37472d
#include "mw_util.h"
Packit Service 37472d
#include "mw_st_list.h"
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwSametimeList {
Packit Service 37472d
  guint ver_major;
Packit Service 37472d
  guint ver_minor;
Packit Service 37472d
  guint ver_micro;
Packit Service 37472d
Packit Service 37472d
  GList *groups;
Packit Service 37472d
};
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwSametimeGroup {
Packit Service 37472d
  struct mwSametimeList *list;
Packit Service 37472d
Packit Service 37472d
  enum mwSametimeGroupType type;
Packit Service 37472d
  char *name;
Packit Service 37472d
  char *alias;
Packit Service 37472d
  gboolean open;
Packit Service 37472d
Packit Service 37472d
  GList *users;
Packit Service 37472d
};
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwSametimeUser {
Packit Service 37472d
  struct mwSametimeGroup *group;
Packit Service 37472d
Packit Service 37472d
  enum mwSametimeUserType type;
Packit Service 37472d
  struct mwIdBlock id;
Packit Service 37472d
  char *name;
Packit Service 37472d
  char *alias;
Packit Service 37472d
};
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static void user_free(struct mwSametimeUser *u) {
Packit Service 37472d
  struct mwSametimeGroup *g;
Packit Service 37472d
Packit Service 37472d
  g = u->group;
Packit Service 37472d
  g->users = g_list_remove(g->users, u);
Packit Service 37472d
Packit Service 37472d
  mwIdBlock_clear(&u->id);
Packit Service 37472d
  g_free(u->name);
Packit Service 37472d
  g_free(u->alias);
Packit Service 37472d
  g_free(u);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static void group_free(struct mwSametimeGroup *g) {
Packit Service 37472d
  struct mwSametimeList *l;
Packit Service 37472d
Packit Service 37472d
  l = g->list;
Packit Service 37472d
  l->groups = g_list_remove(l->groups, g);
Packit Service 37472d
Packit Service 37472d
  while(g->users)
Packit Service 37472d
    mwSametimeUser_free(g->users->data);
Packit Service 37472d
Packit Service 37472d
  g_free(g->name);
Packit Service 37472d
  g_free(g->alias);
Packit Service 37472d
  g_free(g);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static void list_free(struct mwSametimeList *l) {
Packit Service 37472d
  while(l->groups)
Packit Service 37472d
    mwSametimeGroup_free(l->groups->data);
Packit Service 37472d
Packit Service 37472d
  g_free(l);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwSametimeList *
Packit Service 37472d
mwSametimeList_new() {
Packit Service 37472d
Packit Service 37472d
  struct mwSametimeList *stl;
Packit Service 37472d
Packit Service 37472d
  stl = g_new0(struct mwSametimeList, 1);
Packit Service 37472d
  stl->ver_major = ST_LIST_MAJOR;
Packit Service 37472d
  stl->ver_minor = ST_LIST_MINOR;
Packit Service 37472d
  stl->ver_micro = ST_LIST_MICRO;
Packit Service 37472d
Packit Service 37472d
  return stl;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwSametimeList_setMajor(struct mwSametimeList *l, guint v) {
Packit Service 37472d
  g_return_if_fail(l != NULL);
Packit Service 37472d
  l->ver_major = v;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
guint mwSametimeList_getMajor(struct mwSametimeList *l) {
Packit Service 37472d
  g_return_val_if_fail(l != NULL, 0);
Packit Service 37472d
  return l->ver_major;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwSametimeList_setMinor(struct mwSametimeList *l, guint v) {
Packit Service 37472d
  g_return_if_fail(l != NULL);
Packit Service 37472d
  l->ver_minor = v;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
guint mwSametimeList_getMinor(struct mwSametimeList *l) {
Packit Service 37472d
  g_return_val_if_fail(l != NULL, 0);
Packit Service 37472d
  return l->ver_minor;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwSametimeList_setMicro(struct mwSametimeList *l, guint v) {
Packit Service 37472d
  g_return_if_fail(l != NULL);
Packit Service 37472d
  l->ver_micro = v;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
guint mwSametimeList_getMicro(struct mwSametimeList *l) {
Packit Service 37472d
  g_return_val_if_fail(l != NULL, 0);
Packit Service 37472d
  return l->ver_micro;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
GList *mwSametimeList_getGroups(struct mwSametimeList *l) {
Packit Service 37472d
  g_return_val_if_fail(l != NULL, NULL);
Packit Service 37472d
  return g_list_copy(l->groups);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwSametimeGroup *
Packit Service 37472d
mwSametimeList_findGroup(struct mwSametimeList *l,
Packit Service 37472d
			 const char *name) {
Packit Service 37472d
  GList *s;
Packit Service 37472d
Packit Service 37472d
  g_return_val_if_fail(l != NULL, NULL);
Packit Service 37472d
  g_return_val_if_fail(name != NULL, NULL);
Packit Service 37472d
  g_return_val_if_fail(*name != '\0', NULL);
Packit Service 37472d
Packit Service 37472d
  for(s = l->groups; s; s = s->next) {
Packit Service 37472d
    struct mwSametimeGroup *g = s->data;
Packit Service 37472d
    if(! strcmp(g->name, name)) return g;
Packit Service 37472d
  }
Packit Service 37472d
Packit Service 37472d
  return NULL;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwSametimeList_free(struct mwSametimeList *l) {
Packit Service 37472d
  g_return_if_fail(l != NULL);
Packit Service 37472d
  list_free(l);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwSametimeGroup *
Packit Service 37472d
mwSametimeGroup_new(struct mwSametimeList *list,
Packit Service 37472d
		    enum mwSametimeGroupType type,
Packit Service 37472d
		    const char *name) {
Packit Service 37472d
  
Packit Service 37472d
  struct mwSametimeGroup *stg;
Packit Service 37472d
Packit Service 37472d
  g_return_val_if_fail(list != NULL, NULL);
Packit Service 37472d
  g_return_val_if_fail(name != NULL, NULL);
Packit Service 37472d
  g_return_val_if_fail(*name != '\0', NULL);
Packit Service 37472d
Packit Service 37472d
  stg = g_new0(struct mwSametimeGroup, 1);
Packit Service 37472d
  stg->list = list;
Packit Service 37472d
  stg->type = type;
Packit Service 37472d
  stg->name = g_strdup(name);
Packit Service 37472d
Packit Service 37472d
  list->groups = g_list_append(list->groups, stg);
Packit Service 37472d
Packit Service 37472d
  return stg;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
enum mwSametimeGroupType mwSametimeGroup_getType(struct mwSametimeGroup *g) {
Packit Service 37472d
  g_return_val_if_fail(g != NULL, mwSametimeGroup_UNKNOWN);
Packit Service 37472d
  return g->type;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
const char *mwSametimeGroup_getName(struct mwSametimeGroup *g) {
Packit Service 37472d
  g_return_val_if_fail(g != NULL, NULL);
Packit Service 37472d
  return g->name;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwSametimeGroup_setAlias(struct mwSametimeGroup *g,
Packit Service 37472d
			      const char *alias) {
Packit Service 37472d
  g_return_if_fail(g != NULL);
Packit Service 37472d
Packit Service 37472d
  g_free(g->alias);
Packit Service 37472d
  g->alias = g_strdup(alias);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
const char *mwSametimeGroup_getAlias(struct mwSametimeGroup *g) {
Packit Service 37472d
  g_return_val_if_fail(g != NULL, NULL);
Packit Service 37472d
  return g->alias;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwSametimeGroup_setOpen(struct mwSametimeGroup *g, gboolean open) {
Packit Service 37472d
  g_return_if_fail(g != NULL);
Packit Service 37472d
  g->open = open;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
gboolean mwSametimeGroup_isOpen(struct mwSametimeGroup *g) {
Packit Service 37472d
  g_return_val_if_fail(g != NULL, FALSE);
Packit Service 37472d
  return g->open;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwSametimeList *mwSametimeGroup_getList(struct mwSametimeGroup *g) {
Packit Service 37472d
  g_return_val_if_fail(g != NULL, NULL);
Packit Service 37472d
  return g->list;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
GList *mwSametimeGroup_getUsers(struct mwSametimeGroup *g) {
Packit Service 37472d
  g_return_val_if_fail(g != NULL, NULL);
Packit Service 37472d
  return g_list_copy(g->users);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwSametimeUser *
Packit Service 37472d
mwSametimeGroup_findUser(struct mwSametimeGroup *g,
Packit Service 37472d
			 struct mwIdBlock *user) {
Packit Service 37472d
  GList *s;
Packit Service 37472d
Packit Service 37472d
  g_return_val_if_fail(g != NULL, NULL);
Packit Service 37472d
  g_return_val_if_fail(user != NULL, NULL);
Packit Service 37472d
Packit Service 37472d
  for(s = g->users; s; s = s->next) {
Packit Service 37472d
    struct mwSametimeUser *u = s->data;
Packit Service 37472d
    if(mwIdBlock_equal(user, &u->id)) return u;
Packit Service 37472d
  }
Packit Service 37472d
Packit Service 37472d
  return NULL;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwSametimeGroup_free(struct mwSametimeGroup *g) {
Packit Service 37472d
  g_return_if_fail(g != NULL);
Packit Service 37472d
  g_return_if_fail(g->list != NULL);
Packit Service 37472d
  group_free(g);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwSametimeUser *
Packit Service 37472d
mwSametimeUser_new(struct mwSametimeGroup *group,
Packit Service 37472d
		   enum mwSametimeUserType type,
Packit Service 37472d
		   struct mwIdBlock *id) {
Packit Service 37472d
Packit Service 37472d
  struct mwSametimeUser *stu;
Packit Service 37472d
Packit Service 37472d
  g_return_val_if_fail(group != NULL, NULL);
Packit Service 37472d
  g_return_val_if_fail(id != NULL, NULL);
Packit Service 37472d
  
Packit Service 37472d
  stu = g_new0(struct mwSametimeUser, 1);
Packit Service 37472d
  stu->group = group;
Packit Service 37472d
  stu->type = type;
Packit Service 37472d
  mwIdBlock_clone(&stu->id, id);
Packit Service 37472d
Packit Service 37472d
  group->users = g_list_append(group->users, stu);
Packit Service 37472d
  
Packit Service 37472d
  return stu;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwSametimeGroup *mwSametimeUser_getGroup(struct mwSametimeUser *u) {
Packit Service 37472d
  g_return_val_if_fail(u != NULL, NULL);
Packit Service 37472d
  return u->group;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
enum mwSametimeUserType mwSametimeUser_getType(struct mwSametimeUser *u) {
Packit Service 37472d
  g_return_val_if_fail(u != NULL, mwSametimeUser_UNKNOWN);
Packit Service 37472d
  return u->type;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
const char *mwSametimeUser_getUser(struct mwSametimeUser *u) {
Packit Service 37472d
  g_return_val_if_fail(u != NULL, NULL);
Packit Service 37472d
  return u->id.user;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
const char *mwSametimeUser_getCommunity(struct mwSametimeUser *u) {
Packit Service 37472d
  g_return_val_if_fail(u != NULL, NULL);
Packit Service 37472d
  return u->id.community;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwSametimeUser_setShortName(struct mwSametimeUser *u, const char *name) {
Packit Service 37472d
  g_return_if_fail(u != NULL);
Packit Service 37472d
  g_free(u->name);
Packit Service 37472d
  u->name = g_strdup(name);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
const char *mwSametimeUser_getShortName(struct mwSametimeUser *u) {
Packit Service 37472d
  g_return_val_if_fail(u != NULL, NULL);
Packit Service 37472d
  return u->name;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwSametimeUser_setAlias(struct mwSametimeUser *u, const char *alias) {
Packit Service 37472d
  g_return_if_fail(u != NULL);
Packit Service 37472d
  g_free(u->alias);
Packit Service 37472d
  u->alias = g_strdup(alias);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
const char *mwSametimeUser_getAlias(struct mwSametimeUser *u) {
Packit Service 37472d
  g_return_val_if_fail(u != NULL, NULL);
Packit Service 37472d
  return u->alias;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwSametimeUser_free(struct mwSametimeUser *u) {
Packit Service 37472d
  g_return_if_fail(u != NULL);
Packit Service 37472d
  g_return_if_fail(u->group != NULL);
Packit Service 37472d
  user_free(u);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static void str_replace(char *str, char from, char to) {
Packit Service 37472d
  if(! str) return;
Packit Service 37472d
  for(; *str; str++) if(*str == from) *str = to;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static char user_type_to_char(enum mwSametimeUserType type) {
Packit Service 37472d
  switch(type) {
Packit Service 37472d
  case mwSametimeUser_NORMAL:    return '1';
Packit Service 37472d
  case mwSametimeUser_EXTERNAL:  return '2';
Packit Service 37472d
  case mwSametimeUser_UNKNOWN:
Packit Service 37472d
  default:                       return '9';
Packit Service 37472d
  }
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static enum mwSametimeUserType user_char_to_type(char type) {
Packit Service 37472d
  switch(type) {
Packit Service 37472d
  case '1':  return mwSametimeUser_NORMAL;
Packit Service 37472d
  case '2':  return mwSametimeUser_EXTERNAL;
Packit Service 37472d
  default:   return mwSametimeUser_UNKNOWN;
Packit Service 37472d
  }
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static void user_put(GString *str, struct mwSametimeUser *u) {
Packit Service 37472d
  char *id, *name, *alias;
Packit Service 37472d
  char type;
Packit Service 37472d
  
Packit Service 37472d
  id = g_strdup(u->id.user);
Packit Service 37472d
  name = g_strdup(u->name);
Packit Service 37472d
  alias = g_strdup(u->alias);
Packit Service 37472d
  type = user_type_to_char(u->type);
Packit Service 37472d
Packit Service 37472d
  if(id) str_replace(id, ' ', ';');
Packit Service 37472d
  if(name) str_replace(name, ' ', ';');
Packit Service 37472d
  if(alias) str_replace(alias, ' ', ';');
Packit Service 37472d
Packit Service 37472d
  if(!name && alias) {
Packit Service 37472d
    name = alias;
Packit Service 37472d
    alias = NULL;
Packit Service 37472d
  }
Packit Service 37472d
Packit Service 37472d
  g_string_append_printf(str, "U %s%c:: %s,%s\r\n",
Packit Service 37472d
			 id, type, (name? name: ""), (alias? alias: ""));
Packit Service 37472d
Packit Service 37472d
  g_free(id);
Packit Service 37472d
  g_free(name);
Packit Service 37472d
  g_free(alias);  
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static char group_type_to_char(enum mwSametimeGroupType type) {
Packit Service 37472d
  switch(type) {
Packit Service 37472d
  case mwSametimeGroup_NORMAL:   return '2';
Packit Service 37472d
  case mwSametimeGroup_DYNAMIC:  return '3';
Packit Service 37472d
  case mwSametimeGroup_UNKNOWN:
Packit Service 37472d
  default:                       return '9';
Packit Service 37472d
  }
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static enum mwSametimeGroupType group_char_to_type(char type) {
Packit Service 37472d
  switch(type) {
Packit Service 37472d
  case '2':  return mwSametimeGroup_NORMAL;
Packit Service 37472d
  case '3':  return mwSametimeGroup_DYNAMIC;
Packit Service 37472d
  default:   return mwSametimeGroup_UNKNOWN;
Packit Service 37472d
  }
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static void group_put(GString *str, struct mwSametimeGroup *g) {
Packit Service 37472d
  char *name, *alias;
Packit Service 37472d
  char type;
Packit Service 37472d
  GList *gl;
Packit Service 37472d
Packit Service 37472d
  name = g_strdup(g->name);
Packit Service 37472d
  alias = g_strdup((g->alias)? g->alias: name);
Packit Service 37472d
  type = group_type_to_char(g->type);
Packit Service 37472d
Packit Service 37472d
  str_replace(name, ' ', ';');
Packit Service 37472d
  str_replace(alias, ' ', ';');
Packit Service 37472d
Packit Service 37472d
  g_string_append_printf(str, "G %s%c %s %c\r\n",
Packit Service 37472d
			 name, type, alias, (g->open? 'O':'C'));
Packit Service 37472d
Packit Service 37472d
  for(gl = g->users; gl; gl = gl->next) {
Packit Service 37472d
    user_put(str, gl->data);
Packit Service 37472d
  }
Packit Service 37472d
Packit Service 37472d
  g_free(name);
Packit Service 37472d
  g_free(alias);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** composes a GString with the written contents of a sametime list */
Packit Service 37472d
static GString *list_store(struct mwSametimeList *l) {
Packit Service 37472d
  GString *str;
Packit Service 37472d
  GList *gl;
Packit Service 37472d
Packit Service 37472d
  g_return_val_if_fail(l != NULL, NULL);
Packit Service 37472d
Packit Service 37472d
  str = g_string_new(NULL);
Packit Service 37472d
  g_string_append_printf(str, "Version=%u.%u.%u\r\n",
Packit Service 37472d
			 l->ver_major, l->ver_minor, l->ver_micro);
Packit Service 37472d
Packit Service 37472d
  for(gl = l->groups; gl; gl = gl->next) {
Packit Service 37472d
    group_put(str, gl->data);
Packit Service 37472d
  }
Packit Service 37472d
Packit Service 37472d
  return str;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
char *mwSametimeList_store(struct mwSametimeList *l) {
Packit Service 37472d
  GString *str;
Packit Service 37472d
  char *s;
Packit Service 37472d
Packit Service 37472d
  g_return_val_if_fail(l != NULL, NULL);
Packit Service 37472d
Packit Service 37472d
  str = list_store(l);
Packit Service 37472d
  s = str->str;
Packit Service 37472d
  g_string_free(str, FALSE);
Packit Service 37472d
  return s;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwSametimeList_put(struct mwPutBuffer *b, struct mwSametimeList *l) {
Packit Service 37472d
  GString *str;
Packit Service 37472d
  guint16 len;
Packit Service 37472d
Packit Service 37472d
  g_return_if_fail(l != NULL);
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
Packit Service 37472d
  str = list_store(l);
Packit Service 37472d
  len = (guint16) str->len;
Packit Service 37472d
  guint16_put(b, len);
Packit Service 37472d
  mwPutBuffer_write(b, str->str, len);
Packit Service 37472d
Packit Service 37472d
  g_string_free(str, TRUE);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static void get_version(const char *line, struct mwSametimeList *l) {
Packit Service 37472d
  guint major = 0, minor = 0, micro = 0;
Packit Service 37472d
  int ret;
Packit Service 37472d
Packit Service 37472d
  ret = sscanf(line, "Version=%u.%u.%u\n", &major, &minor, µ);
Packit Service 37472d
  if(ret != 3) {
Packit Service 37472d
    g_warning("strange sametime list version line:\n%s", line);
Packit Service 37472d
  }
Packit Service 37472d
Packit Service 37472d
  l->ver_major = major;
Packit Service 37472d
  l->ver_minor = minor;
Packit Service 37472d
  l->ver_micro = micro;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static struct mwSametimeGroup *get_group(const char *line,
Packit Service 37472d
					 struct mwSametimeList *l) {
Packit Service 37472d
  struct mwSametimeGroup *group;
Packit Service 37472d
  char *name, *alias;
Packit Service 37472d
  char type = '2', open = 'O';
Packit Service 37472d
  int ret;
Packit Service 37472d
Packit Service 37472d
  ret = strlen(line);
Packit Service 37472d
  name = g_malloc0(ret);
Packit Service 37472d
  alias = g_malloc0(ret);
Packit Service 37472d
Packit Service 37472d
  ret = sscanf(line, "G %s %s %c\n",
Packit Service 37472d
	       name, alias, &open;;
Packit Service 37472d
Packit Service 37472d
  if(ret < 3) {
Packit Service 37472d
    g_warning("strange sametime list group line:\n%s", line);
Packit Service 37472d
  }
Packit Service 37472d
  
Packit Service 37472d
  str_replace(name, ';', ' ');
Packit Service 37472d
  str_replace(alias, ';', ' ');
Packit Service 37472d
Packit Service 37472d
  if(name && *name) {
Packit Service 37472d
    int l = strlen(name)-1;
Packit Service 37472d
    type = name[l];
Packit Service 37472d
    name[l] = '\0';
Packit Service 37472d
  }
Packit Service 37472d
Packit Service 37472d
  group = g_new0(struct mwSametimeGroup, 1);
Packit Service 37472d
  group->list = l;
Packit Service 37472d
  group->name = name;
Packit Service 37472d
  group->type = group_char_to_type(type);
Packit Service 37472d
  group->alias = alias;
Packit Service 37472d
  group->open = (open == 'O');
Packit Service 37472d
Packit Service 37472d
  l->groups = g_list_append(l->groups, group);
Packit Service 37472d
Packit Service 37472d
  return group;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static void get_user(const char *line, struct mwSametimeGroup *g) {
Packit Service 37472d
  struct mwSametimeUser *user;
Packit Service 37472d
  struct mwIdBlock idb = { 0, 0 };
Packit Service 37472d
  char *name, *alias = NULL;
Packit Service 37472d
  char type = '1';
Packit Service 37472d
  int ret;
Packit Service 37472d
  
Packit Service 37472d
  ret = strlen(line);
Packit Service 37472d
  idb.user = g_malloc0(ret);
Packit Service 37472d
  name = g_malloc0(ret);
Packit Service 37472d
Packit Service 37472d
  ret = sscanf(line, "U %s %s",
Packit Service 37472d
	       idb.user, name);
Packit Service 37472d
Packit Service 37472d
  if(ret < 2) {
Packit Service 37472d
    g_warning("strange sametime list user line:\n%s", line);
Packit Service 37472d
  }
Packit Service 37472d
Packit Service 37472d
  str_replace(idb.user, ';', ' ');
Packit Service 37472d
  str_replace(name, ';', ' ');
Packit Service 37472d
Packit Service 37472d
  if(idb.user && *idb.user) {
Packit Service 37472d
    char *tmp = strstr(idb.user, "::");
Packit Service 37472d
    if(tmp--) {
Packit Service 37472d
      type = *(tmp);
Packit Service 37472d
      *tmp = '\0';
Packit Service 37472d
    }
Packit Service 37472d
  }
Packit Service 37472d
Packit Service 37472d
  if(name && *name) {
Packit Service 37472d
    char *tmp = strrchr(name, ',');
Packit Service 37472d
    if(tmp) {
Packit Service 37472d
      *tmp++ = '\0';
Packit Service 37472d
      if(*tmp) alias = tmp;
Packit Service 37472d
    }
Packit Service 37472d
  }
Packit Service 37472d
Packit Service 37472d
  user = g_new0(struct mwSametimeUser, 1);
Packit Service 37472d
  user->group = g;
Packit Service 37472d
  user->id.user = idb.user;
Packit Service 37472d
  user->type = user_char_to_type(type);
Packit Service 37472d
  user->name = name;
Packit Service 37472d
  user->alias = g_strdup(alias);
Packit Service 37472d
  
Packit Service 37472d
  g->users = g_list_append(g->users, user);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** returns a line from str, and advances str */
Packit Service 37472d
static char *fetch_line(char **str) {
Packit Service 37472d
  char *start = *str;
Packit Service 37472d
  char *end;
Packit Service 37472d
Packit Service 37472d
  /* move to first non-whitespace character */
Packit Service 37472d
  while(*start && g_ascii_isspace(*start)) start++;
Packit Service 37472d
  if(! *start) return NULL;
Packit Service 37472d
Packit Service 37472d
  for(end = start + 1; *end; end++) {
Packit Service 37472d
    if(*end == '\n' || *end == '\r') {
Packit Service 37472d
      *(end++) = '\0';
Packit Service 37472d
      break;
Packit Service 37472d
    }
Packit Service 37472d
  }
Packit Service 37472d
Packit Service 37472d
  *str = end;
Packit Service 37472d
  return start;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static void list_get(const char *lines, struct mwSametimeList *l) {
Packit Service 37472d
  char *s = (char *) lines;
Packit Service 37472d
  char *line;
Packit Service 37472d
Packit Service 37472d
  struct mwSametimeGroup *g = NULL;
Packit Service 37472d
  
Packit Service 37472d
  while( (line = fetch_line(&s)) ) {
Packit Service 37472d
    switch(*line) {
Packit Service 37472d
    case 'V':
Packit Service 37472d
      get_version(line, l);
Packit Service 37472d
      break;
Packit Service 37472d
Packit Service 37472d
    case 'G':
Packit Service 37472d
      g = get_group(line, l);
Packit Service 37472d
      break;
Packit Service 37472d
Packit Service 37472d
    case 'U':
Packit Service 37472d
      get_user(line, g);
Packit Service 37472d
      break;
Packit Service 37472d
Packit Service 37472d
    default:
Packit Service 37472d
      g_warning("unknown sametime list data line:\n%s", line);
Packit Service 37472d
    }
Packit Service 37472d
  }  
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwSametimeList *mwSametimeList_load(const char *data) {
Packit Service 37472d
  struct mwSametimeList *l;
Packit Service 37472d
Packit Service 37472d
  g_return_val_if_fail(data != NULL, NULL);
Packit Service 37472d
  
Packit Service 37472d
  l = mwSametimeList_new();
Packit Service 37472d
  list_get(data, l);
Packit Service 37472d
Packit Service 37472d
  return l;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwSametimeList_get(struct mwGetBuffer *b, struct mwSametimeList *l) {
Packit Service 37472d
  char *str = NULL;
Packit Service 37472d
Packit Service 37472d
  g_return_if_fail(l != NULL);
Packit Service 37472d
  g_return_if_fail(b != NULL);
Packit Service 37472d
Packit Service 37472d
  mwString_get(b, &str);
Packit Service 9ff6bd
  if (str) {
Packit Service 9ff6bd
    list_get(str, l);
Packit Service 9ff6bd
    g_free(str);
Packit Service 9ff6bd
  }
Packit Service 37472d
}
Packit Service 37472d