📄 zephyr.c
字号:
tempstridx=0; if (!g_ascii_strncasecmp(tempstr,"zephyrid",8)) { gchar* username = g_malloc0(100); int username_idx=0; char *realm; purple_debug_info("zephyr","zephyrid found\n"); tempstridx+=8; while(tempstr[tempstridx] !='"' && tempstridx < 20000) tempstridx++; tempstridx++; while(tempstr[tempstridx] !='"' && tempstridx < 20000) username[username_idx++]=tempstr[tempstridx++]; zephyr->username = g_strdup_printf("%s",username); if ((realm = strchr(username,'@'))) zephyr->realm = g_strdup_printf("%s",realm+1); else { realm = (gchar *)purple_account_get_string(gc->account,"realm",""); if (!*realm) { realm = "local-realm"; } zephyr->realm = g_strdup(realm); g_strlcpy(__Zephyr_realm, (const char*)zephyr->realm, REALM_SZ-1); } /* else { zephyr->realm = g_strdup("local-realm"); }*/ g_free(username); } else { purple_debug_info("zephyr", "something that's not zephyr id found %s\n",tempstr); } /* We don't care about anything else yet */ g_free(tempstr); break; default: purple_debug_info("zephyr","parenlevel is not 1 or 2\n"); /* This shouldn't be happening */ break; } if (parenlevel==0) break; } /* while (ptr < bufcur) */ purple_debug_info("zephyr", "tzc startup done\n"); free(buf); } } else if ( use_zeph02(zephyr)) { gchar* realm; z_call_s(ZInitialize(), "Couldn't initialize zephyr"); z_call_s(ZOpenPort(&(zephyr->port)), "Couldn't open port"); z_call_s(ZSetLocation((char *)zephyr->exposure), "Couldn't set location"); realm = (gchar *)purple_account_get_string(gc->account,"realm",""); if (!*realm) { realm = ZGetRealm(); } zephyr->realm = g_strdup(realm); g_strlcpy(__Zephyr_realm, (const char*)zephyr->realm, REALM_SZ-1); zephyr->username = g_strdup(ZGetSender()); /* zephyr->realm = g_strdup(ZGetRealm()); */ purple_debug_info("zephyr","realm: %s\n",zephyr->realm); } else { purple_connection_error(gc,"Only ZEPH0.2 supported currently"); return; } purple_debug_info("zephyr","does it get here\n"); purple_debug_info("zephyr"," realm: %s username:%s\n", zephyr->realm, zephyr->username); /* For now */ zephyr->galaxy = NULL; zephyr->krbtkfile = NULL; zephyr_inithosts(zephyr); if (zephyr_subscribe_to(zephyr,"MESSAGE","PERSONAL",zephyr->username,NULL) != ZERR_NONE) { /* XXX don't translate this yet. It could be written better */ /* XXX error messages could be handled with more detail */ purple_notify_error(account->gc, NULL, "Unable to subscribe to messages", "Unable to subscribe to initial messages"); return; } purple_connection_set_state(gc, PURPLE_CONNECTED); if (read_anyone) process_anyone(gc); if (read_zsubs) process_zsubs(zephyr); if (use_zeph02(zephyr)) { zephyr->nottimer = purple_timeout_add(100, check_notify_zeph02, gc); } else if (use_tzc(zephyr)) { zephyr->nottimer = purple_timeout_add(100, check_notify_tzc, gc); } zephyr->loctimer = purple_timeout_add(20000, check_loc, gc); }static void write_zsubs(zephyr_account *zephyr){ /* Exports subscription (chat) list back to * .zephyr.subs * XXX deal with %host%, %canon%, unsubscriptions, and negative subscriptions (punts?) */ GSList *s = zephyr->subscrips; zephyr_triple *zt; FILE *fd; char *fname; char **triple; fname = g_strdup_printf("%s/.zephyr.subs", purple_home_dir()); fd = g_fopen(fname, "w"); if (!fd) { g_free(fname); return; } while (s) { char *zclass, *zinst, *zrecip; zt = s->data; triple = g_strsplit(zt->name, ",", 3); /* deal with classes */ if (!g_ascii_strcasecmp(triple[0],zephyr->ourhost)) { zclass = g_strdup("%host%"); } else if (!g_ascii_strcasecmp(triple[0],zephyr->ourhostcanon)) { zclass = g_strdup("%canon%"); } else { zclass = g_strdup(triple[0]); } /* deal with instances */ if (!g_ascii_strcasecmp(triple[1],zephyr->ourhost)) { zinst = g_strdup("%host%"); } else if (!g_ascii_strcasecmp(triple[1],zephyr->ourhostcanon)) { zinst = g_strdup("%canon%");; } else { zinst = g_strdup(triple[1]); } /* deal with recipients */ if (triple[2] == NULL) { zrecip = g_strdup("*"); } else if (!g_ascii_strcasecmp(triple[2],"")){ zrecip = g_strdup("*"); } else if (!g_ascii_strcasecmp(triple[2], zephyr->username)) { zrecip = g_strdup("%me%"); } else { zrecip = g_strdup(triple[2]); } fprintf(fd, "%s,%s,%s\n",zclass,zinst,zrecip); g_free(zclass); g_free(zinst); g_free(zrecip); g_free(triple); s = s->next; } g_free(fname); fclose(fd);}static void write_anyone(PurpleConnection *gc){ PurpleBlistNode *gnode, *cnode, *bnode; PurpleBuddy *b; char *fname; FILE *fd; zephyr_account* zephyr = gc->proto_data; fname = g_strdup_printf("%s/.anyone", purple_home_dir()); fd = g_fopen(fname, "w"); if (!fd) { g_free(fname); return; } 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) { if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) continue; b = (PurpleBuddy *) bnode; if (b->account == gc->account) { gchar *stripped_user = zephyr_strip_local_realm(zephyr,b->name); fprintf(fd, "%s\n", stripped_user); g_free(stripped_user); } } } } fclose(fd); g_free(fname);}static void zephyr_close(PurpleConnection * gc){ GList *l; GSList *s; zephyr_account *zephyr = gc->proto_data; pid_t tzc_pid = zephyr->tzc_pid; l = zephyr->pending_zloc_names; while (l) { g_free((char *)l->data); l = l->next; } g_list_free(zephyr->pending_zloc_names); if (purple_account_get_bool(gc->account, "write_anyone", FALSE)) write_anyone(gc); if (purple_account_get_bool(gc->account, "write_zsubs", FALSE)) write_zsubs(gc->proto_data); s = zephyr->subscrips; while (s) { free_triple((zephyr_triple *) s->data); s = s->next; } g_slist_free(zephyr->subscrips); if (zephyr->nottimer) purple_timeout_remove(zephyr->nottimer); zephyr->nottimer = 0; if (zephyr->loctimer) purple_timeout_remove(zephyr->loctimer); zephyr->loctimer = 0; gc = NULL; if (use_zeph02(zephyr)) { z_call(ZCancelSubscriptions(0)); z_call(ZUnsetLocation()); z_call(ZClosePort()); } else { /* assume tzc */ if (kill(tzc_pid,SIGTERM) == -1) { int err=errno; if (err==EINVAL) { purple_debug_error("zephyr","An invalid signal was specified when killing tzc\n"); } else if (err==ESRCH) { purple_debug_error("zephyr","Tzc's pid didn't exist while killing tzc\n"); } else if (err==EPERM) { purple_debug_error("zephyr","purple didn't have permission to kill tzc\n"); } else { purple_debug_error("zephyr","miscellaneous error while attempting to close tzc\n"); } } }}static int zephyr_send_message(zephyr_account *zephyr,char* zclass, char* instance, char* recipient, const char *im, const char *sig, char *opcode) ;static const char * zephyr_get_signature(){ /* XXX add zephyr error reporting */ const char * sig =ZGetVariable("zwrite-signature"); if (!sig) { sig = g_get_real_name(); } return sig;}static int zephyr_chat_send(PurpleConnection * gc, int id, const char *im, PurpleMessageFlags flags){ zephyr_triple *zt; const char *sig; PurpleConversation *gconv1; PurpleConvChat *gcc; char *inst; char *recipient; zephyr_account *zephyr = gc->proto_data; zt = find_sub_by_id(gc->proto_data,id); if (!zt) /* this should never happen. */ return -EINVAL; sig = zephyr_get_signature(); gconv1 = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, zt->name, gc->account); gcc = purple_conversation_get_chat_data(gconv1); if (!(inst = (char *)purple_conv_chat_get_topic(gcc))) inst = g_strdup("PERSONAL"); if (!g_ascii_strcasecmp(zt->recipient, "*")) recipient = local_zephyr_normalize(zephyr,""); else recipient = local_zephyr_normalize(zephyr,zt->recipient); zephyr_send_message(zephyr,zt->class,inst,recipient,im,sig,""); return 0;}static int zephyr_send_im(PurpleConnection * gc, const char *who, const char *im, PurpleMessageFlags flags){ const char *sig; zephyr_account *zephyr = gc->proto_data; if (flags & PURPLE_MESSAGE_AUTO_RESP) sig = "Automated reply:"; else { sig = zephyr_get_signature(); } zephyr_send_message(zephyr,"MESSAGE","PERSONAL",local_zephyr_normalize(zephyr,who),im,sig,""); return 1; }/* Munge the outgoing zephyr so that any quotes or backslashes are escaped and do not confuse tzc: */static char* zephyr_tzc_escape_msg(const char *message){ int pos = 0; int pos2 = 0; char *newmsg; if (message && (strlen(message) > 0)) { newmsg = g_new0(char,1+strlen(message)*2); while(pos < strlen(message)) { if (message[pos]=='\\') { newmsg[pos2]='\\'; newmsg[pos2+1]='\\'; pos2+=2; } else if (message[pos]=='"') { newmsg[pos2]='\\'; newmsg[pos2+1]='"'; pos2+=2; } else { newmsg[pos2] = message[pos]; pos2++; } pos++; } } else { newmsg = g_strdup(""); } /* fprintf(stderr,"newmsg %s message %s\n",newmsg,message); */ return newmsg;}char* zephyr_tzc_deescape_str(const char *message){ int pos = 0; int pos2 = 0; char *newmsg; if (message && (strlen(message) > 0)) { newmsg = g_new0(char,strlen(message)+1); while(pos < strlen(message)) { if (message[pos]=='\\') { pos++; } newmsg[pos2] = message[pos]; pos++;pos2++; } newmsg[pos2]='\0'; } else { newmsg = g_strdup(""); } return newmsg;}static int zephyr_send_message(zephyr_account *zephyr,char* zclass, char* instance, char* recipient, const char *im, const char *sig, char *opcode) { /* (From the tzc source) * emacs sends something of the form: * ((class . "MESSAGE") * (auth . t) * (recipients ("PERSONAL" . "bovik") ("test" . "")) * (sender . "bovik") * (message . ("Harry Bovik" "my zgram")) * ) */ char *html_buf; char *html_buf2; html_buf = html_to_zephyr(im); html_buf2 = purple_unescape_html(html_buf); if(use_tzc(zephyr)) { char* zsendstr; /* CMU cclub tzc doesn't grok opcodes for now */ char* tzc_sig = zephyr_tzc_escape_msg(sig); char *tzc_body = zephyr_tzc_escape_msg(html_buf2); zsendstr = g_strdup_printf("((tzcfodder . send) (class . \"%s\") (auth . t) (recipients (\"%s\" . \"%s\")) (message . (\"%s\" \"%s\")) ) \n", zclass, instance, recipient, tzc_sig, tzc_body); /* fprintf(stderr,"zsendstr = %s\n",zsendstr); */ write(zephyr->totzc[ZEPHYR_FD_WRITE],zsendstr,strlen(zsendstr)); g_free(zsendstr); } else if (use_zeph02(zephyr)) { ZNotice_t notice; char *buf = g_strdup_printf("%s%c%s", sig, '\0', html_buf2); bzero((char *)¬ice, sizeof(notice)); notice.z_kind = ACKED; notice.z_port = 0; notice.z_opcode = ""; notice.z_class = zclass; notice.z_class_inst = instance; notice.z_recipient = recipient; notice.z_sender = 0; 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(html_buf2) + strlen(sig) + 2; notice.z_message = buf; notice.z_opcode = g_strdup(opcode); purple_debug_info("zephyr","About to send notice"); if (! ZSendNotice(¬ice, ZAUTH) == ZERR_NONE) { /* XXX handle errors here */ return 0; } purple_debug_info("zephyr","notice sent"); g_free(buf); } g_free(html_buf2); g_free(html_buf); return 1;}char *local_zephyr_normalize(zephyr_account *zephyr,const char *orig){ /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -