-struct aim_snac_t *aim_remsnac(u_long id) {
- struct aim_snac_t *cur = aim_outstanding_snacs;
-
- if (cur == NULL)
- return(NULL);
- if (cur->id == id) {
- aim_outstanding_snacs = cur->next;
- return(cur);
- }
- while (cur->next != NULL) {
- if (cur->next->id == id) {
- struct aim_snac_t *tmp = NULL;
-
- tmp = cur->next;
- cur->next = cur->next->next;
- return(tmp);
- }
- cur = cur->next;
- }
- return(NULL);
+/*
+ * Clones the passed snac structure and caches it in the
+ * list/hash.
+ */
+faim_internal unsigned long aim_newsnac(struct aim_session_t *sess,
+ struct aim_snac_t *newsnac)
+{
+ struct aim_snac_t *snac = NULL;
+ int index;
+
+ if (!newsnac)
+ return 0;
+
+ if (!(snac = calloc(1, sizeof(struct aim_snac_t))))
+ return 0;
+ memcpy(snac, newsnac, sizeof(struct aim_snac_t));
+ snac->issuetime = time(&snac->issuetime);
+ snac->next = NULL;
+
+ index = snac->id % FAIM_SNAC_HASH_SIZE;
+
+ faim_mutex_lock(&sess->snac_hash_locks[index]);
+ snac->next = sess->snac_hash[index];
+ sess->snac_hash[index] = snac;
+ faim_mutex_unlock(&sess->snac_hash_locks[index]);
+
+ return(snac->id);
+}
+
+/*
+ * Finds a snac structure with the passed SNAC ID,
+ * removes it from the list/hash, and returns a pointer to it.
+ *
+ * The returned structure must be freed by the caller.
+ *
+ */
+faim_internal struct aim_snac_t *aim_remsnac(struct aim_session_t *sess,
+ u_long id)
+{
+ struct aim_snac_t *cur = NULL;
+ int index;
+
+ index = id % FAIM_SNAC_HASH_SIZE;
+
+ faim_mutex_lock(&sess->snac_hash_locks[index]);
+ if (!sess->snac_hash[index])
+ ;
+ else if (sess->snac_hash[index]->id == id) {
+ cur = sess->snac_hash[index];
+ sess->snac_hash[index] = cur->next;
+ } else {
+ cur = sess->snac_hash[index];
+ while (cur->next) {
+ if (cur->next->id == id) {
+ struct aim_snac_t *tmp;
+
+ tmp = cur->next;
+ cur->next = cur->next->next;
+ cur = tmp;
+ break;
+ }
+ cur = cur->next;
+ }
+ }
+ faim_mutex_unlock(&sess->snac_hash_locks[index]);
+
+ return cur;