tcl_cmds.c

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

C
1,677
字号
		return error;	result = Tcl_GetObjResult(interp);	switch (cmd) {	case CMD_BUDDY_ALIAS:		if (objc != 3) {			Tcl_WrongNumArgs(interp, 2, objv, "buddy");			return TCL_ERROR;		}		if ((error = Tcl_ListObjGetElements(interp, objv[2], &count, &elems)) != TCL_OK)			return error;		if ((node = tcl_list_to_buddy(interp, count, elems)) == NULL)			return TCL_ERROR;		if (node->type == PURPLE_BLIST_CHAT_NODE)			Tcl_SetStringObj(result, ((PurpleChat *)node)->alias, -1);		else if (node->type == PURPLE_BLIST_BUDDY_NODE)			Tcl_SetStringObj(result, (char *)purple_buddy_get_alias((PurpleBuddy *)node), -1);		return TCL_OK;		break;	case CMD_BUDDY_HANDLE:		if (objc != 2) {			Tcl_WrongNumArgs(interp, 2, objv, "");			return TCL_ERROR;		}		Tcl_SetIntObj(result, (int)purple_blist_get_handle());		break;	case CMD_BUDDY_INFO:		if (objc != 3 && objc != 4) {			Tcl_WrongNumArgs(interp, 2, objv, "( buddy | account username )");			return TCL_ERROR;		}		if (objc == 3) {			if ((error = Tcl_ListObjGetElements(interp, objv[2], &count, &elems)) != TCL_OK)				return error;			if (count < 3) {				Tcl_SetStringObj(result, "buddy too short", -1);				return TCL_ERROR;			}			if (strcmp("buddy", Tcl_GetString(elems[0]))) {				Tcl_SetStringObj(result, "invalid buddy", -1);				return TCL_ERROR;			}			if ((account = tcl_validate_account(elems[2], interp)) == NULL)				return TCL_ERROR;			serv_get_info(purple_account_get_connection(account), Tcl_GetString(elems[1]));		} else {			if ((account = tcl_validate_account(objv[2], interp)) == NULL)				return TCL_ERROR;			serv_get_info(purple_account_get_connection(account), Tcl_GetString(objv[3]));		}		break;	case CMD_BUDDY_LIST:		if (objc == 3) {			if (!strcmp("-all", Tcl_GetString(objv[2]))) {				all = 1;			} else {				Tcl_SetStringObj(result, "", -1);				Tcl_AppendStringsToObj(result, "unknown option: ", Tcl_GetString(objv[2]), NULL);				return TCL_ERROR;			}		}		list = Tcl_NewListObj(0, NULL);		blist = purple_get_blist();		for (gnode = blist->root; gnode != NULL; gnode = gnode->next) {			tclgroup = Tcl_NewListObj(0, NULL);			Tcl_ListObjAppendElement(interp, tclgroup, Tcl_NewStringObj("group", -1));			Tcl_ListObjAppendElement(interp, tclgroup,						 Tcl_NewStringObj(((PurpleGroup *)gnode)->name, -1));			tclgrouplist = Tcl_NewListObj(0, NULL);			for (node = gnode->child; node != NULL; node = node->next) {				switch (node->type) {				case PURPLE_BLIST_CONTACT_NODE:					tclcontact = Tcl_NewListObj(0, NULL);					Tcl_IncrRefCount(tclcontact);					Tcl_ListObjAppendElement(interp, tclcontact, Tcl_NewStringObj("contact", -1));					tclcontactlist = Tcl_NewListObj(0, NULL);					Tcl_IncrRefCount(tclcontactlist);					count = 0;					for (bnode = node->child; bnode != NULL; bnode = bnode ->next) {						if (bnode->type != PURPLE_BLIST_BUDDY_NODE)							continue;						bud = (PurpleBuddy *)bnode;						if (!all && !purple_account_is_connected(bud->account))							continue;						count++;						tclbud = Tcl_NewListObj(0, NULL);						Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj("buddy", -1));						Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj(bud->name, -1));						Tcl_ListObjAppendElement(interp, tclbud, purple_tcl_ref_new(PurpleTclRefAccount, bud->account));						Tcl_ListObjAppendElement(interp, tclcontactlist, tclbud);					}					if (count) {						Tcl_ListObjAppendElement(interp, tclcontact, tclcontactlist);						Tcl_ListObjAppendElement(interp, tclgrouplist, tclcontact);					}					Tcl_DecrRefCount(tclcontact);					Tcl_DecrRefCount(tclcontactlist);					break;				case PURPLE_BLIST_CHAT_NODE:					cnode = (PurpleChat *)node;					if (!all && !purple_account_is_connected(cnode->account))						continue;					tclbud = Tcl_NewListObj(0, NULL);					Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj("chat", -1));					Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj(cnode->alias, -1));					Tcl_ListObjAppendElement(interp, tclbud, purple_tcl_ref_new(PurpleTclRefAccount, cnode->account));					Tcl_ListObjAppendElement(interp, tclgrouplist, tclbud);					break;				default:					purple_debug(PURPLE_DEBUG_WARNING, "tcl", "Unexpected buddy type %d", node->type);					continue;				}			}			Tcl_ListObjAppendElement(interp, tclgroup, tclgrouplist);			Tcl_ListObjAppendElement(interp, list, tclgroup);		}		Tcl_SetObjResult(interp, list);		break;	}	return TCL_OK;}int tcl_cmd_cmd(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]){	const char *cmds[] = { "register", "unregister", NULL };	enum { CMD_CMD_REGISTER, CMD_CMD_UNREGISTER } cmd;	struct tcl_cmd_handler *handler;	Tcl_Obj *result = Tcl_GetObjResult(interp);	PurpleCmdId id;	int error;	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_CMD_REGISTER:		if (objc != 9) {			Tcl_WrongNumArgs(interp, 2, objv, "cmd arglist priority flags prpl_id proc helpstr");			return TCL_ERROR;		}		handler = g_new0(struct tcl_cmd_handler, 1);		handler->cmd = objv[2];		handler->args = Tcl_GetString(objv[3]);		handler->nargs = strlen(handler->args);		if ((error = Tcl_GetIntFromObj(interp, objv[4],		                               &handler->priority)) != TCL_OK) {			g_free(handler);			return error;		}		if ((error = Tcl_GetIntFromObj(interp, objv[5],		                               &handler->flags)) != TCL_OK) {			g_free(handler);			return error;		}		handler->prpl_id = Tcl_GetString(objv[6]);		handler->proc = objv[7];		handler->helpstr = Tcl_GetString(objv[8]);		handler->interp = interp;		if ((id = tcl_cmd_register(handler)) == 0) {			tcl_cmd_handler_free(handler);			Tcl_SetIntObj(result, 0);		} else {			handler->id = id;			Tcl_SetIntObj(result, id);		}		break;	case CMD_CMD_UNREGISTER:		if (objc != 3) {			Tcl_WrongNumArgs(interp, 2, objv, "id");			return TCL_ERROR;		}		if ((error = Tcl_GetIntFromObj(interp, objv[2],		                               (int *)&id)) != TCL_OK)			return error;		tcl_cmd_unregister(id, interp);		break;	}	return TCL_OK;}int tcl_cmd_connection(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]){	Tcl_Obj *result = Tcl_GetObjResult(interp), *list, *elem;	const char *cmds[] = { "account", "displayname", "handle", "list", NULL };	enum { CMD_CONN_ACCOUNT, CMD_CONN_DISPLAYNAME, CMD_CONN_HANDLE, CMD_CONN_LIST } cmd;	int error;	GList *cur;	PurpleConnection *gc;	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_CONN_ACCOUNT:		if (objc != 3) {			Tcl_WrongNumArgs(interp, 2, objv, "gc");			return TCL_ERROR;		}		if ((gc = tcl_validate_gc(objv[2], interp)) == NULL)			return TCL_ERROR;		Tcl_SetObjResult(interp,		                 purple_tcl_ref_new(PurpleTclRefAccount,		                                  purple_connection_get_account(gc)));		break;	case CMD_CONN_DISPLAYNAME:		if (objc != 3) {			Tcl_WrongNumArgs(interp, 2, objv, "gc");			return TCL_ERROR;		}		if ((gc = tcl_validate_gc(objv[2], interp)) == NULL)			return TCL_ERROR;		Tcl_SetStringObj(result, (char *)purple_connection_get_display_name(gc), -1);		break;	case CMD_CONN_HANDLE:		if (objc != 2) {			Tcl_WrongNumArgs(interp, 2, objv, "");			return TCL_ERROR;		}		Tcl_SetIntObj(result, (int)purple_connections_get_handle());		break;	case CMD_CONN_LIST:		if (objc != 2) {			Tcl_WrongNumArgs(interp, 2, objv, "");			return TCL_ERROR;		}		list = Tcl_NewListObj(0, NULL);		for (cur = purple_connections_get_all(); cur != NULL; cur = g_list_next(cur)) {			elem = purple_tcl_ref_new(PurpleTclRefConnection, cur->data);			Tcl_ListObjAppendElement(interp, list, elem);		}		Tcl_SetObjResult(interp, list);		break;	}	return TCL_OK;}int tcl_cmd_conversation(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]){	Tcl_Obj *list, *elem, *result = Tcl_GetObjResult(interp);	const char *cmds[] = { "find", "handle", "list", "new", "write", "name", "title", "send", NULL };	enum { CMD_CONV_FIND, CMD_CONV_HANDLE, CMD_CONV_LIST, CMD_CONV_NEW, CMD_CONV_WRITE , CMD_CONV_NAME, CMD_CONV_TITLE, CMD_CONV_SEND } cmd;	const char *styles[] = { "send", "recv", "system", NULL };	enum { CMD_CONV_WRITE_SEND, CMD_CONV_WRITE_RECV, CMD_CONV_WRITE_SYSTEM } style;	const char *newopts[] = { "-chat", "-im" };	enum { CMD_CONV_NEW_CHAT, CMD_CONV_NEW_IM } newopt;	PurpleConversation *convo;	PurpleAccount *account;	PurpleConversationType type;	GList *cur;	char *opt, *from, *what;	int error, argsused, flags = 0;	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_CONV_FIND:		if (objc != 4) {			Tcl_WrongNumArgs(interp, 2, objv, "account name");			return TCL_ERROR;		}		account = NULL;		if ((account = tcl_validate_account(objv[2], interp)) == NULL)			return TCL_ERROR;		convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY,							    Tcl_GetString(objv[3]),							    account);		Tcl_SetObjResult(interp, purple_tcl_ref_new(PurpleTclRefConversation, convo));		break;	case CMD_CONV_HANDLE:		if (objc != 2) {			Tcl_WrongNumArgs(interp, 2, objv, "");			return TCL_ERROR;		}		Tcl_SetIntObj(result, (int)purple_conversations_get_handle());		break;	case CMD_CONV_LIST:		list = Tcl_NewListObj(0, NULL);		for (cur = purple_get_conversations(); cur != NULL; cur = g_list_next(cur)) {			elem = purple_tcl_ref_new(PurpleTclRefConversation, cur->data);			Tcl_ListObjAppendElement(interp, list, elem);		}		Tcl_SetObjResult(interp, list);		break;	case CMD_CONV_NEW:		if (objc < 4) {			Tcl_WrongNumArgs(interp, 2, objv, "?options? account name");			return TCL_ERROR;		}		argsused = 2;		type = PURPLE_CONV_TYPE_IM;		while (argsused < objc) {			opt = Tcl_GetString(objv[argsused]);			if (*opt == '-') {				if ((error = Tcl_GetIndexFromObj(interp, objv[argsused], newopts,								 "option", 0, (int *)&newopt)) != TCL_OK)					return error;				argsused++;				switch (newopt) {				case CMD_CONV_NEW_CHAT:					type = PURPLE_CONV_TYPE_CHAT;					break;				case CMD_CONV_NEW_IM:					type = PURPLE_CONV_TYPE_IM;					break;				}			} else {				break;			}		}		if (objc - argsused != 2) {			Tcl_WrongNumArgs(interp, 2, objv, "?options? account name");			return TCL_ERROR;		}		if ((account = tcl_validate_account(objv[argsused++], interp)) == NULL)			return TCL_ERROR;		convo = purple_conversation_new(type, account, Tcl_GetString(objv[argsused]));		Tcl_SetObjResult(interp, purple_tcl_ref_new(PurpleTclRefConversation, convo));		break;	case CMD_CONV_WRITE:		if (objc != 6) {			Tcl_WrongNumArgs(interp, 2, objv, "conversation style from what");			return TCL_ERROR;		}		if ((convo = tcl_validate_conversation(objv[2], interp)) == NULL)			return TCL_ERROR;		if ((error = Tcl_GetIndexFromObj(interp, objv[3], styles, "style", 0, (int *)&style)) != TCL_OK)			return error;		from = Tcl_GetString(objv[4]);		what = Tcl_GetString(objv[5]);				switch (style) {		case CMD_CONV_WRITE_SEND:			flags = PURPLE_MESSAGE_SEND;			break;		case CMD_CONV_WRITE_RECV:			flags = PURPLE_MESSAGE_RECV;			break;		case CMD_CONV_WRITE_SYSTEM:			flags = PURPLE_MESSAGE_SYSTEM;			break;		}		if (purple_conversation_get_type(convo) == PURPLE_CONV_TYPE_CHAT)			purple_conv_chat_write(PURPLE_CONV_CHAT(convo), from, what, flags, time(NULL));		else			purple_conv_im_write(PURPLE_CONV_IM(convo), from, what, flags, time(NULL));		break;	case CMD_CONV_NAME:		if (objc != 3) {			Tcl_WrongNumArgs(interp, 2, objv, "conversation");			return TCL_ERROR;		}		if ((convo = tcl_validate_conversation(objv[2], interp)) == NULL)			return TCL_ERROR;		Tcl_SetStringObj(result, (char *)purple_conversation_get_name(convo), -1);		break;	case CMD_CONV_TITLE:		if (objc != 3) {			Tcl_WrongNumArgs(interp, 2, objv, "conversation");			return TCL_ERROR;		}		if ((convo = tcl_validate_conversation(objv[2], interp)) == NULL)			return TCL_ERROR;		Tcl_SetStringObj(result, (char *)purple_conversation_get_title(convo), -1);		break;	case CMD_CONV_SEND:		if (objc != 4) {			Tcl_WrongNumArgs(interp, 2, objv, "conversation message");			return TCL_ERROR;		}		if ((convo = tcl_validate_conversation(objv[2], interp)) == NULL)			return TCL_ERROR;		what = Tcl_GetString(objv[3]);		if (purple_conversation_get_type(convo) == PURPLE_CONV_TYPE_CHAT)			purple_conv_chat_send(PURPLE_CONV_CHAT(convo), what);		else			purple_conv_im_send(PURPLE_CONV_IM(convo), what);		break;	}	return TCL_OK;}int tcl_cmd_core(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]){	Tcl_Obj *result = Tcl_GetObjResult(interp);	const char *cmds[] = { "handle", "quit", NULL };	enum { CMD_CORE_HANDLE, CMD_CORE_QUIT } cmd;	int error;	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) {

⌨️ 快捷键说明

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