Annotation of ChivanetAimPidgin/oscarprpl/src/c/snac.c, revision 1.1.1.1

1.1       snw         1: /*
                      2:  * Purple's oscar protocol plugin
                      3:  * This file is the legal property of its developers.
                      4:  * Please see the AUTHORS file distributed alongside this file.
                      5:  *
                      6:  * This library is free software; you can redistribute it and/or
                      7:  * modify it under the terms of the GNU Lesser General Public
                      8:  * License as published by the Free Software Foundation; either
                      9:  * version 2 of the License, or (at your option) any later version.
                     10:  *
                     11:  * This library is distributed in the hope that it will be useful,
                     12:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     14:  * Lesser General Public License for more details.
                     15:  *
                     16:  * You should have received a copy of the GNU Lesser General Public
                     17:  * License along with this library; if not, write to the Free Software
                     18:  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
                     19: */
                     20: 
                     21: /*
                     22:  *
                     23:  * Various SNAC-related dodads...
                     24:  *
                     25:  * outstanding_snacs is a list of aim_snac_t structs.  A SNAC should be added
                     26:  * whenever a new SNAC is sent and it should remain in the list until the
                     27:  * response for it has been received.
                     28:  *
                     29:  * cleansnacs() should be called periodically by the client in order
                     30:  * to facilitate the aging out of unreplied-to SNACs. This can and does
                     31:  * happen, so it should be handled.
                     32:  *
                     33:  */
                     34: 
                     35: #include "oscar.h"
                     36: 
                     37: /*
                     38:  * Called from oscar_session_new() to initialize the hash.
                     39:  */
                     40: void aim_initsnachash(OscarData *od)
                     41: {
                     42:        int i;
                     43: 
                     44:        for (i = 0; i < FAIM_SNAC_HASH_SIZE; i++)
                     45:                od->snac_hash[i] = NULL;
                     46: 
                     47:        return;
                     48: }
                     49: 
                     50: aim_snacid_t aim_cachesnac(OscarData *od, const guint16 family, const guint16 type, const guint16 flags, const void *data, const int datalen)
                     51: {
                     52:        aim_snac_t snac;
                     53: 
                     54:        snac.id = od->snacid_next++;
                     55:        snac.family = family;
                     56:        snac.type = type;
                     57:        snac.flags = flags;
                     58: 
                     59:        if (datalen)
                     60:                snac.data = g_memdup(data, datalen);
                     61:        else
                     62:                snac.data = NULL;
                     63: 
                     64:        return aim_newsnac(od, &snac);
                     65: }
                     66: 
                     67: /*
                     68:  * Clones the passed snac structure and caches it in the
                     69:  * list/hash.
                     70:  */
                     71: aim_snacid_t aim_newsnac(OscarData *od, aim_snac_t *newsnac)
                     72: {
                     73:        aim_snac_t *snac;
                     74:        int index;
                     75: 
                     76:        if (!newsnac)
                     77:                return 0;
                     78: 
                     79:        snac = g_memdup(newsnac, sizeof(aim_snac_t));
                     80:        snac->issuetime = time(NULL);
                     81: 
                     82:        index = snac->id % FAIM_SNAC_HASH_SIZE;
                     83: 
                     84:        snac->next = (aim_snac_t *)od->snac_hash[index];
                     85:        od->snac_hash[index] = (void *)snac;
                     86: 
                     87:        return snac->id;
                     88: }
                     89: 
                     90: /*
                     91:  * Finds a snac structure with the passed SNAC ID,
                     92:  * removes it from the list/hash, and returns a pointer to it.
                     93:  *
                     94:  * The returned structure must be freed by the caller.
                     95:  *
                     96:  */
                     97: aim_snac_t *aim_remsnac(OscarData *od, aim_snacid_t id)
                     98: {
                     99:        aim_snac_t *cur, **prev;
                    100:        int index;
                    101: 
                    102:        index = id % FAIM_SNAC_HASH_SIZE;
                    103: 
                    104:        for (prev = (aim_snac_t **)&od->snac_hash[index]; (cur = *prev); ) {
                    105:                if (cur->id == id) {
                    106:                        *prev = cur->next;
                    107:                        if (cur->flags & AIM_SNACFLAGS_DESTRUCTOR) {
                    108:                                g_free(cur->data);
                    109:                                cur->data = NULL;
                    110:                        }
                    111:                        return cur;
                    112:                } else
                    113:                        prev = &cur->next;
                    114:        }
                    115: 
                    116:        return cur;
                    117: }
                    118: 
                    119: /*
                    120:  * This is for cleaning up old SNACs that either don't get replies or
                    121:  * a reply was never received for.  Garbage collection. Plain and simple.
                    122:  *
                    123:  * maxage is the _minimum_ age in seconds to keep SNACs.
                    124:  *
                    125:  */
                    126: void aim_cleansnacs(OscarData *od, int maxage)
                    127: {
                    128:        int i;
                    129: 
                    130:        for (i = 0; i < FAIM_SNAC_HASH_SIZE; i++) {
                    131:                aim_snac_t *cur, **prev;
                    132:                time_t curtime;
                    133: 
                    134:                if (!od->snac_hash[i])
                    135:                        continue;
                    136: 
                    137:                curtime = time(NULL); /* done here in case we waited for the lock */
                    138: 
                    139:                for (prev = (aim_snac_t **)&od->snac_hash[i]; (cur = *prev); ) {
                    140:                        if ((curtime - cur->issuetime) > maxage) {
                    141: 
                    142:                                *prev = cur->next;
                    143: 
                    144:                                g_free(cur->data);
                    145:                                g_free(cur);
                    146:                        } else
                    147:                                prev = &cur->next;
                    148:                }
                    149:        }
                    150: 
                    151:        return;
                    152: }
                    153: 
                    154: int aim_putsnac(ByteStream *bs, guint16 family, guint16 subtype, aim_snacid_t snacid)
                    155: {
                    156: 
                    157:        byte_stream_put16(bs, family);
                    158:        byte_stream_put16(bs, subtype);
                    159:        byte_stream_put16(bs, 0x0000);
                    160:        byte_stream_put32(bs, snacid);
                    161: 
                    162:        return 10;
                    163: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>