| 1 |
1 /* |
| 2 /* |
2 * Cookie Caching stuff. Adam wrote this, apparently just some |
| 3 * |
3 * derivatives of n's SNAC work. I cleaned it up, added comments. |
| 4 * |
4 * |
| |
5 * I'm going to rewrite this stuff eventually, honest. -jbm |
| |
6 * |
| |
7 */ |
| |
8 |
| |
9 /* |
| |
10 * I'm assuming that cookies are type-specific. that is, we can have |
| |
11 * "1234578" for type 1 and type 2 concurrently. if i'm wrong, then we |
| |
12 * lose some error checking. if we assume cookies are not type-specific and are |
| |
13 * wrong, we get quirky behavior when cookies step on each others' toes. |
| 5 */ |
14 */ |
| 6 |
15 |
| 7 #include <faim/aim.h> |
16 #include <faim/aim.h> |
| |
17 |
| |
18 /* |
| |
19 * aim_cachecookie: |
| |
20 * appends a cookie to the cookie list for sess. |
| |
21 * - if cookie->cookie for type cookie->type is found, addtime is updated. |
| |
22 * - copies cookie struct; you need to free() it afterwards; |
| |
23 * - cookie->data is not copied, but passed along. don't free it. |
| |
24 * - newcook->addtime is updated accordingly; |
| |
25 * - cookie->type is just passed across. |
| |
26 * |
| |
27 * returns -1 on error, 0 on success. */ |
| 8 |
28 |
| 9 int aim_cachecookie(struct aim_session_t *sess, |
29 int aim_cachecookie(struct aim_session_t *sess, |
| 10 struct aim_msgcookie_t *cookie) |
30 struct aim_msgcookie_t *cookie) |
| 11 { |
31 { |
| 12 struct aim_msgcookie_t *newcook = NULL, *cur = NULL; |
32 struct aim_msgcookie_t *newcook = NULL, *cur = NULL; |
| 13 |
33 |
| 14 if (!cookie) |
34 if (!cookie) |
| 15 return -1; |
35 return -1; |
| 16 |
36 |
| |
37 if( (newcook = aim_checkcookie(sess, cookie->cookie, cookie->type)) ) { |
| |
38 newcook->addtime = time(NULL); |
| |
39 if(cookie->data != newcook->data) { |
| |
40 |
| |
41 printf("faim: cachecookie: matching cookie/type pair " |
| |
42 "%x%x%x%x%x%x%x%x/%x has different *data. free()ing cookie copy..\n", |
| |
43 cookie->cookie[0], cookie->cookie[1], cookie->cookie[2], |
| |
44 cookie->cookie[3], cookie->cookie[4], cookie->cookie[5], |
| |
45 cookie->cookie[6], cookie->cookie[7], cookie->type); |
| |
46 |
| |
47 free(cookie->data); |
| |
48 } |
| |
49 return(0); |
| |
50 } |
| |
51 |
| 17 if (!(newcook = malloc(sizeof(struct aim_msgcookie_t)))) |
52 if (!(newcook = malloc(sizeof(struct aim_msgcookie_t)))) |
| 18 return -1; |
53 return -1; |
| 19 memcpy(newcook, cookie, sizeof(struct aim_msgcookie_t)); |
54 memcpy(newcook, cookie, sizeof(struct aim_msgcookie_t)); |
| 20 newcook->addtime = time(NULL); |
55 newcook->addtime = time(NULL); |
| |
56 |
| |
57 if(newcook->next) |
| |
58 printf("faim: cachecookie: newcook->next isn't NULL ???\n"); |
| |
59 |
| 21 newcook->next = NULL; |
60 newcook->next = NULL; |
| 22 |
61 |
| 23 cur = sess->msgcookies; |
62 cur = sess->msgcookies; |
| 24 |
63 |
| 25 if (cur == NULL) { |
64 if (cur == NULL) { |
| 26 sess->msgcookies = newcook; |
65 sess->msgcookies = newcook; |
| 27 return 0; |
66 return 0; |
| 28 } |
67 } |
| |
68 |
| 29 while (cur->next != NULL) |
69 while (cur->next != NULL) |
| 30 cur = cur->next; |
70 cur = cur->next; |
| 31 cur->next = newcook; |
71 cur->next = newcook; |
| 32 |
72 |
| 33 return 0; |
73 return 0; |
| 34 } |
74 } |
| 35 |
75 |
| 36 struct aim_msgcookie_t *aim_uncachecookie(struct aim_session_t *sess, |
76 /* |
| 37 char *cookie) |
77 * aim_uncachecookie: |
| |
78 * takes a cookie string and grabs the cookie struct associated with |
| |
79 * it. removes struct from chain. returns the struct if found, or |
| |
80 * NULL on not found. |
| |
81 */ |
| |
82 |
| |
83 struct aim_msgcookie_t *aim_uncachecookie(struct aim_session_t *sess, char *cookie, int type) |
| 38 { |
84 { |
| 39 struct aim_msgcookie_t *cur; |
85 struct aim_msgcookie_t *cur; |
| 40 |
86 |
| 41 if (!cookie) |
87 if (!cookie || !sess->msgcookies) |
| 42 return NULL; |
88 return NULL; |
| 43 |
89 |
| 44 if (!sess->msgcookies) |
90 cur = sess->msgcookies; |
| 45 return NULL; |
91 |
| 46 |
92 if ( (memcmp(cur->cookie, cookie, 8) == 0) && (cur->type == type) ) { |
| 47 if (memcmp(sess->msgcookies->cookie, cookie, 8) == 0) { |
|
| 48 cur = sess->msgcookies; |
|
| 49 sess->msgcookies = cur->next; |
93 sess->msgcookies = cur->next; |
| 50 return cur; |
94 return cur; |
| 51 } |
95 } |
| 52 |
96 |
| 53 cur = sess->msgcookies; |
|
| 54 while (cur->next) { |
97 while (cur->next) { |
| 55 if (memcmp(cur->next->cookie, cookie, 8) == 0) { |
98 if ( (memcmp(cur->next->cookie, cookie, 8) == 0) && (cur->next->type == type) ) { |
| 56 struct aim_msgcookie_t *tmp; |
99 struct aim_msgcookie_t *tmp; |
| 57 |
100 |
| 58 tmp = cur->next; |
101 tmp = cur->next; |
| 59 cur->next = cur->next->next; |
102 cur->next = cur->next->next; |
| 60 return tmp; |
103 return tmp; |
| 63 } |
106 } |
| 64 return NULL; |
107 return NULL; |
| 65 } |
108 } |
| 66 |
109 |
| 67 /* |
110 /* |
| 68 */ |
111 * aim_purgecookies: |
| 69 int aim_purgecookies(struct aim_session_t *sess) |
112 * purge out old cookies |
| 70 { |
113 * |
| 71 int maxage = 5*60; |
114 * finds old cookies, calls uncache on them. |
| |
115 * |
| |
116 * this is highly inefficient, but It Works. and i don't feel like |
| |
117 * totally rewriting this. it might have some concurrency issues as |
| |
118 * well, if i rewrite it. |
| |
119 * |
| |
120 * i'll avoid the puns. |
| |
121 */ |
| |
122 |
| |
123 int aim_purgecookies(struct aim_session_t *sess, int maxage) |
| |
124 { |
| 72 struct aim_msgcookie_t *cur; |
125 struct aim_msgcookie_t *cur; |
| 73 struct aim_msgcookie_t *remed = NULL; |
126 struct aim_msgcookie_t *remed = NULL; |
| 74 time_t curtime; |
127 time_t curtime; |
| 75 |
128 |
| 76 cur = sess->msgcookies; |
129 cur = sess->msgcookies; |
| 77 |
130 |
| 78 curtime = time(&curtime); |
131 curtime = time(&curtime); |
| 79 |
132 |
| 80 while (cur) { |
133 while (cur) { |
| 81 if ( (cur) && (((cur->addtime) + maxage) < curtime)) { |
134 if ( (cur->addtime) > (curtime - maxage) ) { |
| 82 #if DEBUG > 1 |
135 #if DEBUG > 1 |
| 83 printf("aimmsgcookie: WARNING purged obsolete message cookie %x%x%x%x %x%x%x%x\n", |
136 printf("aimmsgcookie: WARNING purged obsolete message cookie %x%x%x%x %x%x%x%x\n", |
| 84 cur->cookie[0], cur->cookie[1], cur->cookie[2], cur->cookie[3], |
137 cur->cookie[0], cur->cookie[1], cur->cookie[2], cur->cookie[3], |
| 85 cur->cookie[4], cur->cookie[5], cur->cookie[6], cur->cookie[7]); |
138 cur->cookie[4], cur->cookie[5], cur->cookie[6], cur->cookie[7]); |
| 86 #endif |
139 #endif |
| 87 remed = aim_uncachecookie(sess, cur->cookie); |
140 |
| |
141 remed = aim_uncachecookie(sess, cur->cookie, cur->type); |
| 88 if (remed) { |
142 if (remed) { |
| 89 if (remed->data) |
143 if (remed->data) |
| 90 free(remed->data); |
144 free(remed->data); |
| 91 free(remed); |
145 free(remed); |
| 92 } |
146 } |
| 93 } |
147 } |
| |
148 |
| 94 cur = cur->next; |
149 cur = cur->next; |
| |
150 |
| 95 } |
151 } |
| 96 |
152 |
| 97 return 0; |
153 return 0; |
| 98 } |
154 } |
| 99 |
155 |
| |
156 struct aim_msgcookie_t *aim_mkcookie(unsigned char *c, int type, void *data) |
| |
157 { |
| |
158 struct aim_msgcookie_t *cookie; |
| |
159 |
| |
160 if(!c) |
| |
161 return(NULL); |
| |
162 |
| |
163 if( (cookie = calloc(1, sizeof(struct aim_msgcookie_t))) == NULL) |
| |
164 return(NULL); |
| |
165 |
| |
166 cookie->data = data; |
| |
167 |
| |
168 cookie->type = type; |
| |
169 |
| |
170 memcpy(cookie->cookie, c, 8); |
| |
171 |
| |
172 return(cookie); |
| |
173 } |
| |
174 |
| |
175 struct aim_msgcookie_t *aim_checkcookie(struct aim_session_t *sess, char *cookie, int type) |
| |
176 { |
| |
177 struct aim_msgcookie_t *cur; |
| |
178 |
| |
179 if(!sess->msgcookies) |
| |
180 return NULL; |
| |
181 |
| |
182 cur = sess->msgcookies; |
| |
183 |
| |
184 if( (memcmp(cur->cookie, cookie, 8) == 0) && (cur->type == type)) |
| |
185 return(cur); |
| |
186 |
| |
187 while( (cur = cur->next) ) |
| |
188 if( (memcmp(cur->cookie, cookie, 8) == 0) && (cur->type == type)) |
| |
189 return(cur); |
| |
190 |
| |
191 return(NULL); |
| |
192 } |
| |
193 |
| |
194 int aim_freecookie(struct aim_msgcookie_t *cookie) { |
| |
195 return(0); |
| |
196 } |
| |
197 |
| |
198 int aim_msgcookie_gettype(int reqclass) { |
| |
199 /* XXX: hokey-assed. needs fixed. */ |
| |
200 switch(reqclass) { |
| |
201 case AIM_CAPS_BUDDYICON: |
| |
202 return AIM_COOKIETYPE_OFTICON; |
| |
203 break; |
| |
204 case AIM_CAPS_VOICE: |
| |
205 return AIM_COOKIETYPE_OFTVOICE; |
| |
206 break; |
| |
207 case AIM_CAPS_IMIMAGE: |
| |
208 return AIM_COOKIETYPE_OFTIMAGE; |
| |
209 break; |
| |
210 case AIM_CAPS_CHAT: |
| |
211 return AIM_COOKIETYPE_CHAT; |
| |
212 break; |
| |
213 case AIM_CAPS_GETFILE: |
| |
214 return AIM_COOKIETYPE_OFTGET; |
| |
215 break; |
| |
216 case AIM_CAPS_SENDFILE: |
| |
217 return AIM_COOKIETYPE_OFTSEND; |
| |
218 break; |
| |
219 default: |
| |
220 return AIM_COOKIETYPE_UNKNOWN; |
| |
221 break; |
| |
222 } |
| |
223 } |