pidgin/pidgin
Clone
Summary
Browse
Changes
Graph
Route GLib debug logging directly to the Finch debug window
2021-10-18, Elliott Sales de Andrade
1896a80ff8e3
Route GLib debug logging directly to the Finch debug window
Instead of flowing through purple debug, this merges some bits of the existing GLib log handler, and the purple debug printer.
Testing Done:
Open the Debug window an see some `GLib-*` outputs.
Reviewed at https://reviews.imfreedom.org/r/1057/
/*
* 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 Library 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
<glib.h>
#include
<stdlib.h>
#include
<purple.h>
#include
"buddy.h"
#include
"bonjour.h"
#include
"glibcompat.h"
/**
* Creates a new buddy.
*/
BonjourBuddy
*
bonjour_buddy_new
(
const
gchar
*
name
,
PurpleAccount
*
account
)
{
BonjourBuddy
*
buddy
=
g_new0
(
BonjourBuddy
,
1
);
buddy
->
account
=
account
;
buddy
->
name
=
g_strdup
(
name
);
_mdns_init_buddy
(
buddy
);
return
buddy
;
}
void
clear_bonjour_buddy_values
(
BonjourBuddy
*
buddy
)
{
g_clear_pointer
(
&
buddy
->
first
,
g_free
);
g_clear_pointer
(
&
buddy
->
email
,
g_free
);
g_clear_pointer
(
&
buddy
->
ext
,
g_free
);
g_clear_pointer
(
&
buddy
->
jid
,
g_free
);
g_clear_pointer
(
&
buddy
->
last
,
g_free
);
g_clear_pointer
(
&
buddy
->
msg
,
g_free
);
g_clear_pointer
(
&
buddy
->
nick
,
g_free
);
g_clear_pointer
(
&
buddy
->
node
,
g_free
);
g_clear_pointer
(
&
buddy
->
phsh
,
g_free
);
g_clear_pointer
(
&
buddy
->
status
,
g_free
);
g_clear_pointer
(
&
buddy
->
vc
,
g_free
);
g_clear_pointer
(
&
buddy
->
ver
,
g_free
);
g_clear_pointer
(
&
buddy
->
AIM
,
g_free
);
}
void
set_bonjour_buddy_value
(
BonjourBuddy
*
buddy
,
const
char
*
record_key
,
const
char
*
value
,
guint32
len
){
gchar
**
fld
=
NULL
;
g_return_if_fail
(
record_key
!=
NULL
);
if
(
purple_strequal
(
record_key
,
"1st"
))
fld
=
&
buddy
->
first
;
else
if
(
purple_strequal
(
record_key
,
"email"
))
fld
=
&
buddy
->
email
;
else
if
(
purple_strequal
(
record_key
,
"ext"
))
fld
=
&
buddy
->
ext
;
else
if
(
purple_strequal
(
record_key
,
"jid"
))
fld
=
&
buddy
->
jid
;
else
if
(
purple_strequal
(
record_key
,
"last"
))
fld
=
&
buddy
->
last
;
else
if
(
purple_strequal
(
record_key
,
"msg"
))
fld
=
&
buddy
->
msg
;
else
if
(
purple_strequal
(
record_key
,
"nick"
))
fld
=
&
buddy
->
nick
;
else
if
(
purple_strequal
(
record_key
,
"node"
))
fld
=
&
buddy
->
node
;
else
if
(
purple_strequal
(
record_key
,
"phsh"
))
fld
=
&
buddy
->
phsh
;
else
if
(
purple_strequal
(
record_key
,
"status"
))
fld
=
&
buddy
->
status
;
else
if
(
purple_strequal
(
record_key
,
"vc"
))
fld
=
&
buddy
->
vc
;
else
if
(
purple_strequal
(
record_key
,
"ver"
))
fld
=
&
buddy
->
ver
;
else
if
(
purple_strequal
(
record_key
,
"AIM"
))
fld
=
&
buddy
->
AIM
;
if
(
fld
==
NULL
)
return
;
g_free
(
*
fld
);
*
fld
=
NULL
;
*
fld
=
g_strndup
(
value
,
len
);
}
/**
* Check if all the compulsory buddy data is present.
*/
gboolean
bonjour_buddy_check
(
BonjourBuddy
*
buddy
)
{
if
(
buddy
->
account
==
NULL
)
return
FALSE
;
if
(
buddy
->
name
==
NULL
)
return
FALSE
;
return
TRUE
;
}
/**
* If the buddy does not yet exist, then create it and add it to
* our buddy list. In either case we set the correct status for
* the buddy.
*/
void
bonjour_buddy_add_to_purple
(
BonjourBuddy
*
bonjour_buddy
,
PurpleBuddy
*
buddy
)
{
PurpleGroup
*
group
;
PurpleAccount
*
account
=
bonjour_buddy
->
account
;
const
char
*
status_id
,
*
old_hash
,
*
new_hash
,
*
name
;
/* Translate between the Bonjour status and the Purple status */
if
(
bonjour_buddy
->
status
!=
NULL
&&
g_ascii_strcasecmp
(
"dnd"
,
bonjour_buddy
->
status
)
==
0
)
status_id
=
BONJOUR_STATUS_ID_AWAY
;
else
status_id
=
BONJOUR_STATUS_ID_AVAILABLE
;
/*
* TODO: Figure out the idle time by getting the "away"
* field from the DNS SD.
*/
/* Make sure the Bonjour group exists in our buddy list */
group
=
purple_blist_find_group
(
BONJOUR_GROUP_NAME
);
/* Use the buddy's domain, instead? */
if
(
group
==
NULL
)
{
group
=
purple_group_new
(
BONJOUR_GROUP_NAME
);
purple_blist_add_group
(
group
,
NULL
);
}
/* Make sure the buddy exists in our buddy list */
if
(
buddy
==
NULL
)
buddy
=
purple_blist_find_buddy
(
account
,
bonjour_buddy
->
name
);
if
(
buddy
==
NULL
)
{
buddy
=
purple_buddy_new
(
account
,
bonjour_buddy
->
name
,
NULL
);
purple_blist_node_set_transient
(
PURPLE_BLIST_NODE
(
buddy
),
TRUE
);
purple_blist_add_buddy
(
buddy
,
NULL
,
group
,
NULL
);
}
name
=
purple_buddy_get_name
(
buddy
);
purple_buddy_set_protocol_data
(
buddy
,
bonjour_buddy
);
/* Create the alias for the buddy using the first and the last name */
if
(
bonjour_buddy
->
nick
&&
*
bonjour_buddy
->
nick
)
purple_serv_got_alias
(
purple_account_get_connection
(
account
),
name
,
bonjour_buddy
->
nick
);
else
{
gchar
*
alias
=
NULL
;
const
char
*
first
,
*
last
;
first
=
bonjour_buddy
->
first
;
last
=
bonjour_buddy
->
last
;
if
((
first
&&
*
first
)
||
(
last
&&
*
last
))
alias
=
g_strdup_printf
(
"%s%s%s"
,
(
first
&&
*
first
?
first
:
""
),
(
first
&&
*
first
&&
last
&&
*
last
?
" "
:
""
),
(
last
&&
*
last
?
last
:
""
));
purple_serv_got_alias
(
purple_account_get_connection
(
account
),
name
,
alias
);
g_free
(
alias
);
}
/* Set the user's status */
if
(
bonjour_buddy
->
msg
!=
NULL
)
purple_protocol_got_user_status
(
account
,
name
,
status_id
,
"message"
,
bonjour_buddy
->
msg
,
NULL
);
else
purple_protocol_got_user_status
(
account
,
name
,
status_id
,
NULL
);
purple_protocol_got_user_idle
(
account
,
name
,
FALSE
,
0
);
/* TODO: Because we don't save Bonjour buddies in blist.xml,
* we will always have to look up the buddy icon at login time.
* I think we should figure out a way to do something about this. */
/* Deal with the buddy icon */
old_hash
=
purple_buddy_icons_get_checksum_for_user
(
buddy
);
new_hash
=
(
bonjour_buddy
->
phsh
&&
*
(
bonjour_buddy
->
phsh
))
?
bonjour_buddy
->
phsh
:
NULL
;
if
(
new_hash
&&
!
purple_strequal
(
old_hash
,
new_hash
))
{
/* Look up the new icon data */
/* TODO: Make sure the hash assigned to the retrieved buddy icon is the same
* as what we looked up. */
bonjour_dns_sd_retrieve_buddy_icon
(
bonjour_buddy
);
}
else
if
(
!
new_hash
)
purple_buddy_icons_set_for_user
(
account
,
name
,
NULL
,
0
,
NULL
);
}
/**
* The buddy has signed off Bonjour.
* If the buddy is being saved, mark as offline, otherwise delete
*/
void
bonjour_buddy_signed_off
(
PurpleBuddy
*
pb
)
{
if
(
purple_blist_node_is_transient
(
PURPLE_BLIST_NODE
(
pb
)))
{
purple_account_remove_buddy
(
purple_buddy_get_account
(
pb
),
pb
,
NULL
);
purple_blist_remove_buddy
(
pb
);
}
else
{
purple_protocol_got_user_status
(
purple_buddy_get_account
(
pb
),
purple_buddy_get_name
(
pb
),
"offline"
,
NULL
);
bonjour_buddy_delete
(
purple_buddy_get_protocol_data
(
pb
));
purple_buddy_set_protocol_data
(
pb
,
NULL
);
}
}
/**
* We got the buddy icon data; deal with it
*/
void
bonjour_buddy_got_buddy_icon
(
BonjourBuddy
*
buddy
,
gconstpointer
data
,
gsize
len
)
{
/* Recalculate the hash instead of using the current phsh to make sure it is accurate for the icon. */
gchar
*
hash
;
if
(
data
==
NULL
||
len
==
0
)
return
;
hash
=
g_compute_checksum_for_data
(
G_CHECKSUM_SHA1
,
data
,
len
);
purple_debug_info
(
"bonjour"
,
"Got buddy icon for %s icon hash='%s' phsh='%s'.
\n
"
,
buddy
->
name
,
hash
,
buddy
->
phsh
?
buddy
->
phsh
:
"(null)"
);
purple_buddy_icons_set_for_user
(
buddy
->
account
,
buddy
->
name
,
g_memdup2
(
data
,
len
),
len
,
hash
);
g_free
(
hash
);
}
/**
* Deletes a buddy from memory.
*/
void
bonjour_buddy_delete
(
BonjourBuddy
*
buddy
)
{
g_free
(
buddy
->
name
);
g_slist_free_full
(
buddy
->
ips
,
g_free
);
g_free
(
buddy
->
first
);
g_free
(
buddy
->
phsh
);
g_free
(
buddy
->
status
);
g_free
(
buddy
->
email
);
g_free
(
buddy
->
last
);
g_free
(
buddy
->
jid
);
g_free
(
buddy
->
AIM
);
g_free
(
buddy
->
vc
);
g_free
(
buddy
->
msg
);
g_free
(
buddy
->
ext
);
g_free
(
buddy
->
nick
);
g_free
(
buddy
->
node
);
g_free
(
buddy
->
ver
);
bonjour_xmpp_close_conversation
(
buddy
->
conversation
);
buddy
->
conversation
=
NULL
;
/* Clean up any mdns implementation data */
_mdns_delete_buddy
(
buddy
);
g_free
(
buddy
);
}