6694
|
1 /**
|
|
2 * @file tcl_cmds.c Commands for the Gaim Tcl plugin bindings
|
|
3 *
|
|
4 * gaim
|
|
5 *
|
|
6 * Copyright (C) 2003 Ethan Blanton <eblanton@cs.purdue.edu>
|
|
7 *
|
|
8 * This program is free software; you can redistribute it and/or modify
|
|
9 * it under the terms of the GNU General Public License as published by
|
|
10 * the Free Software Foundation; either version 2 of the License, or
|
|
11 * (at your option) any later version.
|
|
12 *
|
|
13 * This program is distributed in the hope that it will be useful,
|
|
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16 * GNU General Public License for more details.
|
|
17 *
|
|
18 * You should have received a copy of the GNU General Public License
|
|
19 * along with this program; if not, write to the Free Software
|
|
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
21 */
|
|
22
|
|
23 #include <tcl.h>
|
|
24
|
|
25 #include "internal.h"
|
|
26 #include "conversation.h"
|
|
27 #include "connection.h"
|
|
28 #include "account.h"
|
|
29 #include "server.h"
|
|
30 #include "notify.h"
|
6700
|
31 #include "blist.h"
|
6694
|
32 #include "debug.h"
|
|
33 #include "prefs.h"
|
|
34 #include "core.h"
|
|
35
|
|
36 #include "tcl_gaim.h"
|
|
37
|
|
38 static gboolean tcl_validate_account(GaimAccount *account, Tcl_Interp *interp);
|
|
39 static gboolean tcl_validate_gc(GaimConnection *gc);
|
|
40
|
|
41 static gboolean tcl_validate_account(GaimAccount *account, Tcl_Interp *interp)
|
|
42 {
|
|
43 GList *cur;
|
|
44 for (cur = gaim_accounts_get_all(); cur != NULL; cur = g_list_next(cur)) {
|
|
45 if (account == cur->data)
|
|
46 return TRUE;
|
|
47 }
|
|
48 if (interp != NULL)
|
|
49 Tcl_SetStringObj(Tcl_GetObjResult(interp), "invalid account", -1);
|
|
50 return FALSE;
|
|
51 }
|
|
52
|
|
53 static gboolean tcl_validate_conversation(GaimConversation *convo, Tcl_Interp *interp)
|
|
54 {
|
|
55 GList *cur;
|
|
56
|
|
57 for (cur = gaim_get_conversations(); cur != NULL; cur = g_list_next(cur)) {
|
|
58 if (convo == cur->data)
|
|
59 return TRUE;
|
|
60 }
|
|
61 if (interp != NULL)
|
|
62 Tcl_SetStringObj(Tcl_GetObjResult(interp), "invalid account", -1);
|
|
63 return FALSE;
|
|
64 }
|
|
65
|
|
66 static gboolean tcl_validate_gc(GaimConnection *gc)
|
|
67 {
|
|
68 GList *cur;
|
|
69 for (cur = gaim_connections_get_all(); cur != NULL; cur = g_list_next(cur)) {
|
|
70 if (gc == cur->data)
|
|
71 return TRUE;
|
|
72 }
|
|
73 return FALSE;
|
|
74 }
|
|
75
|
|
76 int tcl_cmd_account(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
|
|
77 {
|
|
78 Tcl_Obj *result = Tcl_GetObjResult(interp), *list, *elem;
|
6737
|
79 char *cmds[] = { "alias", "connect", "connection", "disconnect", "find",
|
|
80 "handle", "isconnected", "list", "public_ip",
|
|
81 "protocol", "username", NULL };
|
6694
|
82 enum { CMD_ACCOUNT_ALIAS, CMD_ACCOUNT_CONNECT, CMD_ACCOUNT_CONNECTION,
|
|
83 CMD_ACCOUNT_DISCONNECT, CMD_ACCOUNT_FIND, CMD_ACCOUNT_HANDLE,
|
6737
|
84 CMD_ACCOUNT_ISCONNECTED, CMD_ACCOUNT_LIST, CMD_ACCOUNT_PUBLIC_IP,
|
|
85 CMD_ACCOUNT_PROTOCOL, CMD_ACCOUNT_USERNAME } cmd;
|
6694
|
86 char *listopts[] = { "-all", "-online", NULL };
|
|
87 enum { CMD_ACCOUNTLIST_ALL, CMD_ACCOUNTLIST_ONLINE } listopt;
|
6737
|
88 const char *alias, *ip;
|
6694
|
89 GList *cur;
|
|
90 GaimAccount *account;
|
|
91 int error;
|
|
92
|
|
93 if (objc < 2) {
|
|
94 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?");
|
|
95 return TCL_ERROR;
|
|
96 }
|
|
97
|
|
98 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK)
|
|
99 return error;
|
|
100
|
|
101 switch (cmd) {
|
|
102 case CMD_ACCOUNT_ALIAS:
|
|
103 if (objc != 3) {
|
|
104 Tcl_WrongNumArgs(interp, 2, objv, "account");
|
|
105 return TCL_ERROR;
|
|
106 }
|
|
107 error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account);
|
|
108 if (error || !tcl_validate_account(account, interp))
|
|
109 return TCL_ERROR;
|
|
110 alias = gaim_account_get_alias(account);
|
|
111 Tcl_SetStringObj(result, alias ? (char *)alias : "", -1);
|
|
112 break;
|
|
113 case CMD_ACCOUNT_CONNECT:
|
|
114 if (objc != 3) {
|
|
115 Tcl_WrongNumArgs(interp, 2, objv, "account");
|
|
116 return TCL_ERROR;
|
|
117 }
|
|
118 error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account);
|
|
119 if (error || !tcl_validate_account(account, interp))
|
|
120 return TCL_ERROR;
|
|
121 if (gaim_account_is_connected(account))
|
|
122 Tcl_SetIntObj(result, (int)gaim_account_get_connection(account));
|
|
123 else
|
|
124 Tcl_SetIntObj(result, (int)gaim_account_connect(account));
|
|
125 break;
|
|
126 case CMD_ACCOUNT_CONNECTION:
|
|
127 if (objc != 3) {
|
|
128 Tcl_WrongNumArgs(interp, 2, objv, "account");
|
|
129 return TCL_ERROR;
|
|
130 }
|
|
131 error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account);
|
|
132 if (error || !tcl_validate_account(account, interp))
|
|
133 return TCL_ERROR;
|
|
134 Tcl_SetIntObj(result, (int)gaim_account_get_connection(account));
|
|
135 break;
|
|
136 case CMD_ACCOUNT_DISCONNECT:
|
|
137 if (objc != 3) {
|
|
138 Tcl_WrongNumArgs(interp, 2, objv, "account");
|
|
139 return TCL_ERROR;
|
|
140 }
|
|
141 error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account);
|
|
142 if (error || !tcl_validate_account(account, interp))
|
|
143 return TCL_ERROR;
|
|
144 gaim_account_disconnect(account);
|
|
145 break;
|
|
146 case CMD_ACCOUNT_FIND:
|
|
147 if (objc != 4) {
|
|
148 Tcl_WrongNumArgs(interp, 2, objv, "username protocol");
|
|
149 return TCL_ERROR;
|
|
150 }
|
|
151 Tcl_SetIntObj(result, (int)gaim_accounts_find_with_prpl_id(Tcl_GetString(objv[2]),
|
|
152 Tcl_GetString(objv[3])));
|
|
153 break;
|
|
154 case CMD_ACCOUNT_HANDLE:
|
|
155 if (objc != 2) {
|
|
156 Tcl_WrongNumArgs(interp, 2, objv, "");
|
|
157 return TCL_ERROR;
|
|
158 }
|
|
159 Tcl_SetIntObj(result, (int)gaim_accounts_get_handle());
|
|
160 break;
|
|
161 case CMD_ACCOUNT_ISCONNECTED:
|
|
162 if (objc != 3) {
|
|
163 Tcl_WrongNumArgs(interp, 2, objv, "account");
|
|
164 return TCL_ERROR;
|
|
165 }
|
|
166 error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account);
|
|
167 if (error || !tcl_validate_account(account, interp))
|
|
168 return TCL_ERROR;
|
|
169 Tcl_SetBooleanObj(result, gaim_account_is_connected(account));
|
|
170 break;
|
|
171 case CMD_ACCOUNT_LIST:
|
|
172 listopt = CMD_ACCOUNTLIST_ALL;
|
|
173 if (objc > 3) {
|
|
174 Tcl_WrongNumArgs(interp, 2, objv, "?option?");
|
|
175 return TCL_ERROR;
|
|
176 }
|
|
177 if (objc == 3) {
|
|
178 if ((error = Tcl_GetIndexFromObj(interp, objv[2], listopts, "option", 0, (int *)&listopt)) != TCL_OK)
|
|
179 return error;
|
|
180 }
|
|
181 list = Tcl_NewListObj(0, NULL);
|
|
182 for (cur = gaim_accounts_get_all(); cur != NULL; cur = g_list_next(cur)) {
|
|
183 account = cur->data;
|
|
184 if (listopt == CMD_ACCOUNTLIST_ONLINE && !gaim_account_is_connected(account))
|
|
185 continue;
|
|
186 elem = Tcl_NewIntObj((int)account);
|
|
187 Tcl_ListObjAppendElement(interp, list, elem);
|
|
188 }
|
|
189 Tcl_SetObjResult(interp, list);
|
|
190 break;
|
6737
|
191 case CMD_ACCOUNT_PUBLIC_IP:
|
|
192 if (objc != 3) {
|
|
193 Tcl_WrongNumArgs(interp, 2, objv, "account");
|
|
194 return TCL_ERROR;
|
|
195 }
|
|
196 error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account);
|
|
197 if (error || !tcl_validate_account(account, interp))
|
|
198 return TCL_ERROR;
|
|
199 ip = gaim_account_get_public_ip(account);
|
|
200 Tcl_SetStringObj(result, ip != NULL ? (char *)ip : "", -1);
|
|
201 break;
|
6694
|
202 case CMD_ACCOUNT_PROTOCOL:
|
|
203 if (objc != 3) {
|
|
204 Tcl_WrongNumArgs(interp, 2, objv, "account");
|
|
205 return TCL_ERROR;
|
|
206 }
|
|
207 error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account);
|
|
208 if (error || !tcl_validate_account(account, interp))
|
|
209 return TCL_ERROR;
|
|
210 Tcl_SetStringObj(result, (char *)gaim_account_get_protocol_id(account), -1);
|
|
211 break;
|
|
212 case CMD_ACCOUNT_USERNAME:
|
|
213 if (objc != 3) {
|
|
214 Tcl_WrongNumArgs(interp, 2, objv, "account");
|
|
215 return TCL_ERROR;
|
|
216 }
|
|
217 error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account);
|
|
218 if (error || !tcl_validate_account(account, interp))
|
|
219 return TCL_ERROR;
|
|
220 Tcl_SetStringObj(result, (char *)gaim_account_get_username(account), -1);
|
|
221 break;
|
|
222 }
|
|
223
|
|
224 return TCL_OK;
|
|
225 }
|
|
226
|
|
227 static GaimBlistNode *tcl_list_to_buddy(Tcl_Interp *interp, int count, Tcl_Obj **elems)
|
|
228 {
|
|
229 GaimBlistNode *node = NULL;
|
|
230 GaimAccount *account;
|
|
231 char *name;
|
|
232 char *type;
|
|
233
|
|
234 if (count < 3) {
|
|
235 Tcl_SetStringObj(Tcl_GetObjResult(interp), "list too short", -1);
|
|
236 return NULL;
|
|
237 }
|
|
238
|
|
239 type = Tcl_GetString(elems[0]);
|
|
240 name = Tcl_GetString(elems[1]);
|
|
241 if (Tcl_GetIntFromObj(interp, elems[2], (int *)&account) != TCL_OK)
|
|
242 return NULL;
|
|
243 if (!tcl_validate_account(account, interp))
|
|
244 return NULL;
|
|
245
|
|
246 if (!strcmp(type, "buddy")) {
|
|
247 node = (GaimBlistNode *)gaim_find_buddy(account, name);
|
|
248 } else if (!strcmp(type, "group")) {
|
|
249 node = (GaimBlistNode *)gaim_blist_find_chat(account, name);
|
|
250 }
|
|
251
|
|
252 return node;
|
|
253 }
|
|
254
|
|
255 int tcl_cmd_buddy(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
|
|
256 {
|
6746
|
257 Tcl_Obj *list, *tclgroup, *tclgrouplist, *tclcontact, *tclcontactlist, *tclbud, **elems, *result;
|
6694
|
258 char *cmds[] = { "alias", "handle", "info", "list", NULL };
|
|
259 enum { CMD_BUDDY_ALIAS, CMD_BUDDY_HANDLE, CMD_BUDDY_INFO, CMD_BUDDY_LIST } cmd;
|
|
260 struct gaim_buddy_list *blist;
|
6746
|
261 GaimBlistNode *node, *gnode, *bnode;
|
6694
|
262 GaimAccount *account;
|
6746
|
263 GaimBuddy *bud;
|
6700
|
264 GaimBlistChat *cnode;
|
6694
|
265 int error, all = 0, count;
|
|
266
|
|
267 if (objc < 2) {
|
|
268 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?");
|
|
269 return TCL_ERROR;
|
|
270 }
|
|
271 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK)
|
|
272 return error;
|
|
273
|
|
274 result = Tcl_GetObjResult(interp);
|
|
275
|
|
276 switch (cmd) {
|
|
277 case CMD_BUDDY_ALIAS:
|
|
278 if (objc != 3) {
|
|
279 Tcl_WrongNumArgs(interp, 2, objv, "buddy");
|
|
280 return TCL_ERROR;
|
|
281 }
|
|
282 if ((error = Tcl_ListObjGetElements(interp, objv[2], &count, &elems)) != TCL_OK)
|
|
283 return error;
|
|
284 if ((node = tcl_list_to_buddy(interp, count, elems)) == NULL)
|
|
285 return TCL_ERROR;
|
|
286 if (node->type == GAIM_BLIST_CHAT_NODE)
|
6700
|
287 Tcl_SetStringObj(result, ((GaimBlistChat *)node)->alias, -1);
|
6694
|
288 else if (node->type == GAIM_BLIST_BUDDY_NODE)
|
6700
|
289 Tcl_SetStringObj(result, (char *)gaim_get_buddy_alias((GaimBuddy *)node), -1);
|
6694
|
290 return TCL_OK;
|
|
291 break;
|
|
292 case CMD_BUDDY_HANDLE:
|
|
293 if (objc != 2) {
|
|
294 Tcl_WrongNumArgs(interp, 2, objv, "");
|
|
295 return TCL_ERROR;
|
|
296 }
|
|
297 Tcl_SetIntObj(result, (int)gaim_blist_get_handle());
|
|
298 break;
|
|
299 case CMD_BUDDY_INFO:
|
|
300 if (objc != 3 && objc != 4) {
|
|
301 Tcl_WrongNumArgs(interp, 2, objv, "( buddy | account username )");
|
|
302 return TCL_ERROR;
|
|
303 }
|
|
304 if (objc == 3) {
|
|
305 if ((error = Tcl_ListObjGetElements(interp, objv[2], &count, &elems)) != TCL_OK)
|
|
306 return error;
|
|
307 if (count < 3) {
|
|
308 Tcl_SetStringObj(result, "buddy too short", -1);
|
|
309 return TCL_ERROR;
|
|
310 }
|
|
311 if (strcmp("buddy", Tcl_GetString(elems[0]))) {
|
|
312 Tcl_SetStringObj(result, "invalid buddy", -1);
|
|
313 return TCL_ERROR;
|
|
314 }
|
|
315 if ((error = Tcl_GetIntFromObj(interp, elems[2], (int *)&account)) != TCL_OK)
|
|
316 return TCL_ERROR;
|
|
317 if (!tcl_validate_account(account, interp))
|
|
318 return TCL_ERROR;
|
|
319 serv_get_info(gaim_account_get_connection(account), Tcl_GetString(elems[1]));
|
|
320 } else {
|
|
321 if ((error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account)) != TCL_OK)
|
|
322 return error;
|
|
323 if (!tcl_validate_account(account, interp))
|
|
324 return TCL_ERROR;
|
|
325 serv_get_info(gaim_account_get_connection(account), Tcl_GetString(objv[3]));
|
|
326 }
|
|
327 break;
|
|
328 case CMD_BUDDY_LIST:
|
|
329 if (objc == 3) {
|
|
330 if (!strcmp("-all", Tcl_GetString(objv[2]))) {
|
|
331 all = 1;
|
|
332 } else {
|
|
333 Tcl_SetStringObj(result, "", -1);
|
|
334 Tcl_AppendStringsToObj(result, "unknown option: ", Tcl_GetString(objv[2]), NULL);
|
|
335 return TCL_ERROR;
|
|
336 }
|
|
337 }
|
|
338 list = Tcl_NewListObj(0, NULL);
|
|
339 blist = gaim_get_blist();
|
|
340 for (gnode = blist->root; gnode != NULL; gnode = gnode->next) {
|
|
341 tclgroup = Tcl_NewListObj(0, NULL);
|
|
342 Tcl_ListObjAppendElement(interp, tclgroup, Tcl_NewStringObj("group", -1));
|
|
343 Tcl_ListObjAppendElement(interp, tclgroup,
|
6700
|
344 Tcl_NewStringObj(((GaimGroup *)gnode)->name, -1));
|
6694
|
345 tclgrouplist = Tcl_NewListObj(0, NULL);
|
|
346 for (node = gnode->child; node != NULL; node = node->next) {
|
|
347 switch (node->type) {
|
6746
|
348 case GAIM_BLIST_CONTACT_NODE:
|
|
349 tclcontact = Tcl_NewListObj(0, NULL);
|
|
350 Tcl_IncrRefCount(tclcontact);
|
|
351 Tcl_ListObjAppendElement(interp, tclcontact, Tcl_NewStringObj("contact", -1));
|
|
352 tclcontactlist = Tcl_NewListObj(0, NULL);
|
|
353 Tcl_IncrRefCount(tclcontactlist);
|
|
354 count = 0;
|
|
355 for (bnode = node->child; bnode != NULL; bnode = bnode ->next) {
|
|
356 if (bnode->type != GAIM_BLIST_BUDDY_NODE)
|
|
357 continue;
|
|
358 bud = (GaimBuddy *)bnode;
|
|
359 if (!all && !gaim_account_is_connected(bud->account))
|
|
360 continue;
|
|
361 count++;
|
|
362 tclbud = Tcl_NewListObj(0, NULL);
|
|
363 Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj("buddy", -1));
|
|
364 Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj(bud->name, -1));
|
|
365 Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewIntObj((int)bud->account));
|
|
366 Tcl_ListObjAppendElement(interp, tclcontactlist, tclbud);
|
|
367 }
|
|
368 if (count) {
|
|
369 Tcl_ListObjAppendElement(interp, tclcontact, tclcontactlist);
|
|
370 Tcl_ListObjAppendElement(interp, tclgrouplist, tclcontact);
|
|
371 }
|
|
372 Tcl_DecrRefCount(tclcontact);
|
|
373 Tcl_DecrRefCount(tclcontactlist);
|
6694
|
374 break;
|
|
375 case GAIM_BLIST_CHAT_NODE:
|
6700
|
376 cnode = (GaimBlistChat *)node;
|
6694
|
377 if (!all && !gaim_account_is_connected(cnode->account))
|
|
378 continue;
|
|
379 tclbud = Tcl_NewListObj(0, NULL);
|
|
380 Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj("chat", -1));
|
|
381 Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj(cnode->alias, -1));
|
|
382 Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewIntObj((int)cnode->account));
|
6746
|
383 Tcl_ListObjAppendElement(interp, tclgrouplist, tclbud);
|
6694
|
384 break;
|
|
385 default:
|
6746
|
386 gaim_debug(GAIM_DEBUG_WARNING, "tcl", "Unexpected buddy type %d", node->type);
|
6694
|
387 continue;
|
|
388 }
|
|
389 }
|
|
390 Tcl_ListObjAppendElement(interp, tclgroup, tclgrouplist);
|
|
391 Tcl_ListObjAppendElement(interp, list, tclgroup);
|
|
392 }
|
|
393 Tcl_SetObjResult(interp, list);
|
|
394 break;
|
|
395 }
|
|
396
|
|
397 return TCL_OK;
|
|
398 }
|
|
399
|
|
400 int tcl_cmd_connection(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
|
|
401 {
|
|
402 Tcl_Obj *result = Tcl_GetObjResult(interp), *list, *elem;
|
|
403 char *cmds[] = { "account", "handle", "list", NULL };
|
|
404 enum { CMD_CONN_ACCOUNT, CMD_CONN_HANDLE, CMD_CONN_LIST } cmd;
|
|
405 int error;
|
|
406 GList *cur;
|
|
407 GaimConnection *gc;
|
|
408
|
|
409 if (objc < 2) {
|
|
410 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?");
|
|
411 return TCL_ERROR;
|
|
412 }
|
|
413
|
|
414 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK)
|
|
415 return error;
|
|
416
|
|
417 switch (cmd) {
|
|
418 case CMD_CONN_ACCOUNT:
|
|
419 if (objc != 3) {
|
6864
|
420 Tcl_WrongNumArgs(interp, 2, objv, "gc");
|
6694
|
421 return TCL_ERROR;
|
|
422 }
|
|
423 error = Tcl_GetIntFromObj(interp, objv[2], (int *)&gc);
|
|
424 if (error || !tcl_validate_gc(gc)) {
|
|
425 Tcl_SetStringObj(result, "invalid gc", -1);
|
|
426 return TCL_ERROR;
|
|
427 }
|
|
428 Tcl_SetIntObj(result, (int)gaim_connection_get_account(gc));
|
|
429 break;
|
|
430 case CMD_CONN_HANDLE:
|
|
431 if (objc != 2) {
|
|
432 Tcl_WrongNumArgs(interp, 2, objv, "");
|
|
433 return TCL_ERROR;
|
|
434 }
|
|
435 Tcl_SetIntObj(result, (int)gaim_connections_get_handle());
|
|
436 break;
|
|
437 case CMD_CONN_LIST:
|
|
438 if (objc != 2) {
|
|
439 Tcl_WrongNumArgs(interp, 2, objv, "");
|
|
440 return TCL_ERROR;
|
|
441 }
|
|
442 list = Tcl_NewListObj(0, NULL);
|
|
443 for (cur = gaim_connections_get_all(); cur != NULL; cur = g_list_next(cur)) {
|
|
444 elem = Tcl_NewIntObj((int)cur->data);
|
|
445 Tcl_ListObjAppendElement(interp, list, elem);
|
|
446 }
|
|
447 Tcl_SetObjResult(interp, list);
|
|
448 break;
|
|
449 }
|
|
450
|
|
451 return TCL_OK;
|
|
452 }
|
|
453
|
|
454 int tcl_cmd_conversation(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
|
|
455 {
|
|
456 Tcl_Obj *list, *elem, *result = Tcl_GetObjResult(interp);
|
|
457 char *cmds[] = { "find", "handle", "list", "new", "write", NULL };
|
|
458 enum { CMD_CONV_FIND, CMD_CONV_HANDLE, CMD_CONV_LIST, CMD_CONV_NEW, CMD_CONV_WRITE } cmd;
|
|
459 char *styles[] = { "send", "recv", "system", NULL };
|
|
460 enum { CMD_CONV_WRITE_SEND, CMD_CONV_WRITE_RECV, CMD_CONV_WRITE_SYSTEM } style;
|
|
461 char *findopts[] = { "-account", NULL };
|
|
462 enum { CMD_CONV_FIND_ACCOUNT } findopt;
|
|
463 char *newopts[] = { "-chat", "-im" };
|
|
464 enum { CMD_CONV_NEW_CHAT, CMD_CONV_NEW_IM } newopt;
|
|
465 GaimConversation *convo;
|
|
466 GaimAccount *account;
|
|
467 GaimConversationType type;
|
|
468 GList *cur;
|
|
469 char *opt, *from, *what;
|
|
470 int error, argsused, flags;
|
|
471
|
|
472 if (objc < 2) {
|
|
473 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?");
|
|
474 return TCL_ERROR;
|
|
475 }
|
|
476
|
|
477 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK)
|
|
478 return error;
|
|
479
|
|
480 switch (cmd) {
|
|
481 case CMD_CONV_FIND:
|
|
482 if (objc < 3) {
|
|
483 Tcl_WrongNumArgs(interp, 2, objv, "?options? name");
|
|
484 return TCL_ERROR;
|
|
485 }
|
|
486 argsused = 2;
|
|
487 account = NULL;
|
|
488 while (argsused < objc) {
|
|
489 opt = Tcl_GetString(objv[argsused]);
|
|
490 if (*opt == '-') {
|
|
491 if ((error = Tcl_GetIndexFromObj(interp, objv[argsused], findopts,
|
|
492 "option", 0, (int *)&findopt)) != TCL_OK)
|
|
493 return error;
|
|
494 argsused++;
|
|
495 switch (findopt) {
|
|
496 case CMD_CONV_FIND_ACCOUNT:
|
|
497 if (argsused == objc - 1) {
|
|
498 Tcl_SetStringObj(result, "-account requires an argument", -1);
|
|
499 return TCL_ERROR;
|
|
500 }
|
|
501 if ((error = Tcl_GetIntFromObj(interp, objv[argsused],
|
|
502 (int *)&account)) != TCL_OK)
|
|
503 return error;
|
|
504 if (!tcl_validate_account(account, interp))
|
|
505 return TCL_ERROR;
|
|
506 argsused++;
|
|
507 break;
|
|
508 }
|
|
509 } else {
|
|
510 break;
|
|
511 }
|
|
512 }
|
|
513 if (objc - argsused != 1) {
|
|
514 Tcl_WrongNumArgs(interp, 2, objv, "?options? name");
|
|
515 return error;
|
|
516 }
|
|
517 if (account != NULL) {
|
|
518 convo = gaim_find_conversation_with_account(Tcl_GetString(objv[argsused]), account);
|
|
519 } else {
|
|
520 convo = gaim_find_conversation(Tcl_GetString(objv[argsused]));
|
|
521 }
|
|
522 Tcl_SetIntObj(result, (int)convo);
|
|
523 break;
|
|
524 case CMD_CONV_HANDLE:
|
|
525 if (objc != 2) {
|
|
526 Tcl_WrongNumArgs(interp, 2, objv, "");
|
|
527 return TCL_ERROR;
|
|
528 }
|
|
529 Tcl_SetIntObj(result, (int)gaim_conversations_get_handle());
|
|
530 break;
|
|
531 case CMD_CONV_LIST:
|
|
532 list = Tcl_NewListObj(0, NULL);
|
|
533 for (cur = gaim_get_conversations(); cur != NULL; cur = g_list_next(cur)) {
|
|
534 elem = Tcl_NewIntObj((int)cur->data);
|
|
535 Tcl_ListObjAppendElement(interp, list, elem);
|
|
536 }
|
|
537 Tcl_SetObjResult(interp, list);
|
|
538 break;
|
|
539 case CMD_CONV_NEW:
|
|
540 if (objc < 4) {
|
|
541 Tcl_WrongNumArgs(interp, 2, objv, "?options? account name");
|
|
542 return TCL_ERROR;
|
|
543 }
|
|
544 argsused = 2;
|
|
545 type = GAIM_CONV_IM;
|
|
546 while (argsused < objc) {
|
|
547 opt = Tcl_GetString(objv[argsused]);
|
|
548 if (*opt == '-') {
|
|
549 if ((error = Tcl_GetIndexFromObj(interp, objv[argsused], newopts,
|
|
550 "option", 0, (int *)&newopt)) != TCL_OK)
|
|
551 return error;
|
|
552 argsused++;
|
|
553 switch (newopt) {
|
|
554 case CMD_CONV_NEW_CHAT:
|
|
555 type = GAIM_CONV_CHAT;
|
|
556 break;
|
|
557 case CMD_CONV_NEW_IM:
|
|
558 type = GAIM_CONV_IM;
|
|
559 break;
|
|
560 }
|
|
561 } else {
|
|
562 break;
|
|
563 }
|
|
564 }
|
|
565 if (objc - argsused != 2) {
|
|
566 Tcl_WrongNumArgs(interp, 2, objv, "?options? account name");
|
|
567 return TCL_ERROR;
|
|
568 }
|
|
569 if ((error = Tcl_GetIntFromObj(interp, objv[argsused++], (int *)&account)) != TCL_OK)
|
|
570 return error;
|
|
571 if (!tcl_validate_account(account, interp))
|
|
572 return TCL_ERROR;
|
|
573 convo = gaim_conversation_new(type, account, Tcl_GetString(objv[argsused]));
|
|
574 Tcl_SetIntObj(result, (int)convo);
|
|
575 break;
|
|
576 case CMD_CONV_WRITE:
|
|
577 if (objc != 6) {
|
|
578 Tcl_WrongNumArgs(interp, 2, objv, "conversation style from what");
|
|
579 return TCL_ERROR;
|
|
580 }
|
|
581 if ((error = Tcl_GetIntFromObj(interp, objv[2], (int *)&convo)) != TCL_OK)
|
|
582 return error;
|
|
583 if ((error = Tcl_GetIndexFromObj(interp, objv[3], styles, "style", 0, (int *)&style)) != TCL_OK)
|
|
584 return error;
|
|
585 if (!tcl_validate_conversation(convo, interp))
|
|
586 return TCL_ERROR;
|
|
587 from = Tcl_GetString(objv[4]);
|
|
588 what = Tcl_GetString(objv[5]);
|
|
589
|
|
590 switch (style) {
|
|
591 case CMD_CONV_WRITE_SEND:
|
|
592 flags = GAIM_MESSAGE_SEND;
|
|
593 break;
|
|
594 case CMD_CONV_WRITE_RECV:
|
|
595 flags = GAIM_MESSAGE_RECV;
|
|
596 break;
|
|
597 case CMD_CONV_WRITE_SYSTEM:
|
|
598 flags = GAIM_MESSAGE_SYSTEM;
|
|
599 break;
|
|
600 }
|
|
601 if (gaim_conversation_get_type(convo) == GAIM_CONV_CHAT)
|
|
602 gaim_chat_write(GAIM_CHAT(convo), from, what, flags, time(NULL));
|
|
603 else
|
|
604 gaim_im_write(GAIM_IM(convo), from, what, -1, flags, time(NULL));
|
|
605 break;
|
|
606 }
|
|
607
|
|
608 return TCL_OK;
|
|
609 }
|
|
610
|
|
611 int tcl_cmd_core(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
|
|
612 {
|
|
613 Tcl_Obj *result = Tcl_GetObjResult(interp);
|
|
614 char *cmds[] = { "handle", "quit", NULL };
|
|
615 enum { CMD_CORE_HANDLE, CMD_CORE_QUIT } cmd;
|
|
616 int error;
|
|
617
|
|
618 if (objc < 2) {
|
|
619 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?");
|
|
620 return TCL_ERROR;
|
|
621 }
|
|
622
|
|
623 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK)
|
|
624 return error;
|
|
625
|
|
626 switch (cmd) {
|
|
627 case CMD_CORE_HANDLE:
|
|
628 if (objc != 2) {
|
|
629 Tcl_WrongNumArgs(interp, 2, objv, "");
|
|
630 return TCL_ERROR;
|
|
631 }
|
|
632 Tcl_SetIntObj(result, (int)gaim_get_core());
|
|
633 break;
|
|
634 case CMD_CORE_QUIT:
|
|
635 if (objc != 2) {
|
|
636 Tcl_WrongNumArgs(interp, 2, objv, "");
|
|
637 return TCL_ERROR;
|
|
638 }
|
|
639 gaim_core_quit();
|
|
640 break;
|
|
641 }
|
|
642
|
|
643 return TCL_OK;
|
|
644 }
|
|
645
|
|
646 int tcl_cmd_debug(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
|
|
647 {
|
|
648 char *category, *message;
|
|
649 int lev;
|
|
650 char *levels[] = { "-misc", "-info", "-warning", "-error", NULL };
|
|
651 GaimDebugLevel levelind[] = { GAIM_DEBUG_MISC, GAIM_DEBUG_INFO, GAIM_DEBUG_WARNING, GAIM_DEBUG_ERROR };
|
|
652 int error;
|
|
653
|
|
654 if (objc != 4) {
|
|
655 Tcl_WrongNumArgs(interp, 1, objv, "level category message");
|
|
656 return TCL_ERROR;
|
|
657 }
|
|
658
|
|
659 error = Tcl_GetIndexFromObj(interp, objv[1], levels, "debug level", 0, &lev);
|
|
660 if (error != TCL_OK)
|
|
661 return error;
|
|
662
|
|
663 category = Tcl_GetString(objv[2]);
|
|
664 message = Tcl_GetString(objv[3]);
|
|
665
|
|
666 gaim_debug(levelind[lev], category, "%s\n", message);
|
|
667
|
|
668 return TCL_OK;
|
|
669 }
|
|
670
|
|
671 int tcl_cmd_notify(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
|
|
672 {
|
|
673 int error, type;
|
|
674 char *opts[] = { "-error", "-warning", "-info", NULL };
|
|
675 GaimNotifyMsgType optind[] = { GAIM_NOTIFY_MSG_ERROR, GAIM_NOTIFY_MSG_WARNING, GAIM_NOTIFY_MSG_INFO };
|
|
676 char *title, *msg1, *msg2;
|
|
677
|
|
678 if (objc < 4 || objc > 5) {
|
|
679 Tcl_WrongNumArgs(interp, 1, objv, "?type? title primary secondary");
|
|
680 return TCL_ERROR;
|
|
681 }
|
|
682
|
|
683 if (objc == 4) {
|
|
684 title = Tcl_GetString(objv[1]);
|
|
685 msg1 = Tcl_GetString(objv[2]);
|
|
686 msg2 = Tcl_GetString(objv[3]);
|
|
687 } else {
|
|
688 error = Tcl_GetIndexFromObj(interp, objv[1], opts, "message type", 0, &type);
|
|
689 if (error != TCL_OK)
|
|
690 return error;
|
|
691 title = Tcl_GetString(objv[2]);
|
|
692 msg1 = Tcl_GetString(objv[3]);
|
|
693 msg2 = Tcl_GetString(objv[4]);
|
|
694 }
|
|
695
|
|
696 gaim_notify_message(_tcl_plugin, optind[type], title, msg1, msg2, NULL, NULL);
|
|
697
|
|
698 return TCL_OK;
|
|
699 }
|
|
700
|
|
701 int tcl_cmd_prefs(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
|
|
702 {
|
|
703 Tcl_Obj *result, *list, *elem, **elems;
|
|
704 char *cmds[] = { "get", "set", "type", NULL };
|
|
705 enum { CMD_PREFS_GET, CMD_PREFS_SET, CMD_PREFS_TYPE } cmd;
|
|
706 /* char *types[] = { "none", "boolean", "int", "string", "stringlist", NULL }; */
|
|
707 /* enum { TCL_PREFS_NONE, TCL_PREFS_BOOL, TCL_PREFS_INT, TCL_PREFS_STRING, TCL_PREFS_STRINGLIST } type; */
|
|
708 GaimPrefType preftype;
|
|
709 GList *cur;
|
|
710 int error, intval, nelem, i;
|
|
711
|
|
712 if (objc < 2) {
|
|
713 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?");
|
|
714 return TCL_ERROR;
|
|
715 }
|
|
716
|
|
717 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK)
|
|
718 return error;
|
|
719
|
|
720 result = Tcl_GetObjResult(interp);
|
|
721 switch (cmd) {
|
|
722 case CMD_PREFS_GET:
|
|
723 if (objc != 3) {
|
|
724 Tcl_WrongNumArgs(interp, 1, objv, "path");
|
|
725 return TCL_ERROR;
|
|
726 }
|
|
727 preftype = gaim_prefs_get_type(Tcl_GetString(objv[2]));
|
|
728 switch (preftype) {
|
|
729 case GAIM_PREF_NONE:
|
|
730 Tcl_SetStringObj(result, "pref type none", -1);
|
|
731 return TCL_ERROR;
|
|
732 break;
|
|
733 case GAIM_PREF_BOOLEAN:
|
|
734 Tcl_SetBooleanObj(result, gaim_prefs_get_bool(Tcl_GetString(objv[2])));
|
|
735 break;
|
|
736 case GAIM_PREF_INT:
|
|
737 Tcl_SetIntObj(result, gaim_prefs_get_int(Tcl_GetString(objv[2])));
|
|
738 break;
|
|
739 case GAIM_PREF_STRING:
|
|
740 Tcl_SetStringObj(result, (char *)gaim_prefs_get_string(Tcl_GetString(objv[2])), -1);
|
|
741 break;
|
|
742 case GAIM_PREF_STRING_LIST:
|
|
743 cur = gaim_prefs_get_string_list(Tcl_GetString(objv[2]));
|
|
744 list = Tcl_NewListObj(0, NULL);
|
|
745 while (cur != NULL) {
|
|
746 elem = Tcl_NewStringObj((char *)cur->data, -1);
|
|
747 Tcl_ListObjAppendElement(interp, list, elem);
|
|
748 cur = g_list_next(cur);
|
|
749 }
|
|
750 Tcl_SetObjResult(interp, list);
|
|
751 break;
|
|
752 default:
|
|
753 gaim_debug(GAIM_DEBUG_ERROR, "tcl", "tcl does not know about pref type %d\n", preftype);
|
|
754 Tcl_SetStringObj(result, "unknown pref type", -1);
|
|
755 return TCL_ERROR;
|
|
756 }
|
|
757 break;
|
|
758 case CMD_PREFS_SET:
|
|
759 if (objc != 4) {
|
|
760 Tcl_WrongNumArgs(interp, 1, objv, "path value");
|
|
761 return TCL_ERROR;
|
|
762 }
|
|
763 preftype = gaim_prefs_get_type(Tcl_GetString(objv[2]));
|
|
764 switch (preftype) {
|
|
765 case GAIM_PREF_NONE:
|
|
766 Tcl_SetStringObj(result, "bad path or pref type none", -1);
|
|
767 return TCL_ERROR;
|
|
768 break;
|
|
769 case GAIM_PREF_BOOLEAN:
|
|
770 if ((error = Tcl_GetBooleanFromObj(interp, objv[3], &intval)) != TCL_OK)
|
|
771 return error;
|
|
772 gaim_prefs_set_bool(Tcl_GetString(objv[2]), intval);
|
|
773 break;
|
|
774 case GAIM_PREF_INT:
|
|
775 if ((error = Tcl_GetIntFromObj(interp, objv[3], &intval)) != TCL_OK)
|
|
776 return error;
|
|
777 gaim_prefs_set_int(Tcl_GetString(objv[2]), intval);
|
|
778 break;
|
|
779 case GAIM_PREF_STRING:
|
|
780 gaim_prefs_set_string(Tcl_GetString(objv[2]), Tcl_GetString(objv[3]));
|
|
781 break;
|
|
782 case GAIM_PREF_STRING_LIST:
|
|
783 if ((error = Tcl_ListObjGetElements(interp, objv[3], &nelem, &elems)) != TCL_OK)
|
|
784 return error;
|
|
785 cur = NULL;
|
|
786 for (i = 0; i < nelem; i++) {
|
|
787 cur = g_list_append(cur, (gpointer)Tcl_GetString(elems[i]));
|
|
788 }
|
|
789 gaim_prefs_set_string_list(Tcl_GetString(objv[2]), cur);
|
|
790 g_list_free(cur);
|
|
791 break;
|
|
792 default:
|
|
793 gaim_debug(GAIM_DEBUG_ERROR, "tcl", "tcl does not know about pref type %d\n", preftype);
|
|
794 return TCL_ERROR;
|
|
795 }
|
|
796 break;
|
|
797 case CMD_PREFS_TYPE:
|
|
798 if (objc != 3) {
|
|
799 Tcl_WrongNumArgs(interp, 1, objv, "path");
|
|
800 return TCL_ERROR;
|
|
801 }
|
|
802 preftype = gaim_prefs_get_type(Tcl_GetString(objv[2]));
|
|
803 switch (preftype) {
|
|
804 case GAIM_PREF_NONE:
|
|
805 Tcl_SetStringObj(result, "none", -1);
|
|
806 break;
|
|
807 case GAIM_PREF_BOOLEAN:
|
|
808 Tcl_SetStringObj(result, "boolean", -1);
|
|
809 break;
|
|
810 case GAIM_PREF_INT:
|
|
811 Tcl_SetStringObj(result, "int", -1);
|
|
812 break;
|
|
813 case GAIM_PREF_STRING:
|
|
814 Tcl_SetStringObj(result, "string", -1);
|
|
815 break;
|
|
816 case GAIM_PREF_STRING_LIST:
|
|
817 Tcl_SetStringObj(result, "stringlist", -1);
|
|
818 break;
|
|
819 default:
|
|
820 gaim_debug(GAIM_DEBUG_ERROR, "tcl", "tcl does not know about pref type %d\n", preftype);
|
|
821 Tcl_SetStringObj(result, "unknown", -1);
|
|
822 }
|
|
823 break;
|
|
824 }
|
|
825
|
|
826 return TCL_OK;
|
|
827 }
|
|
828
|
|
829 int tcl_cmd_send_im(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
|
|
830 {
|
|
831 GaimConnection *gc;
|
|
832 char *who, *text;
|
|
833 int error;
|
|
834 Tcl_Obj *result;
|
|
835
|
|
836 if (objc != 4) {
|
|
837 Tcl_WrongNumArgs(interp, 1, objv, "gc who text");
|
|
838 return TCL_ERROR;
|
|
839 }
|
|
840
|
|
841 if ((error = Tcl_GetIntFromObj(interp, objv[1], (int *)&gc)) != TCL_OK)
|
|
842 return error;
|
|
843 if (!tcl_validate_gc(gc)) {
|
|
844 result = Tcl_GetObjResult(interp);
|
|
845 Tcl_SetStringObj(result, "invalid gc", -1);
|
|
846 return TCL_ERROR;
|
|
847 }
|
|
848
|
|
849 who = Tcl_GetString(objv[2]);
|
|
850 text = Tcl_GetString(objv[3]);
|
|
851
|
|
852 serv_send_im(gc, who, text, -1, 0);
|
|
853
|
|
854 return TCL_OK;
|
|
855 }
|
|
856
|
|
857 int tcl_cmd_signal(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
|
|
858 {
|
|
859 char *cmds[] = { "connect", "disconnect", NULL };
|
|
860 enum { CMD_SIGNAL_CONNECT, CMD_SIGNAL_DISCONNECT } cmd;
|
|
861 struct tcl_signal_handler *handler;
|
|
862 Tcl_Obj **elems, *result = Tcl_GetObjResult(interp);
|
|
863 void *instance;
|
|
864 int error, nelems, i;
|
|
865
|
|
866 if (objc < 2) {
|
|
867 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?");
|
|
868 return TCL_ERROR;
|
|
869 }
|
|
870
|
|
871 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK)
|
|
872 return error;
|
|
873
|
|
874 switch (cmd) {
|
|
875 case CMD_SIGNAL_CONNECT:
|
|
876 if (objc != 6) {
|
|
877 Tcl_WrongNumArgs(interp, 2, objv, "instance signal args proc");
|
|
878 return TCL_ERROR;
|
|
879 }
|
|
880 if ((error = Tcl_ListObjGetElements(interp, objv[4], &nelems, &elems)) != TCL_OK)
|
|
881 return error;
|
|
882 handler = g_new0(struct tcl_signal_handler, 1);
|
|
883 if ((error = Tcl_GetIntFromObj(interp, objv[2], (int *)&handler->instance)) != TCL_OK) {
|
|
884 g_free(handler);
|
|
885 return error;
|
|
886 }
|
|
887 handler->signal = g_strdup(Tcl_GetString(objv[3]));
|
|
888 if (nelems) {
|
|
889 handler->argnames = g_new0(char *, nelems);
|
|
890 for (i = 0; i < nelems; i++) {
|
|
891 handler->argnames[i] = g_strdup(Tcl_GetString(elems[i]));
|
|
892 }
|
|
893 }
|
|
894 handler->nnames = nelems;
|
|
895 handler->proc = Tcl_NewStringObj("namespace eval ::gaim::_callback { ", -1);
|
|
896 Tcl_AppendStringsToObj(handler->proc, Tcl_GetString(objv[5]), " }", NULL);
|
|
897 Tcl_IncrRefCount(handler->proc);
|
|
898 handler->interp = interp;
|
|
899 if (!tcl_signal_connect(handler)) {
|
|
900 tcl_signal_handler_free(handler);
|
|
901 Tcl_SetIntObj(result, 1);
|
|
902 } else {
|
|
903 Tcl_SetIntObj(result, 0);
|
|
904 }
|
|
905 break;
|
|
906 case CMD_SIGNAL_DISCONNECT:
|
|
907 if (objc != 4) {
|
|
908 Tcl_WrongNumArgs(interp, 2, objv, "signal");
|
|
909 return TCL_ERROR;
|
|
910 }
|
|
911 if ((error = Tcl_GetIntFromObj(interp, objv[2], (int *)&instance)) != TCL_OK)
|
|
912 return error;
|
|
913 tcl_signal_disconnect(instance, Tcl_GetString(objv[3]), interp);
|
|
914 break;
|
|
915 }
|
|
916
|
|
917 return TCL_OK;
|
|
918 }
|
|
919
|
|
920 static gboolean unload_self(gpointer data)
|
|
921 {
|
|
922 GaimPlugin *plugin = data;
|
|
923 gaim_plugin_unload(plugin);
|
|
924 return FALSE;
|
|
925 }
|
|
926
|
|
927 int tcl_cmd_unload(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
|
|
928 {
|
|
929 GaimPlugin *plugin;
|
|
930 if (objc != 1) {
|
|
931 Tcl_WrongNumArgs(interp, 1, objv, "");
|
|
932 return TCL_ERROR;
|
|
933 }
|
|
934
|
|
935 if ((plugin = tcl_interp_get_plugin(interp)) == NULL) {
|
|
936 /* This isn't exactly OK, but heh. What do you do? */
|
|
937 return TCL_OK;
|
|
938 }
|
|
939 /* We can't unload immediately, but we can unload at the first
|
|
940 * known safe opportunity. */
|
|
941 g_idle_add(unload_self, (gpointer)plugin);
|
|
942
|
|
943 return TCL_OK;
|
|
944 }
|