diff options
Diffstat (limited to 'protocols/oscar/msgcookie.c')
| -rw-r--r-- | protocols/oscar/msgcookie.c | 196 | 
1 files changed, 196 insertions, 0 deletions
diff --git a/protocols/oscar/msgcookie.c b/protocols/oscar/msgcookie.c new file mode 100644 index 00000000..bb498d72 --- /dev/null +++ b/protocols/oscar/msgcookie.c @@ -0,0 +1,196 @@ +/* + * Cookie Caching stuff. Adam wrote this, apparently just some + * derivatives of n's SNAC work. I cleaned it up, added comments. + *  + */ + +/* + * I'm assuming that cookies are type-specific. that is, we can have + * "1234578" for type 1 and type 2 concurrently. if i'm wrong, then we + * lose some error checking. if we assume cookies are not type-specific and are + * wrong, we get quirky behavior when cookies step on each others' toes. + */ + +#include <aim.h> +#include "info.h" + +/** + * aim_cachecookie - appends a cookie to the cookie list + * @sess: session to add to + * @cookie: pointer to struct to append + * + * if cookie->cookie for type cookie->type is found, updates the + * ->addtime of the found structure; otherwise adds the given cookie + * to the cache + * + * returns -1 on error, 0 on append, 1 on update.  the cookie you pass + * in may be free'd, so don't count on its value after calling this! + *  + */ +int aim_cachecookie(aim_session_t *sess, aim_msgcookie_t *cookie) +{ +	aim_msgcookie_t *newcook; + +	if (!sess || !cookie) +		return -EINVAL; + +	newcook = aim_checkcookie(sess, cookie->cookie, cookie->type); +	 +	if (newcook == cookie) { +		newcook->addtime = time(NULL); +		return 1; +	} else if (newcook) +		aim_cookie_free(sess, newcook); + +	cookie->addtime = time(NULL);   + +	cookie->next = sess->msgcookies; +	sess->msgcookies = cookie; + +	return 0; +} + +/** + * aim_uncachecookie - grabs a cookie from the cookie cache (removes it from the list) + * @sess: session to grab cookie from + * @cookie: cookie string to look for + * @type: cookie type to look for + * + * 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. + * + * if found, returns the struct; if none found (or on error), returns NULL: + */ +aim_msgcookie_t *aim_uncachecookie(aim_session_t *sess, guint8 *cookie, int type) +{ +	aim_msgcookie_t *cur, **prev; + +	if (!cookie || !sess->msgcookies) +		return NULL; + +	for (prev = &sess->msgcookies; (cur = *prev); ) { +		if ((cur->type == type) &&  +				(memcmp(cur->cookie, cookie, 8) == 0)) { +			*prev = cur->next; +			return cur; +		} +		prev = &cur->next; +	} + +	return NULL; +} + +/** + * aim_mkcookie - generate an aim_msgcookie_t *struct from a cookie string, a type, and a data pointer. + * @c: pointer to the cookie string array + * @type: cookie type to use + * @data: data to be cached with the cookie + * + * returns NULL on error, a pointer to the newly-allocated cookie on + * success. + * + */ +aim_msgcookie_t *aim_mkcookie(guint8 *c, int type, void *data)  +{ +	aim_msgcookie_t *cookie; + +	if (!c) +		return NULL; + +	if (!(cookie = g_new0(aim_msgcookie_t,1))) +		return NULL; + +	cookie->data = data; +	cookie->type = type; +	memcpy(cookie->cookie, c, 8); + +	return cookie; +} + +/** + * aim_checkcookie - check to see if a cookietuple has been cached + * @sess: session to check for the cookie in + * @cookie: pointer to the cookie string array + * @type: type of the cookie to look for + * + * this returns a pointer to the cookie struct (still in the list) on + * success; returns NULL on error/not found + * + */ + +aim_msgcookie_t *aim_checkcookie(aim_session_t *sess, const guint8 *cookie, int type) +{ +	aim_msgcookie_t *cur; + +	for (cur = sess->msgcookies; cur; cur = cur->next) { +		if ((cur->type == type) &&  +				(memcmp(cur->cookie, cookie, 8) == 0)) +			return cur;    +	} + +	return NULL; +} + +#if 0 /* debugging feature */ +int aim_dumpcookie(aim_msgcookie_t *cookie)  +{ + +	if (!cookie) +		return -EINVAL; + +	printf("\tCookie at %p: %d/%s with %p, next %p\n",  +			cookie, cookie->type, cookie->cookie,  +			cookie->data, cookie->next); + +	return 0; +} +#endif + +/** + * aim_cookie_free - free an aim_msgcookie_t struct + * @sess: session to remove the cookie from + * @cookiep: the address of a pointer to the cookie struct to remove + * + * this function removes the cookie *cookie from teh list of cookies + * in sess, and then frees all memory associated with it. including + * its data! if you want to use the private data after calling this, + * make sure you copy it first. + * + * returns -1 on error, 0 on success. + * + */ +int aim_cookie_free(aim_session_t *sess, aim_msgcookie_t *cookie)  +{ +	aim_msgcookie_t *cur, **prev; + +	if (!sess || !cookie) +		return -EINVAL; + +	for (prev = &sess->msgcookies; (cur = *prev); ) { +		if (cur == cookie) +			*prev = cur->next; +		else +			prev = &cur->next; +	} + +	g_free(cookie->data); +	g_free(cookie); + +	return 0; +}  + +/* XXX I hate switch */ +int aim_msgcookie_gettype(int reqclass)  +{ +	/* XXX: hokey-assed. needs fixed. */ +	switch(reqclass) { +	case AIM_CAPS_BUDDYICON: return AIM_COOKIETYPE_OFTICON; +	case AIM_CAPS_VOICE: return AIM_COOKIETYPE_OFTVOICE; +	case AIM_CAPS_IMIMAGE: return AIM_COOKIETYPE_OFTIMAGE; +	case AIM_CAPS_CHAT: return AIM_COOKIETYPE_CHAT; +	case AIM_CAPS_GETFILE: return AIM_COOKIETYPE_OFTGET; +	case AIM_CAPS_SENDFILE: return AIM_COOKIETYPE_OFTSEND; +	default: return AIM_COOKIETYPE_UNKNOWN; +	}            +} + +  | 
