1535
|
1 /*
|
|
2 * Cookie Caching stuff. Adam wrote this, apparently just some
|
|
3 * derivatives of n's SNAC work. I cleaned it up, added comments.
|
|
4 *
|
|
5 */
|
|
6
|
|
7 /*
|
|
8 * I'm assuming that cookies are type-specific. that is, we can have
|
|
9 * "1234578" for type 1 and type 2 concurrently. if i'm wrong, then we
|
|
10 * lose some error checking. if we assume cookies are not type-specific and are
|
|
11 * wrong, we get quirky behavior when cookies step on each others' toes.
|
|
12 */
|
|
13
|
|
14 #define FAIM_INTERNAL
|
|
15 #include <aim.h>
|
|
16
|
|
17 /**
|
|
18 * aim_cachecookie - appends a cookie to the cookie list
|
|
19 * @sess: session to add to
|
|
20 * @cookie: pointer to struct to append
|
|
21 *
|
|
22 * if cookie->cookie for type cookie->type is found, updates the
|
|
23 * ->addtime of the found structure; otherwise adds the given cookie
|
|
24 * to the cache
|
|
25 *
|
|
26 * returns -1 on error, 0 on append, 1 on update. the cookie you pass
|
|
27 * in may be free'd, so don't count on its value after calling this!
|
|
28 *
|
|
29 */
|
|
30 faim_internal int aim_cachecookie(struct aim_session_t *sess,
|
|
31 struct aim_msgcookie_t *cookie)
|
|
32 {
|
|
33 struct aim_msgcookie_t *newcook;
|
|
34
|
|
35 if (!sess || !cookie)
|
|
36 return -1;
|
|
37
|
|
38 if( (newcook = aim_checkcookie(sess, cookie->cookie, cookie->type)) ) {
|
|
39 if(newcook != cookie) {
|
|
40 aim_cookie_free(sess, newcook);
|
|
41 } else {
|
|
42 newcook->addtime = time(NULL);
|
|
43 return 1;
|
|
44 }
|
|
45 }
|
|
46
|
|
47 cookie->addtime = time(NULL);
|
|
48
|
|
49 cookie->next = sess->msgcookies;
|
|
50 sess->msgcookies = cookie;
|
|
51
|
|
52 return 0;
|
|
53 }
|
|
54
|
|
55 /**
|
|
56 * aim_uncachecookie - grabs a cookie from the cookie cache (removes it from the list)
|
|
57 * @sess: session to grab cookie from
|
|
58 * @cookie: cookie string to look for
|
|
59 * @type: cookie type to look for
|
|
60 *
|
|
61 * takes a cookie string and a cookie type and finds the cookie struct associated with that duple, removing it from the cookie list ikn the process.
|
|
62 *
|
|
63 * if found, returns the struct; if none found (or on error), returns NULL:
|
|
64 */
|
|
65 faim_internal struct aim_msgcookie_t *aim_uncachecookie(struct aim_session_t *sess, unsigned char *cookie, int type)
|
|
66 {
|
|
67 struct aim_msgcookie_t *cur, **prev;
|
|
68
|
|
69 if (!cookie || !sess->msgcookies)
|
|
70 return NULL;
|
|
71
|
|
72 for (prev = &sess->msgcookies; (cur = *prev); ) {
|
|
73 if ((cur->type == type) &&
|
|
74 (memcmp(cur->cookie, cookie, 8) == 0)) {
|
|
75 *prev = cur->next;
|
|
76 return cur;
|
|
77 }
|
|
78 prev = &cur->next;
|
|
79 }
|
|
80
|
|
81 return NULL;
|
|
82 }
|
|
83
|
|
84 /**
|
|
85 * aim_mkcookie - generate an aim_msgcookie_t *struct from a cookie string, a type, and a data pointer.
|
|
86 * @c: pointer to the cookie string array
|
|
87 * @type: cookie type to use
|
|
88 * @data: data to be cached with the cookie
|
|
89 *
|
|
90 * returns NULL on error, a pointer to the newly-allocated cookie on
|
|
91 * success.
|
|
92 *
|
|
93 */
|
|
94 faim_internal struct aim_msgcookie_t *aim_mkcookie(unsigned char *c, int type, void *data)
|
|
95 {
|
|
96 struct aim_msgcookie_t *cookie;
|
|
97
|
|
98 if (!c)
|
|
99 return NULL;
|
|
100
|
|
101 if (!(cookie = calloc(1, sizeof(struct aim_msgcookie_t))))
|
|
102 return NULL;
|
|
103
|
|
104 cookie->data = data;
|
|
105 cookie->type = type;
|
|
106 memcpy(cookie->cookie, c, 8);
|
|
107
|
|
108 return cookie;
|
|
109 }
|
|
110
|
|
111 /**
|
|
112 * aim_checkcookie - check to see if a cookietuple has been cached
|
|
113 * @sess: session to check for the cookie in
|
|
114 * @cookie: pointer to the cookie string array
|
|
115 * @type: type of the cookie to look for
|
|
116 *
|
|
117 * this returns a pointer to the cookie struct (still in the list) on
|
|
118 * success; returns NULL on error/not found
|
|
119 *
|
|
120 */
|
|
121
|
|
122 faim_internal struct aim_msgcookie_t *aim_checkcookie(struct aim_session_t *sess,
|
|
123 const unsigned char *cookie,
|
|
124 const int type)
|
|
125 {
|
|
126 struct aim_msgcookie_t *cur;
|
|
127
|
|
128 for (cur = sess->msgcookies; cur; cur = cur->next) {
|
|
129 if ((cur->type == type) &&
|
|
130 (memcmp(cur->cookie, cookie, 8) == 0))
|
|
131 return cur;
|
|
132 }
|
|
133
|
|
134 return NULL;
|
|
135 }
|
|
136
|
|
137 #if 0 /* debugging feature */
|
|
138 faim_internal int aim_dumpcookie(struct aim_msgcookie_t *cookie)
|
|
139 {
|
|
140 if(!cookie)
|
|
141 return -1;
|
|
142 printf("\tCookie at %p: %d/%s with %p, next %p\n", cookie, cookie->type, cookie->cookie, cookie->data, cookie->next);
|
|
143 return 0;
|
|
144 }
|
|
145 #endif
|
|
146
|
|
147 /**
|
|
148 * aim_cookie_free - free an aim_msgcookie_t struct
|
|
149 * @sess: session to remove the cookie from
|
|
150 * @cookiep: the address of a pointer to the cookie struct to remove
|
|
151 *
|
|
152 * this function removes the cookie *cookie from teh list of cookies
|
|
153 * in sess, and then frees all memory associated with it. including
|
|
154 * its data! if you want to use the private data after calling this,
|
|
155 * make sure you copy it first.
|
|
156 *
|
|
157 * returns -1 on error, 0 on success.
|
|
158 *
|
|
159 */
|
|
160
|
|
161 faim_internal int aim_cookie_free(struct aim_session_t *sess,
|
|
162 struct aim_msgcookie_t *cookie)
|
|
163 {
|
|
164 struct aim_msgcookie_t *cur, **prev;
|
|
165
|
|
166 if (!sess || !cookie)
|
|
167 return -1;
|
|
168
|
|
169 if(!cookie)
|
|
170 return 0;
|
|
171
|
|
172 for (prev = &sess->msgcookies; (cur = *prev); ) {
|
|
173 if (cur == cookie) {
|
|
174 *prev = cur->next;
|
|
175 } else
|
|
176 prev = &cur->next;
|
|
177 }
|
|
178
|
|
179 if(cookie->data)
|
|
180 free(cookie->data);
|
|
181
|
|
182 free(cookie);
|
|
183
|
|
184 return 0;
|
|
185 }
|
|
186
|
|
187 faim_internal int aim_msgcookie_gettype(int reqclass) {
|
|
188 /* XXX: hokey-assed. needs fixed. */
|
|
189 switch(reqclass) {
|
|
190 case AIM_CAPS_BUDDYICON:
|
|
191 return AIM_COOKIETYPE_OFTICON;
|
|
192 break;
|
|
193 case AIM_CAPS_VOICE:
|
|
194 return AIM_COOKIETYPE_OFTVOICE;
|
|
195 break;
|
|
196 case AIM_CAPS_IMIMAGE:
|
|
197 return AIM_COOKIETYPE_OFTIMAGE;
|
|
198 break;
|
|
199 case AIM_CAPS_CHAT:
|
|
200 return AIM_COOKIETYPE_CHAT;
|
|
201 break;
|
|
202 case AIM_CAPS_GETFILE:
|
|
203 return AIM_COOKIETYPE_OFTGET;
|
|
204 break;
|
|
205 case AIM_CAPS_SENDFILE:
|
|
206 return AIM_COOKIETYPE_OFTSEND;
|
|
207 break;
|
|
208 default:
|
|
209 return AIM_COOKIETYPE_UNKNOWN;
|
|
210 break;
|
|
211 }
|
|
212 }
|