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.
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.
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.
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
23 * Various SNAC-related dodads...
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.
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.
38 * Called from oscar_session_new() to initialize the hash.
40 void aim_initsnachash(OscarData
*od
)
44 for (i
= 0; i
< FAIM_SNAC_HASH_SIZE
; i
++)
45 od
->snac_hash
[i
] = NULL
;
50 aim_snacid_t
aim_cachesnac(OscarData
*od
, const guint16 family
, const guint16 type
, const guint16 flags
, const void *data
, const int datalen
)
54 snac
.id
= od
->snacid_next
++;
60 snac
.data
= g_memdup(data
, datalen
);
64 return aim_newsnac(od
, &snac
);
68 * Clones the passed snac structure and caches it in the
71 aim_snacid_t
aim_newsnac(OscarData
*od
, aim_snac_t
*newsnac
)
79 snac
= g_memdup(newsnac
, sizeof(aim_snac_t
));
80 snac
->issuetime
= time(NULL
);
82 index
= snac
->id
% FAIM_SNAC_HASH_SIZE
;
84 snac
->next
= (aim_snac_t
*)od
->snac_hash
[index
];
85 od
->snac_hash
[index
] = (void *)snac
;
91 * Finds a snac structure with the passed SNAC ID,
92 * removes it from the list/hash, and returns a pointer to it.
94 * The returned structure must be freed by the caller.
97 aim_snac_t
*aim_remsnac(OscarData
*od
, aim_snacid_t id
)
99 aim_snac_t
*cur
, **prev
;
102 index
= id
% FAIM_SNAC_HASH_SIZE
;
104 for (prev
= (aim_snac_t
**)&od
->snac_hash
[index
]; (cur
= *prev
); ) {
107 if (cur
->flags
& AIM_SNACFLAGS_DESTRUCTOR
) {
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.
123 * maxage is the _minimum_ age in seconds to keep SNACs.
126 void aim_cleansnacs(OscarData
*od
, int maxage
)
130 for (i
= 0; i
< FAIM_SNAC_HASH_SIZE
; i
++) {
131 aim_snac_t
*cur
, **prev
;
134 if (!od
->snac_hash
[i
])
137 curtime
= time(NULL
); /* done here in case we waited for the lock */
139 for (prev
= (aim_snac_t
**)&od
->snac_hash
[i
]; (cur
= *prev
); ) {
140 if ((curtime
- cur
->issuetime
) > maxage
) {
154 int aim_putsnac(ByteStream
*bs
, guint16 family
, guint16 subtype
, aim_snacid_t snacid
)
157 byte_stream_put16(bs
, family
);
158 byte_stream_put16(bs
, subtype
);
159 byte_stream_put16(bs
, 0x0000);
160 byte_stream_put32(bs
, snacid
);