Mercurial > pidgin.yaz
annotate plugins/tcl/tcl_cmds.c @ 7665:0351ff7030d0
[gaim-migrate @ 8309]
Felipe Contreras (aka revo aka shx) writes:
" Basically that, currently gaim will not display
international "subjects" or "from" fields from emails,
like "a??a" or "Pa?l".
This implements the propper RFC that specify the format
for those fields."
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Sun, 30 Nov 2003 04:17:17 +0000 |
parents | bb484e976aa8 |
children | 1adc71ed6d45 |
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); | |
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 } | |
7156 | 151 Tcl_SetIntObj(result, (int)gaim_accounts_find(Tcl_GetString(objv[2]), |
6694 | 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; | |
7100
abdc55ffadba
[gaim-migrate @ 7665]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
260 GaimBuddyList *blist; |
6746 | 261 GaimBlistNode *node, *gnode, *bnode; |
6694 | 262 GaimAccount *account; |
6746 | 263 GaimBuddy *bud; |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7100
diff
changeset
|
264 GaimChat *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) | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7100
diff
changeset
|
287 Tcl_SetStringObj(result, ((GaimChat *)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: | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7100
diff
changeset
|
376 cnode = (GaimChat *)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; | |
7156 | 470 int error, argsused, flags = 0; |
6694 | 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) | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7100
diff
changeset
|
602 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), from, what, flags, time(NULL)); |
6694 | 603 else |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7100
diff
changeset
|
604 gaim_conv_im_write(GAIM_CONV_IM(convo), from, what, flags, time(NULL)); |
6694 | 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 | |
6982 | 852 serv_send_im(gc, who, text, 0); |
6694 | 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 } |