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 + -
显示快捷键?