Annotation of ChivanetAimPidgin/oscarprpl/src/c/snac.c, revision 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>