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