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