view mcabber/libjabber/pproxy.c @ 1566:d64e0b2855fc

Fix display of last character in the input line when Aspell support is enabled The rightmost character displayed in the input line was always the last character of the line. (Reported by isbear.)
author Mikael Berthe <mikael@lilotux.net>
date Sun, 08 Feb 2009 10:08:05 +0100
parents c3ae9251c197
children
line wrap: on
line source

/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * Copyrights
 *
 * Portions created by or assigned to Jabber.com, Inc. are
 * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
 * information for Jabber.com, Inc. is available at http://www.jabber.com/.
 *
 * Portions Copyright (c) 1998-1999 Jeremie Miller.
 *
 * Acknowledgements
 *
 * Special thanks to the Jabber Open Source Contributors for their
 * suggestions and support of Jabber.
 *
 *
 */

/**
 * @file pproxy.c
 * @brief presence proxy database - DEPRECATED
 *
 * @deprecated these functions are not used by jabberd itself (but aim-t uses them), they will be removed from jabberd
 *
 * The presence proxy database is used to store presences for different resources of a JID.
 *
 * these aren't the most efficient things in the world, a hash optimized for tiny spaces would be far better
 */

#include "jabber.h"

/* these aren't the most efficient things in the world, a hash optimized for tiny spaces would be far better */

ppdb _ppdb_new(pool p, jid id)
{
    ppdb ret;
    ret = pmalloc(p,sizeof(_ppdb));
    ret->p = p;
    ret->pri = -1;
    ret->next = NULL;
    ret->user = NULL;
    ret->x = NULL;
    ret->id = jid_new(p,jid_full(id));

    return ret;
}

ppdb _ppdb_get(ppdb db, jid id)
{
    ppdb cur;

    if(db == NULL || id == NULL) return NULL;

    for(cur = db->next; cur != NULL; cur = cur->next)
        if(jid_cmp(cur->id,id) == 0) return cur;

    return NULL;
}

ppdb ppdb_insert(ppdb db, jid id, xmlnode x)
{
    ppdb cur, curu;
    pool p;

    if(id == NULL || id->server == NULL || x == NULL)
        return db;

    /* new ppdb list dummy holder */
    if(db == NULL)
    {
        p = pool_heap(1024);
        db = _ppdb_new(p,NULL);
    }

    cur = _ppdb_get(db,id);

    /* just update it */
    if(cur != NULL)
    {
        xmlnode_free(cur->x);
        cur->x = xmlnode_dup(x);
        cur->pri = jutil_priority(x);
        return db;
    }

    /* make an entry for it */
    cur = _ppdb_new(db->p,id);
    cur->x = xmlnode_dup(x);
    cur->pri = jutil_priority(x);
    cur->next = db->next;
    db->next = cur;

    /* if this is a user's resource presence, get the the user entry */
    if(id->user != NULL && (curu = _ppdb_get(db,jid_user(id))) != cur)
    {
        /* no user entry, make one */
        if(curu == NULL)
        {
            curu = _ppdb_new(db->p,jid_user(id));
            curu->next = db->next;
            db->next = curu;
        }

        /* insert this resource into the user list */
        cur->user = curu->user;
        curu->user = cur;
    }

    return db;
}

xmlnode ppdb_primary(ppdb db, jid id)
{
    ppdb cur, top;

    if(db == NULL || id == NULL) return NULL;

    cur = _ppdb_get(db,id);

    if(cur == NULL) return NULL;

    /* not user@host check, just return */
    if(id->user == NULL || id->resource != NULL) return cur->x;

    top = cur;
    for(cur = cur->user; cur != NULL; cur = cur->user)
        if(cur->pri >= top->pri) top = cur;

    if(top != NULL && top->pri >= 0) return top->x;

    return NULL;
}

/* return the presence for the id, successive calls return all of the known resources for a user@host address */
xmlnode ppdb_get(ppdb db, jid id)
{
    static ppdb last = NULL;
    ppdb cur;

    if(db == NULL || id == NULL) return NULL;

    /* MODE: if this is NOT just user@host addy, return just the single entry */
    if(id->user == NULL || id->resource != NULL)
    {
        /* we were just here, return now */
        if(last != NULL)
        {
            last = NULL;
            return NULL;
        }

        last = _ppdb_get(db,id);
        if(last != NULL)
            return last->x;
        else
            return NULL;
    }

    /* handle looping for user@host */

    /* we're already in the loop */
    if(last != NULL)
    {
        /* this is the last entry in the list */
        if(last->user == NULL)
        {
            last = NULL;
            return NULL;
        }

        last = last->user;
        return last->x;
    }

    /* start a new loop */
    cur = _ppdb_get(db,id);

    if(cur == NULL) return NULL;

    last = cur->user;
    if(last != NULL)
        return last->x;
    else
        return NULL;
}


void ppdb_free(ppdb db)
{
    ppdb cur;

    if(db == NULL) return;

    for(cur = db; cur != NULL; cur = cur->next)
        xmlnode_free(cur->x);

    pool_free(db->p);
}