File:  [Coherent Logic Development] / ChivanetAimPidgin / oscarprpl / src / c / snac.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Mon Jan 27 19:48:25 2025 UTC (6 months ago) by snw
Branches: MAIN, CoherentLogicDevelopment
CVS tags: test-tag, start, HEAD
Pidgin AIM Plugin for ChivaNet

    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>