📄 toc.c
字号:
} else { g_snprintf(buf, sizeof(buf) / 2, "toc_chat_join %d \"%s\"", atoi(exchange), name); } sflap_send(g, buf, -1, TYPE_DATA);}static void toc_chat_invite(PurpleConnection *gc, int id, const char *message, const char *name){ char buf[BUF_LONG]; g_snprintf(buf, sizeof(buf) / 2, "toc_chat_invite %d \"%s\" %s", id, message ? message : "", purple_normalize(gc->account, name)); sflap_send(gc, buf, -1, TYPE_DATA);}static void toc_chat_leave(PurpleConnection *g, int id){ GSList *bcs = g->buddy_chats; PurpleConversation *b = NULL; char buf[BUF_LEN * 2]; while (bcs) { b = (PurpleConversation *)bcs->data; if (id == purple_conv_chat_get_id(PURPLE_CONV_CHAT(b))) break; b = NULL; bcs = bcs->next; } if (!b) return; /* can this happen? */ if (purple_conversation_get_account(b) == NULL) { /* TOC already kicked us out of this room */ serv_got_chat_left(g, id); } else { g_snprintf(buf, 255, "toc_chat_leave %d", id); sflap_send(g, buf, -1, TYPE_DATA); }}static void toc_chat_whisper(PurpleConnection *gc, int id, const char *who, const char *message){ char *buf1, *buf2; buf1 = escape_text(message); buf2 = g_strdup_printf("toc_chat_whisper %d %s \"%s\"", id, purple_normalize(gc->account, who), buf1); g_free(buf1); sflap_send(gc, buf2, -1, TYPE_DATA); g_free(buf2);}static int toc_chat_send(PurpleConnection *g, int id, const char *message, PurpleMessageFlags flags){ char *buf1, *buf2; buf1 = escape_text(message); if (strlen(buf1) > 2000) { g_free(buf1); return -E2BIG; } buf2 = g_strdup_printf("toc_chat_send %d \"%s\"", id, buf1); g_free(buf1); sflap_send(g, buf2, -1, TYPE_DATA); g_free(buf2); return 0;}static void toc_keepalive(PurpleConnection *gc){ sflap_send(gc, "", 0, TYPE_KEEPALIVE);}static const char *toc_normalize(const PurpleAccount *account, const char *str){ static char buf[BUF_LEN]; char *tmp1, *tmp2; int i, j; g_return_val_if_fail(str != NULL, NULL); strncpy(buf, str, BUF_LEN); for (i=0, j=0; buf[j]; i++, j++) { while (buf[j] == ' ') j++; buf[i] = buf[j]; } buf[i] = '\0'; tmp1 = g_utf8_strdown(buf, -1); tmp2 = g_utf8_normalize(tmp1, -1, G_NORMALIZE_DEFAULT); g_snprintf(buf, sizeof(buf), "%s", tmp2); g_free(tmp2); g_free(tmp1); return buf;}static const char *toc_list_icon(PurpleAccount *a, PurpleBuddy *b){ if (!b || (b && b->name && b->name[0] == '+')) { if (a != NULL && isdigit(*purple_account_get_username(a))) return "icq"; else return "aim"; } if (b && b->name && isdigit(b->name[0])) return "icq"; return "aim";}static const char* toc_list_emblem(PurpleBuddy *b){ if (b->uc & UC_AOL) return "aol"; if (b->uc & UC_ADMIN) return "admin"; if (b->uc & UC_WIRELESS) return "mobile"; return NULL }static GList *toc_blist_node_menu(PurpleBlistNode *node){ GList *m = NULL; PurpleMenuAction *act; if(PURPLE_BLIST_NODE_IS_BUDDY(node)) { act = purple_menu_action_new(_("Get Dir Info"), toc_get_dir, NULL, NULL); m = g_list_append(m, act); } return m;}static void toc_add_permit(PurpleConnection *gc, const char *who){ char buf2[BUF_LEN * 2]; if (gc->account->perm_deny != 3) return; g_snprintf(buf2, sizeof(buf2), "toc_add_permit %s", purple_normalize(gc->account, who)); sflap_send(gc, buf2, -1, TYPE_DATA); toc_set_config(gc);}static void toc_add_deny(PurpleConnection *gc, const char *who){ char buf2[BUF_LEN * 2]; if (gc->account->perm_deny != 4) return; g_snprintf(buf2, sizeof(buf2), "toc_add_deny %s", purple_normalize(gc->account, who)); sflap_send(gc, buf2, -1, TYPE_DATA); toc_set_config(gc);}static void toc_set_permit_deny(PurpleConnection *gc){ char buf2[BUF_LEN * 2]; GSList *list; int at; switch (gc->account->perm_deny) { case 1: /* permit all, deny none. to get here reliably we need to have been in permit * mode, and send an empty toc_add_deny message, which will switch us to deny none */ g_snprintf(buf2, sizeof(buf2), "toc_add_permit "); sflap_send(gc, buf2, -1, TYPE_DATA); g_snprintf(buf2, sizeof(buf2), "toc_add_deny "); sflap_send(gc, buf2, -1, TYPE_DATA); break; case 2: /* deny all, permit none. to get here reliably we need to have been in deny * mode, and send an empty toc_add_permit message, which will switch us to permit none */ g_snprintf(buf2, sizeof(buf2), "toc_add_deny "); sflap_send(gc, buf2, -1, TYPE_DATA); g_snprintf(buf2, sizeof(buf2), "toc_add_permit "); sflap_send(gc, buf2, -1, TYPE_DATA); break; case 3: /* permit some. we want to switch to deny mode first, then send the toc_add_permit * message, which will clear and set our permit list. toc sucks. */ g_snprintf(buf2, sizeof(buf2), "toc_add_deny "); sflap_send(gc, buf2, -1, TYPE_DATA); at = g_snprintf(buf2, sizeof(buf2), "toc_add_permit "); list = gc->account->permit; while (list) { at += g_snprintf(buf2 + at, sizeof(buf2) - at, "%s ", purple_normalize(gc->account, list->data)); if (at > MSG_LEN + 32) { /* from out my ass comes greatness */ sflap_send(gc, buf2, -1, TYPE_DATA); at = g_snprintf(buf2, sizeof(buf2), "toc_add_permit "); } list = list->next; } sflap_send(gc, buf2, -1, TYPE_DATA); break; case 4: /* deny some. we want to switch to permit mode first, then send the toc_add_deny * message, which will clear and set our deny list. toc sucks. */ g_snprintf(buf2, sizeof(buf2), "toc_add_permit "); sflap_send(gc, buf2, -1, TYPE_DATA); at = g_snprintf(buf2, sizeof(buf2), "toc_add_deny "); list = gc->account->deny; while (list) { at += g_snprintf(buf2 + at, sizeof(buf2) - at, "%s ", purple_normalize(gc->account, list->data)); if (at > MSG_LEN + 32) { /* from out my ass comes greatness */ sflap_send(gc, buf2, -1, TYPE_DATA); at = g_snprintf(buf2, sizeof(buf2), "toc_add_deny "); } list = list->next; } sflap_send(gc, buf2, -1, TYPE_DATA); break; default: break; } toc_set_config(gc);}static void toc_rem_permit(PurpleConnection *gc, const char *who){ if (gc->account->perm_deny != 3) return; toc_set_permit_deny(gc);}static void toc_rem_deny(PurpleConnection *gc, const char *who){ if (gc->account->perm_deny != 4) return; toc_set_permit_deny(gc);}static GList *toc_away_states(PurpleAccount *account){#if 0 /* do we care about TOC any more? */ return g_list_append(NULL, PURPLE_AWAY_CUSTOM);#else return NULL;#endif}static voidshow_set_info(PurplePluginAction *action){ PurpleConnection *gc = (PurpleConnection *) action->context; purple_account_request_change_user_info(purple_connection_get_account(gc));}static voidchange_pass(PurplePluginAction *action){ PurpleConnection *gc = (PurpleConnection *) action->context; purple_account_request_change_password(purple_connection_get_account(gc));}static GList *toc_actions(PurplePlugin *plugin, gpointer context){ GList *m = NULL; PurplePluginAction *act; act = purple_plugin_action_new(_("Set User Info"), show_set_info); m = g_list_append(m, act);#if 0 act = purple_plugin_action_new(_("Set Dir Info"), show_set_dir); m = g_list_append(m, act);#endif act = purple_plugin_action_new(_("Change Password"), change_pass); m = g_list_append(m, act); return m;}#if 0/********* * RVOUS ACTIONS ********/struct file_header { char magic[4]; /* 0 */ short hdrlen; /* 4 */ short hdrtype; /* 6 */ char bcookie[8]; /* 8 */ short encrypt; /* 16 */ short compress; /* 18 */ short totfiles; /* 20 */ short filesleft; /* 22 */ short totparts; /* 24 */ short partsleft; /* 26 */ long totsize; /* 28 */ long size; /* 32 */ long modtime; /* 36 */ long checksum; /* 40 */ long rfrcsum; /* 44 */ long rfsize; /* 48 */ long cretime; /* 52 */ long rfcsum; /* 56 */ long nrecvd; /* 60 */ long recvcsum; /* 64 */ char idstring[32]; /* 68 */ char flags; /* 100 */ char lnameoffset; /* 101 */ char lsizeoffset; /* 102 */ char dummy[69]; /* 103 */ char macfileinfo[16]; /* 172 */ short nencode; /* 188 */ short nlanguage; /* 190 */ char name[64]; /* 192 */ /* 256 */};struct file_transfer { struct file_header hdr; PurpleConnection *gc; char *user; char *cookie; char *ip; int port; long size; struct stat st; GtkWidget *window; int files; char *filename; FILE *file; int recvsize; gint inpa;};static void debug_header(struct file_transfer *ft) { struct file_header *f = (struct file_header *)ft; purple_debug(PURPLE_DEBUG_MISC, "toc", "FT HEADER:\n" "\t%s %d 0x%04x\n" "\t%s %d %d\n" "\t%d %d %d %d %d %d\n" "\t%d %d %d %d %d %d %d %d\n" "\t%s\n" "\t0x%02x, 0x%02x, 0x%02x\n" "\t%s %s\n" "\t%d %d\n" "\t%s\n", f->magic, ntohs(f->hdrlen), f->hdrtype, f->bcookie, ntohs(f->encrypt), ntohs(f->compress), ntohs(f->totfiles), ntohs(f->filesleft), ntohs(f->totparts), ntohs(f->partsleft), ntohl(f->totsize), ntohl(f->size), ntohl(f->modtime), ntohl(f->checksum), ntohl(f->rfrcsum), ntohl(f->rfsize), ntohl(f->cretime), ntohl(f->rfcsum), ntohl(f->nrecvd), ntohl(f->recvcsum), f->idstring, f->flags, f->lnameoffset, f->lsizeoffset, f->dummy, f->macfileinfo, ntohs(f->nencode), ntohs(f->nlanguage), f->name);}static void toc_send_file_callback(gpointer data, gint source, PurpleInputCondition cond){ char buf[BUF_LONG]; int rt, i; struct file_transfer *ft = data; if (ft->hdr.hdrtype != 0x202) { char *buf; frombase64(ft->cookie, &buf, NULL); read(source, ft, 8); read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); debug_header(ft); ft->hdr.hdrtype = 0x202; memcpy(ft->hdr.bcookie, buf, 8); g_free(buf); ft->hdr.encrypt = 0; ft->hdr.compress = 0; debug_header(ft); write(source, ft, 256); if (ft->files == 1) { ft->file = g_fopen(ft->filename, "w"); if (!ft->file) { buf = g_strdup_printf(_("Could not open %s for writing!"), ft->filename); purple_notify_error(ft->gc, NULL, buf, strerror(errno)); g_free(buf); purple_input_remove(ft->inpa); close(source); g_free(ft->filename); g_free(ft->user); g_free(ft->ip); g_free(ft->cookie); g_free(ft); } } else { buf = g_strdup_printf("%s/%s", ft->filename, ft->hdr.name); ft->file = g_fopen(buf, "w"); g_free(buf); if (!ft->file) { buf = g_strdup_printf("Could not open %s/%s for writing!", ft->filename, ft->hdr.name); purple_notify_error(ft->gc, NULL, buf, strerror(errno)); g_free(buf); purple_input_remove(ft->inpa); close(source); g_free(ft->filename); g_free(ft->user); g_free(ft->ip); g_free(ft->cookie); g_free(ft); } } return; } rt = read(source, buf, MIN(ntohl(ft->hdr.size) - ft->recvsize, 1024)); if (rt < 0) { purple_notify_error(ft->gc, NULL, _("File transfer failed; other side probably " "canceled."), NULL); purple_input_remove(ft->inpa); close(source); g_free(ft->user); g_free(ft->ip); g_free(ft->cookie); if (ft->file) fclose(ft->file); g_free(ft); return; } ft->recvsize += rt; for (i = 0; i < rt; i++) fprintf(ft->file, "%c", buf[i]); if (ft->recvsize == ntohl(ft->hdr.size)) { ft->hdr.hdrtype = htons(0x0204); ft->hdr.filesleft = htons(ntohs(ft->hdr.filesleft) - 1); ft->hdr.partsleft = htons(ntohs(ft->hdr.partsleft) - 1); ft->hdr.recvcsum = ft->hdr.checksum; /* uh... */ ft->hdr.nrecvd = htons(ntohs(ft->hdr.nrecvd) + 1); ft->hdr.flags = 0; write(source, ft, 256); debug_header(ft); ft->recvsize = 0; fclose(ft->file); if (ft->hdr.filesleft == 0) { purple_input_remove(ft->inpa); close(source); g_free(ft->filename); g_free(ft->user); g_free(ft->ip); g_free(ft->cookie); g_free(ft); } }}static void toc_send_file_connect(gpointer data, gint src, PurpleInputCondition cond)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -