source: protocols/oscar/snac.c @ 55bc71e

Last change on this file since 55bc71e 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
RevLine 
[b7d3cc34]1/*
2 *
[5ebff60]3 * Various SNAC-related dodads...
[b7d3cc34]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
[5ebff60]7 * response for it has been receieved.
[b7d3cc34]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
[b4a8cd8]17static aim_snacid_t aim_newsnac(aim_session_t *sess, aim_snac_t *newsnac);
18
[b7d3cc34]19/*
20 * Called from aim_session_init() to initialize the hash.
21 */
22void aim_initsnachash(aim_session_t *sess)
23{
24        int i;
25
[5ebff60]26        for (i = 0; i < AIM_SNAC_HASH_SIZE; i++) {
[b7d3cc34]27                sess->snac_hash[i] = NULL;
[5ebff60]28        }
[b7d3cc34]29
30        return;
31}
32
[5ebff60]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)
[b7d3cc34]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) {
[5ebff60]44                if (!(snac.data = g_malloc(datalen))) {
[b7d3cc34]45                        return 0; /* er... */
[5ebff60]46                }
[b7d3cc34]47                memcpy(snac.data, data, datalen);
[5ebff60]48        } else {
[b7d3cc34]49                snac.data = NULL;
[5ebff60]50        }
[b7d3cc34]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 */
[b4a8cd8]59static aim_snacid_t aim_newsnac(aim_session_t *sess, aim_snac_t *newsnac)
[b7d3cc34]60{
61        aim_snac_t *snac;
62        int index;
63
[5ebff60]64        if (!newsnac) {
[b7d3cc34]65                return 0;
[5ebff60]66        }
[b7d3cc34]67
[5ebff60]68        if (!(snac = g_malloc(sizeof(aim_snac_t)))) {
[b7d3cc34]69                return 0;
[5ebff60]70        }
[b7d3cc34]71        memcpy(snac, newsnac, sizeof(aim_snac_t));
72        snac->issuetime = time(NULL);
73
74        index = snac->id % AIM_SNAC_HASH_SIZE;
75
[5ebff60]76        snac->next = (aim_snac_t *) sess->snac_hash[index];
77        sess->snac_hash[index] = (void *) snac;
[b7d3cc34]78
79        return snac->id;
80}
81
82/*
[5ebff60]83 * Finds a snac structure with the passed SNAC ID,
[b7d3cc34]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 */
[5ebff60]89aim_snac_t *aim_remsnac(aim_session_t *sess, aim_snacid_t id)
[b7d3cc34]90{
91        aim_snac_t *cur, **prev;
92        int index;
93
94        index = id % AIM_SNAC_HASH_SIZE;
95
[5ebff60]96        for (prev = (aim_snac_t **) &sess->snac_hash[index]; (cur = *prev); ) {
[b7d3cc34]97                if (cur->id == id) {
98                        *prev = cur->next;
99                        return cur;
[5ebff60]100                } else {
[b7d3cc34]101                        prev = &cur->next;
[5ebff60]102                }
[b7d3cc34]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
[5ebff60]123                if (!sess->snac_hash[i]) {
[b7d3cc34]124                        continue;
[5ebff60]125                }
[b7d3cc34]126
127                curtime = time(NULL); /* done here in case we waited for the lock */
128
[5ebff60]129                for (prev = (aim_snac_t **) &sess->snac_hash[i]; (cur = *prev); ) {
[b7d3cc34]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
[5ebff60]138                        } else {
[b7d3cc34]139                                prev = &cur->next;
[5ebff60]140                        }
[b7d3cc34]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.