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