comparison src/list.c @ 4687:283fb289c510

[gaim-migrate @ 4998] This is a new buddy list. Lots of things about it just Don't Work. I probably already know about those things, and you'd just be wasting my time in submitting a bug report about it. I decided that instead of getting it to all work perfectly before committing, that I'd get it in cvs, and slowly fix it with regular commits. That way, it's easier to keep track of things, and other developers can help. Plus, I'm getting pissed off at the buddy list and want it to die. It's kinda boring, and doing nothing but the buddy list for such a long time has just gotten me very bitter. After 0.60 is released later this week, Gaim will resume being fun. This week is going to be very stressful, though, I'm sure. Things you ought to know about this buddy list: - It crashes - It leaks - There's no way to edit the buddy list, or access offline buddies - Most of the menus and buttons and whatnot just plain ol' don't work. - Status icons are only implemented for AIM. That's mostly just because I'm lazy. As such, you may want to be wary of updating this. If you do decide to update this, you may want to learn "cvs update -D yesterday" as well :) All the art there is just placeholder art. You probably won't really have as many problems as it sounds like you will from reading this. This message is extra-negative to stress that I don't want to be bothered with complaints about something not working about it :). I'll repeat: If something doesn't work, I probably already know about it. If you want to actually help with something, I'd be delighted to have it. IM me. -s. committer: Tailor Script <tailor@pidgin.im>
author Sean Egan <seanegan@gmail.com>
date Mon, 10 Mar 2003 05:30:31 +0000
parents 5968bcd8ddb6
children e19f91053ad0
comparison
equal deleted inserted replaced
4686:a1de8a9c99ba 4687:283fb289c510
1 /* 1 /*
2 * gaim 2 * gaim
3 * 3 *
4 * Copyright (C) 2003, Sean Egan <sean.egan@binghamton.edu>
4 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net> 5 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net>
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or 9 * the Free Software Foundation; either version 2 of the License, or
32 #include <direct.h> 33 #include <direct.h>
33 #endif 34 #endif
34 #include <ctype.h> 35 #include <ctype.h>
35 #include "gaim.h" 36 #include "gaim.h"
36 #include "prpl.h" 37 #include "prpl.h"
38 #include "list.h"
37 39
38 #ifdef _WIN32 40 #ifdef _WIN32
39 #include "win32dep.h" 41 #include "win32dep.h"
40 #endif 42 #endif
41 43
42 #define PATHSIZE 1024 44 #define PATHSIZE 1024
43 45
44 void remove_buddy(struct buddy *rem_b) 46 struct gaim_buddy_list *gaimbuddylist = NULL;
45 { 47 static struct gaim_blist_ui_ops *blist_ui_ops = NULL;
46 if(rem_b->account->gc) { 48
47 struct group *rem_g = find_group_by_buddy(rem_b); 49 /*****************************************************************************
48 50 * Private Utility functions *
49 ui_remove_buddy(rem_b); 51 *****************************************************************************/
50 52 static GaimBlistNode *gaim_blist_get_last_sibling(GaimBlistNode *node)
51 rem_g->members = g_slist_remove(rem_g->members, rem_b); 53 {
52 54 GaimBlistNode *n = node;
53 g_hash_table_destroy(rem_b->settings); 55 if (!n)
54 56 return NULL;
55 g_free(rem_b); 57 while (n->next)
58 n = n->next;
59 return n;
60 }
61 static GaimBlistNode *gaim_blist_get_last_child(GaimBlistNode *node)
62 {
63 if (!node)
64 return NULL;
65 return gaim_blist_get_last_sibling(node->child);
66 }
67
68 static void gaim_blist_print()
69 {
70 GaimBlistNode *group = gaimbuddylist->root;
71 GaimBlistNode *buddy;
72 if (!gaimbuddylist)
73 return;
74 while (group) {
75 debug_printf("+-%s %d\n", ((struct group*)group)->name, group);
76 buddy = group->child;
77 while (buddy) {
78 debug_printf("|--- %d %s\t\t%d\n", ((struct buddy*)buddy)->present, ((struct buddy*)buddy)->name, ((struct buddy*)buddy)->idle);
79 buddy = buddy->next;
80 }
81 group = group->next;
82 }
83 }
84
85 /*****************************************************************************
86 * Public API functions *
87 *****************************************************************************/
88
89 struct gaim_buddy_list *gaim_blist_new()
90 {
91 struct gaim_buddy_list *gbl = g_new0(struct gaim_buddy_list, 1);
92 gbl->ui_ops = blist_ui_ops;
93 return gbl;
94 }
95
96 void gaim_blist_show ()
97 {
98 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops;
99 if (ops)
100 ops->show(gaimbuddylist);
101 }
102
103 void gaim_blist_destroy()
104 {
105 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops;
106 GaimBlistNode *node = gaimbuddylist->root;
107 if (ops)
108 ops->destroy(gaimbuddylist);
109 }
110
111 void gaim_blist_set_visible (gboolean show)
112 {
113 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops;
114 if (ops)
115 ops->set_visible(gaimbuddylist, show);
116 }
117
118 void gaim_blist_update_buddy_status (struct buddy *buddy, int status)
119 {
120 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops;
121 buddy->uc = status;
122 if (ops)
123 ops->update(gaimbuddylist, (GaimBlistNode*)buddy);
124 }
125
126 void gaim_blist_update_buddy_presence(struct buddy *buddy, int presence) {
127 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops;
128 if (!buddy->present && presence)
129 buddy->present = 2;
130 else if (buddy->present != 2)
131 buddy->present = presence;
132 if (ops)
133 ops->update(gaimbuddylist, (GaimBlistNode*)buddy);
134 }
135
136
137 void gaim_blist_update_buddy_idle (struct buddy *buddy, int idle)
138 {
139 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops;
140 buddy->idle = idle;
141 if (ops)
142 ops->update(gaimbuddylist, (GaimBlistNode*)buddy);
143 }
144 void gaim_blist_update_buddy_evil (struct buddy *buddy, int warning)
145 {
146 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops;
147 buddy->evil = warning;
148 if (ops)
149 ops->update(gaimbuddylist,(GaimBlistNode*)buddy);
150 }
151 void gaim_blist_rename_buddy (struct buddy *buddy, const char *name)
152 {
153 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops;
154 g_free(buddy->name);
155 buddy->name = g_strdup(name);
156 if (ops)
157 ops->update(gaimbuddylist, (GaimBlistNode*)buddy);
158 }
159 void gaim_blist_alias_buddy (struct buddy *buddy, const char *alias)
160 {
161 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops;
162 g_free(buddy->alias);
163 buddy->alias = g_strdup(alias);
164 if (ops)
165 ops->update(gaimbuddylist, (GaimBlistNode*)buddy);
166 }
167 void gaim_blist_rename_group(struct group *group, const char *name)
168 {
169 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops;
170 g_free(group->name);
171 group->name = g_strdup(name);
172 if (ops)
173 ops->update(gaimbuddylist, (GaimBlistNode*)group);
174 }
175 struct buddy *gaim_buddy_new(struct gaim_account *account, const char *screenname, const char *alias)
176 {
177 struct buddy *b = g_new0(struct buddy, 1);
178 b->account = account;
179 b->name = g_strdup(screenname);
180 b->alias = g_strdup(alias);
181 b->settings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
182 ((GaimBlistNode*)b)->type = GAIM_BLIST_BUDDY_NODE;
183
184 return b;
185 }
186 void gaim_blist_add_buddy (struct buddy *buddy, struct group *group, GaimBlistNode *node)
187 {
188 GaimBlistNode *n = node, *node2, *node3;
189 struct group *g = group;
190 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops;
191 if (!n) {
192 if (!g) {
193 g = gaim_group_new(_("Buddies"));
194 gaim_blist_add_group(g, NULL);
195 }
196 n = gaim_blist_get_last_child((GaimBlistNode*)g);
197 }
198
199 node2 = ((GaimBlistNode*)buddy)->next;
200 node3 = ((GaimBlistNode*)buddy)->prev;
201
202 if (node2)
203 node2->prev = node3;
204 if (node3)
205 node3->next = node2;
206
207 if (n) {
208 ((GaimBlistNode*)buddy)->next = n->next;
209 ((GaimBlistNode*)buddy)->prev = n;
210 ((GaimBlistNode*)buddy)->parent = n->parent;
211 n->next = (GaimBlistNode*)buddy;
56 } else { 212 } else {
57 char *buf = g_strdup_printf(_("%s was not removed from your buddy " 213 ((GaimBlistNode*)g)->child = (GaimBlistNode*)buddy;
58 "list, because your account (%s) is not logged in."), 214 ((GaimBlistNode*)buddy)->next = NULL;
59 rem_b->name, rem_b->account->username); 215 ((GaimBlistNode*)buddy)->prev = NULL;
60 do_error_dialog(_("Buddy Not Removed"), buf, GAIM_ERROR); 216 ((GaimBlistNode*)buddy)->parent = (GaimBlistNode*)g;
61 g_free(buf); 217 }
62 } 218
63 } 219 g->members = g_slist_append(g->members, buddy);
64 220
65 void remove_group(struct group *rem_g) 221 if (ops)
66 { 222 ops->update(gaimbuddylist, (GaimBlistNode*)buddy);
67 GSList *accounts; 223 }
68 224
69 for(accounts = gaim_accounts; accounts; accounts = accounts->next) { 225 struct group *gaim_group_new(const char *name)
70 struct gaim_account *account = accounts->data; 226 {
71 if(account->gc) { 227 struct group *g = gaim_find_group(name);
72 GList *tmp = NULL; 228 if (!g) {
73 GSList *buds = rem_g->members; 229 g= g_new0(struct group, 1);
74 230 g->name = g_strdup(name);
75 while (buds) { 231 ((GaimBlistNode*)g)->type = GAIM_BLIST_GROUP_NODE;
76 struct buddy *delb = (struct buddy *)buds->data; 232
77 buds = buds->next; 233 }
78 234 return g;
79 if(delb->account == account) { 235 }
80 tmp = g_list_append(tmp, g_strdup(delb->name)); 236
81 remove_buddy(delb); /* this should take care of removing 237 void gaim_blist_add_group (struct group *group, GaimBlistNode *node)
82 the group_show if necessary */ 238 {
83 } 239 struct gaim_blist_ui_ops *ops;
84 } 240
85 241 if (!gaimbuddylist)
86 if(tmp) 242 gaimbuddylist = gaim_blist_new();
87 serv_remove_buddies(account->gc, tmp, rem_g->name); 243 ops = gaimbuddylist->ui_ops;
88 244
89 while (tmp) { 245 if (!gaimbuddylist->root) {
90 g_free(tmp->data); 246 gaimbuddylist->root = (GaimBlistNode*)group;
91 tmp = g_list_remove(tmp, tmp->data);
92 }
93 }
94 }
95
96 if(rem_g->members) {
97 char *buf = g_strdup_printf(_("%d buddies from group %s were not "
98 "removed because their accounts were not logged in. These "
99 "buddies, and the group were not removed.\n"),
100 g_slist_length(rem_g->members), rem_g->name);
101 do_error_dialog(_("Group Not Removed"), buf, GAIM_ERROR);
102 g_free(buf);
103
104 return; 247 return;
105 } 248 }
106 249
107 ui_remove_group(rem_g); 250 if (gaim_find_group(group->name))
108 251 return;
109 groups = g_slist_remove(groups, rem_g); 252
110 253 if (!node)
111 g_free(rem_g); 254 node = gaim_blist_get_last_sibling(gaimbuddylist->root);
112 255
113 /* don't flush buddy list to cache in order to be consistent with remove_buddy, 256 ((GaimBlistNode*)group)->next = node ? node->next : NULL;
114 * mostly. remove_group is only called from one place, so we'll let it handle it. */ 257 ((GaimBlistNode*)group)->prev = node;
115 } 258 node->next = (GaimBlistNode*)group;
116 259
117 struct buddy *add_buddy(struct gaim_account *account, const char *group, const char *buddy, const char *show) 260 if (ops)
118 { 261 ops->update(gaimbuddylist, (GaimBlistNode*)group);
119 struct buddy *b; 262 }
120 struct group *g; 263
121 const char *good; 264 void gaim_blist_remove_buddy (struct buddy *buddy)
122 265 {
123 if ((b = find_buddy(account, buddy)) != NULL) 266 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops;
124 return b; 267
125 268 GaimBlistNode *node = (GaimBlistNode*)buddy;
126 g = find_group(group); 269
127 270 if (node->prev)
128 if (g == NULL) 271 node->prev->next = node->next;
129 g = add_group(group); 272 if (node->next)
130 273 node->next->prev = node->prev;
131 b = (struct buddy *)g_new0(struct buddy, 1); 274
132 275 ops->remove(gaimbuddylist, node);
133 if (!b) 276 g_free(buddy->name);
277 g_free(buddy->alias);
278 g_free(buddy);
279 }
280
281 void gaim_blist_remove_group (struct group *group)
282 {
283 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops;
284 GaimBlistNode *node = (GaimBlistNode*)group;
285 GaimBlistNode *child = node->child;
286 while (child) {
287 GaimBlistNode *n = child;
288 child = child->next;
289 gaim_blist_remove_buddy((struct buddy*)n);
290 }
291 ops->remove(gaimbuddylist, node);
292 g_free(group->name);
293 g_free(group);
294 }
295
296 char *gaim_get_buddy_alias_only(struct buddy *b) {
297 if(!b)
298 return NULL;
299 if(b->alias && b->alias[0])
300 return b->alias;
301 else if((misc_options & OPT_MISC_USE_SERVER_ALIAS) && b->server_alias)
302 return b->server_alias;
303 return NULL;
304 }
305
306 char * gaim_get_buddy_alias (struct buddy *buddy)
307 {
308 char *ret = gaim_get_buddy_alias_only(buddy);
309 if(!ret)
310 return buddy ? buddy->name : _("Unknown");
311 return ret;
312
313 }
314
315 struct buddy *gaim_find_buddy(struct gaim_account *account, const char *name)
316 {
317 GaimBlistNode *group = gaimbuddylist->root;
318 GaimBlistNode *buddy;
319 if (!gaimbuddylist)
134 return NULL; 320 return NULL;
135 321 while (group) {
136 b->account = account; 322 buddy = group->child;
137 b->present = 0; 323 while (buddy) {
138 324 if (!g_strcasecmp(((struct buddy*)buddy)->name, name) && account == ((struct buddy*)buddy)->account)
139 b->settings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); 325 return (struct buddy*)buddy;
140 326 buddy = buddy->next;
141 good = buddy; 327 }
142 328 group = group->next;
143 g_snprintf(b->name, sizeof(b->name), "%s", good); 329 }
144 if(show && show[0]) 330 return NULL;
145 g_snprintf(b->alias, sizeof(b->alias), "%s", show); 331 }
146 else 332
147 b->alias[0] = '\0'; 333 struct group *gaim_find_group(const char *name)
148 334 {
149 g->members = g_slist_append(g->members, b); 335 GaimBlistNode *node;
150 336 if (!gaimbuddylist)
151 b->idle = 0;
152 b->caps = 0;
153
154 ui_add_buddy(account->gc, g, b);
155
156 return b;
157 }
158
159 struct group *add_group(const char *group)
160 {
161 struct group *g = find_group(group);
162 if (g)
163 return g;
164 g = (struct group *)g_new0(struct group, 1);
165 if (!g)
166 return NULL; 337 return NULL;
167 338 node = gaimbuddylist->root;
168 strncpy(g->name, group, sizeof(g->name)); 339 while(node) {
169 groups = g_slist_append(groups, g); 340 if (!strcmp(((struct group*)node)->name, name))
170 341 return (struct group*)node;
171 g->members = NULL; 342 node = node->next;
172 343 }
173 ui_add_group(g);
174
175 return g;
176 }
177
178 struct group *find_group(const char *group)
179 {
180 struct group *g;
181 GSList *grp;
182 char *grpname = g_strdup(normalize(group));
183
184 grp = groups;
185 while (grp) {
186 g = (struct group *)grp->data;
187 if (!g_strcasecmp(normalize (g->name), grpname)) {
188 g_free(grpname);
189 return g;
190 }
191 grp = g_slist_next(grp);
192 }
193 g_free(grpname);
194 return NULL; 344 return NULL;
195 } 345 }
196 346 struct group *gaim_find_buddys_group(struct buddy *buddy)
197 struct group *find_group_by_buddy(struct buddy *b) 347 {
198 { 348 return (struct group*)(((GaimBlistNode*)buddy)->parent);
199 GSList *grp = groups; 349 }
200 350
201 while(grp) { 351 GSList *gaim_group_get_accounts(struct group *g)
202 struct group *g = grp->data; 352 {
203 if(g_slist_find(g->members, b)) 353 GSList *l = NULL;
204 return g; 354 GaimBlistNode *child = ((GaimBlistNode *)g)->child;
205 grp = grp->next; 355
206 } 356 while (child) {
207 return NULL; 357 if (!g_slist_find(l, ((struct buddy*)child)->account))
208 } 358 l = g_slist_append(l, ((struct buddy*)child)->account);
209 359 child = child->next;
210 struct buddy *find_buddy(struct gaim_account *account, const char *who) 360 }
211 { 361 return l;
212 struct group *g; 362 }
213 struct buddy *b; 363
214 GSList *grp; 364 void gaim_blist_remove_account(struct gaim_account *account)
215 GSList *mem; 365 {
216 char *whoname = NULL; 366 struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops;
217 char *(*norm)(const char *); 367 GaimBlistNode *group = gaimbuddylist->root;
218 368 GaimBlistNode *buddy;
219 grp = groups; 369 if (!gaimbuddylist)
220 while (grp) { 370 return;
221 g = (struct group *)grp->data; 371 while (group) {
222 372 buddy = group->child;
223 mem = g->members; 373 while (buddy) {
224 while (mem) { 374 if (account == ((struct buddy*)buddy)->account) {
225 b = (struct buddy *)mem->data; 375 ((struct buddy*)buddy)->present = 0;
226 /* 376 ops->remove(gaimbuddylist, buddy);
227 norm = (b->user->gc && b->user->gc->prpl->normalize) ? b->user->gc->prpl->normalize : normalize; 377 }
228 */ 378 buddy = buddy->next;
229 norm = normalize; 379 }
230 whoname = g_strdup(norm(who)); 380 group = group->next;
231 if ((b->account == account || !account) && !strcmp(norm(b->name), whoname)) { 381 }
232 g_free(whoname);
233 return b;
234 }
235 g_free(whoname);
236 mem = mem->next;
237 }
238 grp = g_slist_next(grp);
239 }
240 return NULL;
241 } 382 }
242 383
243 void parse_toc_buddy_list(struct gaim_account *account, char *config) 384 void parse_toc_buddy_list(struct gaim_account *account, char *config)
244 { 385 {
245 char *c; 386 char *c;
263 g_strlcpy(current, _("Invalid Groupname"), sizeof(current)); 404 g_strlcpy(current, _("Invalid Groupname"), sizeof(current));
264 } else { 405 } else {
265 g_strlcpy(current, utf8, sizeof(current)); 406 g_strlcpy(current, utf8, sizeof(current));
266 g_free(utf8); 407 g_free(utf8);
267 } 408 }
268 if (!find_group(current)) { 409 if (!gaim_find_group(current)) {
269 add_group(current); 410 struct group *g = gaim_group_new(current);
411 gaim_blist_add_group(g, NULL);
270 } 412 }
271 } else if (*c == 'b') { /*&& !find_buddy(user, c + 2)) {*/ 413 } else if (*c == 'b') { /*&& !gaim_find_buddy(user, c + 2)) {*/
272 char nm[80], sw[BUDDY_ALIAS_MAXLEN], *a, *utf8 = NULL; 414 char nm[80], sw[388], *a, *utf8 = NULL;
273 415
274 if ((a = strchr(c + 2, ':')) != NULL) { 416 if ((a = strchr(c + 2, ':')) != NULL) {
275 *a++ = '\0'; /* nul the : */ 417 *a++ = '\0'; /* nul the : */
276 } 418 }
277 419
289 * but who cares? */ 431 * but who cares? */
290 g_strlcpy(sw, utf8, sizeof(sw)); 432 g_strlcpy(sw, utf8, sizeof(sw));
291 g_free(utf8); 433 g_free(utf8);
292 } 434 }
293 435
294 if (!find_buddy(account, nm)) { 436 if (!gaim_find_buddy(account, nm)) {
295 add_buddy(account, current, nm, sw); 437 struct buddy *b = gaim_buddy_new(account, nm, sw);
438 struct group *g = gaim_find_group(current);
439 gaim_blist_add_buddy(b, g, NULL);
296 bud = g_list_append(bud, nm); 440 bud = g_list_append(bud, nm);
297 } 441 }
298 } else if (*c == 'p') { 442 } else if (*c == 'p') {
299 gaim_privacy_permit_add(account, c + 2); 443 gaim_privacy_permit_add(account, c + 2);
300 } else if (*c == 'd') { 444 } else if (*c == 'd') {
319 } 463 }
320 g_list_free(bud); 464 g_list_free(bud);
321 } 465 }
322 } 466 }
323 467
324 void toc_build_config(struct gaim_account *account, char *s, int len, gboolean show) 468 #if 0
325 {
326 GSList *grp = groups;
327 GSList *mem;
328 struct group *g;
329 struct buddy *b;
330 GSList *plist = account->permit;
331 GSList *dlist = account->deny;
332
333 int pos = 0;
334
335 if (!account->permdeny)
336 account->permdeny = 1;
337
338 pos += g_snprintf(&s[pos], len - pos, "m %d\n", account->permdeny);
339 while (len > pos && grp) {
340 g = (struct group *)grp->data;
341 if(gaim_group_on_account(g, account)) {
342 pos += g_snprintf(&s[pos], len - pos, "g %s\n", g->name);
343 mem = g->members;
344 while (len > pos && mem) {
345 b = (struct buddy *)mem->data;
346 if(b->account == account) {
347 pos += g_snprintf(&s[pos], len - pos, "b %s%s%s\n", b->name,
348 (show && b->alias[0]) ? ":" : "",
349 (show && b->alias[0]) ? b->alias : "");
350 }
351 mem = mem->next;
352 }
353 }
354 grp = g_slist_next(grp);
355 }
356
357 while (len > pos && plist) {
358 pos += g_snprintf(&s[pos], len - pos, "p %s\n", (char *)plist->data);
359 plist = plist->next;
360 }
361
362 while (len > pos && dlist) {
363 pos += g_snprintf(&s[pos], len - pos, "d %s\n", (char *)dlist->data);
364 dlist = dlist->next;
365 }
366 }
367
368 /* translate an AIM 3 buddylist (*.lst) to a Gaim buddylist */ 469 /* translate an AIM 3 buddylist (*.lst) to a Gaim buddylist */
369 static GString *translate_lst(FILE *src_fp) 470 static GString *translate_lst(FILE *src_fp)
370 { 471 {
371 char line[BUF_LEN], *line2; 472 char line[BUF_LEN], *line2;
372 char *name; 473 char *name;
516 dest = g_string_append_c(dest, '\n'); 617 dest = g_string_append_c(dest, '\n');
517 } 618 }
518 619
519 return dest; 620 return dest;
520 } 621 }
622 #endif
521 623
522 static gchar *get_screenname_filename(const char *name) 624 static gchar *get_screenname_filename(const char *name)
523 { 625 {
524 gchar **split; 626 gchar **split;
525 gchar *good; 627 gchar *good;
533 return good; 635 return good;
534 } 636 }
535 637
536 static gboolean gaim_blist_read(const char *filename); 638 static gboolean gaim_blist_read(const char *filename);
537 639
538 void do_import(struct gaim_account *account, const char *filename) 640
641 static void do_import(struct gaim_account *account, const char *filename)
539 { 642 {
540 GString *buf = NULL; 643 GString *buf = NULL;
541 char first[64]; 644 char first[64];
542 char path[PATHSIZE]; 645 char path[PATHSIZE];
543 int len; 646 int len;
573 fgets(first, 64, f); 676 fgets(first, 64, f);
574 677
575 if ((first[0] == '\n') || (first[0] == '\r' && first[1] == '\n')) 678 if ((first[0] == '\n') || (first[0] == '\r' && first[1] == '\n'))
576 fgets(first, 64, f); 679 fgets(first, 64, f);
577 680
681 #if 0
578 if (!g_strncasecmp(first, "<xml", strlen("<xml"))) { 682 if (!g_strncasecmp(first, "<xml", strlen("<xml"))) {
579 /* new gaim XML buddy list */ 683 /* new gaim XML buddy list */
580 gaim_blist_read(path); 684 gaim_blist_read(path);
685
686 /* We really don't need to bother doing stuf like translating AIM 3 buddy lists anymore */
687
581 } else if (!g_strncasecmp(first, "Config {", strlen("Config {"))) { 688 } else if (!g_strncasecmp(first, "Config {", strlen("Config {"))) {
582 /* AIM 4 buddy list */ 689 /* AIM 4 buddy list */
583 debug_printf("aim 4\n"); 690 debug_printf("aim 4\n");
584 rewind(f); 691 rewind(f);
585 buf = translate_blt(f); 692 buf = translate_blt(f);
591 } else if (!g_strncasecmp(first, "[User]", strlen("[User]"))) { 698 } else if (!g_strncasecmp(first, "[User]", strlen("[User]"))) {
592 /* GnomeICU (hopefully) */ 699 /* GnomeICU (hopefully) */
593 debug_printf("gnomeicu\n"); 700 debug_printf("gnomeicu\n");
594 rewind(f); 701 rewind(f);
595 buf = translate_gnomeicu(f); 702 buf = translate_gnomeicu(f);
596 } else if (first[0] == 'm') { 703
597 /* Gaim buddy list - no translation */ 704 } else
598 char buf2[BUF_LONG * 2]; 705 #endif
599 buf = g_string_new(""); 706 if (first[0] == 'm') {
600 rewind(f); 707 /* Gaim buddy list - no translation */
601 while (1) { 708 char buf2[BUF_LONG * 2];
602 len = fread(buf2, 1, BUF_LONG * 2 - 1, f); 709 buf = g_string_new("");
603 if (len <= 0) 710 rewind(f);
604 break; 711 while (1) {
712 len = fread(buf2, 1, BUF_LONG * 2 - 1, f);
713 if (len <= 0)
714 break;
605 buf2[len] = '\0'; 715 buf2[len] = '\0';
606 buf = g_string_append(buf, buf2); 716 buf = g_string_append(buf, buf2);
607 if (len != BUF_LONG * 2 - 1) 717 if (len != BUF_LONG * 2 - 1)
608 break; 718 break;
609 } 719 }
610 } 720 }
611 721
612 fclose(f); 722 fclose(f);
613 723
614 if (buf) { 724 if (buf) {
615 buf = g_string_prepend(buf, "toc_set_config {"); 725 buf = g_string_prepend(buf, "toc_set_config {");
616 buf = g_string_append(buf, "}\n"); 726 buf = g_string_append(buf, "}\n");
617 parse_toc_buddy_list(account, buf->str); 727 parse_toc_buddy_list(account, buf->str);
618 g_string_free(buf, TRUE); 728 g_string_free(buf, TRUE);
619 } 729 }
620 }
621
622 static gboolean is_blocked(struct buddy *b)
623 {
624 struct gaim_account *account = b->account;
625
626 if (account->permdeny == PERMIT_ALL)
627 return FALSE;
628
629 if (account->permdeny == PERMIT_NONE) {
630 if (account->gc && g_strcasecmp(b->name, account->gc->username))
631 return TRUE;
632 else
633 return FALSE;
634 }
635
636 if (account->permdeny == PERMIT_SOME) {
637 char *x = g_strdup(normalize(b->name));
638 GSList *s = account->permit;
639 while (s) {
640 if (!g_strcasecmp(x, normalize(s->data)))
641 break;
642 s = s->next;
643 }
644 g_free(x);
645 if (s)
646 return FALSE;
647 return TRUE;
648 }
649
650 if (account->permdeny == DENY_SOME) {
651 char *x = g_strdup(normalize(b->name));
652 GSList *s = account->deny;
653 while (s) {
654 if (!g_strcasecmp(x, normalize(s->data)))
655 break;
656 s = s->next;
657 }
658 g_free(x);
659 if (s)
660 return TRUE;
661 return FALSE;
662 }
663
664 return FALSE;
665 }
666
667 void signoff_blocked(struct gaim_connection *gc)
668 {
669 GSList *g = groups;
670 while (g) {
671 GSList *m = ((struct group *)g->data)->members;
672 while (m) {
673 struct buddy *b = m->data;
674 if (is_blocked(b))
675 serv_got_update(gc, b->name, 0, 0, 0, 0, 0, 0);
676 m = m->next;
677 }
678 g = g->next;
679 }
680 }
681
682 char *get_buddy_alias_only(struct buddy *b) {
683 if(!b)
684 return NULL;
685 if(b->alias[0])
686 return b->alias;
687 else if((misc_options & OPT_MISC_USE_SERVER_ALIAS) && b->server_alias[0])
688 return b->server_alias;
689 return NULL;
690 }
691
692
693 char *get_buddy_alias(struct buddy *b) {
694 char *ret = get_buddy_alias_only(b);
695 if(!ret)
696 return b ? b->name : _("Unknown");
697 return ret;
698 }
699
700 GSList *gaim_group_get_accounts(struct group *g) {
701 GSList *buds = g->members;
702 GSList *ret = NULL;
703 while(buds) {
704 struct buddy *b = buds->data;
705 if(!g_slist_find(ret, b->account))
706 ret = g_slist_append(ret, b->account);
707 buds = buds->next;
708 }
709 return ret;
710 } 730 }
711 731
712 gboolean gaim_group_on_account(struct group *g, struct gaim_account *account) { 732 gboolean gaim_group_on_account(struct group *g, struct gaim_account *account) {
713 GSList *buds = g->members; 733 GSList *buds = g->members;
714 while(buds) { 734 while(buds) {
768 g_free(blist_parser_group_name); 788 g_free(blist_parser_group_name);
769 blist_parser_group_name = g_strdup(attribute_values[i]); 789 blist_parser_group_name = g_strdup(attribute_values[i]);
770 } 790 }
771 } 791 }
772 if(blist_parser_group_name) { 792 if(blist_parser_group_name) {
773 add_group(blist_parser_group_name); 793 struct group *g = gaim_group_new(blist_parser_group_name);
794 gaim_blist_add_group(g,NULL);
774 } 795 }
775 } else if(!strcmp(element_name, "person")) { 796 } else if(!strcmp(element_name, "person")) {
776 blist_parser_current_tag = BLIST_TAG_PERSON; 797 blist_parser_current_tag = BLIST_TAG_PERSON;
777 for(i=0; attribute_names[i]; i++) { 798 for(i=0; attribute_names[i]; i++) {
778 if(!strcmp(attribute_names[i], "name")) { 799 if(!strcmp(attribute_names[i], "name")) {
838 blist_parser_person_name = NULL; 859 blist_parser_person_name = NULL;
839 } else if(!strcmp(element_name, "buddy")) { 860 } else if(!strcmp(element_name, "buddy")) {
840 struct gaim_account *account = gaim_account_find(blist_parser_account_name, 861 struct gaim_account *account = gaim_account_find(blist_parser_account_name,
841 blist_parser_account_protocol); 862 blist_parser_account_protocol);
842 if(account) { 863 if(account) {
843 struct buddy *b = add_buddy(account, blist_parser_group_name, 864 struct buddy *b = gaim_buddy_new(account, blist_parser_buddy_name, blist_parser_buddy_alias);
844 blist_parser_buddy_name, blist_parser_buddy_alias); 865 struct group *g = gaim_find_group(blist_parser_group_name);
866 gaim_blist_add_buddy(b,g,NULL);
845 if(blist_parser_buddy_settings) { 867 if(blist_parser_buddy_settings) {
846 g_hash_table_destroy(b->settings); 868 g_hash_table_destroy(b->settings);
847 b->settings = blist_parser_buddy_settings; 869 b->settings = blist_parser_buddy_settings;
848 } 870 }
849 } 871 }
1034 g_free(key_val); 1056 g_free(key_val);
1035 g_free(data_val); 1057 g_free(data_val);
1036 } 1058 }
1037 1059
1038 static void gaim_blist_write(FILE *file, struct gaim_account *exp_acct) { 1060 static void gaim_blist_write(FILE *file, struct gaim_account *exp_acct) {
1039 GSList *grps, *buds, *accounts; 1061 GSList *accounts, *buds;
1062 struct group *group;
1063 struct buddy *bud;
1040 fprintf(file, "<?xml version='1.0' encoding='UTF-8' ?>\n"); 1064 fprintf(file, "<?xml version='1.0' encoding='UTF-8' ?>\n");
1041 fprintf(file, "<gaim version=\"1\">\n"); 1065 fprintf(file, "<gaim version=\"1\">\n");
1042 fprintf(file, "\t<blist>\n"); 1066 fprintf(file, "\t<blist>\n");
1043 1067
1044 for(grps = groups; grps; grps = grps->next) { 1068 for(group = (struct group*)gaimbuddylist->root; group; group = (struct group*)((GaimBlistNode*)group)->next) {
1045 struct group *g = grps->data; 1069 if(!exp_acct || gaim_group_on_account(group, exp_acct)) {
1046 if(!exp_acct || gaim_group_on_account(g, exp_acct)) { 1070 char *group_name = g_markup_escape_text(group->name, -1);
1047 char *group_name = g_markup_escape_text(g->name, -1);
1048 fprintf(file, "\t\t<group name=\"%s\">\n", group_name); 1071 fprintf(file, "\t\t<group name=\"%s\">\n", group_name);
1049 for(buds = g->members; buds; buds = buds->next) { 1072 for(buds = group->members; buds; buds = buds->next) {
1050 struct buddy *b = buds->data; 1073 bud = buds->data;
1051 if(!exp_acct || b->account == exp_acct) { 1074 if(!exp_acct || bud->account == exp_acct) {
1052 char *bud_name = g_markup_escape_text(b->name, -1); 1075 char *bud_name = g_markup_escape_text(bud->name, -1);
1053 char *bud_alias = NULL; 1076 char *bud_alias = NULL;
1054 char *acct_name = g_markup_escape_text(b->account->username, -1); 1077 char *acct_name = g_markup_escape_text(bud->account->username, -1);
1055 if(b->alias[0]) 1078 if(bud->alias)
1056 bud_alias= g_markup_escape_text(b->alias, -1); 1079 bud_alias= g_markup_escape_text(bud->alias, -1);
1057 fprintf(file, "\t\t\t<person name=\"%s\">\n", 1080 fprintf(file, "\t\t\t<person name=\"%s\">\n",
1058 bud_alias ? bud_alias : bud_name); 1081 bud_alias ? bud_alias : bud_name);
1059 fprintf(file, "\t\t\t\t<buddy protocol=\"%d\" " 1082 fprintf(file, "\t\t\t\t<buddy protocol=\"%d\" "
1060 "account=\"%s\">\n", b->account->protocol, 1083 "account=\"%s\">\n", bud->account->protocol,
1061 acct_name); 1084 acct_name);
1062 fprintf(file, "\t\t\t\t\t<name>%s</name>\n", bud_name); 1085 fprintf(file, "\t\t\t\t\t<name>%s</name>\n", bud_name);
1063 if(bud_alias) { 1086 if(bud_alias) {
1064 fprintf(file, "\t\t\t\t\t<alias>%s</alias>\n", 1087 fprintf(file, "\t\t\t\t\t<alias>%s</alias>\n",
1065 bud_alias); 1088 bud_alias);
1066 } 1089 }
1067 g_hash_table_foreach(b->settings, 1090 g_hash_table_foreach(bud->settings,
1068 blist_print_buddy_settings, file); 1091 blist_print_buddy_settings, file);
1069 fprintf(file, "\t\t\t\t</buddy>\n"); 1092 fprintf(file, "\t\t\t\t</buddy>\n");
1070 fprintf(file, "\t\t\t</person>\n"); 1093 fprintf(file, "\t\t\t</person>\n");
1071 g_free(bud_name); 1094 g_free(bud_name);
1072 g_free(bud_alias); 1095 g_free(bud_alias);
1216 char *gaim_buddy_get_setting(struct buddy *b, const char *key) { 1239 char *gaim_buddy_get_setting(struct buddy *b, const char *key) {
1217 if(!b) 1240 if(!b)
1218 return NULL; 1241 return NULL;
1219 return g_strdup(g_hash_table_lookup(b->settings, key)); 1242 return g_strdup(g_hash_table_lookup(b->settings, key));
1220 } 1243 }
1244
1245 void gaim_set_blist_ui_ops(struct gaim_blist_ui_ops *ops)
1246 {
1247 gaimbuddylist->ui_ops = blist_ui_ops = ops;
1248 }