]> andersk Git - libfaim.git/blob - src/snac.c
- Mon Sep 10 06:15:43 PDT 2001
[libfaim.git] / src / snac.c
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  */
21 faim_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
31 faim_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  */
54 faim_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  */
82 faim_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                         return cur;
93                 } else
94                         prev = &cur->next;
95         }
96
97         return cur;
98 }
99
100 /*
101  * This is for cleaning up old SNACs that either don't get replies or
102  * a reply was never received for.  Garabage collection. Plain and simple.
103  *
104  * maxage is the _minimum_ age in seconds to keep SNACs.
105  *
106  */
107 faim_internal void aim_cleansnacs(aim_session_t *sess, int maxage)
108 {
109         int i;
110
111         for (i = 0; i < FAIM_SNAC_HASH_SIZE; i++) {
112                 aim_snac_t *cur, **prev;
113                 time_t curtime;
114
115                 if (!sess->snac_hash[i])
116                         continue;
117
118                 curtime = time(NULL); /* done here in case we waited for the lock */
119
120                 for (prev = (aim_snac_t **)&sess->snac_hash[i]; (cur = *prev); ) {
121                         if ((curtime - cur->issuetime) > maxage) {
122
123                                 *prev = cur->next;
124
125                                 /* XXX should we have destructors here? */
126                                 free(cur->data);
127                                 free(cur);
128
129                         } else
130                                 prev = &cur->next;
131                 }
132         }
133
134         return;
135 }
136
137 faim_internal int aim_putsnac(aim_bstream_t *bs, fu16_t family, fu16_t subtype, fu16_t flags, aim_snacid_t snacid)
138 {
139
140         aimbs_put16(bs, family);
141         aimbs_put16(bs, subtype);
142         aimbs_put16(bs, flags);
143         aimbs_put32(bs, snacid);
144
145         return 10;
146 }
This page took 0.052482 seconds and 5 git commands to generate.