3 * Purple is the legal property of its developers, whose names are too numerous
4 * to list here. Please refer to the COPYRIGHT file distributed with this
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
22 #include "glibcompat.h"
26 #include "dbus-maybe.h"
37 #define PURPLE_ACCOUNT_GET_PRIVATE(obj) \
38 (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_ACCOUNT, PurpleAccountPrivate))
42 char *username
; /* The username. */
43 char *alias
; /* How you appear to yourself. */
44 char *password
; /* The account password. */
45 char *user_info
; /* User information. */
47 char *buddy_icon_path
; /* The buddy icon's non-cached path. */
49 gboolean remember_pass
; /* Remember the password. */
52 * TODO: After a GObject representing a protocol is ready, use it
53 * here instead of the protocol ID.
55 char *protocol_id
; /* The ID of the protocol. */
57 PurpleConnection
*gc
; /* The connection handle. */
58 gboolean disconnecting
; /* The account is currently disconnecting */
60 GHashTable
*settings
; /* Protocol-specific settings. */
61 GHashTable
*ui_settings
; /* UI-specific settings. */
63 PurpleProxyInfo
*proxy_info
; /* Proxy information. This will be set */
64 /* to NULL when the account inherits */
65 /* proxy settings from global prefs. */
68 * TODO: Instead of linked lists for permit and deny, use a data
69 * structure that allows fast lookups AND decent performance when
70 * iterating through all items. Fast lookups should help performance
71 * for protocols like MSN, where all your buddies exist in your permit
72 * list therefore the permit list is large. Possibly GTree or
75 GSList
*permit
; /* Permit list. */
76 GSList
*deny
; /* Deny list. */
77 PurpleAccountPrivacyType privacy_type
; /* The permit/deny setting. */
79 GList
*status_types
; /* Status types. */
81 PurplePresence
*presence
; /* Presence. */
82 PurpleLog
*system_log
; /* The system log */
84 PurpleAccountRegistrationCb registration_cb
;
85 void *registration_cb_user_data
;
87 PurpleConnectionErrorInfo
*current_error
; /* Errors */
88 } PurpleAccountPrivate
;
95 } PurpleAccountSetting
;
99 PurpleAccountRequestType type
;
100 PurpleAccount
*account
;
104 PurpleAccountRequestAuthorizationCb auth_cb
;
105 PurpleAccountRequestAuthorizationCb deny_cb
;
107 } PurpleAccountRequestInfo
;
113 } PurpleCallbackBundle
;
115 /* GObject Property enums */
125 PROP_BUDDY_ICON_PATH
,
126 PROP_REMEMBER_PASSWORD
,
131 static GObjectClass
*parent_class
= NULL
;
132 static GParamSpec
*properties
[PROP_LAST
];
133 static GList
*handles
= NULL
;
139 purple_account_set_register_callback(PurpleAccount
*account
, PurpleAccountRegistrationCb cb
, void *user_data
)
141 PurpleAccountPrivate
*priv
;
143 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
145 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
147 priv
->registration_cb
= cb
;
148 priv
->registration_cb_user_data
= user_data
;
152 purple_account_register_got_password_cb(PurpleAccount
*account
,
153 const gchar
*password
, GError
*error
, gpointer data
)
155 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
157 _purple_connection_new(account
, TRUE
, password
);
161 purple_account_register(PurpleAccount
*account
)
163 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
165 purple_debug_info("account", "Registering account %s\n",
166 purple_account_get_username(account
));
168 purple_keyring_get_password(account
,
169 purple_account_register_got_password_cb
, NULL
);
173 purple_account_unregister_got_password_cb(PurpleAccount
*account
,
174 const gchar
*password
, GError
*error
, gpointer data
)
176 PurpleCallbackBundle
*cbb
= data
;
177 PurpleAccountUnregistrationCb cb
;
179 cb
= (PurpleAccountUnregistrationCb
)cbb
->cb
;
180 _purple_connection_new_unregister(account
, password
, cb
, cbb
->data
);
185 struct register_completed_closure
187 PurpleAccount
*account
;
192 purple_account_register_completed_cb(gpointer data
)
194 struct register_completed_closure
*closure
= data
;
195 PurpleAccountPrivate
*priv
;
197 priv
= PURPLE_ACCOUNT_GET_PRIVATE(closure
->account
);
199 if (priv
->registration_cb
)
200 (priv
->registration_cb
)(closure
->account
, closure
->succeeded
,
201 priv
->registration_cb_user_data
);
203 g_object_unref(closure
->account
);
210 purple_account_register_completed(PurpleAccount
*account
, gboolean succeeded
)
212 struct register_completed_closure
*closure
;
214 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
216 closure
= g_new0(struct register_completed_closure
, 1);
217 closure
->account
= g_object_ref(account
);
218 closure
->succeeded
= succeeded
;
220 g_timeout_add(0, purple_account_register_completed_cb
, closure
);
224 purple_account_unregister(PurpleAccount
*account
, PurpleAccountUnregistrationCb cb
, void *user_data
)
226 PurpleCallbackBundle
*cbb
;
228 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
230 purple_debug_info("account", "Unregistering account %s\n",
231 purple_account_get_username(account
));
233 cbb
= g_new0(PurpleCallbackBundle
, 1);
234 cbb
->cb
= PURPLE_CALLBACK(cb
);
235 cbb
->data
= user_data
;
237 purple_keyring_get_password(account
,
238 purple_account_unregister_got_password_cb
, cbb
);
242 request_password_ok_cb(PurpleAccount
*account
, PurpleRequestFields
*fields
)
247 entry
= purple_request_fields_get_string(fields
, "password");
248 remember
= purple_request_fields_get_bool(fields
, "remember");
250 if (!entry
|| !*entry
)
252 purple_notify_error(account
, NULL
,
253 _("Password is required to sign on."), NULL
,
254 purple_request_cpar_from_account(account
));
258 purple_account_set_remember_password(account
, remember
);
260 purple_account_set_password(account
, entry
, NULL
, NULL
);
261 _purple_connection_new(account
, FALSE
, entry
);
265 request_password_cancel_cb(PurpleAccount
*account
, PurpleRequestFields
*fields
)
267 /* Disable the account as the user has cancelled connecting */
268 purple_account_set_enabled(account
, purple_core_get_ui(), FALSE
);
273 purple_account_request_password(PurpleAccount
*account
, GCallback ok_cb
,
274 GCallback cancel_cb
, void *user_data
)
277 const gchar
*username
;
278 PurpleRequestFieldGroup
*group
;
279 PurpleRequestField
*field
;
280 PurpleRequestFields
*fields
;
282 /* Close any previous password request windows */
283 purple_request_close_with_handle(account
);
285 username
= purple_account_get_username(account
);
286 primary
= g_strdup_printf(_("Enter password for %s (%s)"), username
,
287 purple_account_get_protocol_name(account
));
289 fields
= purple_request_fields_new();
290 group
= purple_request_field_group_new(NULL
);
291 purple_request_fields_add_group(fields
, group
);
293 field
= purple_request_field_string_new("password", _("Enter Password"), NULL
, FALSE
);
294 purple_request_field_string_set_masked(field
, TRUE
);
295 purple_request_field_set_required(field
, TRUE
);
296 purple_request_field_group_add_field(group
, field
);
298 field
= purple_request_field_bool_new("remember", _("Save password"), FALSE
);
299 purple_request_field_group_add_field(group
, field
);
301 purple_request_fields(account
, NULL
, primary
, NULL
, fields
, _("OK"),
302 ok_cb
, _("Cancel"), cancel_cb
,
303 purple_request_cpar_from_account(account
), user_data
);
308 purple_account_connect_got_password_cb(PurpleAccount
*account
,
309 const gchar
*password
, GError
*error
, gpointer data
)
311 PurpleProtocol
*protocol
= data
;
313 if ((password
== NULL
|| *password
== '\0') &&
314 !(purple_protocol_get_options(protocol
) & OPT_PROTO_NO_PASSWORD
) &&
315 !(purple_protocol_get_options(protocol
) & OPT_PROTO_PASSWORD_OPTIONAL
))
316 purple_account_request_password(account
,
317 G_CALLBACK(request_password_ok_cb
),
318 G_CALLBACK(request_password_cancel_cb
), account
);
320 _purple_connection_new(account
, FALSE
, password
);
324 purple_account_connect(PurpleAccount
*account
)
326 const char *username
;
327 PurpleProtocol
*protocol
;
328 PurpleAccountPrivate
*priv
;
330 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
332 username
= purple_account_get_username(account
);
334 if (!purple_account_get_enabled(account
, purple_core_get_ui())) {
335 purple_debug_info("account",
336 "Account %s not enabled, not connecting.\n",
341 protocol
= purple_protocols_find(purple_account_get_protocol_id(account
));
342 if (protocol
== NULL
) {
345 message
= g_strdup_printf(_("Missing protocol for %s"), username
);
346 purple_notify_error(account
, _("Connection Error"), message
,
347 NULL
, purple_request_cpar_from_account(account
));
352 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
354 purple_debug_info("account", "Connecting to account %s.\n", username
);
356 if (priv
->password
!= NULL
) {
357 purple_account_connect_got_password_cb(account
,
358 priv
->password
, NULL
, protocol
);
360 purple_keyring_get_password(account
,
361 purple_account_connect_got_password_cb
, protocol
);
366 purple_account_disconnect(PurpleAccount
*account
)
368 PurpleConnection
*gc
;
369 PurpleAccountPrivate
*priv
;
370 const char *username
;
372 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
373 g_return_if_fail(!purple_account_is_disconnecting(account
));
374 g_return_if_fail(!purple_account_is_disconnected(account
));
376 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
378 username
= purple_account_get_username(account
);
379 purple_debug_info("account", "Disconnecting account %s (%p)\n",
380 username
? username
: "(null)", account
);
382 priv
->disconnecting
= TRUE
;
384 gc
= purple_account_get_connection(account
);
386 purple_account_set_connection(account
, NULL
);
388 priv
->disconnecting
= FALSE
;
392 purple_account_is_disconnecting(const PurpleAccount
*account
)
394 PurpleAccountPrivate
*priv
;
396 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), TRUE
);
398 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
399 return priv
->disconnecting
;
403 purple_account_notify_added(PurpleAccount
*account
, const char *remote_user
,
404 const char *id
, const char *alias
,
407 PurpleAccountUiOps
*ui_ops
;
409 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
410 g_return_if_fail(remote_user
!= NULL
);
412 ui_ops
= purple_accounts_get_ui_ops();
414 if (ui_ops
!= NULL
&& ui_ops
->notify_added
!= NULL
)
415 ui_ops
->notify_added(account
, remote_user
, id
, alias
, message
);
419 purple_account_request_add(PurpleAccount
*account
, const char *remote_user
,
420 const char *id
, const char *alias
,
423 PurpleAccountUiOps
*ui_ops
;
425 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
426 g_return_if_fail(remote_user
!= NULL
);
428 ui_ops
= purple_accounts_get_ui_ops();
430 if (ui_ops
!= NULL
&& ui_ops
->request_add
!= NULL
)
431 ui_ops
->request_add(account
, remote_user
, id
, alias
, message
);
434 static PurpleAccountRequestInfo
*
435 purple_account_request_info_unref(PurpleAccountRequestInfo
*info
)
440 /* TODO: This will leak info->user_data, but there is no callback to just clean that up */
447 purple_account_request_close_info(PurpleAccountRequestInfo
*info
)
449 PurpleAccountUiOps
*ops
;
451 ops
= purple_accounts_get_ui_ops();
453 if (ops
!= NULL
&& ops
->close_account_request
!= NULL
)
454 ops
->close_account_request(info
->ui_handle
);
456 purple_account_request_info_unref(info
);
460 purple_account_request_close_with_account(PurpleAccount
*account
)
464 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
466 for (l
= handles
; l
!= NULL
; l
= l_next
) {
467 PurpleAccountRequestInfo
*info
= l
->data
;
471 if (info
->account
== account
) {
472 handles
= g_list_remove(handles
, info
);
473 purple_account_request_close_info(info
);
479 purple_account_request_close(void *ui_handle
)
483 g_return_if_fail(ui_handle
!= NULL
);
485 for (l
= handles
; l
!= NULL
; l
= l_next
) {
486 PurpleAccountRequestInfo
*info
= l
->data
;
490 if (info
->ui_handle
== ui_handle
) {
491 handles
= g_list_remove(handles
, info
);
492 purple_account_request_close_info(info
);
498 request_auth_cb(const char *message
, void *data
)
500 PurpleAccountRequestInfo
*info
= data
;
502 handles
= g_list_remove(handles
, info
);
504 if (info
->auth_cb
!= NULL
)
505 info
->auth_cb(message
, info
->userdata
);
507 purple_signal_emit(purple_accounts_get_handle(),
508 "account-authorization-granted", info
->account
, info
->user
, message
);
510 purple_account_request_info_unref(info
);
514 request_deny_cb(const char *message
, void *data
)
516 PurpleAccountRequestInfo
*info
= data
;
518 handles
= g_list_remove(handles
, info
);
520 if (info
->deny_cb
!= NULL
)
521 info
->deny_cb(message
, info
->userdata
);
523 purple_signal_emit(purple_accounts_get_handle(),
524 "account-authorization-denied", info
->account
, info
->user
, message
);
526 purple_account_request_info_unref(info
);
530 purple_account_request_authorization(PurpleAccount
*account
, const char *remote_user
,
531 const char *id
, const char *alias
, const char *message
, gboolean on_list
,
532 PurpleAccountRequestAuthorizationCb auth_cb
, PurpleAccountRequestAuthorizationCb deny_cb
, void *user_data
)
534 PurpleAccountUiOps
*ui_ops
;
535 PurpleAccountRequestInfo
*info
;
537 char *response
= NULL
;
539 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), NULL
);
540 g_return_val_if_fail(remote_user
!= NULL
, NULL
);
542 ui_ops
= purple_accounts_get_ui_ops();
544 plugin_return
= GPOINTER_TO_INT(
545 purple_signal_emit_return_1(
546 purple_accounts_get_handle(),
547 "account-authorization-requested",
548 account
, remote_user
, message
, &response
551 switch (plugin_return
)
553 case PURPLE_ACCOUNT_RESPONSE_IGNORE
:
556 case PURPLE_ACCOUNT_RESPONSE_ACCEPT
:
558 auth_cb(response
, user_data
);
561 case PURPLE_ACCOUNT_RESPONSE_DENY
:
563 deny_cb(response
, user_data
);
570 if (ui_ops
!= NULL
&& ui_ops
->request_authorize
!= NULL
) {
571 info
= g_new0(PurpleAccountRequestInfo
, 1);
572 info
->type
= PURPLE_ACCOUNT_REQUEST_AUTHORIZATION
;
573 info
->account
= account
;
574 info
->auth_cb
= auth_cb
;
575 info
->deny_cb
= deny_cb
;
576 info
->userdata
= user_data
;
577 info
->user
= g_strdup(remote_user
);
578 info
->ref
= 2; /* We hold an extra ref to make sure info remains valid
579 if any of the callbacks are called synchronously. We
580 unref it after the function call */
582 info
->ui_handle
= ui_ops
->request_authorize(account
, remote_user
, id
, alias
, message
,
583 on_list
, request_auth_cb
, request_deny_cb
, info
);
585 info
= purple_account_request_info_unref(info
);
587 handles
= g_list_append(handles
, info
);
588 return info
->ui_handle
;
596 change_password_cb(PurpleAccount
*account
, PurpleRequestFields
*fields
)
598 const char *orig_pass
, *new_pass_1
, *new_pass_2
;
600 orig_pass
= purple_request_fields_get_string(fields
, "password");
601 new_pass_1
= purple_request_fields_get_string(fields
, "new_password_1");
602 new_pass_2
= purple_request_fields_get_string(fields
, "new_password_2");
604 if (g_utf8_collate(new_pass_1
, new_pass_2
))
606 purple_notify_error(account
, NULL
,
607 _("New passwords do not match."), NULL
,
608 purple_request_cpar_from_account(account
));
613 if ((purple_request_fields_is_field_required(fields
, "password") &&
614 (orig_pass
== NULL
|| *orig_pass
== '\0')) ||
615 (purple_request_fields_is_field_required(fields
, "new_password_1") &&
616 (new_pass_1
== NULL
|| *new_pass_1
== '\0')) ||
617 (purple_request_fields_is_field_required(fields
, "new_password_2") &&
618 (new_pass_2
== NULL
|| *new_pass_2
== '\0')))
620 purple_notify_error(account
, NULL
,
621 _("Fill out all fields completely."), NULL
,
622 purple_request_cpar_from_account(account
));
626 purple_account_change_password(account
, orig_pass
, new_pass_1
);
630 purple_account_request_change_password(PurpleAccount
*account
)
632 PurpleRequestFields
*fields
;
633 PurpleRequestFieldGroup
*group
;
634 PurpleRequestField
*field
;
635 PurpleConnection
*gc
;
636 PurpleProtocol
*protocol
= NULL
;
639 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
640 g_return_if_fail(purple_account_is_connected(account
));
642 gc
= purple_account_get_connection(account
);
644 protocol
= purple_connection_get_protocol(gc
);
646 fields
= purple_request_fields_new();
648 group
= purple_request_field_group_new(NULL
);
649 purple_request_fields_add_group(fields
, group
);
651 field
= purple_request_field_string_new("password", _("Original password"),
653 purple_request_field_string_set_masked(field
, TRUE
);
654 if (!protocol
|| !(purple_protocol_get_options(protocol
) & OPT_PROTO_PASSWORD_OPTIONAL
))
655 purple_request_field_set_required(field
, TRUE
);
656 purple_request_field_group_add_field(group
, field
);
658 field
= purple_request_field_string_new("new_password_1",
661 purple_request_field_string_set_masked(field
, TRUE
);
662 if (!protocol
|| !(purple_protocol_get_options(protocol
) & OPT_PROTO_PASSWORD_OPTIONAL
))
663 purple_request_field_set_required(field
, TRUE
);
664 purple_request_field_group_add_field(group
, field
);
666 field
= purple_request_field_string_new("new_password_2",
667 _("New password (again)"),
669 purple_request_field_string_set_masked(field
, TRUE
);
670 if (!protocol
|| !(purple_protocol_get_options(protocol
) & OPT_PROTO_PASSWORD_OPTIONAL
))
671 purple_request_field_set_required(field
, TRUE
);
672 purple_request_field_group_add_field(group
, field
);
674 g_snprintf(primary
, sizeof(primary
), _("Change password for %s"),
675 purple_account_get_username(account
));
677 /* I'm sticking this somewhere in the code: bologna */
679 purple_request_fields(purple_account_get_connection(account
), NULL
,
680 primary
, _("Please enter your current password and your new "
681 "password."), fields
, _("OK"), G_CALLBACK(change_password_cb
),
682 _("Cancel"), NULL
, purple_request_cpar_from_account(account
),
687 set_user_info_cb(PurpleAccount
*account
, const char *user_info
)
689 PurpleConnection
*gc
;
691 purple_account_set_user_info(account
, user_info
);
692 gc
= purple_account_get_connection(account
);
693 purple_serv_set_info(gc
, user_info
);
697 purple_account_request_change_user_info(PurpleAccount
*account
)
699 PurpleConnection
*gc
;
702 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
703 g_return_if_fail(purple_account_is_connected(account
));
705 gc
= purple_account_get_connection(account
);
707 g_snprintf(primary
, sizeof(primary
),
708 _("Change user information for %s"),
709 purple_account_get_username(account
));
711 purple_request_input(gc
, _("Set User Info"), primary
, NULL
,
712 purple_account_get_user_info(account
),
713 TRUE
, FALSE
, ((gc
!= NULL
) &&
714 (purple_connection_get_flags(gc
) & PURPLE_CONNECTION_FLAG_HTML
) ? "html" : NULL
),
715 _("Save"), G_CALLBACK(set_user_info_cb
),
717 purple_request_cpar_from_account(account
),
722 purple_account_set_username(PurpleAccount
*account
, const char *username
)
724 PurpleBlistUiOps
*blist_ops
;
725 PurpleAccountPrivate
*priv
;
727 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
729 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
731 g_free(priv
->username
);
732 priv
->username
= g_strdup(username
);
734 g_object_notify_by_pspec(G_OBJECT(account
), properties
[PROP_USERNAME
]);
736 purple_accounts_schedule_save();
738 /* if the name changes, we should re-write the buddy list
739 * to disk with the new name */
740 blist_ops
= purple_blist_get_ui_ops();
741 if (blist_ops
!= NULL
&& blist_ops
->save_account
!= NULL
)
742 blist_ops
->save_account(account
);
746 purple_account_set_password(PurpleAccount
*account
, const gchar
*password
,
747 PurpleKeyringSaveCallback cb
, gpointer data
)
749 PurpleAccountPrivate
*priv
;
751 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
753 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
755 purple_str_wipe(priv
->password
);
756 priv
->password
= g_strdup(password
);
758 purple_accounts_schedule_save();
760 if (!purple_account_get_remember_password(account
)) {
761 purple_debug_info("account",
762 "Password for %s set, not sent to keyring.\n",
763 purple_account_get_username(account
));
766 cb(account
, NULL
, data
);
768 purple_keyring_set_password(account
, password
, cb
, data
);
773 purple_account_set_private_alias(PurpleAccount
*account
, const char *alias
)
775 PurpleAccountPrivate
*priv
;
777 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
779 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
782 * Do nothing if alias and priv->alias are both NULL. Or if
783 * they're the exact same string.
785 if (alias
== priv
->alias
)
788 if ((!alias
&& priv
->alias
) || (alias
&& !priv
->alias
) ||
789 g_utf8_collate(priv
->alias
, alias
))
791 char *old
= priv
->alias
;
793 priv
->alias
= g_strdup(alias
);
794 g_object_notify_by_pspec(G_OBJECT(account
),
795 properties
[PROP_PRIVATE_ALIAS
]);
796 purple_signal_emit(purple_accounts_get_handle(), "account-alias-changed",
800 purple_accounts_schedule_save();
805 purple_account_set_user_info(PurpleAccount
*account
, const char *user_info
)
807 PurpleAccountPrivate
*priv
;
809 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
811 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
813 g_free(priv
->user_info
);
814 priv
->user_info
= g_strdup(user_info
);
816 g_object_notify_by_pspec(G_OBJECT(account
), properties
[PROP_USER_INFO
]);
818 purple_accounts_schedule_save();
821 void purple_account_set_buddy_icon_path(PurpleAccount
*account
, const char *path
)
823 PurpleAccountPrivate
*priv
;
825 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
827 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
829 g_free(priv
->buddy_icon_path
);
830 priv
->buddy_icon_path
= g_strdup(path
);
832 g_object_notify_by_pspec(G_OBJECT(account
),
833 properties
[PROP_BUDDY_ICON_PATH
]);
835 purple_accounts_schedule_save();
839 purple_account_set_protocol_id(PurpleAccount
*account
, const char *protocol_id
)
841 PurpleAccountPrivate
*priv
;
843 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
844 g_return_if_fail(protocol_id
!= NULL
);
846 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
848 g_free(priv
->protocol_id
);
849 priv
->protocol_id
= g_strdup(protocol_id
);
851 g_object_notify_by_pspec(G_OBJECT(account
), properties
[PROP_PROTOCOL_ID
]);
853 purple_accounts_schedule_save();
857 purple_account_set_connection(PurpleAccount
*account
, PurpleConnection
*gc
)
859 PurpleAccountPrivate
*priv
;
861 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
863 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
866 g_object_notify_by_pspec(G_OBJECT(account
), properties
[PROP_CONNECTION
]);
870 purple_account_set_remember_password(PurpleAccount
*account
, gboolean value
)
872 PurpleAccountPrivate
*priv
;
874 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
876 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
877 priv
->remember_pass
= value
;
879 g_object_notify_by_pspec(G_OBJECT(account
),
880 properties
[PROP_REMEMBER_PASSWORD
]);
882 purple_accounts_schedule_save();
886 purple_account_set_check_mail(PurpleAccount
*account
, gboolean value
)
888 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
890 purple_account_set_bool(account
, "check-mail", value
);
892 g_object_notify_by_pspec(G_OBJECT(account
), properties
[PROP_CHECK_MAIL
]);
896 purple_account_set_enabled(PurpleAccount
*account
, const char *ui
,
899 PurpleConnection
*gc
;
900 PurpleAccountPrivate
*priv
;
901 gboolean was_enabled
= FALSE
;
903 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
904 g_return_if_fail(ui
!= NULL
);
906 was_enabled
= purple_account_get_enabled(account
, ui
);
908 purple_account_set_ui_bool(account
, ui
, "auto-login", value
);
909 gc
= purple_account_get_connection(account
);
911 if(was_enabled
&& !value
)
912 purple_signal_emit(purple_accounts_get_handle(), "account-disabled", account
);
913 else if(!was_enabled
&& value
)
914 purple_signal_emit(purple_accounts_get_handle(), "account-enabled", account
);
916 g_object_notify_by_pspec(G_OBJECT(account
), properties
[PROP_ENABLED
]);
918 if ((gc
!= NULL
) && (_purple_connection_wants_to_die(gc
)))
921 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
923 if (value
&& purple_presence_is_online(priv
->presence
))
924 purple_account_connect(account
);
925 else if (!value
&& !purple_account_is_disconnected(account
))
926 purple_account_disconnect(account
);
930 purple_account_set_proxy_info(PurpleAccount
*account
, PurpleProxyInfo
*info
)
932 PurpleAccountPrivate
*priv
;
934 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
936 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
938 if (priv
->proxy_info
!= NULL
)
939 purple_proxy_info_destroy(priv
->proxy_info
);
941 priv
->proxy_info
= info
;
943 purple_accounts_schedule_save();
947 purple_account_set_privacy_type(PurpleAccount
*account
, PurpleAccountPrivacyType privacy_type
)
949 PurpleAccountPrivate
*priv
;
951 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
953 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
954 priv
->privacy_type
= privacy_type
;
958 purple_account_set_status_types(PurpleAccount
*account
, GList
*status_types
)
960 PurpleAccountPrivate
*priv
;
962 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
964 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
966 /* Out with the old... */
967 if (priv
->status_types
!= NULL
)
969 g_list_foreach(priv
->status_types
, (GFunc
)purple_status_type_destroy
, NULL
);
970 g_list_free(priv
->status_types
);
973 /* In with the new... */
974 priv
->status_types
= status_types
;
978 purple_account_set_status(PurpleAccount
*account
, const char *status_id
,
979 gboolean active
, ...)
986 va_start(args
, active
);
987 while ((id
= va_arg(args
, const char *)) != NULL
)
989 attrs
= g_list_append(attrs
, (char *)id
);
990 data
= va_arg(args
, void *);
991 attrs
= g_list_append(attrs
, data
);
993 purple_account_set_status_list(account
, status_id
, active
, attrs
);
999 purple_account_set_status_list(PurpleAccount
*account
, const char *status_id
,
1000 gboolean active
, GList
*attrs
)
1002 PurpleStatus
*status
;
1004 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
1005 g_return_if_fail(status_id
!= NULL
);
1007 status
= purple_account_get_status(account
, status_id
);
1010 purple_debug_error("account",
1011 "Invalid status ID '%s' for account %s (%s)\n",
1012 status_id
, purple_account_get_username(account
),
1013 purple_account_get_protocol_id(account
));
1017 if (active
|| purple_status_is_independent(status
))
1018 purple_status_set_active_with_attrs_list(status
, active
, attrs
);
1021 * Our current statuses are saved to accounts.xml (so that when we
1022 * reconnect, we go back to the previous status).
1024 purple_accounts_schedule_save();
1027 struct public_alias_closure
1029 PurpleAccount
*account
;
1030 gpointer failure_cb
;
1034 set_public_alias_unsupported(gpointer data
)
1036 struct public_alias_closure
*closure
= data
;
1037 PurpleSetPublicAliasFailureCallback failure_cb
= closure
->failure_cb
;
1039 failure_cb(closure
->account
,
1040 _("This protocol does not support setting a public alias."));
1042 g_object_unref(closure
->account
);
1049 purple_account_set_public_alias(PurpleAccount
*account
,
1050 const char *alias
, PurpleSetPublicAliasSuccessCallback success_cb
,
1051 PurpleSetPublicAliasFailureCallback failure_cb
)
1053 PurpleConnection
*gc
;
1054 PurpleProtocol
*protocol
= NULL
;
1056 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
1057 g_return_if_fail(purple_account_is_connected(account
));
1059 gc
= purple_account_get_connection(account
);
1060 protocol
= purple_connection_get_protocol(gc
);
1062 if (PURPLE_PROTOCOL_IMPLEMENTS(protocol
, SERVER_IFACE
, set_public_alias
))
1063 purple_protocol_server_iface_set_public_alias(protocol
, gc
, alias
, success_cb
, failure_cb
);
1064 else if (failure_cb
) {
1065 struct public_alias_closure
*closure
=
1066 g_new0(struct public_alias_closure
, 1);
1067 closure
->account
= g_object_ref(account
);
1068 closure
->failure_cb
= failure_cb
;
1069 g_timeout_add(0, set_public_alias_unsupported
, closure
);
1074 get_public_alias_unsupported(gpointer data
)
1076 struct public_alias_closure
*closure
= data
;
1077 PurpleGetPublicAliasFailureCallback failure_cb
= closure
->failure_cb
;
1079 failure_cb(closure
->account
,
1080 _("This protocol does not support fetching the public alias."));
1082 g_object_unref(closure
->account
);
1089 purple_account_get_public_alias(PurpleAccount
*account
,
1090 PurpleGetPublicAliasSuccessCallback success_cb
,
1091 PurpleGetPublicAliasFailureCallback failure_cb
)
1093 PurpleConnection
*gc
;
1094 PurpleProtocol
*protocol
= NULL
;
1096 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
1097 g_return_if_fail(purple_account_is_connected(account
));
1099 gc
= purple_account_get_connection(account
);
1100 protocol
= purple_connection_get_protocol(gc
);
1102 if (PURPLE_PROTOCOL_IMPLEMENTS(protocol
, SERVER_IFACE
, get_public_alias
))
1103 purple_protocol_server_iface_get_public_alias(protocol
, gc
, success_cb
, failure_cb
);
1104 else if (failure_cb
) {
1105 struct public_alias_closure
*closure
=
1106 g_new0(struct public_alias_closure
, 1);
1107 closure
->account
= g_object_ref(account
);
1108 closure
->failure_cb
= failure_cb
;
1109 g_timeout_add(0, get_public_alias_unsupported
, closure
);
1114 purple_account_get_silence_suppression(const PurpleAccount
*account
)
1116 return purple_account_get_bool(account
, "silence-suppression", FALSE
);
1120 purple_account_set_silence_suppression(PurpleAccount
*account
, gboolean value
)
1122 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
1124 purple_account_set_bool(account
, "silence-suppression", value
);
1128 delete_setting(void *data
)
1130 PurpleAccountSetting
*setting
= (PurpleAccountSetting
*)data
;
1132 g_free(setting
->ui
);
1133 g_value_unset(&setting
->value
);
1139 purple_account_clear_settings(PurpleAccount
*account
)
1141 PurpleAccountPrivate
*priv
;
1143 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
1145 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1146 g_hash_table_destroy(priv
->settings
);
1148 priv
->settings
= g_hash_table_new_full(g_str_hash
, g_str_equal
,
1149 g_free
, delete_setting
);
1153 purple_account_remove_setting(PurpleAccount
*account
, const char *setting
)
1155 PurpleAccountPrivate
*priv
;
1157 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
1158 g_return_if_fail(setting
!= NULL
);
1160 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1162 g_hash_table_remove(priv
->settings
, setting
);
1166 purple_account_set_int(PurpleAccount
*account
, const char *name
, int value
)
1168 PurpleAccountSetting
*setting
;
1169 PurpleAccountPrivate
*priv
;
1171 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
1172 g_return_if_fail(name
!= NULL
);
1174 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1176 setting
= g_new0(PurpleAccountSetting
, 1);
1178 g_value_init(&setting
->value
, G_TYPE_INT
);
1179 g_value_set_int(&setting
->value
, value
);
1181 g_hash_table_insert(priv
->settings
, g_strdup(name
), setting
);
1183 purple_accounts_schedule_save();
1187 purple_account_set_string(PurpleAccount
*account
, const char *name
,
1190 PurpleAccountSetting
*setting
;
1191 PurpleAccountPrivate
*priv
;
1193 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
1194 g_return_if_fail(name
!= NULL
);
1196 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1198 setting
= g_new0(PurpleAccountSetting
, 1);
1200 g_value_init(&setting
->value
, G_TYPE_STRING
);
1201 g_value_set_string(&setting
->value
, value
);
1203 g_hash_table_insert(priv
->settings
, g_strdup(name
), setting
);
1205 purple_accounts_schedule_save();
1209 purple_account_set_bool(PurpleAccount
*account
, const char *name
, gboolean value
)
1211 PurpleAccountSetting
*setting
;
1212 PurpleAccountPrivate
*priv
;
1214 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
1215 g_return_if_fail(name
!= NULL
);
1217 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1219 setting
= g_new0(PurpleAccountSetting
, 1);
1221 g_value_init(&setting
->value
, G_TYPE_BOOLEAN
);
1222 g_value_set_boolean(&setting
->value
, value
);
1224 g_hash_table_insert(priv
->settings
, g_strdup(name
), setting
);
1226 purple_accounts_schedule_save();
1230 get_ui_settings_table(PurpleAccount
*account
, const char *ui
)
1233 PurpleAccountPrivate
*priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1235 table
= g_hash_table_lookup(priv
->ui_settings
, ui
);
1237 if (table
== NULL
) {
1238 table
= g_hash_table_new_full(g_str_hash
, g_str_equal
, g_free
,
1240 g_hash_table_insert(priv
->ui_settings
, g_strdup(ui
), table
);
1247 purple_account_set_ui_int(PurpleAccount
*account
, const char *ui
,
1248 const char *name
, int value
)
1250 PurpleAccountSetting
*setting
;
1253 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
1254 g_return_if_fail(ui
!= NULL
);
1255 g_return_if_fail(name
!= NULL
);
1257 setting
= g_new0(PurpleAccountSetting
, 1);
1259 setting
->ui
= g_strdup(ui
);
1260 g_value_init(&setting
->value
, G_TYPE_INT
);
1261 g_value_set_int(&setting
->value
, value
);
1263 table
= get_ui_settings_table(account
, ui
);
1265 g_hash_table_insert(table
, g_strdup(name
), setting
);
1267 purple_accounts_schedule_save();
1271 purple_account_set_ui_string(PurpleAccount
*account
, const char *ui
,
1272 const char *name
, const char *value
)
1274 PurpleAccountSetting
*setting
;
1277 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
1278 g_return_if_fail(ui
!= NULL
);
1279 g_return_if_fail(name
!= NULL
);
1281 setting
= g_new0(PurpleAccountSetting
, 1);
1283 setting
->ui
= g_strdup(ui
);
1284 g_value_init(&setting
->value
, G_TYPE_STRING
);
1285 g_value_set_string(&setting
->value
, value
);
1287 table
= get_ui_settings_table(account
, ui
);
1289 g_hash_table_insert(table
, g_strdup(name
), setting
);
1291 purple_accounts_schedule_save();
1295 purple_account_set_ui_bool(PurpleAccount
*account
, const char *ui
,
1296 const char *name
, gboolean value
)
1298 PurpleAccountSetting
*setting
;
1301 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
1302 g_return_if_fail(ui
!= NULL
);
1303 g_return_if_fail(name
!= NULL
);
1305 setting
= g_new0(PurpleAccountSetting
, 1);
1307 setting
->ui
= g_strdup(ui
);
1308 g_value_init(&setting
->value
, G_TYPE_BOOLEAN
);
1309 g_value_set_boolean(&setting
->value
, value
);
1311 table
= get_ui_settings_table(account
, ui
);
1313 g_hash_table_insert(table
, g_strdup(name
), setting
);
1315 purple_accounts_schedule_save();
1318 static PurpleConnectionState
1319 purple_account_get_state(const PurpleAccount
*account
)
1321 PurpleConnection
*gc
;
1323 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), PURPLE_CONNECTION_DISCONNECTED
);
1325 gc
= purple_account_get_connection(account
);
1327 return PURPLE_CONNECTION_DISCONNECTED
;
1329 return purple_connection_get_state(gc
);
1333 purple_account_is_connected(const PurpleAccount
*account
)
1335 return (purple_account_get_state(account
) == PURPLE_CONNECTION_CONNECTED
);
1339 purple_account_is_connecting(const PurpleAccount
*account
)
1341 return (purple_account_get_state(account
) == PURPLE_CONNECTION_CONNECTING
);
1345 purple_account_is_disconnected(const PurpleAccount
*account
)
1347 return (purple_account_get_state(account
) == PURPLE_CONNECTION_DISCONNECTED
);
1351 purple_account_get_username(const PurpleAccount
*account
)
1353 PurpleAccountPrivate
*priv
;
1355 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), NULL
);
1357 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1358 return priv
->username
;
1362 purple_account_get_password_got(PurpleAccount
*account
,
1363 const gchar
*password
, GError
*error
, gpointer data
)
1365 PurpleCallbackBundle
*cbb
= data
;
1366 PurpleKeyringReadCallback cb
;
1367 PurpleAccountPrivate
*priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1369 purple_debug_info("account",
1370 "Read password for account %s from async keyring.\n",
1371 purple_account_get_username(account
));
1373 purple_str_wipe(priv
->password
);
1374 priv
->password
= g_strdup(password
);
1376 cb
= (PurpleKeyringReadCallback
)cbb
->cb
;
1378 cb(account
, password
, error
, cbb
->data
);
1384 purple_account_get_password(PurpleAccount
*account
,
1385 PurpleKeyringReadCallback cb
, gpointer data
)
1387 PurpleAccountPrivate
*priv
;
1389 if (account
== NULL
) {
1390 cb(NULL
, NULL
, NULL
, data
);
1394 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1396 if (priv
->password
!= NULL
) {
1397 purple_debug_info("account",
1398 "Reading password for account %s from cache.\n",
1399 purple_account_get_username(account
));
1400 cb(account
, priv
->password
, NULL
, data
);
1402 PurpleCallbackBundle
*cbb
= g_new0(PurpleCallbackBundle
, 1);
1403 cbb
->cb
= PURPLE_CALLBACK(cb
);
1406 purple_debug_info("account",
1407 "Reading password for account %s from async keyring.\n",
1408 purple_account_get_username(account
));
1409 purple_keyring_get_password(account
,
1410 purple_account_get_password_got
, cbb
);
1415 purple_account_get_private_alias(const PurpleAccount
*account
)
1417 PurpleAccountPrivate
*priv
;
1419 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), NULL
);
1421 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1426 purple_account_get_user_info(const PurpleAccount
*account
)
1428 PurpleAccountPrivate
*priv
;
1430 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), NULL
);
1432 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1433 return priv
->user_info
;
1437 purple_account_get_buddy_icon_path(const PurpleAccount
*account
)
1439 PurpleAccountPrivate
*priv
;
1441 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), NULL
);
1443 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1444 return priv
->buddy_icon_path
;
1448 purple_account_get_protocol_id(const PurpleAccount
*account
)
1450 PurpleAccountPrivate
*priv
;
1452 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), NULL
);
1454 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1455 return priv
->protocol_id
;
1459 purple_account_get_protocol_name(const PurpleAccount
*account
)
1463 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), NULL
);
1465 p
= purple_protocols_find(purple_account_get_protocol_id(account
));
1467 return (p
&& purple_protocol_get_name(p
) ?
1468 _(purple_protocol_get_name(p
)) : _("Unknown"));
1472 purple_account_get_connection(const PurpleAccount
*account
)
1474 PurpleAccountPrivate
*priv
;
1476 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), NULL
);
1478 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1483 purple_account_get_name_for_display(const PurpleAccount
*account
)
1485 PurpleBuddy
*self
= NULL
;
1486 PurpleConnection
*gc
= NULL
;
1487 const gchar
*name
= NULL
, *username
= NULL
, *displayname
= NULL
;
1489 name
= purple_account_get_private_alias(account
);
1495 username
= purple_account_get_username(account
);
1496 self
= purple_blist_find_buddy((PurpleAccount
*)account
, username
);
1499 const gchar
*calias
= purple_buddy_get_contact_alias(self
);
1501 /* We don't want to return the buddy name if the buddy/contact
1502 * doesn't have an alias set. */
1503 if (!purple_strequal(username
, calias
)) {
1508 gc
= purple_account_get_connection(account
);
1509 displayname
= purple_connection_get_display_name(gc
);
1519 purple_account_get_remember_password(const PurpleAccount
*account
)
1521 PurpleAccountPrivate
*priv
;
1523 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), FALSE
);
1525 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1526 return priv
->remember_pass
;
1530 purple_account_get_check_mail(const PurpleAccount
*account
)
1532 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), FALSE
);
1534 return purple_account_get_bool(account
, "check-mail", FALSE
);
1538 purple_account_get_enabled(const PurpleAccount
*account
, const char *ui
)
1540 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), FALSE
);
1541 g_return_val_if_fail(ui
!= NULL
, FALSE
);
1543 return purple_account_get_ui_bool(account
, ui
, "auto-login", FALSE
);
1547 purple_account_get_proxy_info(const PurpleAccount
*account
)
1549 PurpleAccountPrivate
*priv
;
1551 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), NULL
);
1553 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1554 return priv
->proxy_info
;
1557 PurpleAccountPrivacyType
1558 purple_account_get_privacy_type(const PurpleAccount
*account
)
1560 PurpleAccountPrivate
*priv
;
1562 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL
);
1564 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1565 return priv
->privacy_type
;
1569 purple_account_privacy_permit_add(PurpleAccount
*account
, const char *who
,
1570 gboolean local_only
)
1575 PurpleBlistUiOps
*blist_ops
;
1576 PurpleAccountPrivate
*priv
;
1577 PurpleAccountUiOps
*ui_ops
= purple_accounts_get_ui_ops();
1579 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), FALSE
);
1580 g_return_val_if_fail(who
!= NULL
, FALSE
);
1582 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1583 name
= g_strdup(purple_normalize(account
, who
));
1585 for (l
= priv
->permit
; l
!= NULL
; l
= l
->next
) {
1586 if (g_str_equal(name
, l
->data
))
1587 /* This buddy already exists */
1593 /* This buddy already exists, so bail out */
1598 priv
->permit
= g_slist_append(priv
->permit
, name
);
1600 if (!local_only
&& purple_account_is_connected(account
))
1601 purple_serv_add_permit(purple_account_get_connection(account
), who
);
1603 if (ui_ops
!= NULL
&& ui_ops
->permit_added
!= NULL
)
1604 ui_ops
->permit_added(account
, who
);
1606 blist_ops
= purple_blist_get_ui_ops();
1607 if (blist_ops
!= NULL
&& blist_ops
->save_account
!= NULL
)
1608 blist_ops
->save_account(account
);
1610 /* This lets the UI know a buddy has had its privacy setting changed */
1611 buddy
= purple_blist_find_buddy(account
, name
);
1612 if (buddy
!= NULL
) {
1613 purple_signal_emit(purple_blist_get_handle(),
1614 "buddy-privacy-changed", buddy
);
1620 purple_account_privacy_permit_remove(PurpleAccount
*account
, const char *who
,
1621 gboolean local_only
)
1627 PurpleBlistUiOps
*blist_ops
;
1628 PurpleAccountPrivate
*priv
;
1629 PurpleAccountUiOps
*ui_ops
= purple_accounts_get_ui_ops();
1631 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), FALSE
);
1632 g_return_val_if_fail(who
!= NULL
, FALSE
);
1634 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1635 name
= purple_normalize(account
, who
);
1637 for (l
= priv
->permit
; l
!= NULL
; l
= l
->next
) {
1638 if (g_str_equal(name
, l
->data
))
1639 /* We found the buddy we were looking for */
1644 /* We didn't find the buddy we were looking for, so bail out */
1647 /* We should not free l->data just yet. There can be occasions where
1648 * l->data == who. In such cases, freeing l->data here can cause crashes
1649 * later when who is used. */
1651 priv
->permit
= g_slist_delete_link(priv
->permit
, l
);
1653 if (!local_only
&& purple_account_is_connected(account
))
1654 purple_serv_rem_permit(purple_account_get_connection(account
), who
);
1656 if (ui_ops
!= NULL
&& ui_ops
->permit_removed
!= NULL
)
1657 ui_ops
->permit_removed(account
, who
);
1659 blist_ops
= purple_blist_get_ui_ops();
1660 if (blist_ops
!= NULL
&& blist_ops
->save_account
!= NULL
)
1661 blist_ops
->save_account(account
);
1663 buddy
= purple_blist_find_buddy(account
, name
);
1664 if (buddy
!= NULL
) {
1665 purple_signal_emit(purple_blist_get_handle(),
1666 "buddy-privacy-changed", buddy
);
1673 purple_account_privacy_deny_add(PurpleAccount
*account
, const char *who
,
1674 gboolean local_only
)
1679 PurpleBlistUiOps
*blist_ops
;
1680 PurpleAccountPrivate
*priv
;
1681 PurpleAccountUiOps
*ui_ops
= purple_accounts_get_ui_ops();
1683 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), FALSE
);
1684 g_return_val_if_fail(who
!= NULL
, FALSE
);
1686 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1687 name
= g_strdup(purple_normalize(account
, who
));
1689 for (l
= priv
->deny
; l
!= NULL
; l
= l
->next
) {
1690 if (g_str_equal(name
, l
->data
))
1691 /* This buddy already exists */
1697 /* This buddy already exists, so bail out */
1702 priv
->deny
= g_slist_append(priv
->deny
, name
);
1704 if (!local_only
&& purple_account_is_connected(account
))
1705 purple_serv_add_deny(purple_account_get_connection(account
), who
);
1707 if (ui_ops
!= NULL
&& ui_ops
->deny_added
!= NULL
)
1708 ui_ops
->deny_added(account
, who
);
1710 blist_ops
= purple_blist_get_ui_ops();
1711 if (blist_ops
!= NULL
&& blist_ops
->save_account
!= NULL
)
1712 blist_ops
->save_account(account
);
1714 buddy
= purple_blist_find_buddy(account
, name
);
1715 if (buddy
!= NULL
) {
1716 purple_signal_emit(purple_blist_get_handle(),
1717 "buddy-privacy-changed", buddy
);
1723 purple_account_privacy_deny_remove(PurpleAccount
*account
, const char *who
,
1724 gboolean local_only
)
1727 const char *normalized
;
1730 PurpleBlistUiOps
*blist_ops
;
1731 PurpleAccountPrivate
*priv
;
1732 PurpleAccountUiOps
*ui_ops
= purple_accounts_get_ui_ops();
1734 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), FALSE
);
1735 g_return_val_if_fail(who
!= NULL
, FALSE
);
1737 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1738 normalized
= purple_normalize(account
, who
);
1740 for (l
= priv
->deny
; l
!= NULL
; l
= l
->next
) {
1741 if (g_str_equal(normalized
, l
->data
))
1742 /* We found the buddy we were looking for */
1747 /* We didn't find the buddy we were looking for, so bail out */
1750 buddy
= purple_blist_find_buddy(account
, normalized
);
1753 priv
->deny
= g_slist_delete_link(priv
->deny
, l
);
1755 if (!local_only
&& purple_account_is_connected(account
))
1756 purple_serv_rem_deny(purple_account_get_connection(account
), name
);
1758 if (ui_ops
!= NULL
&& ui_ops
->deny_removed
!= NULL
)
1759 ui_ops
->deny_removed(account
, who
);
1761 if (buddy
!= NULL
) {
1762 purple_signal_emit(purple_blist_get_handle(),
1763 "buddy-privacy-changed", buddy
);
1768 blist_ops
= purple_blist_get_ui_ops();
1769 if (blist_ops
!= NULL
&& blist_ops
->save_account
!= NULL
)
1770 blist_ops
->save_account(account
);
1776 * This makes sure your permit list contains all buddies from your
1777 * buddy list and ONLY buddies from your buddy list.
1780 add_all_buddies_to_permit_list(PurpleAccount
*account
, gboolean local
)
1783 PurpleAccountPrivate
*priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1785 /* Remove anyone in the permit list who is not in the buddylist */
1786 for (list
= priv
->permit
; list
!= NULL
; ) {
1787 char *person
= list
->data
;
1789 if (!purple_blist_find_buddy(account
, person
))
1790 purple_account_privacy_permit_remove(account
, person
, local
);
1793 /* Now make sure everyone in the buddylist is in the permit list */
1794 list
= purple_blist_find_buddies(account
, NULL
);
1795 while (list
!= NULL
)
1797 PurpleBuddy
*buddy
= list
->data
;
1798 const gchar
*name
= purple_buddy_get_name(buddy
);
1800 if (!g_slist_find_custom(priv
->permit
, name
, (GCompareFunc
)g_utf8_collate
))
1801 purple_account_privacy_permit_add(account
, name
, local
);
1802 list
= g_slist_delete_link(list
, list
);
1807 purple_account_privacy_allow(PurpleAccount
*account
, const char *who
)
1810 PurpleAccountPrivacyType type
= purple_account_get_privacy_type(account
);
1811 PurpleAccountPrivate
*priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1814 case PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL
:
1816 case PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS
:
1817 purple_account_privacy_permit_add(account
, who
, FALSE
);
1819 case PURPLE_ACCOUNT_PRIVACY_DENY_USERS
:
1820 purple_account_privacy_deny_remove(account
, who
, FALSE
);
1822 case PURPLE_ACCOUNT_PRIVACY_DENY_ALL
:
1824 /* Empty the allow-list. */
1825 const char *norm
= purple_normalize(account
, who
);
1826 for (list
= priv
->permit
; list
!= NULL
;) {
1827 char *person
= list
->data
;
1829 if (!purple_strequal(norm
, person
))
1830 purple_account_privacy_permit_remove(account
, person
, FALSE
);
1832 purple_account_privacy_permit_add(account
, who
, FALSE
);
1833 purple_account_set_privacy_type(account
, PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS
);
1836 case PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST
:
1837 if (!purple_blist_find_buddy(account
, who
)) {
1838 add_all_buddies_to_permit_list(account
, FALSE
);
1839 purple_account_privacy_permit_add(account
, who
, FALSE
);
1840 purple_account_set_privacy_type(account
, PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS
);
1844 g_return_if_reached();
1847 /* Notify the server if the privacy setting was changed */
1848 if (type
!= purple_account_get_privacy_type(account
) && purple_account_is_connected(account
))
1849 purple_serv_set_permit_deny(purple_account_get_connection(account
));
1853 purple_account_privacy_deny(PurpleAccount
*account
, const char *who
)
1856 PurpleAccountPrivacyType type
= purple_account_get_privacy_type(account
);
1857 PurpleAccountPrivate
*priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1860 case PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL
:
1862 /* Empty the deny-list. */
1863 const char *norm
= purple_normalize(account
, who
);
1864 for (list
= priv
->deny
; list
!= NULL
; ) {
1865 char *person
= list
->data
;
1867 if (!purple_strequal(norm
, person
))
1868 purple_account_privacy_deny_remove(account
, person
, FALSE
);
1870 purple_account_privacy_deny_add(account
, who
, FALSE
);
1871 purple_account_set_privacy_type(account
, PURPLE_ACCOUNT_PRIVACY_DENY_USERS
);
1874 case PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS
:
1875 purple_account_privacy_permit_remove(account
, who
, FALSE
);
1877 case PURPLE_ACCOUNT_PRIVACY_DENY_USERS
:
1878 purple_account_privacy_deny_add(account
, who
, FALSE
);
1880 case PURPLE_ACCOUNT_PRIVACY_DENY_ALL
:
1882 case PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST
:
1883 if (purple_blist_find_buddy(account
, who
)) {
1884 add_all_buddies_to_permit_list(account
, FALSE
);
1885 purple_account_privacy_permit_remove(account
, who
, FALSE
);
1886 purple_account_set_privacy_type(account
, PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS
);
1890 g_return_if_reached();
1893 /* Notify the server if the privacy setting was changed */
1894 if (type
!= purple_account_get_privacy_type(account
) && purple_account_is_connected(account
))
1895 purple_serv_set_permit_deny(purple_account_get_connection(account
));
1899 purple_account_privacy_get_permitted(PurpleAccount
*account
)
1901 PurpleAccountPrivate
*priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1903 g_return_val_if_fail(priv
!= NULL
, NULL
);
1905 return priv
->permit
;
1909 purple_account_privacy_get_denied(PurpleAccount
*account
)
1911 PurpleAccountPrivate
*priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1913 g_return_val_if_fail(priv
!= NULL
, NULL
);
1919 purple_account_privacy_check(PurpleAccount
*account
, const char *who
)
1922 PurpleAccountPrivate
*priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1924 switch (purple_account_get_privacy_type(account
)) {
1925 case PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL
:
1928 case PURPLE_ACCOUNT_PRIVACY_DENY_ALL
:
1931 case PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS
:
1932 who
= purple_normalize(account
, who
);
1933 for (list
=priv
->permit
; list
!=NULL
; list
=list
->next
) {
1934 if (g_str_equal(who
, list
->data
))
1939 case PURPLE_ACCOUNT_PRIVACY_DENY_USERS
:
1940 who
= purple_normalize(account
, who
);
1941 for (list
=priv
->deny
; list
!=NULL
; list
=list
->next
) {
1942 if (g_str_equal(who
, list
->data
))
1947 case PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST
:
1948 return (purple_blist_find_buddy(account
, who
) != NULL
);
1951 g_return_val_if_reached(TRUE
);
1956 purple_account_get_active_status(const PurpleAccount
*account
)
1958 PurpleAccountPrivate
*priv
;
1960 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), NULL
);
1962 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1963 return purple_presence_get_active_status(priv
->presence
);
1967 purple_account_get_status(const PurpleAccount
*account
, const char *status_id
)
1969 PurpleAccountPrivate
*priv
;
1971 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), NULL
);
1972 g_return_val_if_fail(status_id
!= NULL
, NULL
);
1974 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
1976 return purple_presence_get_status(priv
->presence
, status_id
);
1980 purple_account_get_status_type(const PurpleAccount
*account
, const char *id
)
1984 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), NULL
);
1985 g_return_val_if_fail(id
!= NULL
, NULL
);
1987 for (l
= purple_account_get_status_types(account
); l
!= NULL
; l
= l
->next
)
1989 PurpleStatusType
*status_type
= (PurpleStatusType
*)l
->data
;
1991 if (purple_strequal(purple_status_type_get_id(status_type
), id
))
1999 purple_account_get_status_type_with_primitive(const PurpleAccount
*account
, PurpleStatusPrimitive primitive
)
2003 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), NULL
);
2005 for (l
= purple_account_get_status_types(account
); l
!= NULL
; l
= l
->next
)
2007 PurpleStatusType
*status_type
= (PurpleStatusType
*)l
->data
;
2009 if (purple_status_type_get_primitive(status_type
) == primitive
)
2017 purple_account_get_presence(const PurpleAccount
*account
)
2019 PurpleAccountPrivate
*priv
;
2021 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), NULL
);
2023 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
2024 return priv
->presence
;
2028 purple_account_is_status_active(const PurpleAccount
*account
,
2029 const char *status_id
)
2031 PurpleAccountPrivate
*priv
;
2033 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), FALSE
);
2034 g_return_val_if_fail(status_id
!= NULL
, FALSE
);
2036 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
2038 return purple_presence_is_status_active(priv
->presence
, status_id
);
2042 purple_account_get_status_types(const PurpleAccount
*account
)
2044 PurpleAccountPrivate
*priv
;
2046 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), NULL
);
2048 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
2049 return priv
->status_types
;
2053 purple_account_get_int(const PurpleAccount
*account
, const char *name
,
2056 PurpleAccountSetting
*setting
;
2057 PurpleAccountPrivate
*priv
;
2059 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), default_value
);
2060 g_return_val_if_fail(name
!= NULL
, default_value
);
2062 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
2064 setting
= g_hash_table_lookup(priv
->settings
, name
);
2066 if (setting
== NULL
)
2067 return default_value
;
2069 g_return_val_if_fail(G_VALUE_HOLDS_INT(&setting
->value
), default_value
);
2071 return g_value_get_int(&setting
->value
);
2075 purple_account_get_string(const PurpleAccount
*account
, const char *name
,
2076 const char *default_value
)
2078 PurpleAccountSetting
*setting
;
2079 PurpleAccountPrivate
*priv
;
2081 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), default_value
);
2082 g_return_val_if_fail(name
!= NULL
, default_value
);
2084 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
2086 setting
= g_hash_table_lookup(priv
->settings
, name
);
2088 if (setting
== NULL
)
2089 return default_value
;
2091 g_return_val_if_fail(G_VALUE_HOLDS_STRING(&setting
->value
), default_value
);
2093 return g_value_get_string(&setting
->value
);
2097 purple_account_get_bool(const PurpleAccount
*account
, const char *name
,
2098 gboolean default_value
)
2100 PurpleAccountSetting
*setting
;
2101 PurpleAccountPrivate
*priv
;
2103 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), default_value
);
2104 g_return_val_if_fail(name
!= NULL
, default_value
);
2106 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
2108 setting
= g_hash_table_lookup(priv
->settings
, name
);
2110 if (setting
== NULL
)
2111 return default_value
;
2113 g_return_val_if_fail(G_VALUE_HOLDS_BOOLEAN(&setting
->value
), default_value
);
2115 return g_value_get_boolean(&setting
->value
);
2119 purple_account_get_ui_int(const PurpleAccount
*account
, const char *ui
,
2120 const char *name
, int default_value
)
2122 PurpleAccountSetting
*setting
;
2123 PurpleAccountPrivate
*priv
;
2126 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), default_value
);
2127 g_return_val_if_fail(ui
!= NULL
, default_value
);
2128 g_return_val_if_fail(name
!= NULL
, default_value
);
2130 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
2132 if ((table
= g_hash_table_lookup(priv
->ui_settings
, ui
)) == NULL
)
2133 return default_value
;
2135 if ((setting
= g_hash_table_lookup(table
, name
)) == NULL
)
2136 return default_value
;
2138 g_return_val_if_fail(G_VALUE_HOLDS_INT(&setting
->value
), default_value
);
2140 return g_value_get_int(&setting
->value
);
2144 purple_account_get_ui_string(const PurpleAccount
*account
, const char *ui
,
2145 const char *name
, const char *default_value
)
2147 PurpleAccountSetting
*setting
;
2148 PurpleAccountPrivate
*priv
;
2151 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), default_value
);
2152 g_return_val_if_fail(ui
!= NULL
, default_value
);
2153 g_return_val_if_fail(name
!= NULL
, default_value
);
2155 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
2157 if ((table
= g_hash_table_lookup(priv
->ui_settings
, ui
)) == NULL
)
2158 return default_value
;
2160 if ((setting
= g_hash_table_lookup(table
, name
)) == NULL
)
2161 return default_value
;
2163 g_return_val_if_fail(G_VALUE_HOLDS_STRING(&setting
->value
), default_value
);
2165 return g_value_get_string(&setting
->value
);
2169 purple_account_get_ui_bool(const PurpleAccount
*account
, const char *ui
,
2170 const char *name
, gboolean default_value
)
2172 PurpleAccountSetting
*setting
;
2173 PurpleAccountPrivate
*priv
;
2176 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), default_value
);
2177 g_return_val_if_fail(ui
!= NULL
, default_value
);
2178 g_return_val_if_fail(name
!= NULL
, default_value
);
2180 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
2182 if ((table
= g_hash_table_lookup(priv
->ui_settings
, ui
)) == NULL
)
2183 return default_value
;
2185 if ((setting
= g_hash_table_lookup(table
, name
)) == NULL
)
2186 return default_value
;
2188 g_return_val_if_fail(G_VALUE_HOLDS_BOOLEAN(&setting
->value
), default_value
);
2190 return g_value_get_boolean(&setting
->value
);
2194 purple_account_get_ui_data(const PurpleAccount
*account
)
2196 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), NULL
);
2198 return account
->ui_data
;
2202 purple_account_set_ui_data(PurpleAccount
*account
, gpointer ui_data
)
2204 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
2206 account
->ui_data
= ui_data
;
2210 purple_account_get_log(PurpleAccount
*account
, gboolean create
)
2212 PurpleAccountPrivate
*priv
;
2214 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), NULL
);
2216 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
2218 if(!priv
->system_log
&& create
){
2219 PurplePresence
*presence
;
2223 presence
= purple_account_get_presence(account
);
2224 login_time
= purple_presence_get_login_time(presence
);
2225 if (login_time
!= 0) {
2226 dt
= g_date_time_new_from_unix_local(login_time
);
2228 dt
= g_date_time_new_now_local();
2231 priv
->system_log
= purple_log_new(PURPLE_LOG_SYSTEM
,
2232 purple_account_get_username(account
),
2234 g_date_time_unref(dt
);
2237 return priv
->system_log
;
2241 purple_account_destroy_log(PurpleAccount
*account
)
2243 PurpleAccountPrivate
*priv
;
2245 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
2247 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
2249 if(priv
->system_log
){
2250 purple_log_free(priv
->system_log
);
2251 priv
->system_log
= NULL
;
2256 purple_account_add_buddy(PurpleAccount
*account
, PurpleBuddy
*buddy
, const char *message
)
2258 PurpleProtocol
*protocol
= NULL
;
2259 PurpleConnection
*gc
;
2261 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
2262 g_return_if_fail(PURPLE_IS_BUDDY(buddy
));
2264 gc
= purple_account_get_connection(account
);
2266 protocol
= purple_connection_get_protocol(gc
);
2268 if (protocol
!= NULL
)
2269 purple_protocol_server_iface_add_buddy(protocol
, gc
, buddy
,
2270 purple_buddy_get_group(buddy
), message
);
2274 purple_account_add_buddies(PurpleAccount
*account
, GList
*buddies
, const char *message
)
2276 PurpleProtocol
*protocol
= NULL
;
2277 PurpleConnection
*gc
= purple_account_get_connection(account
);
2280 protocol
= purple_connection_get_protocol(gc
);
2283 GList
*cur
, *groups
= NULL
;
2285 /* Make a list of what group each buddy is in */
2286 for (cur
= buddies
; cur
!= NULL
; cur
= cur
->next
) {
2287 PurpleBuddy
*buddy
= cur
->data
;
2288 groups
= g_list_append(groups
, purple_buddy_get_group(buddy
));
2291 if (PURPLE_PROTOCOL_IMPLEMENTS(protocol
, SERVER_IFACE
, add_buddies
))
2292 purple_protocol_server_iface_add_buddies(protocol
, gc
, buddies
, groups
, message
);
2293 else if (PURPLE_PROTOCOL_IMPLEMENTS(protocol
, SERVER_IFACE
, add_buddy
)) {
2294 GList
*curb
= buddies
, *curg
= groups
;
2296 while ((curb
!= NULL
) && (curg
!= NULL
)) {
2297 purple_protocol_server_iface_add_buddy(protocol
, gc
, curb
->data
, curg
->data
, message
);
2303 g_list_free(groups
);
2308 purple_account_remove_buddy(PurpleAccount
*account
, PurpleBuddy
*buddy
,
2311 PurpleProtocol
*protocol
= NULL
;
2312 PurpleConnection
*gc
= purple_account_get_connection(account
);
2315 protocol
= purple_connection_get_protocol(gc
);
2318 purple_protocol_server_iface_remove_buddy(protocol
, gc
, buddy
, group
);
2322 purple_account_remove_buddies(PurpleAccount
*account
, GList
*buddies
, GList
*groups
)
2324 PurpleProtocol
*protocol
= NULL
;
2325 PurpleConnection
*gc
= purple_account_get_connection(account
);
2328 protocol
= purple_connection_get_protocol(gc
);
2331 if (PURPLE_PROTOCOL_IMPLEMENTS(protocol
, SERVER_IFACE
, remove_buddies
))
2332 purple_protocol_server_iface_remove_buddies(protocol
, gc
, buddies
, groups
);
2334 GList
*curb
= buddies
;
2335 GList
*curg
= groups
;
2336 while ((curb
!= NULL
) && (curg
!= NULL
)) {
2337 purple_account_remove_buddy(account
, curb
->data
, curg
->data
);
2346 purple_account_remove_group(PurpleAccount
*account
, PurpleGroup
*group
)
2348 PurpleProtocol
*protocol
= NULL
;
2349 PurpleConnection
*gc
= purple_account_get_connection(account
);
2352 protocol
= purple_connection_get_protocol(gc
);
2355 purple_protocol_server_iface_remove_group(protocol
, gc
, group
);
2359 purple_account_change_password(PurpleAccount
*account
, const char *orig_pw
,
2362 PurpleProtocol
*protocol
= NULL
;
2363 PurpleConnection
*gc
= purple_account_get_connection(account
);
2365 purple_account_set_password(account
, new_pw
, NULL
, NULL
);
2368 protocol
= purple_connection_get_protocol(gc
);
2371 purple_protocol_server_iface_change_passwd(protocol
, gc
, orig_pw
, new_pw
);
2374 gboolean
purple_account_supports_offline_message(PurpleAccount
*account
, PurpleBuddy
*buddy
)
2376 PurpleConnection
*gc
;
2377 PurpleProtocol
*protocol
= NULL
;
2379 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), FALSE
);
2380 g_return_val_if_fail(PURPLE_IS_BUDDY(buddy
), FALSE
);
2382 gc
= purple_account_get_connection(account
);
2386 protocol
= purple_connection_get_protocol(gc
);
2390 return purple_protocol_client_iface_offline_message(protocol
, buddy
);
2394 _purple_account_set_current_error(PurpleAccount
*account
,
2395 PurpleConnectionErrorInfo
*new_err
)
2397 PurpleConnectionErrorInfo
*old_err
;
2398 PurpleAccountPrivate
*priv
;
2400 g_return_if_fail(PURPLE_IS_ACCOUNT(account
));
2401 priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
2403 old_err
= priv
->current_error
;
2405 if(new_err
== old_err
)
2408 priv
->current_error
= new_err
;
2410 purple_signal_emit(purple_accounts_get_handle(),
2411 "account-error-changed",
2412 account
, old_err
, new_err
);
2413 purple_accounts_schedule_save();
2416 g_free(old_err
->description
);
2418 PURPLE_DBUS_UNREGISTER_POINTER(old_err
);
2422 const PurpleConnectionErrorInfo
*
2423 purple_account_get_current_error(PurpleAccount
*account
)
2425 PurpleAccountPrivate
*priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
2427 return priv
->current_error
;
2431 purple_account_clear_current_error(PurpleAccount
*account
)
2433 _purple_account_set_current_error(account
, NULL
);
2436 static PurpleXmlNode
*
2437 status_attribute_to_xmlnode(const PurpleStatus
*status
, const PurpleStatusType
*type
,
2438 const PurpleStatusAttribute
*attr
)
2440 PurpleXmlNode
*node
;
2443 PurpleStatusAttribute
*default_attr
;
2444 GValue
*default_value
;
2448 id
= purple_status_attribute_get_id(attr
);
2449 g_return_val_if_fail(id
, NULL
);
2451 attr_value
= purple_status_get_attr_value(status
, id
);
2452 g_return_val_if_fail(attr_value
, NULL
);
2453 attr_type
= G_VALUE_TYPE(attr_value
);
2456 * If attr_value is a different type than it should be
2457 * then don't write it to the file.
2459 default_attr
= purple_status_type_get_attr(type
, id
);
2460 default_value
= purple_status_attribute_get_value(default_attr
);
2461 if (attr_type
!= G_VALUE_TYPE(default_value
))
2465 * If attr_value is the same as the default for this status
2466 * then there is no need to write it to the file.
2468 if (attr_type
== G_TYPE_STRING
)
2470 const char *string_value
= g_value_get_string(attr_value
);
2471 const char *default_string_value
= g_value_get_string(default_value
);
2472 if (purple_strequal(string_value
, default_string_value
))
2474 value
= g_strdup(g_value_get_string(attr_value
));
2476 else if (attr_type
== G_TYPE_INT
)
2478 int int_value
= g_value_get_int(attr_value
);
2479 if (int_value
== g_value_get_int(default_value
))
2481 value
= g_strdup_printf("%d", int_value
);
2483 else if (attr_type
== G_TYPE_BOOLEAN
)
2485 gboolean boolean_value
= g_value_get_boolean(attr_value
);
2486 if (boolean_value
== g_value_get_boolean(default_value
))
2488 value
= g_strdup(boolean_value
?
2496 g_return_val_if_fail(value
, NULL
);
2498 node
= purple_xmlnode_new("attribute");
2500 purple_xmlnode_set_attrib(node
, "id", id
);
2501 purple_xmlnode_set_attrib(node
, "value", value
);
2508 static PurpleXmlNode
*
2509 status_attrs_to_xmlnode(const PurpleStatus
*status
)
2511 PurpleStatusType
*type
= purple_status_get_status_type(status
);
2512 PurpleXmlNode
*node
, *child
;
2513 GList
*attrs
, *attr
;
2515 node
= purple_xmlnode_new("attributes");
2517 attrs
= purple_status_type_get_attrs(type
);
2518 for (attr
= attrs
; attr
!= NULL
; attr
= attr
->next
)
2520 child
= status_attribute_to_xmlnode(status
, type
, (const PurpleStatusAttribute
*)attr
->data
);
2522 purple_xmlnode_insert_child(node
, child
);
2528 static PurpleXmlNode
*
2529 status_to_xmlnode(const PurpleStatus
*status
)
2531 PurpleXmlNode
*node
, *child
;
2533 node
= purple_xmlnode_new("status");
2534 purple_xmlnode_set_attrib(node
, "type", purple_status_get_id(status
));
2535 if (purple_status_get_name(status
) != NULL
)
2536 purple_xmlnode_set_attrib(node
, "name", purple_status_get_name(status
));
2537 purple_xmlnode_set_attrib(node
, "active", purple_status_is_active(status
) ? "true" : "false");
2539 child
= status_attrs_to_xmlnode(status
);
2540 purple_xmlnode_insert_child(node
, child
);
2545 static PurpleXmlNode
*
2546 statuses_to_xmlnode(const PurplePresence
*presence
)
2548 PurpleXmlNode
*node
, *child
;
2550 PurpleStatus
*status
;
2552 node
= purple_xmlnode_new("statuses");
2554 statuses
= purple_presence_get_statuses(presence
);
2555 for (; statuses
!= NULL
; statuses
= statuses
->next
)
2557 status
= statuses
->data
;
2558 if (purple_status_type_is_saveable(purple_status_get_status_type(status
)))
2560 child
= status_to_xmlnode(status
);
2561 purple_xmlnode_insert_child(node
, child
);
2568 static PurpleXmlNode
*
2569 proxy_settings_to_xmlnode(PurpleProxyInfo
*proxy_info
)
2571 PurpleXmlNode
*node
, *child
;
2572 PurpleProxyType proxy_type
;
2577 proxy_type
= purple_proxy_info_get_proxy_type(proxy_info
);
2579 node
= purple_xmlnode_new("proxy");
2581 child
= purple_xmlnode_new_child(node
, "type");
2582 purple_xmlnode_insert_data(child
,
2583 (proxy_type
== PURPLE_PROXY_USE_GLOBAL
? "global" :
2584 proxy_type
== PURPLE_PROXY_NONE
? "none" :
2585 proxy_type
== PURPLE_PROXY_HTTP
? "http" :
2586 proxy_type
== PURPLE_PROXY_SOCKS4
? "socks4" :
2587 proxy_type
== PURPLE_PROXY_SOCKS5
? "socks5" :
2588 proxy_type
== PURPLE_PROXY_TOR
? "tor" :
2589 proxy_type
== PURPLE_PROXY_USE_ENVVAR
? "envvar" : "unknown"), -1);
2591 if ((value
= purple_proxy_info_get_host(proxy_info
)) != NULL
)
2593 child
= purple_xmlnode_new_child(node
, "host");
2594 purple_xmlnode_insert_data(child
, value
, -1);
2597 if ((int_value
= purple_proxy_info_get_port(proxy_info
)) != 0)
2599 g_snprintf(buf
, sizeof(buf
), "%d", int_value
);
2600 child
= purple_xmlnode_new_child(node
, "port");
2601 purple_xmlnode_insert_data(child
, buf
, -1);
2604 if ((value
= purple_proxy_info_get_username(proxy_info
)) != NULL
)
2606 child
= purple_xmlnode_new_child(node
, "username");
2607 purple_xmlnode_insert_data(child
, value
, -1);
2610 if ((value
= purple_proxy_info_get_password(proxy_info
)) != NULL
)
2612 child
= purple_xmlnode_new_child(node
, "password");
2613 purple_xmlnode_insert_data(child
, value
, -1);
2619 static PurpleXmlNode
*
2620 current_error_to_xmlnode(PurpleConnectionErrorInfo
*err
)
2622 PurpleXmlNode
*node
, *child
;
2625 node
= purple_xmlnode_new("current_error");
2630 /* It doesn't make sense to have transient errors persist across a
2633 if(!purple_connection_error_is_fatal (err
->type
))
2636 child
= purple_xmlnode_new_child(node
, "type");
2637 g_snprintf(type_str
, sizeof(type_str
), "%u", err
->type
);
2638 purple_xmlnode_insert_data(child
, type_str
, -1);
2640 child
= purple_xmlnode_new_child(node
, "description");
2641 if(err
->description
) {
2642 char *utf8ized
= purple_utf8_try_convert(err
->description
);
2643 if(utf8ized
== NULL
)
2644 utf8ized
= purple_utf8_salvage(err
->description
);
2645 purple_xmlnode_insert_data(child
, utf8ized
, -1);
2653 setting_to_xmlnode(gpointer key
, gpointer value
, gpointer user_data
)
2656 PurpleAccountSetting
*setting
;
2657 PurpleXmlNode
*node
, *child
;
2660 name
= (const char *)key
;
2661 setting
= (PurpleAccountSetting
*)value
;
2662 node
= (PurpleXmlNode
*)user_data
;
2664 child
= purple_xmlnode_new_child(node
, "setting");
2665 purple_xmlnode_set_attrib(child
, "name", name
);
2667 if (G_VALUE_HOLDS_INT(&setting
->value
)) {
2668 purple_xmlnode_set_attrib(child
, "type", "int");
2669 g_snprintf(buf
, sizeof(buf
), "%d", g_value_get_int(&setting
->value
));
2670 purple_xmlnode_insert_data(child
, buf
, -1);
2672 else if (G_VALUE_HOLDS_STRING(&setting
->value
) && g_value_get_string(&setting
->value
) != NULL
) {
2673 purple_xmlnode_set_attrib(child
, "type", "string");
2674 purple_xmlnode_insert_data(child
, g_value_get_string(&setting
->value
), -1);
2676 else if (G_VALUE_HOLDS_BOOLEAN(&setting
->value
)) {
2677 purple_xmlnode_set_attrib(child
, "type", "bool");
2678 g_snprintf(buf
, sizeof(buf
), "%d", g_value_get_boolean(&setting
->value
));
2679 purple_xmlnode_insert_data(child
, buf
, -1);
2684 ui_setting_to_xmlnode(gpointer key
, gpointer value
, gpointer user_data
)
2688 PurpleXmlNode
*node
, *child
;
2690 ui
= (const char *)key
;
2691 table
= (GHashTable
*)value
;
2692 node
= (PurpleXmlNode
*)user_data
;
2694 if (g_hash_table_size(table
) > 0)
2696 child
= purple_xmlnode_new_child(node
, "settings");
2697 purple_xmlnode_set_attrib(child
, "ui", ui
);
2698 g_hash_table_foreach(table
, setting_to_xmlnode
, child
);
2703 _purple_account_to_xmlnode(PurpleAccount
*account
)
2705 PurpleXmlNode
*node
, *child
;
2707 PurplePresence
*presence
;
2708 PurpleProxyInfo
*proxy_info
;
2709 PurpleAccountPrivate
*priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
2711 node
= purple_xmlnode_new("account");
2713 child
= purple_xmlnode_new_child(node
, "protocol");
2714 purple_xmlnode_insert_data(child
, purple_account_get_protocol_id(account
), -1);
2716 child
= purple_xmlnode_new_child(node
, "name");
2717 purple_xmlnode_insert_data(child
, purple_account_get_username(account
), -1);
2719 if (purple_account_get_remember_password(account
))
2721 const char *keyring_id
= NULL
;
2722 const char *mode
= NULL
;
2724 GError
*error
= NULL
;
2725 GDestroyNotify destroy
= NULL
;
2726 gboolean exported
= purple_keyring_export_password(account
,
2727 &keyring_id
, &mode
, &data
, &error
, &destroy
);
2729 if (error
!= NULL
) {
2730 purple_debug_error("account",
2731 "Failed to export password for account %s: %s.\n",
2732 purple_account_get_username(account
),
2734 } else if (exported
) {
2735 child
= purple_xmlnode_new_child(node
, "password");
2736 if (keyring_id
!= NULL
)
2737 purple_xmlnode_set_attrib(child
, "keyring_id", keyring_id
);
2739 purple_xmlnode_set_attrib(child
, "mode", mode
);
2741 purple_xmlnode_insert_data(child
, data
, -1);
2743 if (destroy
!= NULL
)
2748 if ((tmp
= purple_account_get_private_alias(account
)) != NULL
)
2750 child
= purple_xmlnode_new_child(node
, "alias");
2751 purple_xmlnode_insert_data(child
, tmp
, -1);
2754 if ((presence
= purple_account_get_presence(account
)) != NULL
)
2756 child
= statuses_to_xmlnode(presence
);
2757 purple_xmlnode_insert_child(node
, child
);
2760 if ((tmp
= purple_account_get_user_info(account
)) != NULL
)
2762 /* TODO: Do we need to call purple_str_strip_char(tmp, '\r') here? */
2763 child
= purple_xmlnode_new_child(node
, "user-info");
2764 purple_xmlnode_insert_data(child
, tmp
, -1);
2767 if (g_hash_table_size(priv
->settings
) > 0)
2769 child
= purple_xmlnode_new_child(node
, "settings");
2770 g_hash_table_foreach(priv
->settings
, setting_to_xmlnode
, child
);
2773 if (g_hash_table_size(priv
->ui_settings
) > 0)
2775 g_hash_table_foreach(priv
->ui_settings
, ui_setting_to_xmlnode
, node
);
2778 if ((proxy_info
= purple_account_get_proxy_info(account
)) != NULL
)
2780 child
= proxy_settings_to_xmlnode(proxy_info
);
2781 purple_xmlnode_insert_child(node
, child
);
2784 child
= current_error_to_xmlnode(priv
->current_error
);
2785 purple_xmlnode_insert_child(node
, child
);
2794 /* Set method for GObject properties */
2796 purple_account_set_property(GObject
*obj
, guint param_id
, const GValue
*value
,
2799 PurpleAccount
*account
= PURPLE_ACCOUNT(obj
);
2803 purple_account_set_username(account
, g_value_get_string(value
));
2805 case PROP_PRIVATE_ALIAS
:
2806 purple_account_set_private_alias(account
, g_value_get_string(value
));
2809 purple_account_set_enabled(account
, purple_core_get_ui(),
2810 g_value_get_boolean(value
));
2812 case PROP_CONNECTION
:
2813 purple_account_set_connection(account
, g_value_get_object(value
));
2815 case PROP_PROTOCOL_ID
:
2816 purple_account_set_protocol_id(account
, g_value_get_string(value
));
2818 case PROP_USER_INFO
:
2819 purple_account_set_user_info(account
, g_value_get_string(value
));
2821 case PROP_BUDDY_ICON_PATH
:
2822 purple_account_set_buddy_icon_path(account
,
2823 g_value_get_string(value
));
2825 case PROP_REMEMBER_PASSWORD
:
2826 purple_account_set_remember_password(account
,
2827 g_value_get_boolean(value
));
2829 case PROP_CHECK_MAIL
:
2830 purple_account_set_check_mail(account
, g_value_get_boolean(value
));
2833 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj
, param_id
, pspec
);
2838 /* Get method for GObject properties */
2840 purple_account_get_property(GObject
*obj
, guint param_id
, GValue
*value
,
2843 PurpleAccount
*account
= PURPLE_ACCOUNT(obj
);
2847 g_value_set_string(value
, purple_account_get_username(account
));
2849 case PROP_PRIVATE_ALIAS
:
2850 g_value_set_string(value
, purple_account_get_private_alias(account
));
2853 g_value_set_boolean(value
, purple_account_get_enabled(account
,
2854 purple_core_get_ui()));
2856 case PROP_CONNECTION
:
2857 g_value_set_object(value
, purple_account_get_connection(account
));
2859 case PROP_PROTOCOL_ID
:
2860 g_value_set_string(value
, purple_account_get_protocol_id(account
));
2862 case PROP_USER_INFO
:
2863 g_value_set_string(value
, purple_account_get_user_info(account
));
2865 case PROP_BUDDY_ICON_PATH
:
2866 g_value_set_string(value
,
2867 purple_account_get_buddy_icon_path(account
));
2869 case PROP_REMEMBER_PASSWORD
:
2870 g_value_set_boolean(value
,
2871 purple_account_get_remember_password(account
));
2873 case PROP_CHECK_MAIL
:
2874 g_value_set_boolean(value
, purple_account_get_check_mail(account
));
2877 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj
, param_id
, pspec
);
2882 /* GObject initialization function */
2883 static void purple_account_init(GTypeInstance
*instance
, gpointer klass
)
2885 PurpleAccount
*account
= PURPLE_ACCOUNT(instance
);
2886 PurpleAccountPrivate
*priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
2888 priv
->settings
= g_hash_table_new_full(g_str_hash
, g_str_equal
,
2889 g_free
, delete_setting
);
2890 priv
->ui_settings
= g_hash_table_new_full(g_str_hash
, g_str_equal
,
2891 g_free
, (GDestroyNotify
)g_hash_table_destroy
);
2892 priv
->system_log
= NULL
;
2894 priv
->privacy_type
= PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL
;
2896 PURPLE_DBUS_REGISTER_POINTER(account
, PurpleAccount
);
2899 /* Called when done constructing */
2901 purple_account_constructed(GObject
*object
)
2903 PurpleAccount
*account
= PURPLE_ACCOUNT(object
);
2904 PurpleAccountPrivate
*priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
2905 gchar
*username
, *protocol_id
;
2906 PurpleProtocol
*protocol
= NULL
;
2907 PurpleStatusType
*status_type
;
2909 parent_class
->constructed(object
);
2911 g_object_get(object
,
2912 "username", &username
,
2913 "protocol-id", &protocol_id
,
2916 purple_signal_emit(purple_accounts_get_handle(), "account-created",
2919 protocol
= purple_protocols_find(protocol_id
);
2920 if (protocol
== NULL
) {
2922 g_free(protocol_id
);
2926 purple_account_set_status_types(account
,
2927 purple_protocol_class_status_types(protocol
, account
));
2929 priv
->presence
= PURPLE_PRESENCE(purple_account_presence_new(account
));
2931 status_type
= purple_account_get_status_type_with_primitive(account
,
2932 PURPLE_STATUS_AVAILABLE
);
2933 if (status_type
!= NULL
)
2934 purple_presence_set_status_active(priv
->presence
,
2935 purple_status_type_get_id(status_type
),
2938 purple_presence_set_status_active(priv
->presence
,
2943 g_free(protocol_id
);
2946 /* GObject dispose function */
2948 purple_account_dispose(GObject
*object
)
2950 PurpleAccount
*account
= PURPLE_ACCOUNT(object
);
2951 PurpleAccountPrivate
*priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
2953 if (!purple_account_is_disconnected(account
))
2954 purple_account_disconnect(account
);
2956 if (priv
->presence
) {
2957 g_object_unref(priv
->presence
);
2958 priv
->presence
= NULL
;
2961 parent_class
->dispose(object
);
2964 /* GObject finalize function */
2966 purple_account_finalize(GObject
*object
)
2969 PurpleAccount
*account
= PURPLE_ACCOUNT(object
);
2970 PurpleAccountPrivate
*priv
= PURPLE_ACCOUNT_GET_PRIVATE(account
);
2972 purple_debug_info("account", "Destroying account %p\n", account
);
2973 purple_signal_emit(purple_accounts_get_handle(), "account-destroying",
2976 for (l
= purple_conversations_get_all(); l
!= NULL
; l
= l
->next
)
2978 PurpleConversation
*conv
= (PurpleConversation
*)l
->data
;
2980 if (purple_conversation_get_account(conv
) == account
)
2981 purple_conversation_set_account(conv
, NULL
);
2984 purple_account_set_status_types(account
, NULL
);
2986 if (priv
->proxy_info
)
2987 purple_proxy_info_destroy(priv
->proxy_info
);
2989 if(priv
->system_log
)
2990 purple_log_free(priv
->system_log
);
2992 PURPLE_DBUS_UNREGISTER_POINTER(priv
->current_error
);
2993 if (priv
->current_error
) {
2994 g_free(priv
->current_error
->description
);
2995 g_free(priv
->current_error
);
2998 g_free(priv
->username
);
2999 g_free(priv
->alias
);
3000 purple_str_wipe(priv
->password
);
3001 g_free(priv
->user_info
);
3002 g_free(priv
->buddy_icon_path
);
3003 g_free(priv
->protocol_id
);
3005 g_hash_table_destroy(priv
->settings
);
3006 g_hash_table_destroy(priv
->ui_settings
);
3008 while (priv
->deny
) {
3009 g_free(priv
->deny
->data
);
3010 priv
->deny
= g_slist_delete_link(priv
->deny
, priv
->deny
);
3013 while (priv
->permit
) {
3014 g_free(priv
->permit
->data
);
3015 priv
->permit
= g_slist_delete_link(priv
->permit
, priv
->permit
);
3018 PURPLE_DBUS_UNREGISTER_POINTER(account
);
3020 parent_class
->finalize(object
);
3023 /* Class initializer function */
3025 purple_account_class_init(PurpleAccountClass
*klass
)
3027 GObjectClass
*obj_class
= G_OBJECT_CLASS(klass
);
3029 parent_class
= g_type_class_peek_parent(klass
);
3031 obj_class
->dispose
= purple_account_dispose
;
3032 obj_class
->finalize
= purple_account_finalize
;
3033 obj_class
->constructed
= purple_account_constructed
;
3035 /* Setup properties */
3036 obj_class
->get_property
= purple_account_get_property
;
3037 obj_class
->set_property
= purple_account_set_property
;
3039 g_type_class_add_private(klass
, sizeof(PurpleAccountPrivate
));
3041 properties
[PROP_USERNAME
] = g_param_spec_string("username", "Username",
3042 "The username for the account.", NULL
,
3043 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
| G_PARAM_STATIC_STRINGS
);
3045 properties
[PROP_PRIVATE_ALIAS
] = g_param_spec_string("private-alias",
3047 "The private alias for the account.", NULL
,
3048 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
);
3050 properties
[PROP_USER_INFO
] = g_param_spec_string("user-info",
3052 "Detailed user information for the account.", NULL
,
3053 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
);
3055 properties
[PROP_BUDDY_ICON_PATH
] = g_param_spec_string("buddy-icon-path",
3057 "Path to the buddyicon for the account.", NULL
,
3058 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
);
3060 properties
[PROP_ENABLED
] = g_param_spec_boolean("enabled", "Enabled",
3061 "Whether the account is enabled or not.", FALSE
,
3062 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
);
3064 properties
[PROP_REMEMBER_PASSWORD
] = g_param_spec_boolean(
3065 "remember-password", "Remember password",
3066 "Whether to remember and store the password for this account.",
3067 FALSE
, G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
);
3069 properties
[PROP_CHECK_MAIL
] = g_param_spec_boolean("check-mail",
3071 "Whether to check mails for this account.", FALSE
,
3072 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
);
3074 properties
[PROP_CONNECTION
] = g_param_spec_object("connection",
3076 "The connection for the account.", PURPLE_TYPE_CONNECTION
,
3077 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
);
3079 properties
[PROP_PROTOCOL_ID
] = g_param_spec_string("protocol-id",
3081 "ID of the protocol that is responsible for the account.", NULL
,
3082 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT_ONLY
|
3083 G_PARAM_STATIC_STRINGS
);
3085 g_object_class_install_properties(obj_class
, PROP_LAST
, properties
);
3089 purple_account_get_type(void)
3091 static GType type
= 0;
3094 static const GTypeInfo info
= {
3095 sizeof(PurpleAccountClass
),
3098 (GClassInitFunc
)purple_account_class_init
,
3101 sizeof(PurpleAccount
),
3103 (GInstanceInitFunc
)purple_account_init
,
3107 type
= g_type_register_static(G_TYPE_OBJECT
,
3116 purple_account_new(const char *username
, const char *protocol_id
)
3118 PurpleAccount
*account
;
3120 g_return_val_if_fail(username
!= NULL
, NULL
);
3121 g_return_val_if_fail(protocol_id
!= NULL
, NULL
);
3123 account
= purple_accounts_find(username
, protocol_id
);
3125 if (account
!= NULL
)
3128 account
= g_object_new(PURPLE_TYPE_ACCOUNT
,
3129 "username", username
,
3130 "protocol-id", protocol_id
,