qulogic/pidgin
Clone
Summary
Browse
Changes
Graph
merge of 'e91f57b507c8c0f946f9c4646b4851b3345df1c6'
release-2.2.1
2007-10-01, Luke Schierer
0ef161c44415
merge of 'e91f57b507c8c0f946f9c4646b4851b3345df1c6'
and '82e9073951f69854ef77a01dcbb02a5aae6b5d88'
/**
* @file account.c Account API
* @ingroup core
*/
/* purple
*
* Purple is the legal property of its developers, whose names are too numerous
* to list here. Please refer to the COPYRIGHT file distributed with this
* source distribution.
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#include
"internal.h"
#include
"account.h"
#include
"core.h"
#include
"dbus-maybe.h"
#include
"debug.h"
#include
"network.h"
#include
"notify.h"
#include
"pounce.h"
#include
"prefs.h"
#include
"privacy.h"
#include
"prpl.h"
#include
"request.h"
#include
"server.h"
#include
"signals.h"
#include
"status.h"
#include
"util.h"
#include
"xmlnode.h"
/* TODO: Should use PurpleValue instead of this? What about "ui"? */
typedef
struct
{
PurplePrefType
type
;
char
*
ui
;
union
{
int
integer
;
char
*
string
;
gboolean
bool
;
}
value
;
}
PurpleAccountSetting
;
typedef
struct
{
PurpleAccountRequestType
type
;
PurpleAccount
*
account
;
void
*
ui_handle
;
}
PurpleAccountRequestInfo
;
static
PurpleAccountUiOps
*
account_ui_ops
=
NULL
;
static
GList
*
accounts
=
NULL
;
static
guint
save_timer
=
0
;
static
gboolean
accounts_loaded
=
FALSE
;
static
GList
*
handles
=
NULL
;
/*********************************************************************
* Writing to disk *
*********************************************************************/
static
void
setting_to_xmlnode
(
gpointer
key
,
gpointer
value
,
gpointer
user_data
)
{
const
char
*
name
;
PurpleAccountSetting
*
setting
;
xmlnode
*
node
,
*
child
;
char
buf
[
20
];
name
=
(
const
char
*
)
key
;
setting
=
(
PurpleAccountSetting
*
)
value
;
node
=
(
xmlnode
*
)
user_data
;
child
=
xmlnode_new_child
(
node
,
"setting"
);
xmlnode_set_attrib
(
child
,
"name"
,
name
);
if
(
setting
->
type
==
PURPLE_PREF_INT
)
{
xmlnode_set_attrib
(
child
,
"type"
,
"int"
);
snprintf
(
buf
,
sizeof
(
buf
),
"%d"
,
setting
->
value
.
integer
);
xmlnode_insert_data
(
child
,
buf
,
-1
);
}
else
if
(
setting
->
type
==
PURPLE_PREF_STRING
&&
setting
->
value
.
string
!=
NULL
)
{
xmlnode_set_attrib
(
child
,
"type"
,
"string"
);
xmlnode_insert_data
(
child
,
setting
->
value
.
string
,
-1
);
}
else
if
(
setting
->
type
==
PURPLE_PREF_BOOLEAN
)
{
xmlnode_set_attrib
(
child
,
"type"
,
"bool"
);
snprintf
(
buf
,
sizeof
(
buf
),
"%d"
,
setting
->
value
.
bool
);
xmlnode_insert_data
(
child
,
buf
,
-1
);
}
}
static
void
ui_setting_to_xmlnode
(
gpointer
key
,
gpointer
value
,
gpointer
user_data
)
{
const
char
*
ui
;
GHashTable
*
table
;
xmlnode
*
node
,
*
child
;
ui
=
(
const
char
*
)
key
;
table
=
(
GHashTable
*
)
value
;
node
=
(
xmlnode
*
)
user_data
;
if
(
g_hash_table_size
(
table
)
>
0
)
{
child
=
xmlnode_new_child
(
node
,
"settings"
);
xmlnode_set_attrib
(
child
,
"ui"
,
ui
);
g_hash_table_foreach
(
table
,
setting_to_xmlnode
,
child
);
}
}
static
xmlnode
*
status_attr_to_xmlnode
(
const
PurpleStatus
*
status
,
const
PurpleStatusType
*
type
,
const
PurpleStatusAttr
*
attr
)
{
xmlnode
*
node
;
const
char
*
id
;
char
*
value
=
NULL
;
PurpleStatusAttr
*
default_attr
;
PurpleValue
*
default_value
;
PurpleType
attr_type
;
PurpleValue
*
attr_value
;
id
=
purple_status_attr_get_id
(
attr
);
g_return_val_if_fail
(
id
,
NULL
);
attr_value
=
purple_status_get_attr_value
(
status
,
id
);
g_return_val_if_fail
(
attr_value
,
NULL
);
attr_type
=
purple_value_get_type
(
attr_value
);
/*
* If attr_value is a different type than it should be
* then don't write it to the file.
*/
default_attr
=
purple_status_type_get_attr
(
type
,
id
);
default_value
=
purple_status_attr_get_value
(
default_attr
);
if
(
attr_type
!=
purple_value_get_type
(
default_value
))
return
NULL
;
/*
* If attr_value is the same as the default for this status
* then there is no need to write it to the file.
*/
if
(
attr_type
==
PURPLE_TYPE_STRING
)
{
const
char
*
string_value
=
purple_value_get_string
(
attr_value
);
const
char
*
default_string_value
=
purple_value_get_string
(
default_value
);
if
(((
string_value
==
NULL
)
&&
(
default_string_value
==
NULL
))
||
((
string_value
!=
NULL
)
&&
(
default_string_value
!=
NULL
)
&&
!
strcmp
(
string_value
,
default_string_value
)))
return
NULL
;
value
=
g_strdup
(
purple_value_get_string
(
attr_value
));
}
else
if
(
attr_type
==
PURPLE_TYPE_INT
)
{
int
int_value
=
purple_value_get_int
(
attr_value
);
if
(
int_value
==
purple_value_get_int
(
default_value
))
return
NULL
;
value
=
g_strdup_printf
(
"%d"
,
int_value
);
}
else
if
(
attr_type
==
PURPLE_TYPE_BOOLEAN
)
{
gboolean
boolean_value
=
purple_value_get_boolean
(
attr_value
);
if
(
boolean_value
==
purple_value_get_boolean
(
default_value
))
return
NULL
;
value
=
g_strdup
(
boolean_value
?
"true"
:
"false"
);
}
else
{
return
NULL
;
}
g_return_val_if_fail
(
value
,
NULL
);
node
=
xmlnode_new
(
"attribute"
);
xmlnode_set_attrib
(
node
,
"id"
,
id
);
xmlnode_set_attrib
(
node
,
"value"
,
value
);
g_free
(
value
);
return
node
;
}
static
xmlnode
*
status_attrs_to_xmlnode
(
const
PurpleStatus
*
status
)
{
PurpleStatusType
*
type
=
purple_status_get_type
(
status
);
xmlnode
*
node
,
*
child
;
GList
*
attrs
,
*
attr
;
node
=
xmlnode_new
(
"attributes"
);
attrs
=
purple_status_type_get_attrs
(
type
);
for
(
attr
=
attrs
;
attr
!=
NULL
;
attr
=
attr
->
next
)
{
child
=
status_attr_to_xmlnode
(
status
,
type
,
(
const
PurpleStatusAttr
*
)
attr
->
data
);
if
(
child
)
xmlnode_insert_child
(
node
,
child
);
}
return
node
;
}
static
xmlnode
*
status_to_xmlnode
(
const
PurpleStatus
*
status
)
{
xmlnode
*
node
,
*
child
;
node
=
xmlnode_new
(
"status"
);
xmlnode_set_attrib
(
node
,
"type"
,
purple_status_get_id
(
status
));
if
(
purple_status_get_name
(
status
)
!=
NULL
)
xmlnode_set_attrib
(
node
,
"name"
,
purple_status_get_name
(
status
));
xmlnode_set_attrib
(
node
,
"active"
,
purple_status_is_active
(
status
)
?
"true"
:
"false"
);
child
=
status_attrs_to_xmlnode
(
status
);
xmlnode_insert_child
(
node
,
child
);
return
node
;
}
static
xmlnode
*
statuses_to_xmlnode
(
const
PurplePresence
*
presence
)
{
xmlnode
*
node
,
*
child
;
GList
*
statuses
,
*
status
;
node
=
xmlnode_new
(
"statuses"
);
statuses
=
purple_presence_get_statuses
(
presence
);
for
(
status
=
statuses
;
status
!=
NULL
;
status
=
status
->
next
)
{
child
=
status_to_xmlnode
((
PurpleStatus
*
)
status
->
data
);
xmlnode_insert_child
(
node
,
child
);
}
return
node
;
}
static
xmlnode
*
proxy_settings_to_xmlnode
(
PurpleProxyInfo
*
proxy_info
)
{
xmlnode
*
node
,
*
child
;
PurpleProxyType
proxy_type
;
const
char
*
value
;
int
int_value
;
char
buf
[
20
];
proxy_type
=
purple_proxy_info_get_type
(
proxy_info
);
node
=
xmlnode_new
(
"proxy"
);
child
=
xmlnode_new_child
(
node
,
"type"
);
xmlnode_insert_data
(
child
,
(
proxy_type
==
PURPLE_PROXY_USE_GLOBAL
?
"global"
:
proxy_type
==
PURPLE_PROXY_NONE
?
"none"
:
proxy_type
==
PURPLE_PROXY_HTTP
?
"http"
:
proxy_type
==
PURPLE_PROXY_SOCKS4
?
"socks4"
:
proxy_type
==
PURPLE_PROXY_SOCKS5
?
"socks5"
:
proxy_type
==
PURPLE_PROXY_USE_ENVVAR
?
"envvar"
:
"unknown"
),
-1
);
if
((
value
=
purple_proxy_info_get_host
(
proxy_info
))
!=
NULL
)
{
child
=
xmlnode_new_child
(
node
,
"host"
);
xmlnode_insert_data
(
child
,
value
,
-1
);
}
if
((
int_value
=
purple_proxy_info_get_port
(
proxy_info
))
!=
0
)
{
snprintf
(
buf
,
sizeof
(
buf
),
"%d"
,
int_value
);
child
=
xmlnode_new_child
(
node
,
"port"
);
xmlnode_insert_data
(
child
,
buf
,
-1
);
}
if
((
value
=
purple_proxy_info_get_username
(
proxy_info
))
!=
NULL
)
{
child
=
xmlnode_new_child
(
node
,
"username"
);
xmlnode_insert_data
(
child
,
value
,
-1
);
}
if
((
value
=
purple_proxy_info_get_password
(
proxy_info
))
!=
NULL
)
{
child
=
xmlnode_new_child
(
node
,
"password"
);
xmlnode_insert_data
(
child
,
value
,
-1
);
}
return
node
;
}
static
xmlnode
*
account_to_xmlnode
(
PurpleAccount
*
account
)
{
xmlnode
*
node
,
*
child
;
const
char
*
tmp
;
PurplePresence
*
presence
;
PurpleProxyInfo
*
proxy_info
;
node
=
xmlnode_new
(
"account"
);
child
=
xmlnode_new_child
(
node
,
"protocol"
);
xmlnode_insert_data
(
child
,
purple_account_get_protocol_id
(
account
),
-1
);
child
=
xmlnode_new_child
(
node
,
"name"
);
xmlnode_insert_data
(
child
,
purple_account_get_username
(
account
),
-1
);
if
(
purple_account_get_remember_password
(
account
)
&&
((
tmp
=
purple_account_get_password
(
account
))
!=
NULL
))
{
child
=
xmlnode_new_child
(
node
,
"password"
);
xmlnode_insert_data
(
child
,
tmp
,
-1
);
}
if
((
tmp
=
purple_account_get_alias
(
account
))
!=
NULL
)
{
child
=
xmlnode_new_child
(
node
,
"alias"
);
xmlnode_insert_data
(
child
,
tmp
,
-1
);
}
if
((
presence
=
purple_account_get_presence
(
account
))
!=
NULL
)
{
child
=
statuses_to_xmlnode
(
presence
);
xmlnode_insert_child
(
node
,
child
);
}
if
((
tmp
=
purple_account_get_user_info
(
account
))
!=
NULL
)
{
/* TODO: Do we need to call purple_str_strip_char(tmp, '\r') here? */
child
=
xmlnode_new_child
(
node
,
"userinfo"
);
xmlnode_insert_data
(
child
,
tmp
,
-1
);
}
if
(
g_hash_table_size
(
account
->
settings
)
>
0
)
{
child
=
xmlnode_new_child
(
node
,
"settings"
);
g_hash_table_foreach
(
account
->
settings
,
setting_to_xmlnode
,
child
);
}
if
(
g_hash_table_size
(
account
->
ui_settings
)
>
0
)
{
g_hash_table_foreach
(
account
->
ui_settings
,
ui_setting_to_xmlnode
,
node
);
}
if
((
proxy_info
=
purple_account_get_proxy_info
(
account
))
!=
NULL
)
{
child
=
proxy_settings_to_xmlnode
(
proxy_info
);
xmlnode_insert_child
(
node
,
child
);
}
return
node
;
}
static
xmlnode
*
accounts_to_xmlnode
(
void
)
{
xmlnode
*
node
,
*
child
;
GList
*
cur
;
node
=
xmlnode_new
(
"account"
);
xmlnode_set_attrib
(
node
,
"version"
,
"1.0"
);
for
(
cur
=
purple_accounts_get_all
();
cur
!=
NULL
;
cur
=
cur
->
next
)
{
child
=
account_to_xmlnode
(
cur
->
data
);
xmlnode_insert_child
(
node
,
child
);
}
return
node
;
}
static
void
sync_accounts
(
void
)
{
xmlnode
*
node
;
char
*
data
;
if
(
!
accounts_loaded
)
{
purple_debug_error
(
"account"
,
"Attempted to save accounts before "
"they were read!
\n
"
);
return
;
}
node
=
accounts_to_xmlnode
();
data
=
xmlnode_to_formatted_str
(
node
,
NULL
);
purple_util_write_data_to_file
(
"accounts.xml"
,
data
,
-1
);
g_free
(
data
);
xmlnode_free
(
node
);
}
static
gboolean
save_cb
(
gpointer
data
)
{
sync_accounts
();
save_timer
=
0
;
return
FALSE
;
}
static
void
schedule_accounts_save
()
{
if
(
save_timer
==
0
)
save_timer
=
purple_timeout_add_seconds
(
5
,
save_cb
,
NULL
);
}
/*********************************************************************
* Reading from disk *
*********************************************************************/
static
void
parse_settings
(
xmlnode
*
node
,
PurpleAccount
*
account
)
{
const
char
*
ui
;
xmlnode
*
child
;
/* Get the UI string, if these are UI settings */
ui
=
xmlnode_get_attrib
(
node
,
"ui"
);
/* Read settings, one by one */
for
(
child
=
xmlnode_get_child
(
node
,
"setting"
);
child
!=
NULL
;
child
=
xmlnode_get_next_twin
(
child
))
{
const
char
*
name
,
*
str_type
;
PurplePrefType
type
;
char
*
data
;
name
=
xmlnode_get_attrib
(
child
,
"name"
);
if
(
name
==
NULL
)
/* Ignore this setting */
continue
;
str_type
=
xmlnode_get_attrib
(
child
,
"type"
);
if
(
str_type
==
NULL
)
/* Ignore this setting */
continue
;
if
(
!
strcmp
(
str_type
,
"string"
))
type
=
PURPLE_PREF_STRING
;
else
if
(
!
strcmp
(
str_type
,
"int"
))
type
=
PURPLE_PREF_INT
;
else
if
(
!
strcmp
(
str_type
,
"bool"
))
type
=
PURPLE_PREF_BOOLEAN
;
else
/* Ignore this setting */
continue
;
data
=
xmlnode_get_data
(
child
);
if
(
data
==
NULL
)
/* Ignore this setting */
continue
;
if
(
ui
==
NULL
)
{
if
(
type
==
PURPLE_PREF_STRING
)
purple_account_set_string
(
account
,
name
,
data
);
else
if
(
type
==
PURPLE_PREF_INT
)
purple_account_set_int
(
account
,
name
,
atoi
(
data
));
else
if
(
type
==
PURPLE_PREF_BOOLEAN
)
purple_account_set_bool
(
account
,
name
,
(
*
data
==
'0'
?
FALSE
:
TRUE
));
}
else
{
if
(
type
==
PURPLE_PREF_STRING
)
purple_account_set_ui_string
(
account
,
ui
,
name
,
data
);
else
if
(
type
==
PURPLE_PREF_INT
)
purple_account_set_ui_int
(
account
,
ui
,
name
,
atoi
(
data
));
else
if
(
type
==
PURPLE_PREF_BOOLEAN
)
purple_account_set_ui_bool
(
account
,
ui
,
name
,
(
*
data
==
'0'
?
FALSE
:
TRUE
));
}
g_free
(
data
);
}
}
static
GList
*
parse_status_attrs
(
xmlnode
*
node
,
PurpleStatus
*
status
)
{
GList
*
list
=
NULL
;
xmlnode
*
child
;
PurpleValue
*
attr_value
;
for
(
child
=
xmlnode_get_child
(
node
,
"attribute"
);
child
!=
NULL
;
child
=
xmlnode_get_next_twin
(
child
))
{
const
char
*
id
=
xmlnode_get_attrib
(
child
,
"id"
);
const
char
*
value
=
xmlnode_get_attrib
(
child
,
"value"
);
if
(
!
id
||
!*
id
||
!
value
||
!*
value
)
continue
;
attr_value
=
purple_status_get_attr_value
(
status
,
id
);
if
(
!
attr_value
)
continue
;
list
=
g_list_append
(
list
,
(
char
*
)
id
);
switch
(
purple_value_get_type
(
attr_value
))
{
case
PURPLE_TYPE_STRING
:
list
=
g_list_append
(
list
,
(
char
*
)
value
);
break
;
case
PURPLE_TYPE_INT
:
case
PURPLE_TYPE_BOOLEAN
:
{
int
v
;
if
(
sscanf
(
value
,
"%d"
,
&
v
)
==
1
)
list
=
g_list_append
(
list
,
GINT_TO_POINTER
(
v
));
else
list
=
g_list_remove
(
list
,
id
);
break
;
}
default
:
break
;
}
}
return
list
;
}
static
void
parse_status
(
xmlnode
*
node
,
PurpleAccount
*
account
)
{
gboolean
active
=
FALSE
;
const
char
*
data
;
const
char
*
type
;
xmlnode
*
child
;
GList
*
attrs
=
NULL
;
/* Get the active/inactive state */
data
=
xmlnode_get_attrib
(
node
,
"active"
);
if
(
data
==
NULL
)
return
;
if
(
g_ascii_strcasecmp
(
data
,
"true"
)
==
0
)
active
=
TRUE
;
else
if
(
g_ascii_strcasecmp
(
data
,
"false"
)
==
0
)
active
=
FALSE
;
else
return
;
/* Get the type of the status */
type
=
xmlnode_get_attrib
(
node
,
"type"
);
if
(
type
==
NULL
)
return
;
/* Read attributes into a GList */
child
=
xmlnode_get_child
(
node
,
"attributes"
);
if
(
child
!=
NULL
)
{
attrs
=
parse_status_attrs
(
child
,
purple_account_get_status
(
account
,
type
));
}
purple_account_set_status_list
(
account
,
type
,
active
,
attrs
);
g_list_free
(
attrs
);
}
static
void
parse_statuses
(
xmlnode
*
node
,
PurpleAccount
*
account
)
{
xmlnode
*
child
;
for
(
child
=
xmlnode_get_child
(
node
,
"status"
);
child
!=
NULL
;
child
=
xmlnode_get_next_twin
(
child
))
{
parse_status
(
child
,
account
);
}
}
static
void
parse_proxy_info
(
xmlnode
*
node
,
PurpleAccount
*
account
)
{
PurpleProxyInfo
*
proxy_info
;
xmlnode
*
child
;
char
*
data
;
proxy_info
=
purple_proxy_info_new
();
/* Use the global proxy settings, by default */
purple_proxy_info_set_type
(
proxy_info
,
PURPLE_PROXY_USE_GLOBAL
);
/* Read proxy type */
child
=
xmlnode_get_child
(
node
,
"type"
);
if
((
child
!=
NULL
)
&&
((
data
=
xmlnode_get_data
(
child
))
!=
NULL
))
{
if
(
!
strcmp
(
data
,
"global"
))
purple_proxy_info_set_type
(
proxy_info
,
PURPLE_PROXY_USE_GLOBAL
);
else
if
(
!
strcmp
(
data
,
"none"
))
purple_proxy_info_set_type
(
proxy_info
,
PURPLE_PROXY_NONE
);
else
if
(
!
strcmp
(
data
,
"http"
))
purple_proxy_info_set_type
(
proxy_info
,
PURPLE_PROXY_HTTP
);
else
if
(
!
strcmp
(
data
,
"socks4"
))
purple_proxy_info_set_type
(
proxy_info
,
PURPLE_PROXY_SOCKS4
);
else
if
(
!
strcmp
(
data
,
"socks5"
))
purple_proxy_info_set_type
(
proxy_info
,
PURPLE_PROXY_SOCKS5
);
else
if
(
!
strcmp
(
data
,
"envvar"
))
purple_proxy_info_set_type
(
proxy_info
,
PURPLE_PROXY_USE_ENVVAR
);
else
{
purple_debug_error
(
"account"
,
"Invalid proxy type found when "
"loading account information for %s
\n
"
,
purple_account_get_username
(
account
));
}
g_free
(
data
);
}
/* Read proxy host */
child
=
xmlnode_get_child
(
node
,
"host"
);
if
((
child
!=
NULL
)
&&
((
data
=
xmlnode_get_data
(
child
))
!=
NULL
))
{
purple_proxy_info_set_host
(
proxy_info
,
data
);
g_free
(
data
);
}
/* Read proxy port */
child
=
xmlnode_get_child
(
node
,
"port"
);
if
((
child
!=
NULL
)
&&
((
data
=
xmlnode_get_data
(
child
))
!=
NULL
))
{
purple_proxy_info_set_port
(
proxy_info
,
atoi
(
data
));
g_free
(
data
);
}
/* Read proxy username */
child
=
xmlnode_get_child
(
node
,
"username"
);
if
((
child
!=
NULL
)
&&
((
data
=
xmlnode_get_data
(
child
))
!=
NULL
))
{
purple_proxy_info_set_username
(
proxy_info
,
data
);
g_free
(
data
);
}
/* Read proxy password */
child
=
xmlnode_get_child
(
node
,
"password"
);
if
((
child
!=
NULL
)
&&
((
data
=
xmlnode_get_data
(
child
))
!=
NULL
))
{
purple_proxy_info_set_password
(
proxy_info
,
data
);
g_free
(
data
);
}
/* If there are no values set then proxy_info NULL */
if
((
purple_proxy_info_get_type
(
proxy_info
)
==
PURPLE_PROXY_USE_GLOBAL
)
&&
(
purple_proxy_info_get_host
(
proxy_info
)
==
NULL
)
&&
(
purple_proxy_info_get_port
(
proxy_info
)
==
0
)
&&
(
purple_proxy_info_get_username
(
proxy_info
)
==
NULL
)
&&
(
purple_proxy_info_get_password
(
proxy_info
)
==
NULL
))
{
purple_proxy_info_destroy
(
proxy_info
);
return
;
}
purple_account_set_proxy_info
(
account
,
proxy_info
);
}
static
PurpleAccount
*
parse_account
(
xmlnode
*
node
)
{
PurpleAccount
*
ret
;
xmlnode
*
child
;
char
*
protocol_id
=
NULL
;
char
*
name
=
NULL
;
char
*
data
;
child
=
xmlnode_get_child
(
node
,
"protocol"
);
if
(
child
!=
NULL
)
protocol_id
=
xmlnode_get_data
(
child
);
child
=
xmlnode_get_child
(
node
,
"name"
);
if
(
child
!=
NULL
)
name
=
xmlnode_get_data
(
child
);
if
(
name
==
NULL
)
{
/* Do we really need to do this? */
child
=
xmlnode_get_child
(
node
,
"username"
);
if
(
child
!=
NULL
)
name
=
xmlnode_get_data
(
child
);
}
if
((
protocol_id
==
NULL
)
||
(
name
==
NULL
))
{
g_free
(
protocol_id
);
g_free
(
name
);
return
NULL
;
}
ret
=
purple_account_new
(
name
,
_purple_oscar_convert
(
name
,
protocol_id
));
/* XXX: */
g_free
(
name
);
g_free
(
protocol_id
);
/* Read the password */
child
=
xmlnode_get_child
(
node
,
"password"
);
if
((
child
!=
NULL
)
&&
((
data
=
xmlnode_get_data
(
child
))
!=
NULL
))
{
purple_account_set_remember_password
(
ret
,
TRUE
);
purple_account_set_password
(
ret
,
data
);
g_free
(
data
);
}
/* Read the alias */
child
=
xmlnode_get_child
(
node
,
"alias"
);
if
((
child
!=
NULL
)
&&
((
data
=
xmlnode_get_data
(
child
))
!=
NULL
))
{
if
(
*
data
!=
'\0'
)
purple_account_set_alias
(
ret
,
data
);
g_free
(
data
);
}
/* Read the statuses */
child
=
xmlnode_get_child
(
node
,
"statuses"
);
if
(
child
!=
NULL
)
{
parse_statuses
(
child
,
ret
);
}
/* Read the userinfo */
child
=
xmlnode_get_child
(
node
,
"userinfo"
);
if
((
child
!=
NULL
)
&&
((
data
=
xmlnode_get_data
(
child
))
!=
NULL
))
{
purple_account_set_user_info
(
ret
,
data
);
g_free
(
data
);
}
/* Read an old buddyicon */
child
=
xmlnode_get_child
(
node
,
"buddyicon"
);
if
((
child
!=
NULL
)
&&
((
data
=
xmlnode_get_data
(
child
))
!=
NULL
))
{
const
char
*
dirname
=
purple_buddy_icons_get_cache_dir
();
char
*
filename
=
g_build_filename
(
dirname
,
data
,
NULL
);
gchar
*
contents
;
gsize
len
;
if
(
g_file_get_contents
(
filename
,
&
contents
,
&
len
,
NULL
))
{
purple_buddy_icons_set_account_icon
(
ret
,
(
guchar
*
)
contents
,
len
);
}
else
{
/* Try to see if the icon got left behind in the old cache. */
g_free
(
filename
);
filename
=
g_build_filename
(
g_get_home_dir
(),
".gaim"
,
"icons"
,
data
,
NULL
);
if
(
g_file_get_contents
(
filename
,
&
contents
,
&
len
,
NULL
))
{
purple_buddy_icons_set_account_icon
(
ret
,
(
guchar
*
)
contents
,
len
);
}
}
g_free
(
filename
);
g_free
(
data
);
}
/* Read settings (both core and UI) */
for
(
child
=
xmlnode_get_child
(
node
,
"settings"
);
child
!=
NULL
;
child
=
xmlnode_get_next_twin
(
child
))
{
parse_settings
(
child
,
ret
);
}
/* Read proxy */
child
=
xmlnode_get_child
(
node
,
"proxy"
);
if
(
child
!=
NULL
)
{
parse_proxy_info
(
child
,
ret
);
}
return
ret
;
}
static
void
load_accounts
(
void
)
{
xmlnode
*
node
,
*
child
;
accounts_loaded
=
TRUE
;
node
=
purple_util_read_xml_from_file
(
"accounts.xml"
,
_
(
"accounts"
));
if
(
node
==
NULL
)
return
;
for
(
child
=
xmlnode_get_child
(
node
,
"account"
);
child
!=
NULL
;
child
=
xmlnode_get_next_twin
(
child
))
{
PurpleAccount
*
new_acct
;
new_acct
=
parse_account
(
child
);
purple_accounts_add
(
new_acct
);
}
xmlnode_free
(
node
);
_purple_buddy_icons_account_loaded_cb
();
}
static
void
delete_setting
(
void
*
data
)
{
PurpleAccountSetting
*
setting
=
(
PurpleAccountSetting
*
)
data
;
g_free
(
setting
->
ui
);
if
(
setting
->
type
==
PURPLE_PREF_STRING
)
g_free
(
setting
->
value
.
string
);
g_free
(
setting
);
}
PurpleAccount
*
purple_account_new
(
const
char
*
username
,
const
char
*
protocol_id
)
{
PurpleAccount
*
account
=
NULL
;
PurplePlugin
*
prpl
=
NULL
;
PurplePluginProtocolInfo
*
prpl_info
=
NULL
;
PurpleStatusType
*
status_type
;
g_return_val_if_fail
(
username
!=
NULL
,
NULL
);
g_return_val_if_fail
(
protocol_id
!=
NULL
,
NULL
);
account
=
purple_accounts_find
(
username
,
protocol_id
);
if
(
account
!=
NULL
)
return
account
;
account
=
g_new0
(
PurpleAccount
,
1
);
PURPLE_DBUS_REGISTER_POINTER
(
account
,
PurpleAccount
);
purple_account_set_username
(
account
,
username
);
purple_account_set_protocol_id
(
account
,
protocol_id
);
account
->
settings
=
g_hash_table_new_full
(
g_str_hash
,
g_str_equal
,
g_free
,
delete_setting
);
account
->
ui_settings
=
g_hash_table_new_full
(
g_str_hash
,
g_str_equal
,
g_free
,
(
GDestroyNotify
)
g_hash_table_destroy
);
account
->
system_log
=
NULL
;
/* 0 is not a valid privacy setting */
account
->
perm_deny
=
PURPLE_PRIVACY_ALLOW_ALL
;
prpl
=
purple_find_prpl
(
protocol_id
);
if
(
prpl
==
NULL
)
return
account
;
prpl_info
=
PURPLE_PLUGIN_PROTOCOL_INFO
(
prpl
);
if
(
prpl_info
!=
NULL
&&
prpl_info
->
status_types
!=
NULL
)
purple_account_set_status_types
(
account
,
prpl_info
->
status_types
(
account
));
account
->
presence
=
purple_presence_new_for_account
(
account
);
status_type
=
purple_account_get_status_type_with_primitive
(
account
,
PURPLE_STATUS_AVAILABLE
);
if
(
status_type
!=
NULL
)
purple_presence_set_status_active
(
account
->
presence
,
purple_status_type_get_id
(
status_type
),
TRUE
);
else
purple_presence_set_status_active
(
account
->
presence
,
"offline"
,
TRUE
);
return
account
;
}
void
purple_account_destroy
(
PurpleAccount
*
account
)
{
GList
*
l
;
g_return_if_fail
(
account
!=
NULL
);
purple_debug_info
(
"account"
,
"Destroying account %p
\n
"
,
account
);
for
(
l
=
purple_get_conversations
();
l
!=
NULL
;
l
=
l
->
next
)
{
PurpleConversation
*
conv
=
(
PurpleConversation
*
)
l
->
data
;
if
(
purple_conversation_get_account
(
conv
)
==
account
)
purple_conversation_set_account
(
conv
,
NULL
);
}
g_free
(
account
->
username
);
g_free
(
account
->
alias
);
g_free
(
account
->
password
);
g_free
(
account
->
user_info
);
g_free
(
account
->
buddy_icon_path
);
g_free
(
account
->
protocol_id
);
g_hash_table_destroy
(
account
->
settings
);
g_hash_table_destroy
(
account
->
ui_settings
);
purple_account_set_status_types
(
account
,
NULL
);
purple_presence_destroy
(
account
->
presence
);
if
(
account
->
system_log
)
purple_log_free
(
account
->
system_log
);
PURPLE_DBUS_UNREGISTER_POINTER
(
account
);
g_free
(
account
);
}
void
purple_account_set_register_callback
(
PurpleAccount
*
account
,
PurpleAccountRegistrationCb
cb
,
void
*
user_data
)
{
g_return_if_fail
(
account
!=
NULL
);
account
->
registration_cb
=
cb
;
account
->
registration_cb_user_data
=
user_data
;
}
void
purple_account_register
(
PurpleAccount
*
account
)
{
g_return_if_fail
(
account
!=
NULL
);
purple_debug_info
(
"account"
,
"Registering account %s
\n
"
,
purple_account_get_username
(
account
));
purple_connection_new
(
account
,
TRUE
,
purple_account_get_password
(
account
));
}
void
purple_account_unregister
(
PurpleAccount
*
account
,
PurpleAccountUnregistrationCb
cb
,
void
*
user_data
)
{
g_return_if_fail
(
account
!=
NULL
);
purple_debug_info
(
"account"
,
"Unregistering account %s
\n
"
,
purple_account_get_username
(
account
));
purple_connection_new_unregister
(
account
,
purple_account_get_password
(
account
),
cb
,
user_data
);
}
static
void
request_password_ok_cb
(
PurpleAccount
*
account
,
PurpleRequestFields
*
fields
)
{
const
char
*
entry
;
gboolean
remember
;
entry
=
purple_request_fields_get_string
(
fields
,
"password"
);
remember
=
purple_request_fields_get_bool
(
fields
,
"remember"
);
if
(
!
entry
||
!*
entry
)
{
purple_notify_error
(
account
,
NULL
,
_
(
"Password is required to sign on."
),
NULL
);
return
;
}
if
(
remember
)
purple_account_set_remember_password
(
account
,
TRUE
);
purple_account_set_password
(
account
,
entry
);
purple_connection_new
(
account
,
FALSE
,
entry
);
}
static
void
request_password_cancel_cb
(
PurpleAccount
*
account
,
PurpleRequestFields
*
fields
)
{
/* Disable the account as the user has canceled connecting */
purple_account_set_enabled
(
account
,
purple_core_get_ui
(),
FALSE
);
}
void
purple_account_request_password
(
PurpleAccount
*
account
,
GCallback
ok_cb
,
GCallback
cancel_cb
,
void
*
user_data
)
{
gchar
*
primary
;
const
gchar
*
username
;
PurpleRequestFieldGroup
*
group
;
PurpleRequestField
*
field
;
PurpleRequestFields
*
fields
;
/* Close any previous password request windows */
purple_request_close_with_handle
(
account
);
username
=
purple_account_get_username
(
account
);
primary
=
g_strdup_printf
(
_
(
"Enter password for %s (%s)"
),
username
,
purple_account_get_protocol_name
(
account
));
fields
=
purple_request_fields_new
();
group
=
purple_request_field_group_new
(
NULL
);
purple_request_fields_add_group
(
fields
,
group
);
field
=
purple_request_field_string_new
(
"password"
,
_
(
"Enter Password"
),
NULL
,
FALSE
);
purple_request_field_string_set_masked
(
field
,
TRUE
);
purple_request_field_set_required
(
field
,
TRUE
);
purple_request_field_group_add_field
(
group
,
field
);
field
=
purple_request_field_bool_new
(
"remember"
,
_
(
"Save password"
),
FALSE
);
purple_request_field_group_add_field
(
group
,
field
);
purple_request_fields
(
account
,
NULL
,
primary
,
NULL
,
fields
,
_
(
"OK"
),
ok_cb
,
_
(
"Cancel"
),
cancel_cb
,
account
,
NULL
,
NULL
,
user_data
);
g_free
(
primary
);
}
void
purple_account_connect
(
PurpleAccount
*
account
)
{
PurplePlugin
*
prpl
;
PurplePluginProtocolInfo
*
prpl_info
;
const
char
*
password
;
g_return_if_fail
(
account
!=
NULL
);
purple_debug_info
(
"account"
,
"Connecting to account %s
\n
"
,
purple_account_get_username
(
account
));
if
(
!
purple_account_get_enabled
(
account
,
purple_core_get_ui
()))
return
;
prpl
=
purple_find_prpl
(
purple_account_get_protocol_id
(
account
));
if
(
prpl
==
NULL
)
{
gchar
*
message
;
message
=
g_strdup_printf
(
_
(
"Missing protocol plugin for %s"
),
purple_account_get_username
(
account
));
purple_notify_error
(
account
,
_
(
"Connection Error"
),
message
,
NULL
);
g_free
(
message
);
return
;
}
prpl_info
=
PURPLE_PLUGIN_PROTOCOL_INFO
(
prpl
);
password
=
purple_account_get_password
(
account
);
if
((
password
==
NULL
)
&&
!
(
prpl_info
->
options
&
OPT_PROTO_NO_PASSWORD
)
&&
!
(
prpl_info
->
options
&
OPT_PROTO_PASSWORD_OPTIONAL
))
purple_account_request_password
(
account
,
G_CALLBACK
(
request_password_ok_cb
),
G_CALLBACK
(
request_password_cancel_cb
),
account
);
else
purple_connection_new
(
account
,
FALSE
,
password
);
}
void
purple_account_disconnect
(
PurpleAccount
*
account
)
{
PurpleConnection
*
gc
;
g_return_if_fail
(
account
!=
NULL
);
g_return_if_fail
(
!
purple_account_is_disconnected
(
account
));
purple_debug_info
(
"account"
,
"Disconnecting account %p
\n
"
,
account
);
account
->
disconnecting
=
TRUE
;
gc
=
purple_account_get_connection
(
account
);
purple_connection_destroy
(
gc
);
if
(
!
purple_account_get_remember_password
(
account
))
purple_account_set_password
(
account
,
NULL
);
purple_account_set_connection
(
account
,
NULL
);
account
->
disconnecting
=
FALSE
;
}
void
purple_account_notify_added
(
PurpleAccount
*
account
,
const
char
*
remote_user
,
const
char
*
id
,
const
char
*
alias
,
const
char
*
message
)
{
PurpleAccountUiOps
*
ui_ops
;
g_return_if_fail
(
account
!=
NULL
);
g_return_if_fail
(
remote_user
!=
NULL
);
ui_ops
=
purple_accounts_get_ui_ops
();
if
(
ui_ops
!=
NULL
&&
ui_ops
->
notify_added
!=
NULL
)
ui_ops
->
notify_added
(
account
,
remote_user
,
id
,
alias
,
message
);
}
void
purple_account_request_add
(
PurpleAccount
*
account
,
const
char
*
remote_user
,
const
char
*
id
,
const
char
*
alias
,
const
char
*
message
)
{
PurpleAccountUiOps
*
ui_ops
;
g_return_if_fail
(
account
!=
NULL
);
g_return_if_fail
(
remote_user
!=
NULL
);
ui_ops
=
purple_accounts_get_ui_ops
();
if
(
ui_ops
!=
NULL
&&
ui_ops
->
request_add
!=
NULL
)
ui_ops
->
request_add
(
account
,
remote_user
,
id
,
alias
,
message
);
}
static
void
purple_account_request_close_info
(
PurpleAccountRequestInfo
*
info
)
{
PurpleAccountUiOps
*
ops
;
ops
=
purple_accounts_get_ui_ops
();
if
(
ops
!=
NULL
&&
ops
->
close_account_request
!=
NULL
)
ops
->
close_account_request
(
info
->
ui_handle
);
g_free
(
info
);
}
void
purple_account_request_close_with_account
(
PurpleAccount
*
account
)
{
GList
*
l
,
*
l_next
;
g_return_if_fail
(
account
!=
NULL
);
for
(
l
=
handles
;
l
!=
NULL
;
l
=
l_next
)
{
PurpleAccountRequestInfo
*
info
=
l
->
data
;
l_next
=
l
->
next
;
if
(
info
->
account
==
account
)
{
handles
=
g_list_remove
(
handles
,
info
);
purple_account_request_close_info
(
info
);
}
}
}
void
purple_account_request_close
(
void
*
ui_handle
)
{
GList
*
l
,
*
l_next
;
g_return_if_fail
(
ui_handle
!=
NULL
);
for
(
l
=
handles
;
l
!=
NULL
;
l
=
l_next
)
{
PurpleAccountRequestInfo
*
info
=
l
->
data
;
l_next
=
l
->
next
;
if
(
info
->
ui_handle
==
ui_handle
)
{
handles
=
g_list_remove
(
handles
,
info
);
purple_account_request_close_info
(
info
);
}
}
}
void
*
purple_account_request_authorization
(
PurpleAccount
*
account
,
const
char
*
remote_user
,
const
char
*
id
,
const
char
*
alias
,
const
char
*
message
,
gboolean
on_list
,
PurpleAccountRequestAuthorizationCb
auth_cb
,
PurpleAccountRequestAuthorizationCb
deny_cb
,
void
*
user_data
)
{
PurpleAccountUiOps
*
ui_ops
;
PurpleAccountRequestInfo
*
info
;
g_return_val_if_fail
(
account
!=
NULL
,
NULL
);
g_return_val_if_fail
(
remote_user
!=
NULL
,
NULL
);
ui_ops
=
purple_accounts_get_ui_ops
();
if
(
ui_ops
!=
NULL
&&
ui_ops
->
request_authorize
!=
NULL
)
{
info
=
g_new0
(
PurpleAccountRequestInfo
,
1
);
info
->
type
=
PURPLE_ACCOUNT_REQUEST_AUTHORIZATION
;
info
->
account
=
account
;
info
->
ui_handle
=
ui_ops
->
request_authorize
(
account
,
remote_user
,
id
,
alias
,
message
,
on_list
,
auth_cb
,
deny_cb
,
user_data
);
handles
=
g_list_append
(
handles
,
info
);
return
info
->
ui_handle
;
}
return
NULL
;
}
static
void
change_password_cb
(
PurpleAccount
*
account
,
PurpleRequestFields
*
fields
)
{
const
char
*
orig_pass
,
*
new_pass_1
,
*
new_pass_2
;
orig_pass
=
purple_request_fields_get_string
(
fields
,
"password"
);
new_pass_1
=
purple_request_fields_get_string
(
fields
,
"new_password_1"
);
new_pass_2
=
purple_request_fields_get_string
(
fields
,
"new_password_2"
);
if
(
g_utf8_collate
(
new_pass_1
,
new_pass_2
))
{
purple_notify_error
(
account
,
NULL
,
_
(
"New passwords do not match."
),
NULL
);
return
;
}
if
(
orig_pass
==
NULL
||
new_pass_1
==
NULL
||
new_pass_2
==
NULL
||
*
orig_pass
==
'\0'
||
*
new_pass_1
==
'\0'
||
*
new_pass_2
==
'\0'
)
{
purple_notify_error
(
account
,
NULL
,
_
(
"Fill out all fields completely."
),
NULL
);
return
;
}
purple_account_change_password
(
account
,
orig_pass
,
new_pass_1
);
}
void
purple_account_request_change_password
(
PurpleAccount
*
account
)
{
PurpleRequestFields
*
fields
;
PurpleRequestFieldGroup
*
group
;
PurpleRequestField
*
field
;
char
primary
[
256
];
g_return_if_fail
(
account
!=
NULL
);
g_return_if_fail
(
purple_account_is_connected
(
account
));
fields
=
purple_request_fields_new
();
group
=
purple_request_field_group_new
(
NULL
);
purple_request_fields_add_group
(
fields
,
group
);
field
=
purple_request_field_string_new
(
"password"
,
_
(
"Original password"
),
NULL
,
FALSE
);
purple_request_field_string_set_masked
(
field
,
TRUE
);
purple_request_field_set_required
(
field
,
TRUE
);
purple_request_field_group_add_field
(
group
,
field
);
field
=
purple_request_field_string_new
(
"new_password_1"
,
_
(
"New password"
),
NULL
,
FALSE
);
purple_request_field_string_set_masked
(
field
,
TRUE
);
purple_request_field_set_required
(
field
,
TRUE
);
purple_request_field_group_add_field
(
group
,
field
);
field
=
purple_request_field_string_new
(
"new_password_2"
,
_
(
"New password (again)"
),
NULL
,
FALSE
);
purple_request_field_string_set_masked
(
field
,
TRUE
);
purple_request_field_set_required
(
field
,
TRUE
);
purple_request_field_group_add_field
(
group
,
field
);
g_snprintf
(
primary
,
sizeof
(
primary
),
_
(
"Change password for %s"
),
purple_account_get_username
(
account
));
/* I'm sticking this somewhere in the code: bologna */
purple_request_fields
(
purple_account_get_connection
(
account
),
NULL
,
primary
,
_
(
"Please enter your current password and your "
"new password."
),
fields
,
_
(
"OK"
),
G_CALLBACK
(
change_password_cb
),
_
(
"Cancel"
),
NULL
,
account
,
NULL
,
NULL
,
account
);
}
static
void
set_user_info_cb
(
PurpleAccount
*
account
,
const
char
*
user_info
)
{
PurpleConnection
*
gc
;
purple_account_set_user_info
(
account
,
user_info
);
gc
=
purple_account_get_connection
(
account
);
serv_set_info
(
gc
,
user_info
);
}
void
purple_account_request_change_user_info
(
PurpleAccount
*
account
)
{
PurpleConnection
*
gc
;
char
primary
[
256
];
g_return_if_fail
(
account
!=
NULL
);
g_return_if_fail
(
purple_account_is_connected
(
account
));
gc
=
purple_account_get_connection
(
account
);
g_snprintf
(
primary
,
sizeof
(
primary
),
_
(
"Change user information for %s"
),
purple_account_get_username
(
account
));
purple_request_input
(
gc
,
_
(
"Set User Info"
),
primary
,
NULL
,
purple_account_get_user_info
(
account
),
TRUE
,
FALSE
,
((
gc
!=
NULL
)
&&
(
gc
->
flags
&
PURPLE_CONNECTION_HTML
)
?
"html"
:
NULL
),
_
(
"Save"
),
G_CALLBACK
(
set_user_info_cb
),
_
(
"Cancel"
),
NULL
,
account
,
NULL
,
NULL
,
account
);
}
void
purple_account_set_username
(
PurpleAccount
*
account
,
const
char
*
username
)
{
g_return_if_fail
(
account
!=
NULL
);
g_free
(
account
->
username
);
account
->
username
=
g_strdup
(
username
);
schedule_accounts_save
();
/* if the name changes, we should re-write the buddy list
* to disk with the new name */
purple_blist_schedule_save
();
}
void
purple_account_set_password
(
PurpleAccount
*
account
,
const
char
*
password
)
{
g_return_if_fail
(
account
!=
NULL
);
g_free
(
account
->
password
);
account
->
password
=
g_strdup
(
password
);
schedule_accounts_save
();
}
void
purple_account_set_alias
(
PurpleAccount
*
account
,
const
char
*
alias
)
{
g_return_if_fail
(
account
!=
NULL
);
/*
* Do nothing if alias and account->alias are both NULL. Or if
* they're the exact same string.
*/
if
(
alias
==
account
->
alias
)
return
;
if
((
!
alias
&&
account
->
alias
)
||
(
alias
&&
!
account
->
alias
)
||
g_utf8_collate
(
account
->
alias
,
alias
))
{
char
*
old
=
account
->
alias
;
account
->
alias
=
g_strdup
(
alias
);
purple_signal_emit
(
purple_accounts_get_handle
(),
"account-alias-changed"
,
account
,
old
);
g_free
(
old
);
schedule_accounts_save
();
}
}
void
purple_account_set_user_info
(
PurpleAccount
*
account
,
const
char
*
user_info
)
{
g_return_if_fail
(
account
!=
NULL
);
g_free
(
account
->
user_info
);
account
->
user_info
=
g_strdup
(
user_info
);
schedule_accounts_save
();
}
void
purple_account_set_buddy_icon_path
(
PurpleAccount
*
account
,
const
char
*
path
)
{
g_return_if_fail
(
account
!=
NULL
);
g_free
(
account
->
buddy_icon_path
);
account
->
buddy_icon_path
=
g_strdup
(
path
);
schedule_accounts_save
();
}
void
purple_account_set_protocol_id
(
PurpleAccount
*
account
,
const
char
*
protocol_id
)
{
g_return_if_fail
(
account
!=
NULL
);
g_return_if_fail
(
protocol_id
!=
NULL
);
g_free
(
account
->
protocol_id
);
account
->
protocol_id
=
g_strdup
(
protocol_id
);
schedule_accounts_save
();
}
void
purple_account_set_connection
(
PurpleAccount
*
account
,
PurpleConnection
*
gc
)
{
g_return_if_fail
(
account
!=
NULL
);
account
->
gc
=
gc
;
}
void
purple_account_set_remember_password
(
PurpleAccount
*
account
,
gboolean
value
)
{
g_return_if_fail
(
account
!=
NULL
);
account
->
remember_pass
=
value
;
schedule_accounts_save
();
}
void
purple_account_set_check_mail
(
PurpleAccount
*
account
,
gboolean
value
)
{
g_return_if_fail
(
account
!=
NULL
);
purple_account_set_bool
(
account
,
"check-mail"
,
value
);
}
void
purple_account_set_enabled
(
PurpleAccount
*
account
,
const
char
*
ui
,
gboolean
value
)
{
PurpleConnection
*
gc
;
gboolean
was_enabled
=
FALSE
;
g_return_if_fail
(
account
!=
NULL
);
g_return_if_fail
(
ui
!=
NULL
);
was_enabled
=
purple_account_get_enabled
(
account
,
ui
);
purple_account_set_ui_bool
(
account
,
ui
,
"auto-login"
,
value
);
gc
=
purple_account_get_connection
(
account
);
if
(
was_enabled
&&
!
value
)
purple_signal_emit
(
purple_accounts_get_handle
(),
"account-disabled"
,
account
);
else
if
(
!
was_enabled
&&
value
)
purple_signal_emit
(
purple_accounts_get_handle
(),
"account-enabled"
,
account
);
if
((
gc
!=
NULL
)
&&
(
gc
->
wants_to_die
==
TRUE
))
return
;
if
(
value
&&
purple_presence_is_online
(
account
->
presence
))
purple_account_connect
(
account
);
else
if
(
!
value
&&
!
purple_account_is_disconnected
(
account
))
purple_account_disconnect
(
account
);
}
void
purple_account_set_proxy_info
(
PurpleAccount
*
account
,
PurpleProxyInfo
*
info
)
{
g_return_if_fail
(
account
!=
NULL
);
if
(
account
->
proxy_info
!=
NULL
)
purple_proxy_info_destroy
(
account
->
proxy_info
);
account
->
proxy_info
=
info
;
schedule_accounts_save
();
}
void
purple_account_set_status_types
(
PurpleAccount
*
account
,
GList
*
status_types
)
{
g_return_if_fail
(
account
!=
NULL
);
/* Out with the old... */
if
(
account
->
status_types
!=
NULL
)
{
g_list_foreach
(
account
->
status_types
,
(
GFunc
)
purple_status_type_destroy
,
NULL
);
g_list_free
(
account
->
status_types
);
}
/* In with the new... */
account
->
status_types
=
status_types
;
}
void
purple_account_set_status
(
PurpleAccount
*
account
,
const
char
*
status_id
,
gboolean
active
,
...)
{
GList
*
attrs
=
NULL
;
const
gchar
*
id
;
gpointer
data
;
va_list
args
;
va_start
(
args
,
active
);
while
((
id
=
va_arg
(
args
,
const
char
*
))
!=
NULL
)
{
attrs
=
g_list_append
(
attrs
,
(
char
*
)
id
);
data
=
va_arg
(
args
,
void
*
);
attrs
=
g_list_append
(
attrs
,
data
);
}
purple_account_set_status_list
(
account
,
status_id
,
active
,
attrs
);
g_list_free
(
attrs
);
va_end
(
args
);
}
void
purple_account_set_status_list
(
PurpleAccount
*
account
,
const
char
*
status_id
,
gboolean
active
,
GList
*
attrs
)
{
PurpleStatus
*
status
;
g_return_if_fail
(
account
!=
NULL
);
g_return_if_fail
(
status_id
!=
NULL
);
status
=
purple_account_get_status
(
account
,
status_id
);
if
(
status
==
NULL
)
{
purple_debug_error
(
"account"
,
"Invalid status ID %s for account %s (%s)
\n
"
,
status_id
,
purple_account_get_username
(
account
),
purple_account_get_protocol_id
(
account
));
return
;
}
if
(
active
||
purple_status_is_independent
(
status
))
purple_status_set_active_with_attrs_list
(
status
,
active
,
attrs
);
/*
* Our current statuses are saved to accounts.xml (so that when we
* reconnect, we go back to the previous status).
*/
schedule_accounts_save
();
}
void
purple_account_clear_settings
(
PurpleAccount
*
account
)
{
g_return_if_fail
(
account
!=
NULL
);
g_hash_table_destroy
(
account
->
settings
);
account
->
settings
=
g_hash_table_new_full
(
g_str_hash
,
g_str_equal
,
g_free
,
delete_setting
);
}
void
purple_account_set_int
(
PurpleAccount
*
account
,
const
char
*
name
,
int
value
)
{
PurpleAccountSetting
*
setting
;
g_return_if_fail
(
account
!=
NULL
);
g_return_if_fail
(
name
!=
NULL
);
setting
=
g_new0
(
PurpleAccountSetting
,
1
);
setting
->
type
=
PURPLE_PREF_INT
;
setting
->
value
.
integer
=
value
;
g_hash_table_insert
(
account
->
settings
,
g_strdup
(
name
),
setting
);
schedule_accounts_save
();
}
void
purple_account_set_string
(
PurpleAccount
*
account
,
const
char
*
name
,
const
char
*
value
)
{
PurpleAccountSetting
*
setting
;
g_return_if_fail
(
account
!=
NULL
);
g_return_if_fail
(
name
!=
NULL
);
setting
=
g_new0
(
PurpleAccountSetting
,
1
);
setting
->
type
=
PURPLE_PREF_STRING
;
setting
->
value
.
string
=
g_strdup
(
value
);
g_hash_table_insert
(
account
->
settings
,
g_strdup
(
name
),
setting
);
schedule_accounts_save
();
}
void
purple_account_set_bool
(
PurpleAccount
*
account
,
const
char
*
name
,
gboolean
value
)
{
PurpleAccountSetting
*
setting
;
g_return_if_fail
(
account
!=
NULL
);
g_return_if_fail
(
name
!=
NULL
);
setting
=
g_new0
(
PurpleAccountSetting
,
1
);
setting
->
type
=
PURPLE_PREF_BOOLEAN
;
setting
->
value
.
bool
=
value
;
g_hash_table_insert
(
account
->
settings
,
g_strdup
(
name
),
setting
);
schedule_accounts_save
();
}
static
GHashTable
*
get_ui_settings_table
(
PurpleAccount
*
account
,
const
char
*
ui
)
{
GHashTable
*
table
;
table
=
g_hash_table_lookup
(
account
->
ui_settings
,
ui
);
if
(
table
==
NULL
)
{
table
=
g_hash_table_new_full
(
g_str_hash
,
g_str_equal
,
g_free
,
delete_setting
);
g_hash_table_insert
(
account
->
ui_settings
,
g_strdup
(
ui
),
table
);
}
return
table
;
}
void
purple_account_set_ui_int
(
PurpleAccount
*
account
,
const
char
*
ui
,
const
char
*
name
,
int
value
)
{
PurpleAccountSetting
*
setting
;
GHashTable
*
table
;
g_return_if_fail
(
account
!=
NULL
);
g_return_if_fail
(
ui
!=
NULL
);
g_return_if_fail
(
name
!=
NULL
);
setting
=
g_new0
(
PurpleAccountSetting
,
1
);
setting
->
type
=
PURPLE_PREF_INT
;
setting
->
ui
=
g_strdup
(
ui
);
setting
->
value
.
integer
=
value
;
table
=
get_ui_settings_table
(
account
,
ui
);
g_hash_table_insert
(
table
,
g_strdup
(
name
),
setting
);
schedule_accounts_save
();
}
void
purple_account_set_ui_string
(
PurpleAccount
*
account
,
const
char
*
ui
,
const
char
*
name
,
const
char
*
value
)
{
PurpleAccountSetting
*
setting
;
GHashTable
*
table
;
g_return_if_fail
(
account
!=
NULL
);
g_return_if_fail
(
ui
!=
NULL
);
g_return_if_fail
(
name
!=
NULL
);
setting
=
g_new0
(
PurpleAccountSetting
,
1
);
setting
->
type
=
PURPLE_PREF_STRING
;
setting
->
ui
=
g_strdup
(
ui
);
setting
->
value
.
string
=
g_strdup
(
value
);
table
=
get_ui_settings_table
(
account
,
ui
);
g_hash_table_insert
(
table
,
g_strdup
(
name
),
setting
);
schedule_accounts_save
();
}
void
purple_account_set_ui_bool
(
PurpleAccount
*
account
,
const
char
*
ui
,
const
char
*
name
,
gboolean
value
)
{
PurpleAccountSetting
*
setting
;
GHashTable
*
table
;
g_return_if_fail
(
account
!=
NULL
);
g_return_if_fail
(
ui
!=
NULL
);
g_return_if_fail
(
name
!=
NULL
);
setting
=
g_new0
(
PurpleAccountSetting
,
1
);
setting
->
type
=
PURPLE_PREF_BOOLEAN
;
setting
->
ui
=
g_strdup
(
ui
);
setting
->
value
.
bool
=
value
;
table
=
get_ui_settings_table
(
account
,
ui
);
g_hash_table_insert
(
table
,
g_strdup
(
name
),
setting
);
schedule_accounts_save
();
}
static
PurpleConnectionState
purple_account_get_state
(
const
PurpleAccount
*
account
)
{
PurpleConnection
*
gc
;
g_return_val_if_fail
(
account
!=
NULL
,
PURPLE_DISCONNECTED
);
gc
=
purple_account_get_connection
(
account
);
if
(
!
gc
)
return
PURPLE_DISCONNECTED
;
return
purple_connection_get_state
(
gc
);
}
gboolean
purple_account_is_connected
(
const
PurpleAccount
*
account
)
{
return
(
purple_account_get_state
(
account
)
==
PURPLE_CONNECTED
);
}
gboolean
purple_account_is_connecting
(
const
PurpleAccount
*
account
)
{
return
(
purple_account_get_state
(
account
)
==
PURPLE_CONNECTING
);
}
gboolean
purple_account_is_disconnected
(
const
PurpleAccount
*
account
)
{
return
(
purple_account_get_state
(
account
)
==
PURPLE_DISCONNECTED
);
}
const
char
*
purple_account_get_username
(
const
PurpleAccount
*
account
)
{
g_return_val_if_fail
(
account
!=
NULL
,
NULL
);
return
account
->
username
;
}
const
char
*
purple_account_get_password
(
const
PurpleAccount
*
account
)
{
g_return_val_if_fail
(
account
!=
NULL
,
NULL
);
return
account
->
password
;
}
const
char
*
purple_account_get_alias
(
const
PurpleAccount
*
account
)
{
g_return_val_if_fail
(
account
!=
NULL
,
NULL
);
return
account
->
alias
;
}
const
char
*
purple_account_get_user_info
(
const
PurpleAccount
*
account
)
{
g_return_val_if_fail
(
account
!=
NULL
,
NULL
);
return
account
->
user_info
;
}
const
char
*
purple_account_get_buddy_icon_path
(
const
PurpleAccount
*
account
)
{
g_return_val_if_fail
(
account
!=
NULL
,
NULL
);
return
account
->
buddy_icon_path
;
}
const
char
*
purple_account_get_protocol_id
(
const
PurpleAccount
*
account
)
{
g_return_val_if_fail
(
account
!=
NULL
,
NULL
);
return
account
->
protocol_id
;
}
const
char
*
purple_account_get_protocol_name
(
const
PurpleAccount
*
account
)
{
PurplePlugin
*
p
;
g_return_val_if_fail
(
account
!=
NULL
,
NULL
);
p
=
purple_find_prpl
(
purple_account_get_protocol_id
(
account
));
return
((
p
&&
p
->
info
->
name
)
?
_
(
p
->
info
->
name
)
:
_
(
"Unknown"
));
}
PurpleConnection
*
purple_account_get_connection
(
const
PurpleAccount
*
account
)
{
g_return_val_if_fail
(
account
!=
NULL
,
NULL
);
return
account
->
gc
;
}
gboolean
purple_account_get_remember_password
(
const
PurpleAccount
*
account
)
{
g_return_val_if_fail
(
account
!=
NULL
,
FALSE
);
return
account
->
remember_pass
;
}
gboolean
purple_account_get_check_mail
(
const
PurpleAccount
*
account
)
{
g_return_val_if_fail
(
account
!=
NULL
,
FALSE
);
return
purple_account_get_bool
(
account
,
"check-mail"
,
FALSE
);
}
gboolean
purple_account_get_enabled
(
const
PurpleAccount
*
account
,
const
char
*
ui
)
{
g_return_val_if_fail
(
account
!=
NULL
,
FALSE
);
g_return_val_if_fail
(
ui
!=
NULL
,
FALSE
);
return
purple_account_get_ui_bool
(
account
,
ui
,
"auto-login"
,
FALSE
);
}
PurpleProxyInfo
*
purple_account_get_proxy_info
(
const
PurpleAccount
*
account
)
{
g_return_val_if_fail
(
account
!=
NULL
,
NULL
);
return
account
->
proxy_info
;
}
PurpleStatus
*
purple_account_get_active_status
(
const
PurpleAccount
*
account
)
{
g_return_val_if_fail
(
account
!=
NULL
,
NULL
);
return
purple_presence_get_active_status
(
account
->
presence
);
}
PurpleStatus
*
purple_account_get_status
(
const
PurpleAccount
*
account
,
const
char
*
status_id
)
{
g_return_val_if_fail
(
account
!=
NULL
,
NULL
);
g_return_val_if_fail
(
status_id
!=
NULL
,
NULL
);
return
purple_presence_get_status
(
account
->
presence
,
status_id
);
}
PurpleStatusType
*
purple_account_get_status_type
(
const
PurpleAccount
*
account
,
const
char
*
id
)
{
GList
*
l
;
g_return_val_if_fail
(
account
!=
NULL
,
NULL
);
g_return_val_if_fail
(
id
!=
NULL
,
NULL
);
for
(
l
=
purple_account_get_status_types
(
account
);
l
!=
NULL
;
l
=
l
->
next
)
{
PurpleStatusType
*
status_type
=
(
PurpleStatusType
*
)
l
->
data
;
if
(
!
strcmp
(
purple_status_type_get_id
(
status_type
),
id
))
return
status_type
;
}
return
NULL
;
}
PurpleStatusType
*
purple_account_get_status_type_with_primitive
(
const
PurpleAccount
*
account
,
PurpleStatusPrimitive
primitive
)
{
GList
*
l
;
g_return_val_if_fail
(
account
!=
NULL
,
NULL
);
for
(
l
=
purple_account_get_status_types
(
account
);
l
!=
NULL
;
l
=
l
->
next
)
{
PurpleStatusType
*
status_type
=
(
PurpleStatusType
*
)
l
->
data
;
if
(
purple_status_type_get_primitive
(
status_type
)
==
primitive
)
return
status_type
;
}
return
NULL
;
}
PurplePresence
*
purple_account_get_presence
(
const
PurpleAccount
*
account
)
{
g_return_val_if_fail
(
account
!=
NULL
,
NULL
);
return
account
->
presence
;
}
gboolean
purple_account_is_status_active
(
const
PurpleAccount
*
account
,
const
char
*
status_id
)
{
g_return_val_if_fail
(
account
!=
NULL
,
FALSE
);
g_return_val_if_fail
(
status_id
!=
NULL
,
FALSE
);
return
purple_presence_is_status_active
(
account
->
presence
,
status_id
);
}
GList
*
purple_account_get_status_types
(
const
PurpleAccount
*
account
)
{
g_return_val_if_fail
(
account
!=
NULL
,
NULL
);
return
account
->
status_types
;
}
int
purple_account_get_int
(
const
PurpleAccount
*
account
,
const
char
*
name
,
int
default_value
)
{
PurpleAccountSetting
*
setting
;
g_return_val_if_fail
(
account
!=
NULL
,
default_value
);
g_return_val_if_fail
(
name
!=
NULL
,
default_value
);
setting
=
g_hash_table_lookup
(
account
->
settings
,
name
);
if
(
setting
==
NULL
)
return
default_value
;
g_return_val_if_fail
(
setting
->
type
==
PURPLE_PREF_INT
,
default_value
);
return
setting
->
value
.
integer
;
}
const
char
*
purple_account_get_string
(
const
PurpleAccount
*
account
,
const
char
*
name
,
const
char
*
default_value
)
{
PurpleAccountSetting
*
setting
;
g_return_val_if_fail
(
account
!=
NULL
,
default_value
);
g_return_val_if_fail
(
name
!=
NULL
,
default_value
);
setting
=
g_hash_table_lookup
(
account
->
settings
,
name
);
if
(
setting
==
NULL
)
return
default_value
;
g_return_val_if_fail
(
setting
->
type
==
PURPLE_PREF_STRING
,
default_value
);
return
setting
->
value
.
string
;
}
gboolean
purple_account_get_bool
(
const
PurpleAccount
*
account
,
const
char
*
name
,
gboolean
default_value
)
{
PurpleAccountSetting
*
setting
;
g_return_val_if_fail
(
account
!=
NULL
,
default_value
);
g_return_val_if_fail
(
name
!=
NULL
,
default_value
);
setting
=
g_hash_table_lookup
(
account
->
settings
,
name
);
if
(
setting
==
NULL
)
return
default_value
;
g_return_val_if_fail
(
setting
->
type
==
PURPLE_PREF_BOOLEAN
,
default_value
);
return
setting
->
value
.
bool
;
}
int
purple_account_get_ui_int
(
const
PurpleAccount
*
account
,
const
char
*
ui
,
const
char
*
name
,
int
default_value
)
{
PurpleAccountSetting
*
setting
;
GHashTable
*
table
;
g_return_val_if_fail
(
account
!=
NULL
,
default_value
);
g_return_val_if_fail
(
ui
!=
NULL
,
default_value
);
g_return_val_if_fail
(
name
!=
NULL
,
default_value
);
if
((
table
=
g_hash_table_lookup
(
account
->
ui_settings
,
ui
))
==
NULL
)
return
default_value
;
if
((
setting
=
g_hash_table_lookup
(
table
,
name
))
==
NULL
)
return
default_value
;
g_return_val_if_fail
(
setting
->
type
==
PURPLE_PREF_INT
,
default_value
);
return
setting
->
value
.
integer
;
}
const
char
*
purple_account_get_ui_string
(
const
PurpleAccount
*
account
,
const
char
*
ui
,
const
char
*
name
,
const
char
*
default_value
)
{
PurpleAccountSetting
*
setting
;
GHashTable
*
table
;
g_return_val_if_fail
(
account
!=
NULL
,
default_value
);
g_return_val_if_fail
(
ui
!=
NULL
,
default_value
);
g_return_val_if_fail
(
name
!=
NULL
,
default_value
);
if
((
table
=
g_hash_table_lookup
(
account
->
ui_settings
,
ui
))
==
NULL
)
return
default_value
;
if
((
setting
=
g_hash_table_lookup
(
table
,
name
))
==
NULL
)
return
default_value
;
g_return_val_if_fail
(
setting
->
type
==
PURPLE_PREF_STRING
,
default_value
);
return
setting
->
value
.
string
;
}
gboolean
purple_account_get_ui_bool
(
const
PurpleAccount
*
account
,
const
char
*
ui
,
const
char
*
name
,
gboolean
default_value
)
{
PurpleAccountSetting
*
setting
;
GHashTable
*
table
;
g_return_val_if_fail
(
account
!=
NULL
,
default_value
);
g_return_val_if_fail
(
ui
!=
NULL
,
default_value
);
g_return_val_if_fail
(
name
!=
NULL
,
default_value
);
if
((
table
=
g_hash_table_lookup
(
account
->
ui_settings
,
ui
))
==
NULL
)
return
default_value
;
if
((
setting
=
g_hash_table_lookup
(
table
,
name
))
==
NULL
)
return
default_value
;
g_return_val_if_fail
(
setting
->
type
==
PURPLE_PREF_BOOLEAN
,
default_value
);
return
setting
->
value
.
bool
;
}
PurpleLog
*
purple_account_get_log
(
PurpleAccount
*
account
,
gboolean
create
)
{
g_return_val_if_fail
(
account
!=
NULL
,
NULL
);
if
(
!
account
->
system_log
&&
create
){
PurplePresence
*
presence
;
int
login_time
;
presence
=
purple_account_get_presence
(
account
);
login_time
=
purple_presence_get_login_time
(
presence
);
account
->
system_log
=
purple_log_new
(
PURPLE_LOG_SYSTEM
,
purple_account_get_username
(
account
),
account
,
NULL
,
(
login_time
!=
0
)
?
login_time
:
time
(
NULL
),
NULL
);
}
return
account
->
system_log
;
}
void
purple_account_destroy_log
(
PurpleAccount
*
account
)
{
g_return_if_fail
(
account
!=
NULL
);
if
(
account
->
system_log
){
purple_log_free
(
account
->
system_log
);
account
->
system_log
=
NULL
;
}
}
void
purple_account_add_buddy
(
PurpleAccount
*
account
,
PurpleBuddy
*
buddy
)
{
PurplePluginProtocolInfo
*
prpl_info
=
NULL
;
PurpleConnection
*
gc
=
purple_account_get_connection
(
account
);
if
(
gc
!=
NULL
&&
gc
->
prpl
!=
NULL
)
prpl_info
=
PURPLE_PLUGIN_PROTOCOL_INFO
(
gc
->
prpl
);
if
(
prpl_info
!=
NULL
&&
prpl_info
->
add_buddy
!=
NULL
)
prpl_info
->
add_buddy
(
gc
,
buddy
,
purple_buddy_get_group
(
buddy
));
}
void
purple_account_add_buddies
(
PurpleAccount
*
account
,
GList
*
buddies
)
{
PurplePluginProtocolInfo
*
prpl_info
=
NULL
;
PurpleConnection
*
gc
=
purple_account_get_connection
(
account
);
if
(
gc
!=
NULL
&&
gc
->
prpl
!=
NULL
)
prpl_info
=
PURPLE_PLUGIN_PROTOCOL_INFO
(
gc
->
prpl
);
if
(
prpl_info
)
{
GList
*
cur
,
*
groups
=
NULL
;
/* Make a list of what group each buddy is in */
for
(
cur
=
buddies
;
cur
!=
NULL
;
cur
=
cur
->
next
)
{
PurpleBlistNode
*
node
=
cur
->
data
;
groups
=
g_list_append
(
groups
,
node
->
parent
->
parent
);
}
if
(
prpl_info
->
add_buddies
!=
NULL
)
prpl_info
->
add_buddies
(
gc
,
buddies
,
groups
);
else
if
(
prpl_info
->
add_buddy
!=
NULL
)
{
GList
*
curb
=
buddies
,
*
curg
=
groups
;
while
((
curb
!=
NULL
)
&&
(
curg
!=
NULL
))
{
prpl_info
->
add_buddy
(
gc
,
curb
->
data
,
curg
->
data
);
curb
=
curb
->
next
;
curg
=
curg
->
next
;
}
}
g_list_free
(
groups
);
}
}
void
purple_account_remove_buddy
(
PurpleAccount
*
account
,
PurpleBuddy
*
buddy
,
PurpleGroup
*
group
)
{
PurplePluginProtocolInfo
*
prpl_info
=
NULL
;
PurpleConnection
*
gc
=
purple_account_get_connection
(
account
);
if
(
gc
!=
NULL
&&
gc
->
prpl
!=
NULL
)
prpl_info
=
PURPLE_PLUGIN_PROTOCOL_INFO
(
gc
->
prpl
);
if
(
prpl_info
&&
prpl_info
->
remove_buddy
)
prpl_info
->
remove_buddy
(
gc
,
buddy
,
group
);
}
void
purple_account_remove_buddies
(
PurpleAccount
*
account
,
GList
*
buddies
,
GList
*
groups
)
{
PurplePluginProtocolInfo
*
prpl_info
=
NULL
;
PurpleConnection
*
gc
=
purple_account_get_connection
(
account
);
if
(
gc
!=
NULL
&&
gc
->
prpl
!=
NULL
)
prpl_info
=
PURPLE_PLUGIN_PROTOCOL_INFO
(
gc
->
prpl
);
if
(
prpl_info
)
{
if
(
prpl_info
->
remove_buddies
)
prpl_info
->
remove_buddies
(
gc
,
buddies
,
groups
);
else
{
GList
*
curb
=
buddies
;
GList
*
curg
=
groups
;
while
((
curb
!=
NULL
)
&&
(
curg
!=
NULL
))
{
purple_account_remove_buddy
(
account
,
curb
->
data
,
curg
->
data
);
curb
=
curb
->
next
;
curg
=
curg
->
next
;
}
}
}
}
void
purple_account_remove_group
(
PurpleAccount
*
account
,
PurpleGroup
*
group
)
{
PurplePluginProtocolInfo
*
prpl_info
=
NULL
;
PurpleConnection
*
gc
=
purple_account_get_connection
(
account
);
if
(
gc
!=
NULL
&&
gc
->
prpl
!=
NULL
)
prpl_info
=
PURPLE_PLUGIN_PROTOCOL_INFO
(
gc
->
prpl
);
if
(
prpl_info
&&
prpl_info
->
remove_group
)
prpl_info
->
remove_group
(
gc
,
group
);
}
void
purple_account_change_password
(
PurpleAccount
*
account
,
const
char
*
orig_pw
,
const
char
*
new_pw
)
{
PurplePluginProtocolInfo
*
prpl_info
=
NULL
;
PurpleConnection
*
gc
=
purple_account_get_connection
(
account
);
purple_account_set_password
(
account
,
new_pw
);
if
(
gc
!=
NULL
&&
gc
->
prpl
!=
NULL
)
prpl_info
=
PURPLE_PLUGIN_PROTOCOL_INFO
(
gc
->
prpl
);
if
(
prpl_info
&&
prpl_info
->
change_passwd
)
prpl_info
->
change_passwd
(
gc
,
orig_pw
,
new_pw
);
}
gboolean
purple_account_supports_offline_message
(
PurpleAccount
*
account
,
PurpleBuddy
*
buddy
)
{
PurpleConnection
*
gc
;
PurplePluginProtocolInfo
*
prpl_info
;
g_return_val_if_fail
(
account
,
FALSE
);
g_return_val_if_fail
(
buddy
,
FALSE
);
gc
=
purple_account_get_connection
(
account
);
if
(
gc
==
NULL
)
return
FALSE
;
prpl_info
=
PURPLE_PLUGIN_PROTOCOL_INFO
(
gc
->
prpl
);
if
(
!
prpl_info
||
!
prpl_info
->
offline_message
)
return
FALSE
;
return
prpl_info
->
offline_message
(
buddy
);
}
void
purple_accounts_add
(
PurpleAccount
*
account
)
{
g_return_if_fail
(
account
!=
NULL
);
if
(
g_list_find
(
accounts
,
account
)
!=
NULL
)
return
;
accounts
=
g_list_append
(
accounts
,
account
);
schedule_accounts_save
();
purple_signal_emit
(
purple_accounts_get_handle
(),
"account-added"
,
account
);
}
void
purple_accounts_remove
(
PurpleAccount
*
account
)
{
g_return_if_fail
(
account
!=
NULL
);
accounts
=
g_list_remove
(
accounts
,
account
);
schedule_accounts_save
();
purple_signal_emit
(
purple_accounts_get_handle
(),
"account-removed"
,
account
);
}
void
purple_accounts_delete
(
PurpleAccount
*
account
)
{
PurpleBlistNode
*
gnode
,
*
cnode
,
*
bnode
;
GList
*
iter
;
g_return_if_fail
(
account
!=
NULL
);
/*
* Disable the account before blowing it out of the water.
* Conceptually it probably makes more sense to disable the
* account for all UIs rather than the just the current UI,
* but it doesn't really matter.
*/
purple_account_set_enabled
(
account
,
purple_core_get_ui
(),
FALSE
);
purple_notify_close_with_handle
(
account
);
purple_request_close_with_handle
(
account
);
purple_accounts_remove
(
account
);
/* Remove this account's buddies */
for
(
gnode
=
purple_get_blist
()
->
root
;
gnode
!=
NULL
;
gnode
=
gnode
->
next
)
{
if
(
!
PURPLE_BLIST_NODE_IS_GROUP
(
gnode
))
continue
;
cnode
=
gnode
->
child
;
while
(
cnode
)
{
PurpleBlistNode
*
cnode_next
=
cnode
->
next
;
if
(
PURPLE_BLIST_NODE_IS_CONTACT
(
cnode
))
{
bnode
=
cnode
->
child
;
while
(
bnode
)
{
PurpleBlistNode
*
bnode_next
=
bnode
->
next
;
if
(
PURPLE_BLIST_NODE_IS_BUDDY
(
bnode
))
{
PurpleBuddy
*
b
=
(
PurpleBuddy
*
)
bnode
;
if
(
b
->
account
==
account
)
purple_blist_remove_buddy
(
b
);
}
bnode
=
bnode_next
;
}
}
else
if
(
PURPLE_BLIST_NODE_IS_CHAT
(
cnode
))
{
PurpleChat
*
c
=
(
PurpleChat
*
)
cnode
;
if
(
c
->
account
==
account
)
purple_blist_remove_chat
(
c
);
}
cnode
=
cnode_next
;
}
}
/* Remove any open conversation for this account */
for
(
iter
=
purple_get_conversations
();
iter
;
)
{
PurpleConversation
*
conv
=
iter
->
data
;
iter
=
iter
->
next
;
if
(
purple_conversation_get_account
(
conv
)
==
account
)
purple_conversation_destroy
(
conv
);
}
/* Remove this account's pounces */
purple_pounce_destroy_all_by_account
(
account
);
/* This will cause the deletion of an old buddy icon. */
purple_buddy_icons_set_account_icon
(
account
,
NULL
,
0
);
purple_account_destroy
(
account
);
}
void
purple_accounts_reorder
(
PurpleAccount
*
account
,
gint
new_index
)
{
gint
index
;
GList
*
l
;
g_return_if_fail
(
account
!=
NULL
);
g_return_if_fail
(
new_index
<=
g_list_length
(
accounts
));
index
=
g_list_index
(
accounts
,
account
);
if
(
index
==
-1
)
{
purple_debug_error
(
"account"
,
"Unregistered account (%s) discovered during reorder!
\n
"
,
purple_account_get_username
(
account
));
return
;
}
l
=
g_list_nth
(
accounts
,
index
);
if
(
new_index
>
index
)
new_index
--
;
/* Remove the old one. */
accounts
=
g_list_delete_link
(
accounts
,
l
);
/* Insert it where it should go. */
accounts
=
g_list_insert
(
accounts
,
account
,
new_index
);
schedule_accounts_save
();
}
GList
*
purple_accounts_get_all
(
void
)
{
return
accounts
;
}
GList
*
purple_accounts_get_all_active
(
void
)
{
GList
*
list
=
NULL
;
GList
*
all
=
purple_accounts_get_all
();
while
(
all
!=
NULL
)
{
PurpleAccount
*
account
=
all
->
data
;
if
(
purple_account_get_enabled
(
account
,
purple_core_get_ui
()))
list
=
g_list_append
(
list
,
account
);
all
=
all
->
next
;
}
return
list
;
}
PurpleAccount
*
purple_accounts_find
(
const
char
*
name
,
const
char
*
protocol_id
)
{
PurpleAccount
*
account
=
NULL
;
GList
*
l
;
char
*
who
;
g_return_val_if_fail
(
name
!=
NULL
,
NULL
);
who
=
g_strdup
(
purple_normalize
(
NULL
,
name
));
for
(
l
=
purple_accounts_get_all
();
l
!=
NULL
;
l
=
l
->
next
)
{
account
=
(
PurpleAccount
*
)
l
->
data
;
if
(
!
strcmp
(
purple_normalize
(
NULL
,
purple_account_get_username
(
account
)),
who
)
&&
(
!
protocol_id
||
!
strcmp
(
account
->
protocol_id
,
protocol_id
)))
{
break
;
}
account
=
NULL
;
}
g_free
(
who
);
return
account
;
}
void
purple_accounts_restore_current_statuses
()
{
GList
*
l
;
PurpleAccount
*
account
;
/* If we're not connected to the Internet right now, we bail on this */
if
(
!
purple_network_is_available
())
{
purple_debug_info
(
"account"
,
"Network not connected; skipping reconnect
\n
"
);
return
;
}
for
(
l
=
purple_accounts_get_all
();
l
!=
NULL
;
l
=
l
->
next
)
{
account
=
(
PurpleAccount
*
)
l
->
data
;
if
(
purple_account_get_enabled
(
account
,
purple_core_get_ui
())
&&
(
purple_presence_is_online
(
account
->
presence
)))
{
purple_account_connect
(
account
);
}
}
}
void
purple_accounts_set_ui_ops
(
PurpleAccountUiOps
*
ops
)
{
account_ui_ops
=
ops
;
}
PurpleAccountUiOps
*
purple_accounts_get_ui_ops
(
void
)
{
return
account_ui_ops
;
}
void
*
purple_accounts_get_handle
(
void
)
{
static
int
handle
;
return
&
handle
;
}
void
purple_accounts_init
(
void
)
{
void
*
handle
=
purple_accounts_get_handle
();
purple_signal_register
(
handle
,
"account-connecting"
,
purple_marshal_VOID__POINTER
,
NULL
,
1
,
purple_value_new
(
PURPLE_TYPE_SUBTYPE
,
PURPLE_SUBTYPE_ACCOUNT
));
purple_signal_register
(
handle
,
"account-disabled"
,
purple_marshal_VOID__POINTER
,
NULL
,
1
,
purple_value_new
(
PURPLE_TYPE_SUBTYPE
,
PURPLE_SUBTYPE_ACCOUNT
));
purple_signal_register
(
handle
,
"account-enabled"
,
purple_marshal_VOID__POINTER
,
NULL
,
1
,
purple_value_new
(
PURPLE_TYPE_SUBTYPE
,
PURPLE_SUBTYPE_ACCOUNT
));
purple_signal_register
(
handle
,
"account-setting-info"
,
purple_marshal_VOID__POINTER_POINTER
,
NULL
,
2
,
purple_value_new
(
PURPLE_TYPE_SUBTYPE
,
PURPLE_SUBTYPE_ACCOUNT
),
purple_value_new
(
PURPLE_TYPE_STRING
));
purple_signal_register
(
handle
,
"account-set-info"
,
purple_marshal_VOID__POINTER_POINTER
,
NULL
,
2
,
purple_value_new
(
PURPLE_TYPE_SUBTYPE
,
PURPLE_SUBTYPE_ACCOUNT
),
purple_value_new
(
PURPLE_TYPE_STRING
));
purple_signal_register
(
handle
,
"account-added"
,
purple_marshal_VOID__POINTER
,
NULL
,
1
,
purple_value_new
(
PURPLE_TYPE_SUBTYPE
,
PURPLE_SUBTYPE_ACCOUNT
));
purple_signal_register
(
handle
,
"account-removed"
,
purple_marshal_VOID__POINTER
,
NULL
,
1
,
purple_value_new
(
PURPLE_TYPE_SUBTYPE
,
PURPLE_SUBTYPE_ACCOUNT
));
purple_signal_register
(
handle
,
"account-status-changed"
,
purple_marshal_VOID__POINTER_POINTER_POINTER
,
NULL
,
3
,
purple_value_new
(
PURPLE_TYPE_SUBTYPE
,
PURPLE_SUBTYPE_ACCOUNT
),
purple_value_new
(
PURPLE_TYPE_SUBTYPE
,
PURPLE_SUBTYPE_STATUS
),
purple_value_new
(
PURPLE_TYPE_SUBTYPE
,
PURPLE_SUBTYPE_STATUS
));
purple_signal_register
(
handle
,
"account-alias-changed"
,
purple_marshal_VOID__POINTER_POINTER
,
NULL
,
2
,
purple_value_new
(
PURPLE_TYPE_SUBTYPE
,
PURPLE_SUBTYPE_ACCOUNT
),
purple_value_new
(
PURPLE_TYPE_STRING
));
load_accounts
();
}
void
purple_accounts_uninit
(
void
)
{
if
(
save_timer
!=
0
)
{
purple_timeout_remove
(
save_timer
);
save_timer
=
0
;
sync_accounts
();
}
purple_signals_unregister_by_instance
(
purple_accounts_get_handle
());
}