📄 zephyr.c
字号:
} 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, ¬ice.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 *)¬ice, 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(¬ice, &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(¬ice); } 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 + -