⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 family_feedbag.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	 * additions, then modifications.  Also, both the official and the local	 * list should be in ascending numerical order for the group ID#s and the	 * buddy ID#s, which makes things more efficient.  I think.	 */	/* Additions */	if (!od->ssi.pending) {		for (cur1=od->ssi.local; cur1 && (n < 15); cur1=cur1->next) {			if (!aim_ssi_itemlist_find(od->ssi.official, cur1->gid, cur1->bid)) {				n++;				new = (struct aim_ssi_tmp *)g_malloc(sizeof(struct aim_ssi_tmp));				new->action = SNAC_SUBTYPE_FEEDBAG_ADD;				new->ack = 0xffff;				new->name = NULL;				new->item = cur1;				new->next = NULL;				if (od->ssi.pending) {					for (cur=od->ssi.pending; cur->next; cur=cur->next);					cur->next = new;				} else					od->ssi.pending = new;			}		}	}	/* Deletions */	if (!od->ssi.pending) {		for (cur1=od->ssi.official; cur1 && (n < 15); cur1=cur1->next) {			if (!aim_ssi_itemlist_find(od->ssi.local, cur1->gid, cur1->bid)) {				n++;				new = (struct aim_ssi_tmp *)g_malloc(sizeof(struct aim_ssi_tmp));				new->action = SNAC_SUBTYPE_FEEDBAG_DEL;				new->ack = 0xffff;				new->name = NULL;				new->item = cur1;				new->next = NULL;				if (od->ssi.pending) {					for (cur=od->ssi.pending; cur->next; cur=cur->next);					cur->next = new;				} else					od->ssi.pending = new;			}		}	}	/* Modifications */	if (!od->ssi.pending) {		for (cur1=od->ssi.local; cur1 && (n < 15); cur1=cur1->next) {			cur2 = aim_ssi_itemlist_find(od->ssi.official, cur1->gid, cur1->bid);			if (cur2 && (aim_ssi_itemlist_cmp(cur1, cur2))) {				n++;				new = (struct aim_ssi_tmp *)g_malloc(sizeof(struct aim_ssi_tmp));				new->action = SNAC_SUBTYPE_FEEDBAG_MOD;				new->ack = 0xffff;				new->name = NULL;				new->item = cur1;				new->next = NULL;				if (od->ssi.pending) {					for (cur=od->ssi.pending; cur->next; cur=cur->next);					cur->next = new;				} else					od->ssi.pending = new;			}		}	}	/* We're out of stuff to do, so tell the AIM servers we're done and exit */	if (!od->ssi.pending) {		if (od->ssi.in_transaction) {			aim_ssi_modend(od);			od->ssi.in_transaction = FALSE;		}		return 0;	}	/* If this is the first in a series of add/mod/del	 * requests then send the "begin transaction" message. */	if (!od->ssi.in_transaction)	{		aim_ssi_modbegin(od);		od->ssi.in_transaction = TRUE;	}	/* Make sure we don't send anything else between now	 * and when we receive the ack for the following operation */	od->ssi.waiting_for_ack = TRUE;	/* Now go mail off our data and wait 4 to 6 weeks */	return aim_ssi_addmoddel(od);;}/** * Free all SSI data. * * This doesn't remove it from the server, that's different. * * @param od The oscar odion. * @return Return 0 if no errors, otherwise return the error number. */static voidaim_ssi_freelist(OscarData *od){	struct aim_ssi_item *cur, *del;	struct aim_ssi_tmp *curtmp, *deltmp;	cur = od->ssi.official;	while (cur) {		del = cur;		cur = cur->next;		g_free(del->name);		aim_tlvlist_free(del->data);		g_free(del);	}	cur = od->ssi.local;	while (cur) {		del = cur;		cur = cur->next;		g_free(del->name);		aim_tlvlist_free(del->data);		g_free(del);	}	curtmp = od->ssi.pending;	while (curtmp) {		deltmp = curtmp;		curtmp = curtmp->next;		g_free(deltmp);	}	od->ssi.numitems = 0;	od->ssi.official = NULL;	od->ssi.local = NULL;	od->ssi.pending = NULL;	od->ssi.timestamp = (time_t)0;}/** * This "cleans" the ssi list.  It does the following: * 1) Makes sure all buddies, permits, and denies have names. * 2) Makes sure that all buddies are in a group that exist. * 3) Deletes any empty groups * * @param od The oscar odion. * @return Return 0 if no errors, otherwise return the error number. */int aim_ssi_cleanlist(OscarData *od){	struct aim_ssi_item *cur, *next;	if (!od)		return -EINVAL;	/* Delete any buddies, permits, or denies with empty names. */	/* If there are any buddies directly in the master group, add them to a real group. */	/* DESTROY any buddies that are directly in the master group. */	/* Do the same for buddies that are in a non-existant group. */	/* This will kind of mess up if you hit the item limit, but this function isn't too critical */	cur = od->ssi.local;	while (cur) {		next = cur->next;		if (!cur->name) {			if (cur->type == AIM_SSI_TYPE_BUDDY)				aim_ssi_delbuddy(od, NULL, NULL);			else if (cur->type == AIM_SSI_TYPE_PERMIT)				aim_ssi_delpermit(od, NULL);			else if (cur->type == AIM_SSI_TYPE_DENY)				aim_ssi_deldeny(od, NULL);		} else if ((cur->type == AIM_SSI_TYPE_BUDDY) && ((cur->gid == 0x0000) || (!aim_ssi_itemlist_find(od->ssi.local, cur->gid, 0x0000)))) {			char *alias = aim_ssi_getalias(od->ssi.local, NULL, cur->name);			aim_ssi_addbuddy(od, cur->name, "orphans", NULL, alias, NULL, NULL, FALSE);			aim_ssi_delbuddy(od, cur->name, NULL);			g_free(alias);		}		cur = next;	}	/* Make sure there aren't any duplicate buddies in a group, or duplicate permits or denies */	cur = od->ssi.local;	while (cur) {		if ((cur->type == AIM_SSI_TYPE_BUDDY) || (cur->type == AIM_SSI_TYPE_PERMIT) || (cur->type == AIM_SSI_TYPE_DENY))		{			struct aim_ssi_item *cur2, *next2;			cur2 = cur->next;			while (cur2) {				next2 = cur2->next;				if ((cur->type == cur2->type) && (cur->gid == cur2->gid) && (cur->name != NULL) && (cur2->name != NULL) && (!aim_sncmp(cur->name, cur2->name))) {					aim_ssi_itemlist_del(&od->ssi.local, cur2);				}				cur2 = next2;			}		}		cur = cur->next;	}	/* Check if there are empty groups and delete them */	cur = od->ssi.local;	while (cur) {		next = cur->next;		if (cur->type == AIM_SSI_TYPE_GROUP) {			aim_tlv_t *tlv = aim_tlv_gettlv(cur->data, 0x00c8, 1);			if (!tlv || !tlv->length)				aim_ssi_itemlist_del(&od->ssi.local, cur);		}		cur = next;	}	/* Check if the master group is empty */	if ((cur = aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000)) && (!cur->data))		aim_ssi_itemlist_del(&od->ssi.local, cur);	/* If we've made any changes then sync our list with the server's */	return aim_ssi_sync(od);}/** * Add a buddy to the list. * * @param od The oscar odion. * @param name The name of the item. * @param group The group of the item. * @param data A TLV list to use as the additional data for this item. * @param alias The alias/nickname of the item, or NULL. * @param comment The buddy comment for the item, or NULL. * @param smsnum The locally assigned SMS number, or NULL. * @return Return 0 if no errors, otherwise return the error number. */int aim_ssi_addbuddy(OscarData *od, const char *name, const char *group, GSList *data, const char *alias, const char *comment, const char *smsnum, gboolean needauth){	struct aim_ssi_item *parent;	if (!od || !name || !group)		return -EINVAL;	/* Find the parent */	if (!(parent = aim_ssi_itemlist_finditem(od->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP))) {		/* Find the parent's parent (the master group) */		if (aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000) == NULL)			aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL);		/* Add the parent */		parent = aim_ssi_itemlist_add(&od->ssi.local, group, 0xFFFF, 0x0000, AIM_SSI_TYPE_GROUP, NULL);		/* Modify the parent's parent (the master group) */		aim_ssi_itemlist_rebuildgroup(od->ssi.local, NULL);	}	/* Create a TLV list for the new buddy */	if (needauth)		aim_tlvlist_add_noval(&data, 0x0066);	if (alias != NULL)		aim_tlvlist_add_str(&data, 0x0131, alias);	if (smsnum != NULL)		aim_tlvlist_add_str(&data, 0x013a, smsnum);	if (comment != NULL)		aim_tlvlist_add_str(&data, 0x013c, comment);	/* Add that bad boy */	aim_ssi_itemlist_add(&od->ssi.local, name, parent->gid, 0xFFFF, AIM_SSI_TYPE_BUDDY, data);	aim_tlvlist_free(data);	/* Modify the parent group */	aim_ssi_itemlist_rebuildgroup(od->ssi.local, group);	/* Sync our local list with the server list */	return aim_ssi_sync(od);}/** * Add a permit buddy to the list. * * @param od The oscar odion. * @param name The name of the item.. * @return Return 0 if no errors, otherwise return the error number. */int aim_ssi_addpermit(OscarData *od, const char *name){	if (!od || !name || !od->ssi.received_data)		return -EINVAL;	/* Make sure the master group exists */	if (aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000) == NULL)		aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL);	/* Add that bad boy */	aim_ssi_itemlist_add(&od->ssi.local, name, 0x0000, 0xFFFF, AIM_SSI_TYPE_PERMIT, NULL);	/* Sync our local list with the server list */	return aim_ssi_sync(od);}/** * Add a deny buddy to the list. * * @param od The oscar odion. * @param name The name of the item.. * @return Return 0 if no errors, otherwise return the error number. */int aim_ssi_adddeny(OscarData *od, const char *name){	if (!od || !name || !od->ssi.received_data)		return -EINVAL;	/* Make sure the master group exists */	if (aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000) == NULL)		aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL);	/* Add that bad boy */	aim_ssi_itemlist_add(&od->ssi.local, name, 0x0000, 0xFFFF, AIM_SSI_TYPE_DENY, NULL);	/* Sync our local list with the server list */	return aim_ssi_sync(od);}/** * Deletes a buddy from the list. * * @param od The oscar odion. * @param name The name of the item, or NULL. * @param group The group of the item, or NULL. * @return Return 0 if no errors, otherwise return the error number. */int aim_ssi_delbuddy(OscarData *od, const char *name, const char *group){	struct aim_ssi_item *del;	if (!od)		return -EINVAL;	/* Find the buddy */	if (!(del = aim_ssi_itemlist_finditem(od->ssi.local, group, name, AIM_SSI_TYPE_BUDDY)))		return -EINVAL;	/* Remove the item from the list */	aim_ssi_itemlist_del(&od->ssi.local, del);	/* Modify the parent group */	aim_ssi_itemlist_rebuildgroup(od->ssi.local, group);	/* Check if we should delete the parent group */	if ((del = aim_ssi_itemlist_finditem(od->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP)) && (!del->data)) {		aim_ssi_itemlist_del(&od->ssi.local, del);		/* Modify the parent group */		aim_ssi_itemlist_rebuildgroup(od->ssi.local, NULL);		/* Check if we should delete the parent's parent (the master group) */		if ((del = aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000)) && (!del->data)) {			aim_ssi_itemlist_del(&od->ssi.local, del);		}	}	/* Sync our local list with the server list */	return aim_ssi_sync(od);}/** * Deletes a permit buddy from the list. * * @param od The oscar odion. * @param name The name of the item, or NULL. * @return Return 0 if no errors, otherwise return the error number. */int aim_ssi_delpermit(OscarData *od, const char *name){	struct aim_ssi_item *del;	if (!od)		return -EINVAL;	/* Find the item */	if (!(del = aim_ssi_itemlist_finditem(od->ssi.local, NULL, name, AIM_SSI_TYPE_PERMIT)))		return -EINVAL;	/* Remove the item from the list */	aim_ssi_itemlist_del(&od->ssi.local, del);	/* Sync our local list with the server list */	return aim_ssi_sync(od);}/** * Deletes a deny buddy from the list. * * @param od The oscar odion. * @param name The name of the item, or NULL. * @return Return 0 if no errors, otherwise return the error number. */int aim_ssi_deldeny(OscarData *od, const char *name){	struct aim_ssi_item *del;	if (!od)		return -EINVAL;	/* Find the item */	if (!(del = aim_ssi_itemlist_finditem(od->ssi.local, NULL, name, AIM_SSI_TYPE_DENY)))		return -EINVAL;	/* Remove the item from the list */	aim_ssi_itemlist_del(&od->ssi.local, del);	/* Sync our local list with the server list */	return aim_ssi_sync(od);}/** * Move a buddy from one group to another group.  This basically just deletes the * buddy and re-adds it. * * @param od The oscar odion. * @param oldgn The group that the buddy is currently in. * @param newgn The group that the buddy should be moved in to. * @param sn The name of the buddy to be moved. * @return Return 0 if no errors, otherwise return the error number. */int aim_ssi_movebuddy(OscarData *od, const char *oldgn, const char *newgn, const char *sn){	struct aim_ssi_item *buddy;	GSList *data;	/* Find the buddy */	buddy = aim_ssi_itemlist_finditem(od->ssi.local, oldgn, sn, AIM_SSI_TYPE_BUDDY);	if (buddy == NULL)		return -EINVAL;	/* Make a copy of the buddy's TLV list */	data = aim_tlvlist_copy(buddy->data);	/* Delete the old item */	aim_ssi_delbuddy(od, sn, oldgn);	/* Add the new item using the EXACT SAME TLV list */	aim_ssi_addbuddy(od, sn, newgn, data, NULL, NULL, NULL, FALSE);	return 0;}/** * Change the alias stored on the server for a given buddy. * * @param od The oscar odion. * @param gn The group that the buddy is currently in. * @param sn The screen name of the buddy. * @param alias The new alias for the buddy, or NULL if you want to remove *        a buddy's comment. * @return Return 0 if no errors, otherwise return the error number. */int aim_ssi_aliasbuddy(OscarData *od, const char *gn, const char *sn, const char *alias){	struct aim_ssi_item *tmp;	if (!od || !gn || !sn)		return -EINVAL;	if (!(tmp = aim_ssi_itemlist_finditem(od->ssi.local, gn, sn, AIM_SSI_TYPE_BUDDY)))		return -EINVAL;	/* Either add or remove the 0x0131 TLV from the TLV chain */	if ((alias != NULL) && (strlen(alias) > 0))		aim_tlvlist_replace_str(&tmp->data, 0x0131, alias);	else		aim_tlvlist_remove(&tmp->data, 0x0131);	/* Sync our local list with the server list */	return aim_ssi_sync(od);}/** * Change the comment stored on the server for a given buddy. * * @param od The oscar odion. * @param gn The group that the buddy is currently in. * @param sn The screen name of the buddy. * @param alias The new comment for the buddy, or NULL if you want to remove *        a buddy's comment. * @return Return 0 if no errors, otherwise return the error number. */int aim_ssi_editcomment(OscarData *od, const char *gn, const char *sn, const char *comment){	struct aim_ssi_item *tmp;	if (!od || !gn || !sn)		return -EINVAL;	if (!(tmp = aim_ssi_itemlist_finditem(od->ssi.local, gn, sn, AIM_SSI_TYPE_BUDDY)))		return -EINVAL;	/* Either add or remove the 0x0131 TLV from the TLV chain */	if ((comment != NULL) && (strlen(comment) > 0))		aim_tlvlist_replace_str(&tmp->data, 0x013c, comment);	else		aim_tlvlist_remove(&tmp->data, 0x013c);	/* Sync our local list with the server list */	return aim_ssi_sync(od);}/** * Rename a group.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -