Mercurial > pidgin
comparison libpurple/protocols/oscar/snac.c @ 15373:5fe8042783c1
Rename gtk/ and libgaim/ to pidgin/ and libpurple/
author | Sean Egan <seanegan@gmail.com> |
---|---|
date | Sat, 20 Jan 2007 02:32:10 +0000 |
parents | |
children | 32c366eeeb99 |
comparison
equal
deleted
inserted
replaced
15372:f79e0f4df793 | 15373:5fe8042783c1 |
---|---|
1 /* | |
2 * Gaim'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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 if (!(snac.data = malloc(datalen))) | |
61 return 0; /* er... */ | |
62 memcpy(snac.data, data, datalen); | |
63 } else | |
64 snac.data = NULL; | |
65 | |
66 return aim_newsnac(od, &snac); | |
67 } | |
68 | |
69 /* | |
70 * Clones the passed snac structure and caches it in the | |
71 * list/hash. | |
72 */ | |
73 aim_snacid_t aim_newsnac(OscarData *od, aim_snac_t *newsnac) | |
74 { | |
75 aim_snac_t *snac; | |
76 int index; | |
77 | |
78 if (!newsnac) | |
79 return 0; | |
80 | |
81 if (!(snac = malloc(sizeof(aim_snac_t)))) | |
82 return 0; | |
83 memcpy(snac, newsnac, sizeof(aim_snac_t)); | |
84 snac->issuetime = time(NULL); | |
85 | |
86 index = snac->id % FAIM_SNAC_HASH_SIZE; | |
87 | |
88 snac->next = (aim_snac_t *)od->snac_hash[index]; | |
89 od->snac_hash[index] = (void *)snac; | |
90 | |
91 return snac->id; | |
92 } | |
93 | |
94 /* | |
95 * Finds a snac structure with the passed SNAC ID, | |
96 * removes it from the list/hash, and returns a pointer to it. | |
97 * | |
98 * The returned structure must be freed by the caller. | |
99 * | |
100 */ | |
101 aim_snac_t *aim_remsnac(OscarData *od, aim_snacid_t id) | |
102 { | |
103 aim_snac_t *cur, **prev; | |
104 int index; | |
105 | |
106 index = id % FAIM_SNAC_HASH_SIZE; | |
107 | |
108 for (prev = (aim_snac_t **)&od->snac_hash[index]; (cur = *prev); ) { | |
109 if (cur->id == id) { | |
110 *prev = cur->next; | |
111 if (cur->flags & AIM_SNACFLAGS_DESTRUCTOR) { | |
112 free(cur->data); | |
113 cur->data = NULL; | |
114 } | |
115 return cur; | |
116 } else | |
117 prev = &cur->next; | |
118 } | |
119 | |
120 return cur; | |
121 } | |
122 | |
123 /* | |
124 * This is for cleaning up old SNACs that either don't get replies or | |
125 * a reply was never received for. Garbage collection. Plain and simple. | |
126 * | |
127 * maxage is the _minimum_ age in seconds to keep SNACs. | |
128 * | |
129 */ | |
130 void aim_cleansnacs(OscarData *od, int maxage) | |
131 { | |
132 int i; | |
133 | |
134 for (i = 0; i < FAIM_SNAC_HASH_SIZE; i++) { | |
135 aim_snac_t *cur, **prev; | |
136 time_t curtime; | |
137 | |
138 if (!od->snac_hash[i]) | |
139 continue; | |
140 | |
141 curtime = time(NULL); /* done here in case we waited for the lock */ | |
142 | |
143 for (prev = (aim_snac_t **)&od->snac_hash[i]; (cur = *prev); ) { | |
144 if ((curtime - cur->issuetime) > maxage) { | |
145 | |
146 *prev = cur->next; | |
147 | |
148 free(cur->data); | |
149 free(cur); | |
150 } else | |
151 prev = &cur->next; | |
152 } | |
153 } | |
154 | |
155 return; | |
156 } | |
157 | |
158 int aim_putsnac(ByteStream *bs, guint16 family, guint16 subtype, guint16 flags, aim_snacid_t snacid) | |
159 { | |
160 | |
161 byte_stream_put16(bs, family); | |
162 byte_stream_put16(bs, subtype); | |
163 byte_stream_put16(bs, flags); | |
164 byte_stream_put32(bs, snacid); | |
165 | |
166 return 10; | |
167 } |