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

📄 zephyr.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
				}								if (!in_deny) {					serv_got_im(gc, stripped_sender, buf3, flags, time(NULL));				}			}			g_free(stripped_sender);		} else {			zephyr_triple *zt1, *zt2;			gchar *send_inst_utf8;			zephyr_account *zephyr = gc->proto_data;			zt1 = new_triple(gc->proto_data,notice.z_class, notice.z_class_inst, notice.z_recipient);			zt2 = find_sub_by_triple(gc->proto_data,zt1);			if (!zt2) {				/* This is a server supplied subscription */				zephyr->subscrips = g_slist_append(zephyr->subscrips, new_triple(zephyr,zt1->class,zt1->instance,zt1->recipient));				zt2 = find_sub_by_triple(gc->proto_data,zt1);			} 								if (!zt2->open) {				zt2->open = TRUE;				serv_got_joined_chat(gc, zt2->id, zt2->name);				zephyr_chat_set_topic(gc,zt2->id,notice.z_class_inst);			}			g_free(sendertmp); /* fix memory leak? */			/* If the person is in the default Realm, then strip the 			   Realm from the sender field */			sendertmp = zephyr_strip_local_realm(zephyr,notice.z_sender);			send_inst = g_strdup_printf("%s %s",sendertmp,notice.z_class_inst);								send_inst_utf8 = zephyr_recv_convert(gc,send_inst, strlen(send_inst));			if (!send_inst_utf8) {				purple_debug_error("zephyr","send_inst %s became null\n", send_inst);				send_inst_utf8 = "malformed instance";			}			gconv1 = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,														 zt2->name, gc->account);			gcc = purple_conversation_get_chat_data(gconv1);			if (!purple_conv_chat_find_user(gcc, sendertmp)) {				gchar ipaddr[INET_ADDRSTRLEN];				inet_ntop(AF_INET, &notice.z_sender_addr.s_addr, ipaddr, sizeof(ipaddr));				purple_conv_chat_add_user(gcc, sendertmp, ipaddr, PURPLE_CBFLAGS_NONE, TRUE);			}			g_free(sendertmp);			serv_got_chat_in(gc, zt2->id, send_inst_utf8, 0, buf3, time(NULL));			g_free(send_inst);			g_free(send_inst_utf8);							free_triple(zt1);		}		g_free(buf3);			}}static int  free_parse_tree(parse_tree* tree) {	if (!tree) {		return 0;	}	else {		int i;		if (tree->children) {			for(i=0;i<tree->num_children;i++){				if (tree->children[i]) {					free_parse_tree(tree->children[i]);					g_free(tree->children[i]);				}			}		}		if ((tree != &null_parse_tree) && (tree->contents != NULL))			g_free(tree->contents);	  	}	return 0;}static parse_tree *tree_child(parse_tree* tree,int index) {	if (index < tree->num_children) {		return tree->children[index];	} else {		return &null_parse_tree;	}}static parse_tree *find_node(parse_tree* ptree,gchar* key){	gchar* tc;	if (!ptree || ! key) 		return &null_parse_tree;	tc = tree_child(ptree,0)->contents;	/* g_strcasecmp() is deprecated.  What is the encoding here??? */	if (ptree->num_children > 0  &&	tc && !g_strcasecmp(tc, key)) {		return ptree;	} else {		parse_tree *result = &null_parse_tree;		int i;		for(i = 0; i < ptree->num_children; i++) {			result = find_node(ptree->children[i],key);			if(result != &null_parse_tree) {				break;			}		}		return result;	}}static parse_tree *parse_buffer(gchar* source, gboolean do_parse) {		parse_tree *ptree = g_new0(parse_tree,1);	ptree->contents = NULL;	ptree->num_children=0;	if (do_parse) {		unsigned int p = 0;		while(p < strlen(source)) {			unsigned int end;			gchar *newstr;			/* Eat white space: */			if(g_ascii_isspace(source[p]) || source[p] == '\001') {				p++;				continue;			}						/* Skip comments */			if(source[p] == ';') {				while(source[p] != '\n' && p < strlen(source)) {					p++;				}				continue;			}						if(source[p] == '(') {				int nesting = 0;				gboolean in_quote = FALSE;				gboolean escape_next = FALSE;				p++;				end = p;				while(!(source[end] == ')' && nesting == 0 && !in_quote) && end < strlen(source)) {					if(!escape_next) {						if(source[end] == '\\') {							escape_next = TRUE;						}						if(!in_quote) {							if(source[end] == '(') {								nesting++;							}							if(source[end] == ')') {								nesting--;							}						}						if(source[end] == '"') {							in_quote = !in_quote;						}					} else {						escape_next = FALSE;					}					end++;				}				do_parse = TRUE;			} else {				gchar end_char;				if(source[p] == '"') {					end_char = '"';					p++;				} else {					end_char = ' ';				}					      				do_parse = FALSE;				end = p;				while(source[end] != end_char && end < strlen(source)) {					if(source[end] == '\\') 						end++;					end++;				}			}			newstr = g_new0(gchar, end+1-p);			strncpy(newstr,source+p,end-p);			if (ptree->num_children < MAXCHILDREN) {				/* In case we surpass maxchildren, ignore this */				ptree->children[ptree->num_children++] = parse_buffer( newstr, do_parse);			} else {				purple_debug_error("zephyr","too many children in tzc output. skipping\n");			}			g_free(newstr);			p = end + 1;		}		return ptree;	} else {		/* XXX does this have to be strdup'd */		ptree->contents = g_strdup(source);		return ptree;	}}static parse_tree  *read_from_tzc(zephyr_account* zephyr){	struct timeval tv;	fd_set rfds;	int bufsize = 2048;	char *buf = (char *)calloc(bufsize, 1);	char *bufcur = buf;	int selected = 0;	parse_tree *incoming_msg;	FD_ZERO(&rfds);	FD_SET(zephyr->fromtzc[ZEPHYR_FD_READ], &rfds);	tv.tv_sec = 0;	tv.tv_usec = 0;	incoming_msg=NULL;	while (select(zephyr->fromtzc[ZEPHYR_FD_READ] + 1, &rfds, NULL, NULL, &tv)) {		selected = 1;		read(zephyr->fromtzc[ZEPHYR_FD_READ], bufcur, 1);		bufcur++;		if ((bufcur - buf) > (bufsize - 1)) {			if ((buf = realloc(buf, bufsize * 2)) == NULL) {				purple_debug_error("zephyr","Ran out of memory");				exit(-1);			} else {				bufcur = buf + bufsize;				bufsize *= 2;			}		}	}	*bufcur = '\0';	if (selected) {		incoming_msg = parse_buffer(buf,TRUE);	}	free(buf);	return incoming_msg;}static gint check_notify_tzc(gpointer data){	PurpleConnection *gc = (PurpleConnection *)data;	zephyr_account* zephyr = gc->proto_data;	parse_tree *newparsetree = read_from_tzc(zephyr);	if (newparsetree != NULL) {		gchar *spewtype;		if ( (spewtype =  tree_child(find_node(newparsetree,"tzcspew"),2)->contents) ) {			if (!g_ascii_strncasecmp(spewtype,"message",7)) {				ZNotice_t notice;				parse_tree *msgnode = tree_child(find_node(newparsetree,"message"),2);				parse_tree *bodynode = tree_child(msgnode,1);				/*				char *zsig = g_strdup(" "); */ /* purple doesn't care about zsigs */				char *msg  = zephyr_tzc_deescape_str(bodynode->contents);				size_t bufsize = strlen(msg) + 3;				char *buf = g_new0(char,bufsize);				g_snprintf(buf,1+strlen(msg)+2," %c%s",'\0',msg);				bzero((char *)&notice, sizeof(notice));				notice.z_kind = ACKED;				notice.z_port = 0;				notice.z_opcode = tree_child(find_node(newparsetree,"opcode"),2)->contents;				notice.z_class = zephyr_tzc_deescape_str(tree_child(find_node(newparsetree,"class"),2)->contents);				notice.z_class_inst = tree_child(find_node(newparsetree,"instance"),2)->contents;				notice.z_recipient = local_zephyr_normalize(zephyr,tree_child(find_node(newparsetree,"recipient"),2)->contents);				notice.z_sender = local_zephyr_normalize(zephyr,tree_child(find_node(newparsetree,"sender"),2)->contents);				notice.z_default_format = "Class $class, Instance $instance:\n" "To: @bold($recipient) at $time $date\n" "From: @bold($1) <$sender>\n\n$2";				notice.z_message_len = strlen(msg) + 3;				notice.z_message = buf;				handle_message(gc, notice);				g_free(msg);				/*				  g_free(zsig); */				g_free(buf);				/* free_parse_tree(msgnode);				   free_parse_tree(bodynode); 				   g_free(msg);				   g_free(zsig);				   g_free(buf); 				*/			}			else if (!g_ascii_strncasecmp(spewtype,"zlocation",9)) {				/* check_loc or zephyr_zloc respectively */				/* XXX fix */				char *user; 				PurpleBuddy *b;				int nlocs = 0;				parse_tree *locations;				gchar *locval;				user = tree_child(find_node(newparsetree,"user"),2)->contents;				if ((b = purple_find_buddy(gc->account, user)) == NULL) {					gchar *stripped_user = zephyr_strip_local_realm(zephyr,user);					b = purple_find_buddy(gc->account, stripped_user);					g_free(stripped_user);				}				locations = find_node(newparsetree,"locations");				locval = tree_child(tree_child(tree_child(tree_child(locations,2),0),0),2)->contents;				if (!locval || !g_ascii_strcasecmp(locval," ") || (strlen(locval) == 0)) {					nlocs = 0;				} else {					nlocs = 1;				}					if ((b && pending_zloc(zephyr,b->name)) || pending_zloc(zephyr,user) || pending_zloc(zephyr,local_zephyr_normalize(zephyr,user))){					PurpleNotifyUserInfo *user_info = purple_notify_user_info_new();					char *tmp;					purple_notify_user_info_add_pair(user_info, _("User"), (b ? b->name : user));					if (b && b->alias)						purple_notify_user_info_add_pair(user_info, _("Alias"), b->alias);																if (!nlocs) {						purple_notify_user_info_add_pair(user_info, NULL, _("Hidden or not logged-in"));					} else {						tmp = g_strdup_printf(_("<br>At %s since %s"),									  tree_child(tree_child(tree_child(tree_child(locations,2),0),0),2)->contents,									  tree_child(tree_child(tree_child(tree_child(locations,2),0),2),2)->contents);						purple_notify_user_info_add_pair(user_info, _("Location"), tmp);						g_free(tmp);					}					purple_notify_userinfo(gc, b ? b->name : user,							     user_info, NULL, NULL);					purple_notify_user_info_destroy(user_info);				} else {					if (nlocs>0) 						purple_prpl_got_user_status(gc->account, b ? b->name : user, "available", NULL);					else 						purple_prpl_got_user_status(gc->account, b ? b->name : user, "offline", NULL);				}			}			else if (!g_ascii_strncasecmp(spewtype,"subscribed",10)) {			}			else if (!g_ascii_strncasecmp(spewtype,"start",5)) {			}			else if (!g_ascii_strncasecmp(spewtype,"error",5)) {				/* XXX handle */			}		} else {		}	} else {	}		free_parse_tree(newparsetree);	return TRUE;}static gint check_notify_zeph02(gpointer data){	/* XXX add real error reporting */	PurpleConnection *gc = (PurpleConnection*) data;	while (ZPending()) {		ZNotice_t notice;		struct sockaddr_in from;		/* XXX add real error reporting */		z_call_r(ZReceiveNotice(&notice, &from));		switch (notice.z_kind) {		case UNSAFE:		case UNACKED:		case ACKED:			handle_message(gc,notice);			break;		case SERVACK:			if (!(g_ascii_strcasecmp(notice.z_message, ZSRVACK_NOTSENT))) {				message_failed(gc,notice, from);			}			break;		case CLIENTACK:			purple_debug_error("zephyr", "Client ack received\n");		default:			/* we'll just ignore things for now */			handle_unknown(notice);			purple_debug_error("zephyr", "Unhandled notice.\n");			break;		}		/* XXX add real error reporting */		ZFreeNotice(&notice);	}	return TRUE;}#ifdef WIN32static gint check_loc(gpointer_data){        PurpleBlistNode *gnode, *cnode, *bnode;        ZLocations_t locations;        int numlocs;        int one = 1;	for (gnode = purple_get_blist()->root; gnode; gnode = gnode->next) {		if (!PURPLE_BLIST_NODE_IS_GROUP(gnode))			continue;		for (cnode = gnode->child; cnode; cnode = cnode->next) {			if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode))				continue;			for (bnode = cnode->child; bnode; bnode = bnode->next) {				PurpleBuddy *b = (PurpleBuddy *) bnode;				if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode))					continue;				if (b->account->gc == zgc) {					char *chk;                                        chk = local_zephyr_normalize(b->name);                                        ZLocateUser(chk,&numlocs, ZAUTH);                                        if (numlocs) {                                                int i;                                                for(i=0;i<numlocs;i++) {                                                        ZGetLocations(&locations,&one);                                                        serv_got_update(zgc,b->name,1,0,0,0,0);                                                }                                        }                                }                        }                }        }        return TRUE;}#elsestatic gint check_loc(gpointer data){	PurpleBlistNode *gnode, *cnode, *bnode;	ZAsyncLocateData_t ald;	PurpleConnection *gc = (PurpleConnection *)data;	zephyr_account *zephyr = gc->proto_data;	if (use_zeph02(zephyr)) {		ald.user = NULL;		memset(&(ald.uid), 0, sizeof(ZUnique_Id_t));		ald.version = NULL;	}	for (gnode = purple_get_blist()->root; gnode; gnode = gnode->next) {		if (!PURPLE_BLIST_NODE_IS_GROUP(gnode))			continue;		for (cnode = gnode->child; cnode; cnode = cnode->next) {			if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode))				continue;			for (bnode = cnode->child; bnode; bnode = bnode->next) {				PurpleBuddy *b = (PurpleBuddy *) bnode;				if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode))

⌨️ 快捷键说明

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