gaim/gaim
Clone
Summary
Browse
Changes
Graph
newsination
oldstatus
v1_3_0
2005-05-10, Gary Kramlich
6827d18aed67
newsination
/**
* @file tcl_cmds.c Commands for the Gaim Tcl plugin bindings
*
* gaim
*
* Copyright (C) 2003 Ethan Blanton <eblanton@cs.purdue.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include
<tcl.h>
#include
"internal.h"
#include
"conversation.h"
#include
"connection.h"
#include
"account.h"
#include
"server.h"
#include
"notify.h"
#include
"blist.h"
#include
"debug.h"
#include
"prefs.h"
#include
"core.h"
#include
"tcl_gaim.h"
static
gboolean
tcl_validate_account
(
GaimAccount
*
account
,
Tcl_Interp
*
interp
);
static
gboolean
tcl_validate_gc
(
GaimConnection
*
gc
);
static
gboolean
tcl_validate_account
(
GaimAccount
*
account
,
Tcl_Interp
*
interp
)
{
GList
*
cur
;
for
(
cur
=
gaim_accounts_get_all
();
cur
!=
NULL
;
cur
=
g_list_next
(
cur
))
{
if
(
account
==
cur
->
data
)
return
TRUE
;
}
if
(
interp
!=
NULL
)
Tcl_SetStringObj
(
Tcl_GetObjResult
(
interp
),
"invalid account"
,
-1
);
return
FALSE
;
}
static
gboolean
tcl_validate_conversation
(
GaimConversation
*
convo
,
Tcl_Interp
*
interp
)
{
GList
*
cur
;
for
(
cur
=
gaim_get_conversations
();
cur
!=
NULL
;
cur
=
g_list_next
(
cur
))
{
if
(
convo
==
cur
->
data
)
return
TRUE
;
}
if
(
interp
!=
NULL
)
Tcl_SetStringObj
(
Tcl_GetObjResult
(
interp
),
"invalid account"
,
-1
);
return
FALSE
;
}
static
gboolean
tcl_validate_gc
(
GaimConnection
*
gc
)
{
GList
*
cur
;
for
(
cur
=
gaim_connections_get_all
();
cur
!=
NULL
;
cur
=
g_list_next
(
cur
))
{
if
(
gc
==
cur
->
data
)
return
TRUE
;
}
return
FALSE
;
}
int
tcl_cmd_account
(
ClientData
unused
,
Tcl_Interp
*
interp
,
int
objc
,
Tcl_Obj
*
CONST
objv
[])
{
Tcl_Obj
*
result
=
Tcl_GetObjResult
(
interp
),
*
list
,
*
elem
;
const
char
*
cmds
[]
=
{
"alias"
,
"connect"
,
"connection"
,
"disconnect"
,
"find"
,
"handle"
,
"isconnected"
,
"list"
,
"protocol"
,
"username"
,
NULL
};
enum
{
CMD_ACCOUNT_ALIAS
,
CMD_ACCOUNT_CONNECT
,
CMD_ACCOUNT_CONNECTION
,
CMD_ACCOUNT_DISCONNECT
,
CMD_ACCOUNT_FIND
,
CMD_ACCOUNT_HANDLE
,
CMD_ACCOUNT_ISCONNECTED
,
CMD_ACCOUNT_LIST
,
CMD_ACCOUNT_PROTOCOL
,
CMD_ACCOUNT_USERNAME
}
cmd
;
const
char
*
listopts
[]
=
{
"-all"
,
"-online"
,
NULL
};
enum
{
CMD_ACCOUNTLIST_ALL
,
CMD_ACCOUNTLIST_ONLINE
}
listopt
;
const
char
*
alias
;
GList
*
cur
;
GaimAccount
*
account
;
int
error
;
if
(
objc
<
2
)
{
Tcl_WrongNumArgs
(
interp
,
1
,
objv
,
"subcommand ?args?"
);
return
TCL_ERROR
;
}
if
((
error
=
Tcl_GetIndexFromObj
(
interp
,
objv
[
1
],
cmds
,
"subcommand"
,
0
,
(
int
*
)
&
cmd
))
!=
TCL_OK
)
return
error
;
switch
(
cmd
)
{
case
CMD_ACCOUNT_ALIAS
:
if
(
objc
!=
3
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
"account"
);
return
TCL_ERROR
;
}
error
=
Tcl_GetIntFromObj
(
interp
,
objv
[
2
],
(
int
*
)
&
account
);
if
(
error
||
!
tcl_validate_account
(
account
,
interp
))
return
TCL_ERROR
;
alias
=
gaim_account_get_alias
(
account
);
Tcl_SetStringObj
(
result
,
alias
?
(
char
*
)
alias
:
""
,
-1
);
break
;
case
CMD_ACCOUNT_CONNECT
:
if
(
objc
!=
3
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
"account"
);
return
TCL_ERROR
;
}
error
=
Tcl_GetIntFromObj
(
interp
,
objv
[
2
],
(
int
*
)
&
account
);
if
(
error
||
!
tcl_validate_account
(
account
,
interp
))
return
TCL_ERROR
;
if
(
gaim_account_is_connected
(
account
))
Tcl_SetIntObj
(
result
,
(
int
)
gaim_account_get_connection
(
account
));
else
Tcl_SetIntObj
(
result
,
(
int
)
gaim_account_connect
(
account
));
break
;
case
CMD_ACCOUNT_CONNECTION
:
if
(
objc
!=
3
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
"account"
);
return
TCL_ERROR
;
}
error
=
Tcl_GetIntFromObj
(
interp
,
objv
[
2
],
(
int
*
)
&
account
);
if
(
error
||
!
tcl_validate_account
(
account
,
interp
))
return
TCL_ERROR
;
Tcl_SetIntObj
(
result
,
(
int
)
gaim_account_get_connection
(
account
));
break
;
case
CMD_ACCOUNT_DISCONNECT
:
if
(
objc
!=
3
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
"account"
);
return
TCL_ERROR
;
}
error
=
Tcl_GetIntFromObj
(
interp
,
objv
[
2
],
(
int
*
)
&
account
);
if
(
error
||
!
tcl_validate_account
(
account
,
interp
))
return
TCL_ERROR
;
gaim_account_disconnect
(
account
);
break
;
case
CMD_ACCOUNT_FIND
:
if
(
objc
!=
4
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
"username protocol"
);
return
TCL_ERROR
;
}
Tcl_SetIntObj
(
result
,
(
int
)
gaim_accounts_find
(
Tcl_GetString
(
objv
[
2
]),
Tcl_GetString
(
objv
[
3
])));
break
;
case
CMD_ACCOUNT_HANDLE
:
if
(
objc
!=
2
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
""
);
return
TCL_ERROR
;
}
Tcl_SetIntObj
(
result
,
(
int
)
gaim_accounts_get_handle
());
break
;
case
CMD_ACCOUNT_ISCONNECTED
:
if
(
objc
!=
3
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
"account"
);
return
TCL_ERROR
;
}
error
=
Tcl_GetIntFromObj
(
interp
,
objv
[
2
],
(
int
*
)
&
account
);
if
(
error
||
!
tcl_validate_account
(
account
,
interp
))
return
TCL_ERROR
;
Tcl_SetBooleanObj
(
result
,
gaim_account_is_connected
(
account
));
break
;
case
CMD_ACCOUNT_LIST
:
listopt
=
CMD_ACCOUNTLIST_ALL
;
if
(
objc
>
3
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
"?option?"
);
return
TCL_ERROR
;
}
if
(
objc
==
3
)
{
if
((
error
=
Tcl_GetIndexFromObj
(
interp
,
objv
[
2
],
listopts
,
"option"
,
0
,
(
int
*
)
&
listopt
))
!=
TCL_OK
)
return
error
;
}
list
=
Tcl_NewListObj
(
0
,
NULL
);
for
(
cur
=
gaim_accounts_get_all
();
cur
!=
NULL
;
cur
=
g_list_next
(
cur
))
{
account
=
cur
->
data
;
if
(
listopt
==
CMD_ACCOUNTLIST_ONLINE
&&
!
gaim_account_is_connected
(
account
))
continue
;
elem
=
Tcl_NewIntObj
((
int
)
account
);
Tcl_ListObjAppendElement
(
interp
,
list
,
elem
);
}
Tcl_SetObjResult
(
interp
,
list
);
break
;
case
CMD_ACCOUNT_PROTOCOL
:
if
(
objc
!=
3
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
"account"
);
return
TCL_ERROR
;
}
error
=
Tcl_GetIntFromObj
(
interp
,
objv
[
2
],
(
int
*
)
&
account
);
if
(
error
||
!
tcl_validate_account
(
account
,
interp
))
return
TCL_ERROR
;
Tcl_SetStringObj
(
result
,
(
char
*
)
gaim_account_get_protocol_id
(
account
),
-1
);
break
;
case
CMD_ACCOUNT_USERNAME
:
if
(
objc
!=
3
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
"account"
);
return
TCL_ERROR
;
}
error
=
Tcl_GetIntFromObj
(
interp
,
objv
[
2
],
(
int
*
)
&
account
);
if
(
error
||
!
tcl_validate_account
(
account
,
interp
))
return
TCL_ERROR
;
Tcl_SetStringObj
(
result
,
(
char
*
)
gaim_account_get_username
(
account
),
-1
);
break
;
}
return
TCL_OK
;
}
static
GaimBlistNode
*
tcl_list_to_buddy
(
Tcl_Interp
*
interp
,
int
count
,
Tcl_Obj
**
elems
)
{
GaimBlistNode
*
node
=
NULL
;
GaimAccount
*
account
;
char
*
name
;
char
*
type
;
if
(
count
<
3
)
{
Tcl_SetStringObj
(
Tcl_GetObjResult
(
interp
),
"list too short"
,
-1
);
return
NULL
;
}
type
=
Tcl_GetString
(
elems
[
0
]);
name
=
Tcl_GetString
(
elems
[
1
]);
if
(
Tcl_GetIntFromObj
(
interp
,
elems
[
2
],
(
int
*
)
&
account
)
!=
TCL_OK
)
return
NULL
;
if
(
!
tcl_validate_account
(
account
,
interp
))
return
NULL
;
if
(
!
strcmp
(
type
,
"buddy"
))
{
node
=
(
GaimBlistNode
*
)
gaim_find_buddy
(
account
,
name
);
}
else
if
(
!
strcmp
(
type
,
"group"
))
{
node
=
(
GaimBlistNode
*
)
gaim_blist_find_chat
(
account
,
name
);
}
return
node
;
}
int
tcl_cmd_buddy
(
ClientData
unused
,
Tcl_Interp
*
interp
,
int
objc
,
Tcl_Obj
*
CONST
objv
[])
{
Tcl_Obj
*
list
,
*
tclgroup
,
*
tclgrouplist
,
*
tclcontact
,
*
tclcontactlist
,
*
tclbud
,
**
elems
,
*
result
;
const
char
*
cmds
[]
=
{
"alias"
,
"handle"
,
"info"
,
"list"
,
NULL
};
enum
{
CMD_BUDDY_ALIAS
,
CMD_BUDDY_HANDLE
,
CMD_BUDDY_INFO
,
CMD_BUDDY_LIST
}
cmd
;
GaimBuddyList
*
blist
;
GaimBlistNode
*
node
,
*
gnode
,
*
bnode
;
GaimAccount
*
account
;
GaimBuddy
*
bud
;
GaimChat
*
cnode
;
int
error
,
all
=
0
,
count
;
if
(
objc
<
2
)
{
Tcl_WrongNumArgs
(
interp
,
1
,
objv
,
"subcommand ?args?"
);
return
TCL_ERROR
;
}
if
((
error
=
Tcl_GetIndexFromObj
(
interp
,
objv
[
1
],
cmds
,
"subcommand"
,
0
,
(
int
*
)
&
cmd
))
!=
TCL_OK
)
return
error
;
result
=
Tcl_GetObjResult
(
interp
);
switch
(
cmd
)
{
case
CMD_BUDDY_ALIAS
:
if
(
objc
!=
3
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
"buddy"
);
return
TCL_ERROR
;
}
if
((
error
=
Tcl_ListObjGetElements
(
interp
,
objv
[
2
],
&
count
,
&
elems
))
!=
TCL_OK
)
return
error
;
if
((
node
=
tcl_list_to_buddy
(
interp
,
count
,
elems
))
==
NULL
)
return
TCL_ERROR
;
if
(
node
->
type
==
GAIM_BLIST_CHAT_NODE
)
Tcl_SetStringObj
(
result
,
((
GaimChat
*
)
node
)
->
alias
,
-1
);
else
if
(
node
->
type
==
GAIM_BLIST_BUDDY_NODE
)
Tcl_SetStringObj
(
result
,
(
char
*
)
gaim_buddy_get_alias
((
GaimBuddy
*
)
node
),
-1
);
return
TCL_OK
;
break
;
case
CMD_BUDDY_HANDLE
:
if
(
objc
!=
2
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
""
);
return
TCL_ERROR
;
}
Tcl_SetIntObj
(
result
,
(
int
)
gaim_blist_get_handle
());
break
;
case
CMD_BUDDY_INFO
:
if
(
objc
!=
3
&&
objc
!=
4
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
"( buddy | account username )"
);
return
TCL_ERROR
;
}
if
(
objc
==
3
)
{
if
((
error
=
Tcl_ListObjGetElements
(
interp
,
objv
[
2
],
&
count
,
&
elems
))
!=
TCL_OK
)
return
error
;
if
(
count
<
3
)
{
Tcl_SetStringObj
(
result
,
"buddy too short"
,
-1
);
return
TCL_ERROR
;
}
if
(
strcmp
(
"buddy"
,
Tcl_GetString
(
elems
[
0
])))
{
Tcl_SetStringObj
(
result
,
"invalid buddy"
,
-1
);
return
TCL_ERROR
;
}
if
((
error
=
Tcl_GetIntFromObj
(
interp
,
elems
[
2
],
(
int
*
)
&
account
))
!=
TCL_OK
)
return
TCL_ERROR
;
if
(
!
tcl_validate_account
(
account
,
interp
))
return
TCL_ERROR
;
serv_get_info
(
gaim_account_get_connection
(
account
),
Tcl_GetString
(
elems
[
1
]));
}
else
{
if
((
error
=
Tcl_GetIntFromObj
(
interp
,
objv
[
2
],
(
int
*
)
&
account
))
!=
TCL_OK
)
return
error
;
if
(
!
tcl_validate_account
(
account
,
interp
))
return
TCL_ERROR
;
serv_get_info
(
gaim_account_get_connection
(
account
),
Tcl_GetString
(
objv
[
3
]));
}
break
;
case
CMD_BUDDY_LIST
:
if
(
objc
==
3
)
{
if
(
!
strcmp
(
"-all"
,
Tcl_GetString
(
objv
[
2
])))
{
all
=
1
;
}
else
{
Tcl_SetStringObj
(
result
,
""
,
-1
);
Tcl_AppendStringsToObj
(
result
,
"unknown option: "
,
Tcl_GetString
(
objv
[
2
]),
NULL
);
return
TCL_ERROR
;
}
}
list
=
Tcl_NewListObj
(
0
,
NULL
);
blist
=
gaim_get_blist
();
for
(
gnode
=
blist
->
root
;
gnode
!=
NULL
;
gnode
=
gnode
->
next
)
{
tclgroup
=
Tcl_NewListObj
(
0
,
NULL
);
Tcl_ListObjAppendElement
(
interp
,
tclgroup
,
Tcl_NewStringObj
(
"group"
,
-1
));
Tcl_ListObjAppendElement
(
interp
,
tclgroup
,
Tcl_NewStringObj
(((
GaimGroup
*
)
gnode
)
->
name
,
-1
));
tclgrouplist
=
Tcl_NewListObj
(
0
,
NULL
);
for
(
node
=
gnode
->
child
;
node
!=
NULL
;
node
=
node
->
next
)
{
switch
(
node
->
type
)
{
case
GAIM_BLIST_CONTACT_NODE
:
tclcontact
=
Tcl_NewListObj
(
0
,
NULL
);
Tcl_IncrRefCount
(
tclcontact
);
Tcl_ListObjAppendElement
(
interp
,
tclcontact
,
Tcl_NewStringObj
(
"contact"
,
-1
));
tclcontactlist
=
Tcl_NewListObj
(
0
,
NULL
);
Tcl_IncrRefCount
(
tclcontactlist
);
count
=
0
;
for
(
bnode
=
node
->
child
;
bnode
!=
NULL
;
bnode
=
bnode
->
next
)
{
if
(
bnode
->
type
!=
GAIM_BLIST_BUDDY_NODE
)
continue
;
bud
=
(
GaimBuddy
*
)
bnode
;
if
(
!
all
&&
!
gaim_account_is_connected
(
bud
->
account
))
continue
;
count
++
;
tclbud
=
Tcl_NewListObj
(
0
,
NULL
);
Tcl_ListObjAppendElement
(
interp
,
tclbud
,
Tcl_NewStringObj
(
"buddy"
,
-1
));
Tcl_ListObjAppendElement
(
interp
,
tclbud
,
Tcl_NewStringObj
(
bud
->
name
,
-1
));
Tcl_ListObjAppendElement
(
interp
,
tclbud
,
Tcl_NewIntObj
((
int
)
bud
->
account
));
Tcl_ListObjAppendElement
(
interp
,
tclcontactlist
,
tclbud
);
}
if
(
count
)
{
Tcl_ListObjAppendElement
(
interp
,
tclcontact
,
tclcontactlist
);
Tcl_ListObjAppendElement
(
interp
,
tclgrouplist
,
tclcontact
);
}
Tcl_DecrRefCount
(
tclcontact
);
Tcl_DecrRefCount
(
tclcontactlist
);
break
;
case
GAIM_BLIST_CHAT_NODE
:
cnode
=
(
GaimChat
*
)
node
;
if
(
!
all
&&
!
gaim_account_is_connected
(
cnode
->
account
))
continue
;
tclbud
=
Tcl_NewListObj
(
0
,
NULL
);
Tcl_ListObjAppendElement
(
interp
,
tclbud
,
Tcl_NewStringObj
(
"chat"
,
-1
));
Tcl_ListObjAppendElement
(
interp
,
tclbud
,
Tcl_NewStringObj
(
cnode
->
alias
,
-1
));
Tcl_ListObjAppendElement
(
interp
,
tclbud
,
Tcl_NewIntObj
((
int
)
cnode
->
account
));
Tcl_ListObjAppendElement
(
interp
,
tclgrouplist
,
tclbud
);
break
;
default
:
gaim_debug
(
GAIM_DEBUG_WARNING
,
"tcl"
,
"Unexpected buddy type %d"
,
node
->
type
);
continue
;
}
}
Tcl_ListObjAppendElement
(
interp
,
tclgroup
,
tclgrouplist
);
Tcl_ListObjAppendElement
(
interp
,
list
,
tclgroup
);
}
Tcl_SetObjResult
(
interp
,
list
);
break
;
}
return
TCL_OK
;
}
int
tcl_cmd_connection
(
ClientData
unused
,
Tcl_Interp
*
interp
,
int
objc
,
Tcl_Obj
*
CONST
objv
[])
{
Tcl_Obj
*
result
=
Tcl_GetObjResult
(
interp
),
*
list
,
*
elem
;
const
char
*
cmds
[]
=
{
"account"
,
"displayname"
,
"handle"
,
"list"
,
NULL
};
enum
{
CMD_CONN_ACCOUNT
,
CMD_CONN_DISPLAYNAME
,
CMD_CONN_HANDLE
,
CMD_CONN_LIST
}
cmd
;
int
error
;
GList
*
cur
;
GaimConnection
*
gc
;
if
(
objc
<
2
)
{
Tcl_WrongNumArgs
(
interp
,
1
,
objv
,
"subcommand ?args?"
);
return
TCL_ERROR
;
}
if
((
error
=
Tcl_GetIndexFromObj
(
interp
,
objv
[
1
],
cmds
,
"subcommand"
,
0
,
(
int
*
)
&
cmd
))
!=
TCL_OK
)
return
error
;
switch
(
cmd
)
{
case
CMD_CONN_ACCOUNT
:
if
(
objc
!=
3
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
"gc"
);
return
TCL_ERROR
;
}
error
=
Tcl_GetIntFromObj
(
interp
,
objv
[
2
],
(
int
*
)
&
gc
);
if
(
error
||
!
tcl_validate_gc
(
gc
))
{
Tcl_SetStringObj
(
result
,
"invalid gc"
,
-1
);
return
TCL_ERROR
;
}
Tcl_SetIntObj
(
result
,
(
int
)
gaim_connection_get_account
(
gc
));
break
;
case
CMD_CONN_DISPLAYNAME
:
if
(
objc
!=
3
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
"gc"
);
return
TCL_ERROR
;
}
error
=
Tcl_GetIntFromObj
(
interp
,
objv
[
2
],
(
int
*
)
&
gc
);
if
(
error
||
!
tcl_validate_gc
(
gc
))
{
Tcl_SetStringObj
(
result
,
"invalid gc"
,
-1
);
return
TCL_ERROR
;
}
Tcl_SetStringObj
(
result
,
(
char
*
)
gaim_connection_get_display_name
(
gc
),
-1
);
break
;
case
CMD_CONN_HANDLE
:
if
(
objc
!=
2
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
""
);
return
TCL_ERROR
;
}
Tcl_SetIntObj
(
result
,
(
int
)
gaim_connections_get_handle
());
break
;
case
CMD_CONN_LIST
:
if
(
objc
!=
2
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
""
);
return
TCL_ERROR
;
}
list
=
Tcl_NewListObj
(
0
,
NULL
);
for
(
cur
=
gaim_connections_get_all
();
cur
!=
NULL
;
cur
=
g_list_next
(
cur
))
{
elem
=
Tcl_NewIntObj
((
int
)
cur
->
data
);
Tcl_ListObjAppendElement
(
interp
,
list
,
elem
);
}
Tcl_SetObjResult
(
interp
,
list
);
break
;
}
return
TCL_OK
;
}
int
tcl_cmd_conversation
(
ClientData
unused
,
Tcl_Interp
*
interp
,
int
objc
,
Tcl_Obj
*
CONST
objv
[])
{
Tcl_Obj
*
list
,
*
elem
,
*
result
=
Tcl_GetObjResult
(
interp
);
const
char
*
cmds
[]
=
{
"find"
,
"handle"
,
"list"
,
"new"
,
"write"
,
NULL
};
enum
{
CMD_CONV_FIND
,
CMD_CONV_HANDLE
,
CMD_CONV_LIST
,
CMD_CONV_NEW
,
CMD_CONV_WRITE
}
cmd
;
const
char
*
styles
[]
=
{
"send"
,
"recv"
,
"system"
,
NULL
};
enum
{
CMD_CONV_WRITE_SEND
,
CMD_CONV_WRITE_RECV
,
CMD_CONV_WRITE_SYSTEM
}
style
;
const
char
*
findopts
[]
=
{
"-account"
,
NULL
};
enum
{
CMD_CONV_FIND_ACCOUNT
}
findopt
;
const
char
*
newopts
[]
=
{
"-chat"
,
"-im"
};
enum
{
CMD_CONV_NEW_CHAT
,
CMD_CONV_NEW_IM
}
newopt
;
GaimConversation
*
convo
;
GaimAccount
*
account
;
GaimConversationType
type
;
GList
*
cur
;
char
*
opt
,
*
from
,
*
what
;
int
error
,
argsused
,
flags
=
0
;
if
(
objc
<
2
)
{
Tcl_WrongNumArgs
(
interp
,
1
,
objv
,
"subcommand ?args?"
);
return
TCL_ERROR
;
}
if
((
error
=
Tcl_GetIndexFromObj
(
interp
,
objv
[
1
],
cmds
,
"subcommand"
,
0
,
(
int
*
)
&
cmd
))
!=
TCL_OK
)
return
error
;
switch
(
cmd
)
{
case
CMD_CONV_FIND
:
if
(
objc
<
3
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
"?options? name"
);
return
TCL_ERROR
;
}
argsused
=
2
;
account
=
NULL
;
while
(
argsused
<
objc
)
{
opt
=
Tcl_GetString
(
objv
[
argsused
]);
if
(
*
opt
==
'-'
)
{
if
((
error
=
Tcl_GetIndexFromObj
(
interp
,
objv
[
argsused
],
findopts
,
"option"
,
0
,
(
int
*
)
&
findopt
))
!=
TCL_OK
)
return
error
;
argsused
++
;
switch
(
findopt
)
{
case
CMD_CONV_FIND_ACCOUNT
:
if
(
argsused
==
objc
-
1
)
{
Tcl_SetStringObj
(
result
,
"-account requires an argument"
,
-1
);
return
TCL_ERROR
;
}
if
((
error
=
Tcl_GetIntFromObj
(
interp
,
objv
[
argsused
],
(
int
*
)
&
account
))
!=
TCL_OK
)
return
error
;
if
(
!
tcl_validate_account
(
account
,
interp
))
return
TCL_ERROR
;
argsused
++
;
break
;
}
}
else
{
break
;
}
}
if
(
objc
-
argsused
!=
1
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
"?options? name"
);
return
error
;
}
if
(
account
!=
NULL
)
{
convo
=
gaim_find_conversation_with_account
(
Tcl_GetString
(
objv
[
argsused
]),
account
);
}
else
{
convo
=
gaim_find_conversation
(
Tcl_GetString
(
objv
[
argsused
]));
}
Tcl_SetIntObj
(
result
,
(
int
)
convo
);
break
;
case
CMD_CONV_HANDLE
:
if
(
objc
!=
2
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
""
);
return
TCL_ERROR
;
}
Tcl_SetIntObj
(
result
,
(
int
)
gaim_conversations_get_handle
());
break
;
case
CMD_CONV_LIST
:
list
=
Tcl_NewListObj
(
0
,
NULL
);
for
(
cur
=
gaim_get_conversations
();
cur
!=
NULL
;
cur
=
g_list_next
(
cur
))
{
elem
=
Tcl_NewIntObj
((
int
)
cur
->
data
);
Tcl_ListObjAppendElement
(
interp
,
list
,
elem
);
}
Tcl_SetObjResult
(
interp
,
list
);
break
;
case
CMD_CONV_NEW
:
if
(
objc
<
4
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
"?options? account name"
);
return
TCL_ERROR
;
}
argsused
=
2
;
type
=
GAIM_CONV_IM
;
while
(
argsused
<
objc
)
{
opt
=
Tcl_GetString
(
objv
[
argsused
]);
if
(
*
opt
==
'-'
)
{
if
((
error
=
Tcl_GetIndexFromObj
(
interp
,
objv
[
argsused
],
newopts
,
"option"
,
0
,
(
int
*
)
&
newopt
))
!=
TCL_OK
)
return
error
;
argsused
++
;
switch
(
newopt
)
{
case
CMD_CONV_NEW_CHAT
:
type
=
GAIM_CONV_CHAT
;
break
;
case
CMD_CONV_NEW_IM
:
type
=
GAIM_CONV_IM
;
break
;
}
}
else
{
break
;
}
}
if
(
objc
-
argsused
!=
2
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
"?options? account name"
);
return
TCL_ERROR
;
}
if
((
error
=
Tcl_GetIntFromObj
(
interp
,
objv
[
argsused
++
],
(
int
*
)
&
account
))
!=
TCL_OK
)
return
error
;
if
(
!
tcl_validate_account
(
account
,
interp
))
return
TCL_ERROR
;
convo
=
gaim_conversation_new
(
type
,
account
,
Tcl_GetString
(
objv
[
argsused
]));
Tcl_SetIntObj
(
result
,
(
int
)
convo
);
break
;
case
CMD_CONV_WRITE
:
if
(
objc
!=
6
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
"conversation style from what"
);
return
TCL_ERROR
;
}
if
((
error
=
Tcl_GetIntFromObj
(
interp
,
objv
[
2
],
(
int
*
)
&
convo
))
!=
TCL_OK
)
return
error
;
if
((
error
=
Tcl_GetIndexFromObj
(
interp
,
objv
[
3
],
styles
,
"style"
,
0
,
(
int
*
)
&
style
))
!=
TCL_OK
)
return
error
;
if
(
!
tcl_validate_conversation
(
convo
,
interp
))
return
TCL_ERROR
;
from
=
Tcl_GetString
(
objv
[
4
]);
what
=
Tcl_GetString
(
objv
[
5
]);
switch
(
style
)
{
case
CMD_CONV_WRITE_SEND
:
flags
=
GAIM_MESSAGE_SEND
;
break
;
case
CMD_CONV_WRITE_RECV
:
flags
=
GAIM_MESSAGE_RECV
;
break
;
case
CMD_CONV_WRITE_SYSTEM
:
flags
=
GAIM_MESSAGE_SYSTEM
;
break
;
}
if
(
gaim_conversation_get_type
(
convo
)
==
GAIM_CONV_CHAT
)
gaim_conv_chat_write
(
GAIM_CONV_CHAT
(
convo
),
from
,
what
,
flags
,
time
(
NULL
));
else
gaim_conv_im_write
(
GAIM_CONV_IM
(
convo
),
from
,
what
,
flags
,
time
(
NULL
));
break
;
}
return
TCL_OK
;
}
int
tcl_cmd_core
(
ClientData
unused
,
Tcl_Interp
*
interp
,
int
objc
,
Tcl_Obj
*
CONST
objv
[])
{
Tcl_Obj
*
result
=
Tcl_GetObjResult
(
interp
);
const
char
*
cmds
[]
=
{
"handle"
,
"quit"
,
NULL
};
enum
{
CMD_CORE_HANDLE
,
CMD_CORE_QUIT
}
cmd
;
int
error
;
if
(
objc
<
2
)
{
Tcl_WrongNumArgs
(
interp
,
1
,
objv
,
"subcommand ?args?"
);
return
TCL_ERROR
;
}
if
((
error
=
Tcl_GetIndexFromObj
(
interp
,
objv
[
1
],
cmds
,
"subcommand"
,
0
,
(
int
*
)
&
cmd
))
!=
TCL_OK
)
return
error
;
switch
(
cmd
)
{
case
CMD_CORE_HANDLE
:
if
(
objc
!=
2
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
""
);
return
TCL_ERROR
;
}
Tcl_SetIntObj
(
result
,
(
int
)
gaim_get_core
());
break
;
case
CMD_CORE_QUIT
:
if
(
objc
!=
2
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
""
);
return
TCL_ERROR
;
}
gaim_core_quit
();
break
;
}
return
TCL_OK
;
}
int
tcl_cmd_debug
(
ClientData
unused
,
Tcl_Interp
*
interp
,
int
objc
,
Tcl_Obj
*
CONST
objv
[])
{
char
*
category
,
*
message
;
int
lev
;
const
char
*
levels
[]
=
{
"-misc"
,
"-info"
,
"-warning"
,
"-error"
,
NULL
};
GaimDebugLevel
levelind
[]
=
{
GAIM_DEBUG_MISC
,
GAIM_DEBUG_INFO
,
GAIM_DEBUG_WARNING
,
GAIM_DEBUG_ERROR
};
int
error
;
if
(
objc
!=
4
)
{
Tcl_WrongNumArgs
(
interp
,
1
,
objv
,
"level category message"
);
return
TCL_ERROR
;
}
error
=
Tcl_GetIndexFromObj
(
interp
,
objv
[
1
],
levels
,
"debug level"
,
0
,
&
lev
);
if
(
error
!=
TCL_OK
)
return
error
;
category
=
Tcl_GetString
(
objv
[
2
]);
message
=
Tcl_GetString
(
objv
[
3
]);
gaim_debug
(
levelind
[
lev
],
category
,
"%s
\n
"
,
message
);
return
TCL_OK
;
}
int
tcl_cmd_notify
(
ClientData
unused
,
Tcl_Interp
*
interp
,
int
objc
,
Tcl_Obj
*
CONST
objv
[])
{
int
error
,
type
;
const
char
*
opts
[]
=
{
"-error"
,
"-warning"
,
"-info"
,
NULL
};
GaimNotifyMsgType
optind
[]
=
{
GAIM_NOTIFY_MSG_ERROR
,
GAIM_NOTIFY_MSG_WARNING
,
GAIM_NOTIFY_MSG_INFO
};
char
*
title
,
*
msg1
,
*
msg2
;
if
(
objc
<
4
||
objc
>
5
)
{
Tcl_WrongNumArgs
(
interp
,
1
,
objv
,
"?type? title primary secondary"
);
return
TCL_ERROR
;
}
if
(
objc
==
4
)
{
title
=
Tcl_GetString
(
objv
[
1
]);
msg1
=
Tcl_GetString
(
objv
[
2
]);
msg2
=
Tcl_GetString
(
objv
[
3
]);
}
else
{
error
=
Tcl_GetIndexFromObj
(
interp
,
objv
[
1
],
opts
,
"message type"
,
0
,
&
type
);
if
(
error
!=
TCL_OK
)
return
error
;
title
=
Tcl_GetString
(
objv
[
2
]);
msg1
=
Tcl_GetString
(
objv
[
3
]);
msg2
=
Tcl_GetString
(
objv
[
4
]);
}
gaim_notify_message
(
_tcl_plugin
,
optind
[
type
],
title
,
msg1
,
msg2
,
NULL
,
NULL
);
return
TCL_OK
;
}
int
tcl_cmd_prefs
(
ClientData
unused
,
Tcl_Interp
*
interp
,
int
objc
,
Tcl_Obj
*
CONST
objv
[])
{
Tcl_Obj
*
result
,
*
list
,
*
elem
,
**
elems
;
const
char
*
cmds
[]
=
{
"get"
,
"set"
,
"type"
,
NULL
};
enum
{
CMD_PREFS_GET
,
CMD_PREFS_SET
,
CMD_PREFS_TYPE
}
cmd
;
/* char *types[] = { "none", "boolean", "int", "string", "stringlist", NULL }; */
/* enum { TCL_PREFS_NONE, TCL_PREFS_BOOL, TCL_PREFS_INT, TCL_PREFS_STRING, TCL_PREFS_STRINGLIST } type; */
GaimPrefType
preftype
;
GList
*
cur
;
int
error
,
intval
,
nelem
,
i
;
if
(
objc
<
2
)
{
Tcl_WrongNumArgs
(
interp
,
1
,
objv
,
"subcommand ?args?"
);
return
TCL_ERROR
;
}
if
((
error
=
Tcl_GetIndexFromObj
(
interp
,
objv
[
1
],
cmds
,
"subcommand"
,
0
,
(
int
*
)
&
cmd
))
!=
TCL_OK
)
return
error
;
result
=
Tcl_GetObjResult
(
interp
);
switch
(
cmd
)
{
case
CMD_PREFS_GET
:
if
(
objc
!=
3
)
{
Tcl_WrongNumArgs
(
interp
,
1
,
objv
,
"path"
);
return
TCL_ERROR
;
}
preftype
=
gaim_prefs_get_type
(
Tcl_GetString
(
objv
[
2
]));
switch
(
preftype
)
{
case
GAIM_PREF_NONE
:
Tcl_SetStringObj
(
result
,
"pref type none"
,
-1
);
return
TCL_ERROR
;
break
;
case
GAIM_PREF_BOOLEAN
:
Tcl_SetBooleanObj
(
result
,
gaim_prefs_get_bool
(
Tcl_GetString
(
objv
[
2
])));
break
;
case
GAIM_PREF_INT
:
Tcl_SetIntObj
(
result
,
gaim_prefs_get_int
(
Tcl_GetString
(
objv
[
2
])));
break
;
case
GAIM_PREF_STRING
:
Tcl_SetStringObj
(
result
,
(
char
*
)
gaim_prefs_get_string
(
Tcl_GetString
(
objv
[
2
])),
-1
);
break
;
case
GAIM_PREF_STRING_LIST
:
cur
=
gaim_prefs_get_string_list
(
Tcl_GetString
(
objv
[
2
]));
list
=
Tcl_NewListObj
(
0
,
NULL
);
while
(
cur
!=
NULL
)
{
elem
=
Tcl_NewStringObj
((
char
*
)
cur
->
data
,
-1
);
Tcl_ListObjAppendElement
(
interp
,
list
,
elem
);
cur
=
g_list_next
(
cur
);
}
Tcl_SetObjResult
(
interp
,
list
);
break
;
default
:
gaim_debug
(
GAIM_DEBUG_ERROR
,
"tcl"
,
"tcl does not know about pref type %d
\n
"
,
preftype
);
Tcl_SetStringObj
(
result
,
"unknown pref type"
,
-1
);
return
TCL_ERROR
;
}
break
;
case
CMD_PREFS_SET
:
if
(
objc
!=
4
)
{
Tcl_WrongNumArgs
(
interp
,
1
,
objv
,
"path value"
);
return
TCL_ERROR
;
}
preftype
=
gaim_prefs_get_type
(
Tcl_GetString
(
objv
[
2
]));
switch
(
preftype
)
{
case
GAIM_PREF_NONE
:
Tcl_SetStringObj
(
result
,
"bad path or pref type none"
,
-1
);
return
TCL_ERROR
;
break
;
case
GAIM_PREF_BOOLEAN
:
if
((
error
=
Tcl_GetBooleanFromObj
(
interp
,
objv
[
3
],
&
intval
))
!=
TCL_OK
)
return
error
;
gaim_prefs_set_bool
(
Tcl_GetString
(
objv
[
2
]),
intval
);
break
;
case
GAIM_PREF_INT
:
if
((
error
=
Tcl_GetIntFromObj
(
interp
,
objv
[
3
],
&
intval
))
!=
TCL_OK
)
return
error
;
gaim_prefs_set_int
(
Tcl_GetString
(
objv
[
2
]),
intval
);
break
;
case
GAIM_PREF_STRING
:
gaim_prefs_set_string
(
Tcl_GetString
(
objv
[
2
]),
Tcl_GetString
(
objv
[
3
]));
break
;
case
GAIM_PREF_STRING_LIST
:
if
((
error
=
Tcl_ListObjGetElements
(
interp
,
objv
[
3
],
&
nelem
,
&
elems
))
!=
TCL_OK
)
return
error
;
cur
=
NULL
;
for
(
i
=
0
;
i
<
nelem
;
i
++
)
{
cur
=
g_list_append
(
cur
,
(
gpointer
)
Tcl_GetString
(
elems
[
i
]));
}
gaim_prefs_set_string_list
(
Tcl_GetString
(
objv
[
2
]),
cur
);
g_list_free
(
cur
);
break
;
default
:
gaim_debug
(
GAIM_DEBUG_ERROR
,
"tcl"
,
"tcl does not know about pref type %d
\n
"
,
preftype
);
return
TCL_ERROR
;
}
break
;
case
CMD_PREFS_TYPE
:
if
(
objc
!=
3
)
{
Tcl_WrongNumArgs
(
interp
,
1
,
objv
,
"path"
);
return
TCL_ERROR
;
}
preftype
=
gaim_prefs_get_type
(
Tcl_GetString
(
objv
[
2
]));
switch
(
preftype
)
{
case
GAIM_PREF_NONE
:
Tcl_SetStringObj
(
result
,
"none"
,
-1
);
break
;
case
GAIM_PREF_BOOLEAN
:
Tcl_SetStringObj
(
result
,
"boolean"
,
-1
);
break
;
case
GAIM_PREF_INT
:
Tcl_SetStringObj
(
result
,
"int"
,
-1
);
break
;
case
GAIM_PREF_STRING
:
Tcl_SetStringObj
(
result
,
"string"
,
-1
);
break
;
case
GAIM_PREF_STRING_LIST
:
Tcl_SetStringObj
(
result
,
"stringlist"
,
-1
);
break
;
default
:
gaim_debug
(
GAIM_DEBUG_ERROR
,
"tcl"
,
"tcl does not know about pref type %d
\n
"
,
preftype
);
Tcl_SetStringObj
(
result
,
"unknown"
,
-1
);
}
break
;
}
return
TCL_OK
;
}
int
tcl_cmd_send_im
(
ClientData
unused
,
Tcl_Interp
*
interp
,
int
objc
,
Tcl_Obj
*
CONST
objv
[])
{
GaimConnection
*
gc
;
char
*
who
,
*
text
;
int
error
;
Tcl_Obj
*
result
;
if
(
objc
!=
4
)
{
Tcl_WrongNumArgs
(
interp
,
1
,
objv
,
"gc who text"
);
return
TCL_ERROR
;
}
if
((
error
=
Tcl_GetIntFromObj
(
interp
,
objv
[
1
],
(
int
*
)
&
gc
))
!=
TCL_OK
)
return
error
;
if
(
!
tcl_validate_gc
(
gc
))
{
result
=
Tcl_GetObjResult
(
interp
);
Tcl_SetStringObj
(
result
,
"invalid gc"
,
-1
);
return
TCL_ERROR
;
}
who
=
Tcl_GetString
(
objv
[
2
]);
text
=
Tcl_GetString
(
objv
[
3
]);
serv_send_im
(
gc
,
who
,
text
,
0
);
return
TCL_OK
;
}
int
tcl_cmd_signal
(
ClientData
unused
,
Tcl_Interp
*
interp
,
int
objc
,
Tcl_Obj
*
CONST
objv
[])
{
const
char
*
cmds
[]
=
{
"connect"
,
"disconnect"
,
NULL
};
enum
{
CMD_SIGNAL_CONNECT
,
CMD_SIGNAL_DISCONNECT
}
cmd
;
struct
tcl_signal_handler
*
handler
;
Tcl_Obj
**
elems
,
*
result
=
Tcl_GetObjResult
(
interp
);
void
*
instance
;
int
error
,
nelems
,
i
;
if
(
objc
<
2
)
{
Tcl_WrongNumArgs
(
interp
,
1
,
objv
,
"subcommand ?args?"
);
return
TCL_ERROR
;
}
if
((
error
=
Tcl_GetIndexFromObj
(
interp
,
objv
[
1
],
cmds
,
"subcommand"
,
0
,
(
int
*
)
&
cmd
))
!=
TCL_OK
)
return
error
;
switch
(
cmd
)
{
case
CMD_SIGNAL_CONNECT
:
if
(
objc
!=
6
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
"instance signal args proc"
);
return
TCL_ERROR
;
}
if
((
error
=
Tcl_ListObjGetElements
(
interp
,
objv
[
4
],
&
nelems
,
&
elems
))
!=
TCL_OK
)
return
error
;
handler
=
g_new0
(
struct
tcl_signal_handler
,
1
);
if
((
error
=
Tcl_GetIntFromObj
(
interp
,
objv
[
2
],
(
int
*
)
&
handler
->
instance
))
!=
TCL_OK
)
{
g_free
(
handler
);
return
error
;
}
handler
->
signal
=
g_strdup
(
Tcl_GetString
(
objv
[
3
]));
if
(
nelems
)
{
handler
->
argnames
=
g_new0
(
char
*
,
nelems
);
for
(
i
=
0
;
i
<
nelems
;
i
++
)
{
handler
->
argnames
[
i
]
=
g_strdup
(
Tcl_GetString
(
elems
[
i
]));
}
}
handler
->
nnames
=
nelems
;
handler
->
proc
=
Tcl_NewStringObj
(
"namespace eval ::gaim::_callback { "
,
-1
);
Tcl_AppendStringsToObj
(
handler
->
proc
,
Tcl_GetString
(
objv
[
5
]),
" }"
,
NULL
);
Tcl_IncrRefCount
(
handler
->
proc
);
handler
->
interp
=
interp
;
if
(
!
tcl_signal_connect
(
handler
))
{
tcl_signal_handler_free
(
handler
);
Tcl_SetIntObj
(
result
,
1
);
}
else
{
Tcl_SetIntObj
(
result
,
0
);
}
break
;
case
CMD_SIGNAL_DISCONNECT
:
if
(
objc
!=
4
)
{
Tcl_WrongNumArgs
(
interp
,
2
,
objv
,
"signal"
);
return
TCL_ERROR
;
}
if
((
error
=
Tcl_GetIntFromObj
(
interp
,
objv
[
2
],
(
int
*
)
&
instance
))
!=
TCL_OK
)
return
error
;
tcl_signal_disconnect
(
instance
,
Tcl_GetString
(
objv
[
3
]),
interp
);
break
;
}
return
TCL_OK
;
}
static
gboolean
unload_self
(
gpointer
data
)
{
GaimPlugin
*
plugin
=
data
;
gaim_plugin_unload
(
plugin
);
return
FALSE
;
}
int
tcl_cmd_unload
(
ClientData
unused
,
Tcl_Interp
*
interp
,
int
objc
,
Tcl_Obj
*
CONST
objv
[])
{
GaimPlugin
*
plugin
;
if
(
objc
!=
1
)
{
Tcl_WrongNumArgs
(
interp
,
1
,
objv
,
""
);
return
TCL_ERROR
;
}
if
((
plugin
=
tcl_interp_get_plugin
(
interp
))
==
NULL
)
{
/* This isn't exactly OK, but heh. What do you do? */
return
TCL_OK
;
}
/* We can't unload immediately, but we can unload at the first
* known safe opportunity. */
g_idle_add
(
unload_self
,
(
gpointer
)
plugin
);
return
TCL_OK
;
}