source: protocols/oscar/snac.c @ a6cd799

Last change on this file since a6cd799 was b4a8cd8, checked in by Jelmer Vernooij <jelmer@…>, at 2005-11-08T22:46:12Z

Make another function static.

  • 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#include <aim.h>
16
17static aim_snacid_t aim_newsnac(aim_session_t *sess, aim_snac_t *newsnac);
18
19/*
20 * Called from aim_session_init() to initialize the hash.
21 */
22void aim_initsnachash(aim_session_t *sess)
23{
24        int i;
25
26        for (i = 0; i < AIM_SNAC_HASH_SIZE; i++)
27                sess->snac_hash[i] = NULL;
28
29        return;
30}
31
32aim_snacid_t aim_cachesnac(aim_session_t *sess, const guint16 family, const guint16 type, const guint16 flags, const void *data, const int datalen)
33{
34        aim_snac_t snac;
35
36        snac.id = sess->snacid_next++;
37        snac.family = family;
38        snac.type = type;
39        snac.flags = flags;
40
41        if (datalen) {
42                if (!(snac.data = g_malloc(datalen)))
43                        return 0; /* er... */
44                memcpy(snac.data, data, datalen);
45        } else
46                snac.data = NULL;
47
48        return aim_newsnac(sess, &snac);
49}
50
51/*
52 * Clones the passed snac structure and caches it in the
53 * list/hash.
54 */
55static aim_snacid_t aim_newsnac(aim_session_t *sess, aim_snac_t *newsnac)
56{
57        aim_snac_t *snac;
58        int index;
59
60        if (!newsnac)
61                return 0;
62
63        if (!(snac = g_malloc(sizeof(aim_snac_t))))
64                return 0;
65        memcpy(snac, newsnac, sizeof(aim_snac_t));
66        snac->issuetime = time(NULL);
67
68        index = snac->id % AIM_SNAC_HASH_SIZE;
69
70        snac->next = (aim_snac_t *)sess->snac_hash[index];
71        sess->snac_hash[index] = (void *)snac;
72
73        return snac->id;
74}
75
76/*
77 * Finds a snac structure with the passed SNAC ID,
78 * removes it from the list/hash, and returns a pointer to it.
79 *
80 * The returned structure must be freed by the caller.
81 *
82 */
83aim_snac_t *aim_remsnac(aim_session_t *sess, aim_snacid_t id) 
84{
85        aim_snac_t *cur, **prev;
86        int index;
87
88        index = id % AIM_SNAC_HASH_SIZE;
89
90        for (prev = (aim_snac_t **)&sess->snac_hash[index]; (cur = *prev); ) {
91                if (cur->id == id) {
92                        *prev = cur->next;
93                        return cur;
94                } else
95                        prev = &cur->next;
96        }
97
98        return cur;
99}
100
101/*
102 * This is for cleaning up old SNACs that either don't get replies or
103 * a reply was never received for.  Garabage collection. Plain and simple.
104 *
105 * maxage is the _minimum_ age in seconds to keep SNACs.
106 *
107 */
108void aim_cleansnacs(aim_session_t *sess, int maxage)
109{
110        int i;
111
112        for (i = 0; i < AIM_SNAC_HASH_SIZE; i++) {
113                aim_snac_t *cur, **prev;
114                time_t curtime;
115
116                if (!sess->snac_hash[i])
117                        continue;
118
119                curtime = time(NULL); /* done here in case we waited for the lock */
120
121                for (prev = (aim_snac_t **)&sess->snac_hash[i]; (cur = *prev); ) {
122                        if ((curtime - cur->issuetime) > maxage) {
123
124                                *prev = cur->next;
125
126                                /* XXX should we have destructors here? */
127                                g_free(cur->data);
128                                g_free(cur);
129
130                        } else
131                                prev = &cur->next;
132                }
133        }
134
135        return;
136}
137
138int aim_putsnac(aim_bstream_t *bs, guint16 family, guint16 subtype, guint16 flags, aim_snacid_t snacid)
139{
140
141        aimbs_put16(bs, family);
142        aimbs_put16(bs, subtype);
143        aimbs_put16(bs, flags);
144        aimbs_put32(bs, snacid);
145
146        return 10;
147}
Note: See TracBrowser for help on using the repository browser.