source: libfaim/snac.c @ 601733d

barnowl_perlaimdebianowlrelease-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 601733d was e374dee, checked in by James M. Kretchmar <kretch@mit.edu>, 17 years ago
*** empty log message ***
  • Property mode set to 100644
File size: 3.1 KB
Line 
1/*
2 *
3 * Various SNAC-related dodads...
4 *
5 * outstanding_snacs is a list of aim_snac_t structs.  A SNAC should be added
6 * whenever a new SNAC is sent and it should remain in the list until the
7 * response for it has been receieved. 
8 *
9 * cleansnacs() should be called periodically by the client in order
10 * to facilitate the aging out of unreplied-to SNACs. This can and does
11 * happen, so it should be handled.
12 *
13 */
14
15#define FAIM_INTERNAL
16#include <aim.h>
17
18/*
19 * Called from aim_session_init() to initialize the hash.
20 */
21faim_internal void aim_initsnachash(aim_session_t *sess)
22{
23        int i;
24
25        for (i = 0; i < FAIM_SNAC_HASH_SIZE; i++)
26                sess->snac_hash[i] = NULL;
27
28        return;
29}
30
31faim_internal aim_snacid_t aim_cachesnac(aim_session_t *sess, const fu16_t family, const fu16_t type, const fu16_t flags, const void *data, const int datalen)
32{
33        aim_snac_t snac;
34
35        snac.id = sess->snacid_next++;
36        snac.family = family;
37        snac.type = type;
38        snac.flags = flags;
39
40        if (datalen) {
41                if (!(snac.data = malloc(datalen)))
42                        return 0; /* er... */
43                memcpy(snac.data, data, datalen);
44        } else
45                snac.data = NULL;
46
47        return aim_newsnac(sess, &snac);
48}
49
50/*
51 * Clones the passed snac structure and caches it in the
52 * list/hash.
53 */
54faim_internal aim_snacid_t aim_newsnac(aim_session_t *sess, aim_snac_t *newsnac)
55{
56        aim_snac_t *snac;
57        int index;
58
59        if (!newsnac)
60                return 0;
61
62        if (!(snac = malloc(sizeof(aim_snac_t))))
63                return 0;
64        memcpy(snac, newsnac, sizeof(aim_snac_t));
65        snac->issuetime = time(NULL);
66
67        index = snac->id % FAIM_SNAC_HASH_SIZE;
68
69        snac->next = (aim_snac_t *)sess->snac_hash[index];
70        sess->snac_hash[index] = (void *)snac;
71
72        return snac->id;
73}
74
75/*
76 * Finds a snac structure with the passed SNAC ID,
77 * removes it from the list/hash, and returns a pointer to it.
78 *
79 * The returned structure must be freed by the caller.
80 *
81 */
82faim_internal aim_snac_t *aim_remsnac(aim_session_t *sess, aim_snacid_t id) 
83{
84        aim_snac_t *cur, **prev;
85        int index;
86
87        index = id % FAIM_SNAC_HASH_SIZE;
88
89        for (prev = (aim_snac_t **)&sess->snac_hash[index]; (cur = *prev); ) {
90                if (cur->id == id) {
91                        *prev = cur->next;
92                        if (cur->flags & AIM_SNACFLAGS_DESTRUCTOR) {
93                                free(cur->data);
94                                cur->data = NULL;
95                        }
96                        return cur;
97                } else
98                        prev = &cur->next;
99        }
100
101        return cur;
102}
103
104/*
105 * This is for cleaning up old SNACs that either don't get replies or
106 * a reply was never received for.  Garabage collection. Plain and simple.
107 *
108 * maxage is the _minimum_ age in seconds to keep SNACs.
109 *
110 */
111faim_export void aim_cleansnacs(aim_session_t *sess, int maxage)
112{
113        int i;
114
115        for (i = 0; i < FAIM_SNAC_HASH_SIZE; i++) {
116                aim_snac_t *cur, **prev;
117                time_t curtime;
118
119                if (!sess->snac_hash[i])
120                        continue;
121
122                curtime = time(NULL); /* done here in case we waited for the lock */
123
124                for (prev = (aim_snac_t **)&sess->snac_hash[i]; (cur = *prev); ) {
125                        if ((curtime - cur->issuetime) > maxage) {
126
127                                *prev = cur->next;
128
129                                free(cur->data);
130                                free(cur);
131                        } else
132                                prev = &cur->next;
133                }
134        }
135
136        return;
137}
138
139faim_internal int aim_putsnac(aim_bstream_t *bs, fu16_t family, fu16_t subtype, fu16_t flags, aim_snacid_t snacid)
140{
141
142        aimbs_put16(bs, family);
143        aimbs_put16(bs, subtype);
144        aimbs_put16(bs, flags);
145        aimbs_put32(bs, snacid);
146
147        return 10;
148}
Note: See TracBrowser for help on using the repository browser.