source: protocols/oscar/snac.c @ 952e264

Last change on this file since 952e264 was 5ebff60, checked in by dequis <dx@…>, at 2015-02-20T22:50:54Z

Reindent everything to K&R style with tabs

Used uncrustify, with the configuration file in ./doc/uncrustify.cfg

Commit author set to "Indent <please@…>" so that it's easier to
skip while doing git blame.

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