📄 toc.c
字号:
}static void toc_got_info(void *data, const char *url_text, size_t len){ if (!url_text) return; purple_notify_formatted(data, NULL, _("Buddy Information"), NULL, url_text, NULL, NULL);}static char *show_error_message(){ int no = atoi(strtok(NULL, ":")); char *w = strtok(NULL, ":"); static char buf[256]; switch(no) { case 69: g_snprintf(buf, sizeof(buf), _("Unable to write file %s."), w); break; case 169: g_snprintf(buf, sizeof(buf), _("Unable to read file %s."), w); break; case 269: g_snprintf(buf, sizeof(buf), _("Message too long, last %s bytes truncated."), w); break; case 901: g_snprintf(buf, sizeof(buf), _("%s not currently logged in."), w); break; case 902: g_snprintf(buf, sizeof(buf), _("Warning of %s not allowed."), w); break; case 903: g_snprintf(buf, sizeof(buf), _("A message has been dropped, you are exceeding the server speed limit.")); break; case 950: g_snprintf(buf, sizeof(buf), _("Chat in %s is not available."), w); break; case 960: g_snprintf(buf, sizeof(buf), _("You are sending messages too fast to %s."), w); break; case 961: g_snprintf(buf, sizeof(buf), _("You missed an IM from %s because it was too big."), w); break; case 962: g_snprintf(buf, sizeof(buf), _("You missed an IM from %s because it was sent too fast."), w); break; case 970: g_snprintf(buf, sizeof(buf), _("Failure.")); break; case 971: g_snprintf(buf, sizeof(buf), _("Too many matches.")); break; case 972: g_snprintf(buf, sizeof(buf), _("Need more qualifiers.")); break; case 973: g_snprintf(buf, sizeof(buf), _("Dir service temporarily unavailable.")); break; case 974: g_snprintf(buf, sizeof(buf), _("E-mail lookup restricted.")); break; case 975: g_snprintf(buf, sizeof(buf), _("Keyword ignored.")); break; case 976: g_snprintf(buf, sizeof(buf), _("No keywords.")); break; case 977: g_snprintf(buf, sizeof(buf), _("User has no directory information.")); /* g_snprintf(buf, sizeof(buf), _("Language not supported.")); */ break; case 978: g_snprintf(buf, sizeof(buf), _("Country not supported.")); break; case 979: g_snprintf(buf, sizeof(buf), _("Failure unknown: %s."), w); break; case 980: g_snprintf(buf, sizeof(buf), _("Incorrect screen name or password.")); break; case 981: g_snprintf(buf, sizeof(buf), _("The service is temporarily unavailable.")); break; case 982: g_snprintf(buf, sizeof(buf), _("Your warning level is currently too high to log in.")); break; case 983: g_snprintf(buf, sizeof(buf), _("You have been connecting and disconnecting too frequently. Wait ten minutes and try again. If you continue to try, you will need to wait even longer.")); break; g_snprintf(buf, sizeof(buf), _("An unknown signon error has occurred: %s."), w); break; default: g_snprintf(buf, sizeof(buf), _("An unknown error, %d, has occurred. Info: %s"), no, w); } return buf;}static voidparse_toc_buddy_list(PurpleAccount *account, char *config){ char *c; char current[256]; GList *buddies = NULL; if (config == NULL) return; /* skip "CONFIG:" (if it exists) */ c = strncmp(config + 6 /* sizeof(struct sflap_hdr) */ , "CONFIG:", strlen("CONFIG:")) ? strtok(config, "\n") : strtok(config + 6 /* sizeof(struct sflap_hdr) */ + strlen("CONFIG:"), "\n"); do { if (c == NULL) break; if (*c == 'g') { char *utf8 = NULL; utf8 = purple_utf8_try_convert(c + 2); if (utf8 == NULL) { g_strlcpy(current, _("Invalid Groupname"), sizeof(current)); } else { g_strlcpy(current, utf8, sizeof(current)); g_free(utf8); } if (!purple_find_group(current)) { PurpleGroup *g = purple_group_new(current); purple_blist_add_group(g, NULL); } } else if (*c == 'b') { /*&& !purple_find_buddy(user, c + 2)) {*/ char nm[80], sw[388], *a, *utf8 = NULL; if ((a = strchr(c + 2, ':')) != NULL) { *a++ = '\0'; /* nul the : */ } g_strlcpy(nm, c + 2, sizeof(nm)); if (a) { utf8 = purple_utf8_try_convert(a); if (utf8 == NULL) { purple_debug(PURPLE_DEBUG_ERROR, "toc blist", "Failed to convert alias for " "'%s' to UTF-8\n", nm); } } if (utf8 == NULL) { sw[0] = '\0'; } else { /* This can leave a partial sequence at the end, * but who cares? */ g_strlcpy(sw, utf8, sizeof(sw)); g_free(utf8); } if (!purple_find_buddy(account, nm)) { PurpleBuddy *b = purple_buddy_new(account, nm, sw); PurpleGroup *g = purple_find_group(current); purple_blist_add_buddy(b, NULL, g, NULL); buddies = g_list_append(buddies, b); } } else if (*c == 'p') { purple_privacy_permit_add(account, c + 2, TRUE); } else if (*c == 'd') { purple_privacy_deny_add(account, c + 2, TRUE); } else if (!strncmp("toc", c, 3)) { sscanf(c + strlen(c) - 1, "%d", &account->perm_deny); purple_debug(PURPLE_DEBUG_MISC, "toc blist", "permdeny: %d\n", account->perm_deny); if (account->perm_deny == 0) account->perm_deny = PURPLE_PRIVACY_ALLOW_ALL; } else if (*c == 'm') { sscanf(c + 2, "%d", &account->perm_deny); purple_debug(PURPLE_DEBUG_MISC, "toc blist", "permdeny: %d\n", account->perm_deny); if (account->perm_deny == 0) account->perm_deny = PURPLE_PRIVACY_ALLOW_ALL; } } while ((c = strtok(NULL, "\n"))); if (account->gc) { if (buddies != NULL) { purple_account_add_buddies(account, buddies); g_list_free(buddies); } serv_set_permit_deny(account->gc); } g_list_free(buddies);}static void toc_callback(gpointer data, gint source, PurpleInputCondition condition){ PurpleConnection *gc = (PurpleConnection *)data; PurpleAccount *account = purple_connection_get_account(gc); struct toc_data *tdt = (struct toc_data *)gc->proto_data; struct sflap_hdr *hdr; struct signon so; char buf[8 * 1024], *c; char snd[BUF_LEN * 2]; const char *username = purple_account_get_username(account); char *password; PurpleBuddy *buddy; /* there's data waiting to be read, so read it. */ if (wait_reply(gc, buf, 8 * 1024) <= 0) { purple_connection_error(gc, _("Connection Closed")); return; } if (tdt->state == STATE_FLAPON) { hdr = (struct sflap_hdr *)buf; if (hdr->type != TYPE_SIGNON) purple_debug(PURPLE_DEBUG_ERROR, "toc", "hdr->type != TYPE_SIGNON\n"); else purple_debug(PURPLE_DEBUG_INFO, "toc", "TOC sends Client FLAP SIGNON\n"); tdt->seqno = ntohs(hdr->seqno); tdt->state = STATE_SIGNON_REQUEST; purple_debug(PURPLE_DEBUG_INFO, "toc", "Client sends TOC FLAP SIGNON\n"); g_snprintf(so.username, sizeof(so.username), "%s", username); so.ver = htonl(1); so.tag = htons(1); so.namelen = htons(strlen(so.username)); if (sflap_send(gc, (char *)&so, ntohs(so.namelen) + 8, TYPE_SIGNON) < 0) { purple_connection_error(gc, _("Disconnected.")); return; } purple_debug(PURPLE_DEBUG_INFO, "toc", "Client sends TOC \"toc_signon\" message\n"); /* i hate icq. */ if (username[0] >= '0' && username[0] <= '9') password = g_strndup(purple_connection_get_password(gc), 8); else password = g_strdup(purple_connection_get_password(gc)); g_snprintf(snd, sizeof snd, "toc_signon %s %d %s %s %s \"%s\"", AUTH_HOST, AUTH_PORT, purple_normalize(account, username), roast_password(password), LANGUAGE, REVISION); g_free(password); if (sflap_send(gc, snd, -1, TYPE_DATA) < 0) { purple_connection_error(gc, _("Disconnected.")); return; } purple_connection_update_progress(gc, _("Waiting for reply..."), 2, TOC_CONNECT_STEPS); return; } if (tdt->state == STATE_SIGNON_REQUEST) { purple_debug(PURPLE_DEBUG_INFO, "toc", "TOC sends client SIGN_ON reply\n"); if (g_ascii_strncasecmp(buf + sizeof(struct sflap_hdr), "SIGN_ON", strlen("SIGN_ON"))) { purple_debug(PURPLE_DEBUG_ERROR, "toc", "Didn't get SIGN_ON! buf was: %s\n", buf + sizeof(struct sflap_hdr)); if (!g_ascii_strncasecmp(buf + sizeof(struct sflap_hdr), "ERROR", 5)) { strtok(buf + sizeof(struct sflap_hdr), ":"); purple_connection_error(gc, show_error_message()); } else purple_connection_error(gc, _("Authentication failed")); return; } /* we're supposed to check that it's really TOC v1 here but we know it is ;) */ purple_debug(PURPLE_DEBUG_INFO, "toc", "TOC version: %s\n", buf + sizeof(struct sflap_hdr) + 8); /* we used to check for the CONFIG here, but we'll wait until we've sent our * version of the config and then the toc_init_done message. we'll come back to * the callback in a better state if we get CONFIG anyway */ tdt->state = STATE_ONLINE; purple_connection_set_state(gc, PURPLE_CONNECTED); /* * Add me to my buddy list so that we know the time when * the server thinks I signed on. */ buddy = purple_buddy_new(account, username, NULL); /* XXX - Pick a group to add to */ /* purple_blist_add(buddy, NULL, g, NULL); */ purple_account_add_buddy(gc, buddy); /* Client sends TOC toc_init_done message */ purple_debug(PURPLE_DEBUG_INFO, "toc", "Client sends TOC toc_init_done message\n"); g_snprintf(snd, sizeof snd, "toc_init_done"); sflap_send(gc, snd, -1, TYPE_DATA); /* g_snprintf(snd, sizeof snd, "toc_set_caps %s %s %s", FILE_SEND_UID, FILE_GET_UID, B_ICON_UID); */ g_snprintf(snd, sizeof snd, "toc_set_caps %s %s", FILE_SEND_UID, FILE_GET_UID); sflap_send(gc, snd, -1, TYPE_DATA); return; } purple_debug(PURPLE_DEBUG_INFO, "toc", "S: %s\n", buf + sizeof(struct sflap_hdr)); c = strtok(buf + sizeof(struct sflap_hdr), ":"); /* Ditch the first part */ if (!g_ascii_strcasecmp(c, "SIGN_ON")) { /* we should only get here after a PAUSE */ if (tdt->state != STATE_PAUSE) purple_debug(PURPLE_DEBUG_ERROR, "toc", "got SIGN_ON but not PAUSE!\n"); else { tdt->state = STATE_ONLINE; g_snprintf(snd, sizeof snd, "toc_signon %s %d %s %s %s \"%s\"", AUTH_HOST, AUTH_PORT, purple_normalize(account, purple_account_get_username(account)), roast_password(purple_connection_get_password(gc)), LANGUAGE, REVISION); if (sflap_send(gc, snd, -1, TYPE_DATA) < 0) { purple_connection_error(gc, _("Disconnected.")); return; } g_snprintf(snd, sizeof snd, "toc_init_done"); sflap_send(gc, snd, -1, TYPE_DATA); purple_notify_info(gc, NULL, _("TOC has come back from its pause. You may " "now send messages again."), NULL); } } else if (!g_ascii_strcasecmp(c, "CONFIG")) { c = strtok(NULL, ":"); parse_toc_buddy_list(account, c); } else if (!g_ascii_strcasecmp(c, "NICK")) { /* ignore NICK so that things get imported/exported properly c = strtok(NULL, ":"); g_snprintf(gc->username, sizeof(gc->username), "%s", c); */ } else if (!g_ascii_strcasecmp(c, "IM_IN")) { char *away, *message; int a = 0; c = strtok(NULL, ":"); away = strtok(NULL, ":"); message = away; while (*message && (*message != ':')) message++; message++; a = (away && (*away == 'T')) ? PURPLE_MESSAGE_AUTO_RESP : 0; serv_got_im(gc, c, message, a, time(NULL)); } else if (!g_ascii_strcasecmp(c, "UPDATE_BUDDY")) { char *l, *uc, *tmp; gboolean logged_in; int evil, idle, type = 0; time_t signon, time_idle; c = strtok(NULL, ":"); /* name */ l = strtok(NULL, ":"); /* online */ sscanf(strtok(NULL, ":"), "%d", &evil); sscanf(strtok(NULL, ":"), "%ld", &signon); sscanf(strtok(NULL, ":"), "%d", &idle); uc = strtok(NULL, ":"); logged_in = (l && (*l == 'T')) ? TRUE : FALSE; if (uc[0] == 'A') type |= UC_AOL; switch (uc[1]) { case 'A': type |= UC_ADMIN; break; case 'U': type |= UC_UNCONFIRMED; break; case 'O': type |= UC_NORMAL; break; case 'C': type |= UC_WIRELESS; break; default: break; } if (uc[2] == 'U') type |= UC_UNAVAILABLE; if (idle) { time(&time_idle); time_idle -= idle * 60; } else time_idle = 0; /* * If we have info for ourselves then set our display name, warning * level and official time of login. */ tmp = g_strdup(purple_normalize(account, purple_account_get_username(gc->account))); if (!strcmp(tmp, purple_normalize(account, c))) { purple_connection_set_display_name(gc, c); /* XXX - What should the second parameter be here? */ /* purple_prpl_got_account_warning_level(account, NULL, evil);*/ purple_prpl_got_account_login_time(account, signon); } g_free(tmp); purple_prpl_got_user_status(account, c, (logged_in ? "online" : "offline"), NULL); purple_prpl_got_user_login_time(account, c, signon); if (time_idle > 0) purple_prpl_got_user_idle(account, c, TRUE, time_idle); else purple_prpl_got_user_idle(account, c, FALSE, 0); } else if (!g_ascii_strcasecmp(c, "ERROR")) { purple_notify_error(gc, NULL, show_error_message(), NULL); } else if (!g_ascii_strcasecmp(c, "EVILED")) { int lev; char *name; sscanf(strtok(NULL, ":"), "%d", &lev); name = strtok(NULL, ":"); /* purple_prpl_got_account_warning_level(account, name, lev); */ } else if (!g_ascii_strcasecmp(c, "CHAT_JOIN")) { char *name; int id; sscanf(strtok(NULL, ":"), "%d", &id); name = strtok(NULL, ":"); serv_got_joined_chat(gc, id, name); } else if (!g_ascii_strcasecmp(c, "CHAT_IN")) { int id; PurpleMessageFlags flags; char *m, *who, *whisper; sscanf(strtok(NULL, ":"), "%d", &id); who = strtok(NULL, ":"); whisper = strtok(NULL, ":"); m = whisper; while (*m && (*m != ':')) m++; m++; flags = (whisper && (*whisper == 'T')) ? PURPLE_MESSAGE_WHISPER : 0; serv_got_chat_in(gc, id, who, flags, m, time((time_t)NULL)); } else if (!g_ascii_strcasecmp(c, "CHAT_UPDATE_BUDDY")) { int id; char *in, *buddy; GSList *bcs = gc->buddy_chats; PurpleConversation *b = NULL; PurpleConvChat *chat; sscanf(strtok(NULL, ":"), "%d", &id); in = strtok(NULL, ":"); chat = PURPLE_CONV_CHAT(b); while (bcs) { b = (PurpleConversation *)bcs->data; if (id == purple_conv_chat_get_id(chat)) break; bcs = bcs->next; b = NULL; } if (!b) return; if (in && (*in == 'T'))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -