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

📄 toc.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
}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 + -