]> andersk Git - libfaim.git/blame - aim_snac.c
- Thu Aug 17 23:08:08 UTC 2000
[libfaim.git] / aim_snac.c
CommitLineData
9de3ca7e 1
2/*
3 *
4 * Various SNAC-related dodads...
5 *
6 * outstanding_snacs is a list of aim_snac_t structs. A SNAC should be added
7 * whenever a new SNAC is sent and it should remain in the list until the
b13c9e13 8 * response for it has been receieved.
9de3ca7e 9 *
b13c9e13 10 * cleansnacs() should be called periodically by the client in order
11 * to facilitate the aging out of unreplied-to SNACs. This can and does
12 * happen, so it should be handled.
9de3ca7e 13 *
14 */
15
a25832e6 16#include <faim/aim.h>
9de3ca7e 17
b13c9e13 18/*
19 * Called from aim_session_init() to initialize the hash.
20 */
21void aim_initsnachash(struct 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 faim_mutex_init(&sess->snac_hash_locks[i]);
28 }
29
30 return;
31}
32
33/*
34 * Clones the passed snac structure and caches it in the
35 * list/hash.
36 */
a25832e6 37u_long aim_newsnac(struct aim_session_t *sess,
38 struct aim_snac_t *newsnac)
39{
40 struct aim_snac_t *snac = NULL, *cur = NULL;
b13c9e13 41 int index;
42
a25832e6 43 if (!newsnac)
44 return 0;
9de3ca7e 45
a25832e6 46 snac = calloc(1, sizeof(struct aim_snac_t));
47 if (!snac)
48 return 0;
49 memcpy(snac, newsnac, sizeof(struct aim_snac_t));
50 snac->issuetime = time(&snac->issuetime);
51 snac->next = NULL;
b13c9e13 52
53 index = snac->id % FAIM_SNAC_HASH_SIZE;
54
55 faim_mutex_lock(&sess->snac_hash_locks[index]);
56 if (!sess->snac_hash[index])
57 sess->snac_hash[index] = snac;
58 else {
59 snac->next = sess->snac_hash[index];
60 sess->snac_hash[index] = snac;
a25832e6 61 }
b13c9e13 62 faim_mutex_unlock(&sess->snac_hash_locks[index]);
5b401785 63
a25832e6 64 return(snac->id);
65}
9de3ca7e 66
b13c9e13 67/*
68 * Finds a snac structure with the passed SNAC ID,
69 * removes it from the list/hash, and returns a pointer to it.
70 *
71 * The returned structure must be freed by the caller.
72 *
73 */
a25832e6 74struct aim_snac_t *aim_remsnac(struct aim_session_t *sess,
75 u_long id)
76{
77 struct aim_snac_t *cur;
b13c9e13 78 int index;
5b401785 79
b13c9e13 80 index = id % FAIM_SNAC_HASH_SIZE;
5b401785 81
b13c9e13 82 faim_mutex_lock(&sess->snac_hash_locks[index]);
83 if (!sess->snac_hash[index])
84 ;
85 else if (!sess->snac_hash[index]->next) {
86 if (sess->snac_hash[index]->id == id) {
87 cur = sess->snac_hash[index];
88 sess->snac_hash[index] = NULL;
89 }
90 } else {
91 cur = sess->snac_hash[index];
92 while (cur->next) {
93 if (cur->next->id == id) {
94 struct aim_snac_t *tmp;
95
96 tmp = cur->next;
97 cur->next = cur->next->next;
98 cur = tmp;
99 break;
100 }
101 cur = cur->next;
a25832e6 102 }
a25832e6 103 }
b13c9e13 104 faim_mutex_unlock(&sess->snac_hash_locks[index]);
105
106 return cur;
9de3ca7e 107}
108
109/*
110 * This is for cleaning up old SNACs that either don't get replies or
111 * a reply was never received for. Garabage collection. Plain and simple.
112 *
b13c9e13 113 * maxage is the _minimum_ age in seconds to keep SNACs.
9de3ca7e 114 *
115 */
a25832e6 116int aim_cleansnacs(struct aim_session_t *sess,
117 int maxage)
9de3ca7e 118{
a25832e6 119 struct aim_snac_t *cur;
9de3ca7e 120 struct aim_snac_t *remed = NULL;
121 time_t curtime;
b13c9e13 122 int i;
123
124 for (i = 0; i < FAIM_SNAC_HASH_SIZE; i++) {
125 faim_mutex_lock(&sess->snac_hash_locks[i]);
126 if (!sess->snac_hash[i])
127 ;
128 else if (!sess->snac_hash[i]->next) {
129 if ((sess->snac_hash[i]->issuetime + maxage) >= curtime) {
130 remed = sess->snac_hash[i];
131 if(remed->data)
132 free(remed->data);
133 free(remed);
134 sess->snac_hash[i] = NULL;
135 }
136 } else {
137 cur = sess->snac_hash[i];
138 while(cur && cur->next) {
139 if ((cur->next->issuetime + maxage) >= curtime) {
140 remed = cur->next;
141 cur->next = cur->next->next;
142 if (remed->data)
143 free(remed->data);
144 free(remed);
9de3ca7e 145 }
b13c9e13 146 cur = cur->next;
147 }
9de3ca7e 148 }
b13c9e13 149 faim_mutex_unlock(&sess->snac_hash_locks[i]);
150 }
151
9de3ca7e 152 return 0;
153}
154
155int aim_putsnac(u_char *buf, int family, int subtype, int flags, u_long snacid)
156{
157 int curbyte = 0;
158 curbyte += aimutil_put16(buf+curbyte, (u_short)(family&0xffff));
159 curbyte += aimutil_put16(buf+curbyte, (u_short)(subtype&0xffff));
160 curbyte += aimutil_put16(buf+curbyte, (u_short)(flags&0xffff));
161 curbyte += aimutil_put32(buf+curbyte, snacid);
162 return curbyte;
163}
This page took 0.287709 seconds and 5 git commands to generate.