4 * Purple is the legal property of its developers, whose names are too numerous
5 * to list here. Please refer to the COPYRIGHT file distributed with this
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
29 static PurplePrivacyUiOps
*privacy_ops
= NULL
;
32 purple_privacy_permit_add(PurpleAccount
*account
, const char *who
,
38 PurpleBlistUiOps
*blist_ops
;
40 g_return_val_if_fail(account
!= NULL
, FALSE
);
41 g_return_val_if_fail(who
!= NULL
, FALSE
);
43 name
= g_strdup(purple_normalize(account
, who
));
45 for (l
= account
->permit
; l
!= NULL
; l
= l
->next
) {
46 if (g_str_equal(name
, l
->data
))
47 /* This buddy already exists */
53 /* This buddy already exists, so bail out */
58 account
->permit
= g_slist_append(account
->permit
, name
);
60 if (!local_only
&& purple_account_is_connected(account
))
61 serv_add_permit(purple_account_get_connection(account
), who
);
63 if (privacy_ops
!= NULL
&& privacy_ops
->permit_added
!= NULL
)
64 privacy_ops
->permit_added(account
, who
);
66 blist_ops
= purple_blist_get_ui_ops();
67 if (blist_ops
!= NULL
&& blist_ops
->save_account
!= NULL
)
68 blist_ops
->save_account(account
);
70 /* This lets the UI know a buddy has had its privacy setting changed */
71 buddy
= purple_find_buddy(account
, name
);
73 purple_signal_emit(purple_blist_get_handle(),
74 "buddy-privacy-changed", buddy
);
80 purple_privacy_permit_remove(PurpleAccount
*account
, const char *who
,
87 PurpleBlistUiOps
*blist_ops
;
89 g_return_val_if_fail(account
!= NULL
, FALSE
);
90 g_return_val_if_fail(who
!= NULL
, FALSE
);
92 name
= purple_normalize(account
, who
);
94 for (l
= account
->permit
; l
!= NULL
; l
= l
->next
) {
95 if (g_str_equal(name
, l
->data
))
96 /* We found the buddy we were looking for */
101 /* We didn't find the buddy we were looking for, so bail out */
104 /* We should not free l->data just yet. There can be occasions where
105 * l->data == who. In such cases, freeing l->data here can cause crashes
106 * later when who is used. */
108 account
->permit
= g_slist_delete_link(account
->permit
, l
);
110 if (!local_only
&& purple_account_is_connected(account
))
111 serv_rem_permit(purple_account_get_connection(account
), who
);
113 if (privacy_ops
!= NULL
&& privacy_ops
->permit_removed
!= NULL
)
114 privacy_ops
->permit_removed(account
, who
);
116 blist_ops
= purple_blist_get_ui_ops();
117 if (blist_ops
!= NULL
&& blist_ops
->save_account
!= NULL
)
118 blist_ops
->save_account(account
);
120 buddy
= purple_find_buddy(account
, name
);
122 purple_signal_emit(purple_blist_get_handle(),
123 "buddy-privacy-changed", buddy
);
130 purple_privacy_deny_add(PurpleAccount
*account
, const char *who
,
136 PurpleBlistUiOps
*blist_ops
;
138 g_return_val_if_fail(account
!= NULL
, FALSE
);
139 g_return_val_if_fail(who
!= NULL
, FALSE
);
141 name
= g_strdup(purple_normalize(account
, who
));
143 for (l
= account
->deny
; l
!= NULL
; l
= l
->next
) {
144 if (g_str_equal(name
, l
->data
))
145 /* This buddy already exists */
151 /* This buddy already exists, so bail out */
156 account
->deny
= g_slist_append(account
->deny
, name
);
158 if (!local_only
&& purple_account_is_connected(account
))
159 serv_add_deny(purple_account_get_connection(account
), who
);
161 if (privacy_ops
!= NULL
&& privacy_ops
->deny_added
!= NULL
)
162 privacy_ops
->deny_added(account
, who
);
164 blist_ops
= purple_blist_get_ui_ops();
165 if (blist_ops
!= NULL
&& blist_ops
->save_account
!= NULL
)
166 blist_ops
->save_account(account
);
168 buddy
= purple_find_buddy(account
, name
);
170 purple_signal_emit(purple_blist_get_handle(),
171 "buddy-privacy-changed", buddy
);
177 purple_privacy_deny_remove(PurpleAccount
*account
, const char *who
,
181 const char *normalized
;
184 PurpleBlistUiOps
*blist_ops
;
186 g_return_val_if_fail(account
!= NULL
, FALSE
);
187 g_return_val_if_fail(who
!= NULL
, FALSE
);
189 normalized
= purple_normalize(account
, who
);
191 for (l
= account
->deny
; l
!= NULL
; l
= l
->next
) {
192 if (g_str_equal(normalized
, l
->data
))
193 /* We found the buddy we were looking for */
198 /* We didn't find the buddy we were looking for, so bail out */
201 buddy
= purple_find_buddy(account
, normalized
);
204 account
->deny
= g_slist_delete_link(account
->deny
, l
);
206 if (!local_only
&& purple_account_is_connected(account
))
207 serv_rem_deny(purple_account_get_connection(account
), name
);
209 if (privacy_ops
!= NULL
&& privacy_ops
->deny_removed
!= NULL
)
210 privacy_ops
->deny_removed(account
, who
);
213 purple_signal_emit(purple_blist_get_handle(),
214 "buddy-privacy-changed", buddy
);
219 blist_ops
= purple_blist_get_ui_ops();
220 if (blist_ops
!= NULL
&& blist_ops
->save_account
!= NULL
)
221 blist_ops
->save_account(account
);
227 * This makes sure your permit list contains all buddies from your
228 * buddy list and ONLY buddies from your buddy list.
231 add_all_buddies_to_permit_list(PurpleAccount
*account
, gboolean local
)
235 /* Remove anyone in the permit list who is not in the buddylist */
236 for (list
= account
->permit
; list
!= NULL
; ) {
237 char *person
= list
->data
;
239 if (!purple_find_buddy(account
, person
))
240 purple_privacy_permit_remove(account
, person
, local
);
243 /* Now make sure everyone in the buddylist is in the permit list */
244 list
= purple_find_buddies(account
, NULL
);
247 PurpleBuddy
*buddy
= list
->data
;
248 const gchar
*name
= purple_buddy_get_name(buddy
);
250 if (!g_slist_find_custom(account
->permit
, name
, (GCompareFunc
)g_utf8_collate
))
251 purple_privacy_permit_add(account
, name
, local
);
252 list
= g_slist_delete_link(list
, list
);
257 * TODO: All callers of this function pass in FALSE for local and
258 * restore and I don't understand when you would ever want to
259 * use TRUE for either of them. I think both parameters could
260 * safely be removed in the next major version bump.
263 purple_privacy_allow(PurpleAccount
*account
, const char *who
, gboolean local
,
267 PurplePrivacyType type
= account
->perm_deny
;
269 switch (account
->perm_deny
) {
270 case PURPLE_PRIVACY_ALLOW_ALL
:
272 case PURPLE_PRIVACY_ALLOW_USERS
:
273 purple_privacy_permit_add(account
, who
, local
);
275 case PURPLE_PRIVACY_DENY_USERS
:
276 purple_privacy_deny_remove(account
, who
, local
);
278 case PURPLE_PRIVACY_DENY_ALL
:
280 /* Empty the allow-list. */
281 const char *norm
= purple_normalize(account
, who
);
282 for (list
= account
->permit
; list
!= NULL
;) {
283 char *person
= list
->data
;
285 if (!purple_strequal(norm
, person
))
286 purple_privacy_permit_remove(account
, person
, local
);
289 purple_privacy_permit_add(account
, who
, local
);
290 account
->perm_deny
= PURPLE_PRIVACY_ALLOW_USERS
;
292 case PURPLE_PRIVACY_ALLOW_BUDDYLIST
:
293 if (!purple_find_buddy(account
, who
)) {
294 add_all_buddies_to_permit_list(account
, local
);
295 purple_privacy_permit_add(account
, who
, local
);
296 account
->perm_deny
= PURPLE_PRIVACY_ALLOW_USERS
;
300 g_return_if_reached();
303 /* Notify the server if the privacy setting was changed */
304 if (type
!= account
->perm_deny
&& purple_account_is_connected(account
))
305 serv_set_permit_deny(purple_account_get_connection(account
));
309 * TODO: All callers of this function pass in FALSE for local and
310 * restore and I don't understand when you would ever want to
311 * use TRUE for either of them. I think both parameters could
312 * safely be removed in the next major version bump.
315 purple_privacy_deny(PurpleAccount
*account
, const char *who
, gboolean local
,
319 PurplePrivacyType type
= account
->perm_deny
;
321 switch (account
->perm_deny
) {
322 case PURPLE_PRIVACY_ALLOW_ALL
:
324 /* Empty the deny-list. */
325 const char *norm
= purple_normalize(account
, who
);
326 for (list
= account
->deny
; list
!= NULL
; ) {
327 char *person
= list
->data
;
329 if (!purple_strequal(norm
, person
))
330 purple_privacy_deny_remove(account
, person
, local
);
333 purple_privacy_deny_add(account
, who
, local
);
334 account
->perm_deny
= PURPLE_PRIVACY_DENY_USERS
;
336 case PURPLE_PRIVACY_ALLOW_USERS
:
337 purple_privacy_permit_remove(account
, who
, local
);
339 case PURPLE_PRIVACY_DENY_USERS
:
340 purple_privacy_deny_add(account
, who
, local
);
342 case PURPLE_PRIVACY_DENY_ALL
:
344 case PURPLE_PRIVACY_ALLOW_BUDDYLIST
:
345 if (purple_find_buddy(account
, who
)) {
346 add_all_buddies_to_permit_list(account
, local
);
347 purple_privacy_permit_remove(account
, who
, local
);
348 account
->perm_deny
= PURPLE_PRIVACY_ALLOW_USERS
;
352 g_return_if_reached();
355 /* Notify the server if the privacy setting was changed */
356 if (type
!= account
->perm_deny
&& purple_account_is_connected(account
))
357 serv_set_permit_deny(purple_account_get_connection(account
));
361 purple_privacy_check(PurpleAccount
*account
, const char *who
)
365 switch (account
->perm_deny
) {
366 case PURPLE_PRIVACY_ALLOW_ALL
:
369 case PURPLE_PRIVACY_DENY_ALL
:
372 case PURPLE_PRIVACY_ALLOW_USERS
:
373 who
= purple_normalize(account
, who
);
374 for (list
=account
->permit
; list
!=NULL
; list
=list
->next
) {
375 if (g_str_equal(who
, list
->data
))
380 case PURPLE_PRIVACY_DENY_USERS
:
381 who
= purple_normalize(account
, who
);
382 for (list
=account
->deny
; list
!=NULL
; list
=list
->next
) {
383 if (g_str_equal(who
, list
->data
))
388 case PURPLE_PRIVACY_ALLOW_BUDDYLIST
:
389 return (purple_find_buddy(account
, who
) != NULL
);
392 g_return_val_if_reached(TRUE
);
397 purple_privacy_set_ui_ops(PurplePrivacyUiOps
*ops
)
403 purple_privacy_get_ui_ops(void)
409 purple_privacy_init(void)