14192
|
1 /*
|
|
2 * Gaim's oscar protocol plugin
|
|
3 * This file is the legal property of its developers.
|
|
4 * Please see the AUTHORS file distributed alongside this file.
|
|
5 *
|
|
6 * This library is free software; you can redistribute it and/or
|
|
7 * modify it under the terms of the GNU Lesser General Public
|
|
8 * License as published by the Free Software Foundation; either
|
|
9 * version 2 of the License, or (at your option) any later version.
|
|
10 *
|
|
11 * This library is distributed in the hope that it will be useful,
|
|
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
14 * Lesser General Public License for more details.
|
|
15 *
|
|
16 * You should have received a copy of the GNU Lesser General Public
|
|
17 * License along with this library; if not, write to the Free Software
|
|
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
19 */
|
|
20
|
|
21 /*
|
|
22 * Cookie Caching stuff. Adam wrote this, apparently just some
|
|
23 * derivatives of n's SNAC work. I cleaned it up, added comments.
|
|
24 *
|
|
25 */
|
|
26
|
|
27 /*
|
|
28 * I'm assuming that cookies are type-specific. that is, we can have
|
|
29 * "1234578" for type 1 and type 2 concurrently. if i'm wrong, then we
|
|
30 * lose some error checking. if we assume cookies are not type-specific and are
|
|
31 * wrong, we get quirky behavior when cookies step on each others' toes.
|
|
32 */
|
|
33
|
|
34 #include "oscar.h"
|
|
35
|
|
36 /**
|
|
37 * aim_cachecookie - appends a cookie to the cookie list
|
|
38 *
|
|
39 * if cookie->cookie for type cookie->type is found, updates the
|
|
40 * ->addtime of the found structure; otherwise adds the given cookie
|
|
41 * to the cache
|
|
42 *
|
|
43 * @param od session to add to
|
|
44 * @param cookie pointer to struct to append
|
|
45 * @return returns -1 on error, 0 on append, 1 on update. the cookie you pass
|
|
46 * in may be free'd, so don't count on its value after calling this!
|
|
47 */
|
|
48 int aim_cachecookie(OscarData *od, IcbmCookie *cookie)
|
|
49 {
|
|
50 IcbmCookie *newcook;
|
|
51
|
|
52 if (!od || !cookie)
|
|
53 return -EINVAL;
|
|
54
|
|
55 newcook = aim_checkcookie(od, cookie->cookie, cookie->type);
|
|
56
|
|
57 if (newcook == cookie) {
|
|
58 newcook->addtime = time(NULL);
|
|
59 return 1;
|
|
60 } else if (newcook)
|
|
61 aim_cookie_free(od, newcook);
|
|
62
|
|
63 cookie->addtime = time(NULL);
|
|
64
|
|
65 cookie->next = od->msgcookies;
|
|
66 od->msgcookies = cookie;
|
|
67
|
|
68 return 0;
|
|
69 }
|
|
70
|
|
71 /**
|
|
72 * aim_uncachecookie - grabs a cookie from the cookie cache (removes it from the list)
|
|
73 *
|
|
74 * 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.
|
|
75 *
|
|
76 * @param od session to grab cookie from
|
|
77 * @param cookie cookie string to look for
|
|
78 * @param type cookie type to look for
|
|
79 * @return if found, returns the struct; if none found (or on error), returns NULL:
|
|
80 */
|
|
81 IcbmCookie *aim_uncachecookie(OscarData *od, guint8 *cookie, int type)
|
|
82 {
|
|
83 IcbmCookie *cur, **prev;
|
|
84
|
|
85 if (!cookie || !od->msgcookies)
|
|
86 return NULL;
|
|
87
|
|
88 for (prev = &od->msgcookies; (cur = *prev); ) {
|
|
89 if ((cur->type == type) &&
|
|
90 (memcmp(cur->cookie, cookie, 8) == 0)) {
|
|
91 *prev = cur->next;
|
|
92 return cur;
|
|
93 }
|
|
94 prev = &cur->next;
|
|
95 }
|
|
96
|
|
97 return NULL;
|
|
98 }
|
|
99
|
|
100 /**
|
|
101 * aim_mkcookie - generate an IcbmCookie *struct from a cookie string, a type, and a data pointer.
|
|
102 *
|
|
103 * @param c pointer to the cookie string array
|
|
104 * @param type cookie type to use
|
|
105 * @param data data to be cached with the cookie
|
|
106 * @return returns NULL on error, a pointer to the newly-allocated
|
|
107 * cookie on success.
|
|
108 */
|
|
109 IcbmCookie *aim_mkcookie(guint8 *c, int type, void *data)
|
|
110 {
|
|
111 IcbmCookie *cookie;
|
|
112
|
|
113 if (!c)
|
|
114 return NULL;
|
|
115
|
|
116 cookie = calloc(1, sizeof(IcbmCookie));
|
|
117
|
|
118 cookie->data = data;
|
|
119 cookie->type = type;
|
|
120 memcpy(cookie->cookie, c, 8);
|
|
121
|
|
122 return cookie;
|
|
123 }
|
|
124
|
|
125 /**
|
|
126 * aim_checkcookie - check to see if a cookietuple has been cached
|
|
127 *
|
|
128 * @param od session to check for the cookie in
|
|
129 * @param cookie pointer to the cookie string array
|
|
130 * @param type type of the cookie to look for
|
|
131 * @return returns a pointer to the cookie struct (still in the list)
|
|
132 * on success; returns NULL on error/not found
|
|
133 */
|
|
134
|
|
135 IcbmCookie *aim_checkcookie(OscarData *od, const guint8 *cookie, int type)
|
|
136 {
|
|
137 IcbmCookie *cur;
|
|
138
|
|
139 for (cur = od->msgcookies; cur; cur = cur->next) {
|
|
140 if ((cur->type == type) &&
|
|
141 (memcmp(cur->cookie, cookie, 8) == 0))
|
|
142 return cur;
|
|
143 }
|
|
144
|
|
145 return NULL;
|
|
146 }
|
|
147
|
|
148 /**
|
|
149 * aim_cookie_free - free an IcbmCookie struct
|
|
150 *
|
|
151 * this function removes the cookie *cookie from the list of cookies
|
|
152 * in od, and then frees all memory associated with it. including
|
|
153 * its data! if you want to use the private data after calling this,
|
|
154 * make sure you copy it first.
|
|
155 *
|
|
156 * @param od session to remove the cookie from
|
|
157 * @param cookie the address of a pointer to the cookie struct to remove
|
|
158 * @return returns -1 on error, 0 on success.
|
|
159 *
|
|
160 */
|
|
161 int aim_cookie_free(OscarData *od, IcbmCookie *cookie)
|
|
162 {
|
|
163 IcbmCookie *cur, **prev;
|
|
164
|
|
165 if (!od || !cookie)
|
|
166 return -EINVAL;
|
|
167
|
|
168 for (prev = &od->msgcookies; (cur = *prev); ) {
|
|
169 if (cur == cookie)
|
|
170 *prev = cur->next;
|
|
171 else
|
|
172 prev = &cur->next;
|
|
173 }
|
|
174
|
|
175 free(cookie->data);
|
|
176 free(cookie);
|
|
177
|
|
178 return 0;
|
|
179 }
|
|
180
|
|
181 /* XXX I hate switch */
|
|
182 int aim_msgcookie_gettype(int type)
|
|
183 {
|
|
184 /* XXX: hokey-assed. needs fixed. */
|
|
185 switch(type) {
|
|
186 case OSCAR_CAPABILITY_BUDDYICON: return AIM_COOKIETYPE_OFTICON;
|
|
187 case OSCAR_CAPABILITY_TALK: return AIM_COOKIETYPE_OFTVOICE;
|
|
188 case OSCAR_CAPABILITY_DIRECTIM: return AIM_COOKIETYPE_OFTIMAGE;
|
|
189 case OSCAR_CAPABILITY_CHAT: return AIM_COOKIETYPE_CHAT;
|
|
190 case OSCAR_CAPABILITY_GETFILE: return AIM_COOKIETYPE_OFTGET;
|
|
191 case OSCAR_CAPABILITY_SENDFILE: return AIM_COOKIETYPE_OFTSEND;
|
|
192 default: return AIM_COOKIETYPE_UNKNOWN;
|
|
193 }
|
|
194 }
|