tcl_cmds.c

来自「Linux下的多协议即时通讯程序源代码」· C语言 代码 · 共 1,677 行 · 第 1/4 页

C
1,677
字号
/** * @file tcl_cmds.c Commands for the Purple Tcl plugin bindings * * purple * * Copyright (C) 2003 Ethan Blanton <eblanton@cs.purdue.edu> *  * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <tcl.h>#include "internal.h"#include "conversation.h"#include "connection.h"#include "account.h"#include "server.h"#include "notify.h"#include "blist.h"#include "savedstatuses.h"#include "debug.h"#include "prefs.h"#include "core.h"#include "tcl_purple.h"static PurpleAccount *tcl_validate_account(Tcl_Obj *obj, Tcl_Interp *interp);static PurpleConversation *tcl_validate_conversation(Tcl_Obj *obj, Tcl_Interp *interp);static PurpleConnection *tcl_validate_gc(Tcl_Obj *obj, Tcl_Interp *interp);static PurpleAccount *tcl_validate_account(Tcl_Obj *obj, Tcl_Interp *interp){	PurpleAccount *account;	GList *cur;	account = purple_tcl_ref_get(interp, obj, PurpleTclRefAccount);	if (account == NULL)		return NULL;	for (cur = purple_accounts_get_all(); cur != NULL; cur = g_list_next(cur)) {		if (account == cur->data)			return account;	}	if (interp != NULL)		Tcl_SetStringObj(Tcl_GetObjResult(interp), "invalid account", -1);	return NULL;}static PurpleConversation *tcl_validate_conversation(Tcl_Obj *obj, Tcl_Interp *interp){	PurpleConversation *convo;	GList *cur;	convo = purple_tcl_ref_get(interp, obj, PurpleTclRefConversation);	if (convo == NULL)		return NULL;	for (cur = purple_get_conversations(); cur != NULL; cur = g_list_next(cur)) {		if (convo == cur->data)			return convo;	}	if (interp != NULL)		Tcl_SetStringObj(Tcl_GetObjResult(interp), "invalid conversation", -1);	return NULL;}static PurpleConnection *tcl_validate_gc(Tcl_Obj *obj, Tcl_Interp *interp){	PurpleConnection *gc;	GList *cur;	gc = purple_tcl_ref_get(interp, obj, PurpleTclRefConnection);	if (gc == NULL)		return NULL;	for (cur = purple_connections_get_all(); cur != NULL; cur = g_list_next(cur)) {		if (gc == cur->data)			return gc;	}	return NULL;}int tcl_cmd_account(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]){	Tcl_Obj *result = Tcl_GetObjResult(interp), *list, *elem;	const char *cmds[] = { "alias", "connect", "connection", "disconnect",	                       "enabled", "find", "handle", "isconnected",	                       "list", "presence", "protocol", "status",	                       "status_type", "status_types", "username",	                       NULL };	enum { CMD_ACCOUNT_ALIAS,	       CMD_ACCOUNT_CONNECT, CMD_ACCOUNT_CONNECTION,	       CMD_ACCOUNT_DISCONNECT, CMD_ACCOUNT_ENABLED, CMD_ACCOUNT_FIND,	       CMD_ACCOUNT_HANDLE, CMD_ACCOUNT_ISCONNECTED, CMD_ACCOUNT_LIST,	       CMD_ACCOUNT_PRESENCE, CMD_ACCOUNT_PROTOCOL, CMD_ACCOUNT_STATUS,	       CMD_ACCOUNT_STATUS_TYPE, CMD_ACCOUNT_STATUS_TYPES,	       CMD_ACCOUNT_USERNAME } cmd;	const char *listopts[] = { "-all", "-online", NULL };	enum { CMD_ACCOUNTLIST_ALL, CMD_ACCOUNTLIST_ONLINE } listopt;	const char *alias;	const GList *cur;	PurpleAccount *account;	PurpleStatus *status;	PurpleStatusType *status_type;	PurpleValue *value;	char *attr_id;	int error;	int b, i;	if (objc < 2) {		Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?");		return TCL_ERROR;	}	if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK)		return error;	switch (cmd) {	case CMD_ACCOUNT_ALIAS:		if (objc != 3) {			Tcl_WrongNumArgs(interp, 2, objv, "account");			return TCL_ERROR;		}		if ((account = tcl_validate_account(objv[2], interp)) == NULL)			return TCL_ERROR;		alias = purple_account_get_alias(account);		Tcl_SetStringObj(result, alias ? (char *)alias : "", -1);		break;	case CMD_ACCOUNT_CONNECT:		if (objc != 3) {			Tcl_WrongNumArgs(interp, 2, objv, "account");			return TCL_ERROR;		}		if ((account = tcl_validate_account(objv[2], interp)) == NULL)			return TCL_ERROR;		if (!purple_account_is_connected(account))			purple_account_connect(account);		Tcl_SetObjResult(interp,		                 purple_tcl_ref_new(PurpleTclRefConnection,		                                  purple_account_get_connection(account)));		break;	case CMD_ACCOUNT_CONNECTION:		if (objc != 3) {			Tcl_WrongNumArgs(interp, 2, objv, "account");			return TCL_ERROR;		}		if ((account = tcl_validate_account(objv[2], interp)) == NULL)			return TCL_ERROR;		Tcl_SetObjResult(interp,		                 purple_tcl_ref_new(PurpleTclRefConnection,		                                  purple_account_get_connection(account)));		break;	case CMD_ACCOUNT_DISCONNECT:		if (objc != 3) {			Tcl_WrongNumArgs(interp, 2, objv, "account");			return TCL_ERROR;		}		if ((account = tcl_validate_account(objv[2], interp)) == NULL)			return TCL_ERROR;		purple_account_disconnect(account);		break;	case CMD_ACCOUNT_ENABLED:		if (objc != 3 && objc != 4) {			Tcl_WrongNumArgs(interp, 2, objv, "account ?enabled?");			return TCL_ERROR;		}		if ((account = tcl_validate_account(objv[2], interp)) == NULL)			return TCL_ERROR;		if (objc == 3) {			Tcl_SetBooleanObj(result,					  purple_account_get_enabled(account,								   purple_core_get_ui()));		} else {			if ((error = Tcl_GetBooleanFromObj(interp, objv[3], &b)) != TCL_OK)				return TCL_ERROR;			purple_account_set_enabled(account, purple_core_get_ui(), b);		}		break;	case CMD_ACCOUNT_FIND:		if (objc != 4) {			Tcl_WrongNumArgs(interp, 2, objv, "username protocol");			return TCL_ERROR;		}		account = purple_accounts_find(Tcl_GetString(objv[2]),		                             Tcl_GetString(objv[3]));		Tcl_SetObjResult(interp,		                 purple_tcl_ref_new(PurpleTclRefAccount, account));		break;	case CMD_ACCOUNT_HANDLE:		if (objc != 2) {			Tcl_WrongNumArgs(interp, 2, objv, "");			return TCL_ERROR;		}		Tcl_SetIntObj(result, (int)purple_accounts_get_handle());		break;	case CMD_ACCOUNT_ISCONNECTED:		if (objc != 3) {			Tcl_WrongNumArgs(interp, 2, objv, "account");			return TCL_ERROR;		}		if ((account = tcl_validate_account(objv[2], interp)) == NULL)			return TCL_ERROR;		Tcl_SetBooleanObj(result, purple_account_is_connected(account));		break;	case CMD_ACCOUNT_LIST:		listopt = CMD_ACCOUNTLIST_ALL;		if (objc > 3) {			Tcl_WrongNumArgs(interp, 2, objv, "?option?");			return TCL_ERROR;		}		if (objc == 3) {			if ((error = Tcl_GetIndexFromObj(interp, objv[2], listopts, "option", 0, (int *)&listopt)) != TCL_OK)				return error;		}		list = Tcl_NewListObj(0, NULL);		for (cur = purple_accounts_get_all(); cur != NULL; cur = g_list_next(cur)) {			account = cur->data;			if (listopt == CMD_ACCOUNTLIST_ONLINE && !purple_account_is_connected(account))				continue;			elem = purple_tcl_ref_new(PurpleTclRefAccount, account);			Tcl_ListObjAppendElement(interp, list, elem);		}		Tcl_SetObjResult(interp, list);		break;	case CMD_ACCOUNT_PRESENCE:		if (objc != 3) {			Tcl_WrongNumArgs(interp, 2, objv, "account");			return TCL_ERROR;		}		if ((account = tcl_validate_account(objv[2], interp)) == NULL)			return TCL_ERROR;		Tcl_SetObjResult(interp, purple_tcl_ref_new(PurpleTclRefPresence,							  purple_account_get_presence(account)));		break;	case CMD_ACCOUNT_PROTOCOL:		if (objc != 3) {			Tcl_WrongNumArgs(interp, 2, objv, "account");			return TCL_ERROR;		}		if ((account = tcl_validate_account(objv[2], interp)) == NULL)			return TCL_ERROR;		Tcl_SetStringObj(result, (char *)purple_account_get_protocol_id(account), -1);		break;	case CMD_ACCOUNT_STATUS:		if (objc < 3) {			Tcl_WrongNumArgs(interp, 2, objv, "account ?status_id name value ...?");			return TCL_ERROR;		}		if ((account = tcl_validate_account(objv[2], interp)) == NULL)			return TCL_ERROR;		if (objc == 3) {			Tcl_SetObjResult(interp,					 purple_tcl_ref_new(PurpleTclRefStatus,							  purple_account_get_active_status(account)));		} else {			GList *l = NULL;			if (objc % 2) {				Tcl_SetStringObj(result, "name without value setting status", -1);				return TCL_ERROR;			}			status = purple_account_get_status(account, Tcl_GetString(objv[3]));			if (status == NULL) {				Tcl_SetStringObj(result, "invalid status for account", -1);				return TCL_ERROR;			}			for (i = 4; i < objc; i += 2) {				attr_id = Tcl_GetString(objv[i]);				value = purple_status_get_attr_value(status, attr_id);				if (value == NULL) {					Tcl_SetStringObj(result, "invalid attribute for account", -1);					return TCL_ERROR;				}				switch (purple_value_get_type(value)) {				case PURPLE_TYPE_BOOLEAN:					error = Tcl_GetBooleanFromObj(interp, objv[i + 1], &b);					if (error != TCL_OK)						return error;					l = g_list_append(l, attr_id);					l = g_list_append(l, GINT_TO_POINTER(b));					break;				case PURPLE_TYPE_INT:					error = Tcl_GetIntFromObj(interp, objv[i + 1], &b);					if (error != TCL_OK)						return error;					l = g_list_append(l, attr_id);					l = g_list_append(l, GINT_TO_POINTER(b));					break;				case PURPLE_TYPE_STRING:					l = g_list_append(l, attr_id);					l = g_list_append(l, Tcl_GetString(objv[i + 1]));					break;				default:					Tcl_SetStringObj(result, "unknown PurpleValue type", -1);					return TCL_ERROR;				}			}			purple_account_set_status_list(account, Tcl_GetString(objv[3]), TRUE, l);			g_list_free(l);		}		break;	case CMD_ACCOUNT_STATUS_TYPE:		if (objc != 4 && objc != 5) {			Tcl_WrongNumArgs(interp, 2, objv, "account ?statustype? ?-primitive primitive?");			return TCL_ERROR;		}		if ((account = tcl_validate_account(objv[2], interp)) == NULL)			return TCL_ERROR;		if (objc == 4) {			status_type = purple_account_get_status_type(account,								   Tcl_GetString(objv[3]));		} else {			PurpleStatusPrimitive primitive;			if (strcmp(Tcl_GetString(objv[3]), "-primitive")) {				Tcl_SetStringObj(result, "bad option \"", -1);				Tcl_AppendObjToObj(result, objv[3]);				Tcl_AppendToObj(result,						"\": should be -primitive", -1);				return TCL_ERROR;			}			primitive = purple_primitive_get_type_from_id(Tcl_GetString(objv[4]));			status_type = purple_account_get_status_type_with_primitive(account,										  primitive);		}		if (status_type == NULL) {			Tcl_SetStringObj(result, "status type not found", -1);			return TCL_ERROR;		}		Tcl_SetObjResult(interp,				 purple_tcl_ref_new(PurpleTclRefStatusType,						  status_type));		break;	case CMD_ACCOUNT_STATUS_TYPES:		if (objc != 3) {			Tcl_WrongNumArgs(interp, 2, objv, "account");			return TCL_ERROR;		}		if ((account = tcl_validate_account(objv[2], interp)) == NULL)			return TCL_ERROR;		list = Tcl_NewListObj(0, NULL);		for (cur = purple_account_get_status_types(account); cur != NULL;		     cur = g_list_next(cur)) {			Tcl_ListObjAppendElement(interp, list,						 purple_tcl_ref_new(PurpleTclRefStatusType,								  cur->data));		}		Tcl_SetObjResult(interp, list);		break;	case CMD_ACCOUNT_USERNAME:		if (objc != 3) {			Tcl_WrongNumArgs(interp, 2, objv, "account");			return TCL_ERROR;		}		if ((account = tcl_validate_account(objv[2], interp)) == NULL)			return TCL_ERROR;		Tcl_SetStringObj(result, (char *)purple_account_get_username(account), -1);		break;	}	return TCL_OK;}static PurpleBlistNode *tcl_list_to_buddy(Tcl_Interp *interp, int count, Tcl_Obj **elems){	PurpleBlistNode *node = NULL;	PurpleAccount *account;	char *name;	char *type;	if (count < 3) {		Tcl_SetStringObj(Tcl_GetObjResult(interp), "list too short", -1);		return NULL;	}	type = Tcl_GetString(elems[0]);	name = Tcl_GetString(elems[1]);	if ((account = tcl_validate_account(elems[2], interp)) == NULL)		return NULL;	if (!strcmp(type, "buddy")) {		node = (PurpleBlistNode *)purple_find_buddy(account, name);	} else if (!strcmp(type, "group")) {		node = (PurpleBlistNode *)purple_blist_find_chat(account, name);	}	return node;}int tcl_cmd_buddy(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]){	Tcl_Obj *list, *tclgroup, *tclgrouplist, *tclcontact, *tclcontactlist, *tclbud, **elems, *result;	const char *cmds[] = { "alias", "handle", "info", "list", NULL };	enum { CMD_BUDDY_ALIAS, CMD_BUDDY_HANDLE, CMD_BUDDY_INFO, CMD_BUDDY_LIST } cmd;	PurpleBuddyList *blist;	PurpleBlistNode *node, *gnode, *bnode;	PurpleAccount *account;	PurpleBuddy *bud;	PurpleChat *cnode;	int error, all = 0, count;	if (objc < 2) {		Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?");		return TCL_ERROR;	}	if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?