comparison src/account.c @ 10427:16d63d8c26d8

[gaim-migrate @ 11679] Shuffle some stuff around for uniformity, and call the accounts.xml loading function from gaim_accounts_init() committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Sun, 26 Dec 2004 23:37:55 +0000
parents 30d9ec7d001b
children 04c663ccbcb1
comparison
equal deleted inserted replaced
10426:30d9ec7d001b 10427:16d63d8c26d8
57 57
58 static GList *accounts = NULL; 58 static GList *accounts = NULL;
59 static guint accounts_save_timer = 0; 59 static guint accounts_save_timer = 0;
60 static gboolean accounts_loaded = FALSE; 60 static gboolean accounts_loaded = FALSE;
61 61
62
63 /**************************************************************************
64 * Writting to disk
65 **************************************************************************/
66
62 static void 67 static void
63 delete_setting(void *data) 68 setting_to_xmlnode(gpointer key, gpointer value, gpointer user_data)
64 { 69 {
65 GaimAccountSetting *setting = (GaimAccountSetting *)data; 70 const char *name;
66 71 GaimAccountSetting *setting;
67 if (setting->ui != NULL) 72 xmlnode *node, *child;
68 g_free(setting->ui); 73 char buf[20];
69 74
70 if (setting->type == GAIM_PREF_STRING) 75 name = (const char *)key;
71 g_free(setting->value.string); 76 setting = (GaimAccountSetting *)value;
72 77 node = (xmlnode *)user_data;
73 g_free(setting); 78
79 child = xmlnode_new_child(node, "setting");
80 xmlnode_set_attrib(child, "name", name);
81
82 if (setting->type == GAIM_PREF_INT) {
83 xmlnode_set_attrib(child, "type", "int");
84 snprintf(buf, sizeof(buf), "%d", setting->value.integer);
85 xmlnode_insert_data(child, buf, -1);
86 }
87 else if (setting->type == GAIM_PREF_STRING && setting->value.string != NULL) {
88 xmlnode_set_attrib(child, "type", "string");
89 xmlnode_insert_data(child, setting->value.string, -1);
90 }
91 else if (setting->type == GAIM_PREF_BOOLEAN) {
92 xmlnode_set_attrib(child, "type", "bool");
93 snprintf(buf, sizeof(buf), "%d", setting->value.bool);
94 xmlnode_insert_data(child, buf, -1);
95 }
96 }
97
98 static void
99 ui_setting_to_xmlnode(gpointer key, gpointer value, gpointer user_data)
100 {
101 const char *ui;
102 GHashTable *table;
103 xmlnode *node, *child;
104
105 ui = (const char *)key;
106 table = (GHashTable *)value;
107 node = (xmlnode *)user_data;
108
109 if (g_hash_table_size(table) > 0)
110 {
111 child = xmlnode_new_child(node, "settings");
112 xmlnode_set_attrib(child, "ui", ui);
113 g_hash_table_foreach(table, setting_to_xmlnode, child);
114 }
115 }
116
117 static xmlnode *
118 proxy_settings_to_xmlnode(GaimProxyInfo *proxy_info)
119 {
120 xmlnode *node, *child;
121 GaimProxyType proxy_type;
122 const char *value;
123 int int_value;
124 char buf[20];
125
126 proxy_type = gaim_proxy_info_get_type(proxy_info);
127
128 node = xmlnode_new("proxy");
129
130 child = xmlnode_new_child(node, "type");
131 xmlnode_insert_data(child,
132 (proxy_type == GAIM_PROXY_USE_GLOBAL ? "global" :
133 proxy_type == GAIM_PROXY_NONE ? "none" :
134 proxy_type == GAIM_PROXY_HTTP ? "http" :
135 proxy_type == GAIM_PROXY_SOCKS4 ? "socks4" :
136 proxy_type == GAIM_PROXY_SOCKS5 ? "socks5" :
137 proxy_type == GAIM_PROXY_USE_ENVVAR ? "envvar" : "unknown"), -1);
138
139 if (proxy_type != GAIM_PROXY_USE_GLOBAL &&
140 proxy_type != GAIM_PROXY_NONE &&
141 proxy_type != GAIM_PROXY_USE_ENVVAR)
142 {
143 if ((value = gaim_proxy_info_get_host(proxy_info)) != NULL)
144 {
145 child = xmlnode_new_child(node, "host");
146 xmlnode_insert_data(child, value, -1);
147 }
148
149 if ((int_value = gaim_proxy_info_get_port(proxy_info)) != 0)
150 {
151 snprintf(buf, sizeof(buf), "%d", int_value);
152 child = xmlnode_new_child(node, "port");
153 xmlnode_insert_data(child, buf, -1);
154 }
155
156 if ((value = gaim_proxy_info_get_username(proxy_info)) != NULL)
157 {
158 child = xmlnode_new_child(node, "username");
159 xmlnode_insert_data(child, value, -1);
160 }
161
162 if ((value = gaim_proxy_info_get_password(proxy_info)) != NULL)
163 {
164 child = xmlnode_new_child(node, "password");
165 xmlnode_insert_data(child, value, -1);
166 }
167 }
168
169 return node;
170 }
171
172 static xmlnode *
173 account_to_xmlnode(GaimAccount *account)
174 {
175 xmlnode *node, *child;
176 const char *tmp;
177 GaimProxyInfo *proxy_info;
178
179 node = xmlnode_new("account");
180
181 child = xmlnode_new_child(node, "protocol");
182 xmlnode_insert_data(child, gaim_account_get_protocol_id(account), -1);
183
184 child = xmlnode_new_child(node, "name");
185 xmlnode_insert_data(child, gaim_account_get_username(account), -1);
186
187 if (gaim_account_get_remember_password(account) &&
188 ((tmp = gaim_account_get_password(account)) != NULL))
189 {
190 child = xmlnode_new_child(node, "password");
191 xmlnode_insert_data(child, tmp, -1);
192 }
193
194 if ((tmp = gaim_account_get_alias(account)) != NULL)
195 {
196 child = xmlnode_new_child(node, "alias");
197 xmlnode_insert_data(child, tmp, -1);
198 }
199
200 if ((tmp = gaim_account_get_user_info(account)) != NULL)
201 {
202 /* TODO: Do we need to call gaim_str_strip_cr(tmp) here? */
203 child = xmlnode_new_child(node, "userinfo");
204 xmlnode_insert_data(child, tmp, -1);
205 }
206
207 if ((tmp = gaim_account_get_buddy_icon(account)) != NULL)
208 {
209 child = xmlnode_new_child(node, "buddyicon");
210 xmlnode_insert_data(child, tmp, -1);
211 }
212
213 if (g_hash_table_size(account->settings) > 0)
214 {
215 child = xmlnode_new_child(node, "settings");
216 g_hash_table_foreach(account->settings, setting_to_xmlnode, child);
217 }
218
219 if (g_hash_table_size(account->ui_settings) > 0)
220 {
221 g_hash_table_foreach(account->ui_settings, ui_setting_to_xmlnode, node);
222 }
223
224 if ((proxy_info = gaim_account_get_proxy_info(account)) != NULL)
225 {
226 child = proxy_settings_to_xmlnode(proxy_info);
227 xmlnode_insert_child(node, child);
228 }
229
230 return node;
231 }
232
233 static xmlnode *
234 accounts_to_xmlnode(void)
235 {
236 xmlnode *node, *child;
237 GList *cur;
238
239 node = xmlnode_new("accounts");
240 xmlnode_set_attrib(node, "version", "1.0");
241
242 for (cur = gaim_accounts_get_all(); cur != NULL; cur = cur->next)
243 {
244 child = account_to_xmlnode(cur->data);
245 xmlnode_insert_child(node, child);
246 }
247
248 return node;
249 }
250
251 static void
252 sync_accounts(void)
253 {
254 xmlnode *node;
255 char *data;
256
257 if (!accounts_loaded) {
258 gaim_debug_error("accounts", "Attempted to save accounts before they "
259 "were read!\n");
260 }
261
262 node = accounts_to_xmlnode();
263 data = xmlnode_to_formatted_str(node, NULL);
264 gaim_util_write_data_to_file("accounts.xml", data, -1);
265 g_free(data);
266 xmlnode_free(node);
74 } 267 }
75 268
76 static gboolean 269 static gboolean
77 accounts_save_cb(gpointer unused) 270 save_cb(gpointer data)
78 { 271 {
79 gaim_accounts_sync(); 272 sync_accounts();
80 accounts_save_timer = 0; 273 accounts_save_timer = 0;
81
82 return FALSE; 274 return FALSE;
83 } 275 }
84 276
85 static void 277 static void
86 schedule_accounts_save() 278 schedule_accounts_save()
87 { 279 {
88 if (accounts_save_timer == 0) 280 if (accounts_save_timer == 0)
89 accounts_save_timer = gaim_timeout_add(5000, accounts_save_cb, NULL); 281 accounts_save_timer = gaim_timeout_add(5000, save_cb, NULL);
90 } 282 }
91 283
92 GaimAccount * 284
93 gaim_account_new(const char *username, const char *protocol_id) 285 /**************************************************************************
94 { 286 * Reading from disk
95 GaimAccount *account = NULL; 287 **************************************************************************/
96 GaimPlugin *prpl = NULL;
97 GaimPluginProtocolInfo *prpl_info = NULL;
98
99 g_return_val_if_fail(username != NULL, NULL);
100 g_return_val_if_fail(protocol_id != NULL, NULL);
101
102 account = gaim_accounts_find(username, protocol_id);
103
104 if (account != NULL)
105 return account;
106
107 account = g_new0(GaimAccount, 1);
108
109 gaim_account_set_username(account, username);
110
111 gaim_account_set_protocol_id(account, protocol_id);
112
113 account->settings = g_hash_table_new_full(g_str_hash, g_str_equal,
114 g_free, delete_setting);
115 account->ui_settings = g_hash_table_new_full(g_str_hash, g_str_equal,
116 g_free, (GDestroyNotify)g_hash_table_destroy);
117 account->system_log = NULL;
118
119 account->presence = gaim_presence_new_for_account(account);
120
121 prpl = gaim_find_prpl(gaim_account_get_protocol_id(account));
122
123 if (prpl == NULL)
124 return account;
125
126 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl);
127 if ( prpl_info != NULL && prpl_info->status_types != NULL )
128 gaim_account_set_status_types(account, prpl_info->status_types(account));
129
130 gaim_presence_set_status_active(account->presence, "offline", TRUE);
131
132 return account;
133 }
134
135 void
136 gaim_account_destroy(GaimAccount *account)
137 {
138 GList *l;
139
140 g_return_if_fail(account != NULL);
141
142 gaim_debug_info("account", "Destroying account %p\n", account);
143
144 if (account->gc != NULL)
145 gaim_connection_destroy(account->gc);
146
147 gaim_debug_info("account", "Continuing to destroy account %p\n", account);
148
149 for (l = gaim_get_conversations(); l != NULL; l = l->next)
150 {
151 GaimConversation *conv = (GaimConversation *)l->data;
152
153 if (gaim_conversation_get_account(conv) == account)
154 gaim_conversation_set_account(conv, NULL);
155 }
156
157 if (account->username != NULL) g_free(account->username);
158 if (account->alias != NULL) g_free(account->alias);
159 if (account->password != NULL) g_free(account->password);
160 if (account->user_info != NULL) g_free(account->user_info);
161 if (account->protocol_id != NULL) g_free(account->protocol_id);
162
163 g_hash_table_destroy(account->settings);
164 g_hash_table_destroy(account->ui_settings);
165
166 gaim_account_set_status_types(account, NULL);
167
168 gaim_presence_destroy(account->presence);
169
170 if(account->system_log)
171 gaim_log_free(account->system_log);
172
173 g_free(account);
174 }
175
176 GaimConnection *
177 gaim_account_register(GaimAccount *account)
178 {
179 GaimConnection *gc;
180
181 g_return_val_if_fail(account != NULL, NULL);
182
183 if (gaim_account_get_connection(account) != NULL)
184 return NULL;
185
186 gc = gaim_connection_new(account);
187
188 gaim_debug_info("account", "Registering account %p. gc = %p\n",
189 account, gc);
190
191 gaim_connection_register(gc);
192
193 return gc;
194 }
195
196 GaimConnection *
197 gaim_account_connect(GaimAccount *account, GaimStatus *status)
198 {
199 GaimConnection *gc;
200
201 g_return_val_if_fail(account != NULL, NULL);
202
203 if (gaim_account_get_connection(account) != NULL)
204 return NULL;
205
206 gc = gaim_connection_new(account);
207
208 gaim_debug_info("account", "Connecting to account %p. gc = %p\n",
209 account, gc);
210
211 gaim_connection_connect(gc, status);
212
213 return gc;
214 }
215
216 void
217 gaim_account_disconnect(GaimAccount *account)
218 {
219 GaimConnection *gc;
220
221 g_return_if_fail(account != NULL);
222 g_return_if_fail(gaim_account_is_connected(account));
223
224 gaim_debug_info("account", "Disconnecting account %p\n", account);
225
226 account->disconnecting = TRUE;
227 gc = gaim_account_get_connection(account);
228
229 gaim_connection_disconnect(gc);
230
231 gaim_account_set_connection(account, NULL);
232 account->disconnecting = FALSE;
233 }
234
235 void
236 gaim_account_notify_added(GaimAccount *account, const char *id,
237 const char *remote_user, const char *alias,
238 const char *message)
239 {
240 GaimAccountUiOps *ui_ops;
241
242 g_return_if_fail(account != NULL);
243 g_return_if_fail(remote_user != NULL);
244
245 ui_ops = gaim_accounts_get_ui_ops();
246
247 if (ui_ops != NULL && ui_ops->notify_added != NULL)
248 ui_ops->notify_added(account, remote_user, id, alias, message);
249 }
250
251 static void
252 change_password_cb(GaimAccount *account, GaimRequestFields *fields)
253 {
254 const char *orig_pass, *new_pass_1, *new_pass_2;
255
256 orig_pass = gaim_request_fields_get_string(fields, "password");
257 new_pass_1 = gaim_request_fields_get_string(fields, "new_password_1");
258 new_pass_2 = gaim_request_fields_get_string(fields, "new_password_2");
259
260 if (g_utf8_collate(new_pass_1, new_pass_2))
261 {
262 gaim_notify_error(NULL, NULL,
263 _("New passwords do not match."), NULL);
264
265 return;
266 }
267
268 if (orig_pass == NULL || new_pass_1 == NULL || new_pass_2 == NULL ||
269 *orig_pass == '\0' || *new_pass_1 == '\0' || *new_pass_2 == '\0')
270 {
271 gaim_notify_error(NULL, NULL,
272 _("Fill out all fields completely."), NULL);
273 return;
274 }
275
276 serv_change_passwd(gaim_account_get_connection(account),
277 orig_pass, new_pass_1);
278 gaim_account_set_password(account, new_pass_1);
279 }
280
281 void
282 gaim_account_request_change_password(GaimAccount *account)
283 {
284 GaimRequestFields *fields;
285 GaimRequestFieldGroup *group;
286 GaimRequestField *field;
287 char primary[256];
288
289 g_return_if_fail(account != NULL);
290 g_return_if_fail(gaim_account_is_connected(account));
291
292 fields = gaim_request_fields_new();
293
294 group = gaim_request_field_group_new(NULL);
295 gaim_request_fields_add_group(fields, group);
296
297 field = gaim_request_field_string_new("password", _("Original password"),
298 NULL, FALSE);
299 gaim_request_field_string_set_masked(field, TRUE);
300 gaim_request_field_set_required(field, TRUE);
301 gaim_request_field_group_add_field(group, field);
302
303 field = gaim_request_field_string_new("new_password_1",
304 _("New password"),
305 NULL, FALSE);
306 gaim_request_field_string_set_masked(field, TRUE);
307 gaim_request_field_set_required(field, TRUE);
308 gaim_request_field_group_add_field(group, field);
309
310 field = gaim_request_field_string_new("new_password_2",
311 _("New password (again)"),
312 NULL, FALSE);
313 gaim_request_field_string_set_masked(field, TRUE);
314 gaim_request_field_set_required(field, TRUE);
315 gaim_request_field_group_add_field(group, field);
316
317 g_snprintf(primary, sizeof(primary), _("Change password for %s"),
318 gaim_account_get_username(account));
319
320 /* I'm sticking this somewhere in the code: bologna */
321
322 gaim_request_fields(gaim_account_get_connection(account),
323 NULL,
324 primary,
325 _("Please enter your current password and your "
326 "new password."),
327 fields,
328 _("OK"), G_CALLBACK(change_password_cb),
329 _("Cancel"), NULL,
330 account);
331 }
332
333 static void
334 set_user_info_cb(GaimAccount *account, const char *user_info)
335 {
336 GaimConnection *gc;
337
338 gaim_account_set_user_info(account, user_info);
339
340 gc = gaim_account_get_connection(account);
341
342 if (gc != NULL)
343 serv_set_info(gaim_account_get_connection(account), user_info);
344 }
345
346 void
347 gaim_account_request_change_user_info(GaimAccount *account)
348 {
349 GaimConnection *gc;
350 char primary[256];
351
352 g_return_if_fail(account != NULL);
353 g_return_if_fail(gaim_account_is_connected(account));
354
355 gc = gaim_account_get_connection(account);
356
357 g_snprintf(primary, sizeof(primary),
358 _("Change user information for %s"),
359 gaim_account_get_username(account));
360
361 gaim_request_input(gaim_account_get_connection(account),
362 NULL, primary, NULL,
363 gaim_account_get_user_info(account),
364 TRUE, FALSE, ((gc != NULL) &&
365 (gc->flags & GAIM_CONNECTION_HTML) ? "html" : NULL),
366 _("Save"), G_CALLBACK(set_user_info_cb),
367 _("Cancel"), NULL, account);
368 }
369
370 void
371 gaim_account_set_username(GaimAccount *account, const char *username)
372 {
373 g_return_if_fail(account != NULL);
374
375 if (account->username != NULL)
376 g_free(account->username);
377
378 account->username = (username == NULL ? NULL : g_strdup(username));
379
380 schedule_accounts_save();
381 }
382
383 void
384 gaim_account_set_password(GaimAccount *account, const char *password)
385 {
386 g_return_if_fail(account != NULL);
387
388 if (account->password != NULL)
389 g_free(account->password);
390
391 account->password = (password == NULL ? NULL : g_strdup(password));
392
393 schedule_accounts_save();
394 }
395
396 void
397 gaim_account_set_alias(GaimAccount *account, const char *alias)
398 {
399 g_return_if_fail(account != NULL);
400
401 if (account->alias != NULL)
402 g_free(account->alias);
403
404 account->alias = (alias == NULL ? NULL : g_strdup(alias));
405
406 schedule_accounts_save();
407 }
408
409 void
410 gaim_account_set_user_info(GaimAccount *account, const char *user_info)
411 {
412 g_return_if_fail(account != NULL);
413
414 if (account->user_info != NULL)
415 g_free(account->user_info);
416
417 account->user_info = (user_info == NULL ? NULL : g_strdup(user_info));
418
419 schedule_accounts_save();
420 }
421
422 void
423 gaim_account_set_buddy_icon(GaimAccount *account, const char *icon)
424 {
425 g_return_if_fail(account != NULL);
426
427 if (account->buddy_icon != NULL)
428 g_free(account->buddy_icon);
429
430 account->buddy_icon = (icon == NULL ? NULL : g_strdup(icon));
431 if (account->gc)
432 serv_set_buddyicon(account->gc, icon);
433
434 schedule_accounts_save();
435 }
436
437 void
438 gaim_account_set_protocol_id(GaimAccount *account, const char *protocol_id)
439 {
440 g_return_if_fail(account != NULL);
441 g_return_if_fail(protocol_id != NULL);
442
443 if (account->protocol_id != NULL)
444 g_free(account->protocol_id);
445
446 account->protocol_id = g_strdup(protocol_id);
447
448 schedule_accounts_save();
449 }
450
451 void
452 gaim_account_set_connection(GaimAccount *account, GaimConnection *gc)
453 {
454 g_return_if_fail(account != NULL);
455
456 account->gc = gc;
457 }
458
459 void
460 gaim_account_set_remember_password(GaimAccount *account, gboolean value)
461 {
462 g_return_if_fail(account != NULL);
463
464 account->remember_pass = value;
465
466 schedule_accounts_save();
467 }
468
469 void
470 gaim_account_set_check_mail(GaimAccount *account, gboolean value)
471 {
472 g_return_if_fail(account != NULL);
473
474 gaim_account_set_bool(account, "check-mail", value);
475 }
476
477 void
478 gaim_account_set_enabled(GaimAccount *account, const char *ui,
479 gboolean value)
480 {
481 g_return_if_fail(account != NULL);
482 g_return_if_fail(ui != NULL);
483
484 gaim_account_set_ui_bool(account, ui, "auto-login", value);
485 }
486
487 void
488 gaim_account_set_proxy_info(GaimAccount *account, GaimProxyInfo *info)
489 {
490 g_return_if_fail(account != NULL);
491
492 if (account->proxy_info != NULL)
493 gaim_proxy_info_destroy(account->proxy_info);
494
495 account->proxy_info = info;
496
497 schedule_accounts_save();
498 }
499
500 void
501 gaim_account_set_status_types(GaimAccount *account, GList *status_types)
502 {
503 g_return_if_fail(account != NULL);
504
505 /* Old with the old... */
506 if (account->status_types != NULL)
507 {
508 GList *l;
509
510 for (l = account->status_types; l != NULL; l = l->next)
511 gaim_status_type_destroy((GaimStatusType *)l->data);
512
513 g_list_free(account->status_types);
514 }
515
516 /* In with the new... */
517 account->status_types = status_types;
518 }
519
520 void
521 gaim_account_set_status(GaimAccount *account, const char *status_id,
522 gboolean active, ...)
523 {
524 GaimStatus *status;
525 va_list args;
526
527 g_return_if_fail(account != NULL);
528 g_return_if_fail(status_id != NULL);
529
530 status = gaim_account_get_status(account, status_id);
531
532 if (status == NULL)
533 {
534 gaim_debug_error("accounts",
535 "Invalid status ID %s for account %s (%s)\n",
536 status_id, gaim_account_get_username(account),
537 gaim_account_get_protocol_id(account));
538 return;
539 }
540
541 va_start(args, active);
542 gaim_status_set_active_with_attrs(status, active, args);
543 va_end(args);
544 }
545
546 void
547 gaim_account_clear_settings(GaimAccount *account)
548 {
549 g_return_if_fail(account != NULL);
550
551 g_hash_table_destroy(account->settings);
552
553 account->settings = g_hash_table_new_full(g_str_hash, g_str_equal,
554 g_free, delete_setting);
555 }
556
557 void
558 gaim_account_set_int(GaimAccount *account, const char *name, int value)
559 {
560 GaimAccountSetting *setting;
561
562 g_return_if_fail(account != NULL);
563 g_return_if_fail(name != NULL);
564
565 setting = g_new0(GaimAccountSetting, 1);
566
567 setting->type = GAIM_PREF_INT;
568 setting->value.integer = value;
569
570 g_hash_table_insert(account->settings, g_strdup(name), setting);
571
572 schedule_accounts_save();
573 }
574
575 void
576 gaim_account_set_string(GaimAccount *account, const char *name,
577 const char *value)
578 {
579 GaimAccountSetting *setting;
580
581 g_return_if_fail(account != NULL);
582 g_return_if_fail(name != NULL);
583
584 setting = g_new0(GaimAccountSetting, 1);
585
586 setting->type = GAIM_PREF_STRING;
587 setting->value.string = g_strdup(value);
588
589 g_hash_table_insert(account->settings, g_strdup(name), setting);
590
591 schedule_accounts_save();
592 }
593
594 void
595 gaim_account_set_bool(GaimAccount *account, const char *name, gboolean value)
596 {
597 GaimAccountSetting *setting;
598
599 g_return_if_fail(account != NULL);
600 g_return_if_fail(name != NULL);
601
602 setting = g_new0(GaimAccountSetting, 1);
603
604 setting->type = GAIM_PREF_BOOLEAN;
605 setting->value.bool = value;
606
607 g_hash_table_insert(account->settings, g_strdup(name), setting);
608
609 schedule_accounts_save();
610 }
611
612 static GHashTable *
613 get_ui_settings_table(GaimAccount *account, const char *ui)
614 {
615 GHashTable *table;
616
617 table = g_hash_table_lookup(account->ui_settings, ui);
618
619 if (table == NULL) {
620 table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
621 delete_setting);
622 g_hash_table_insert(account->ui_settings, g_strdup(ui), table);
623 }
624
625 return table;
626 }
627
628 void
629 gaim_account_set_ui_int(GaimAccount *account, const char *ui,
630 const char *name, int value)
631 {
632 GaimAccountSetting *setting;
633 GHashTable *table;
634
635 g_return_if_fail(account != NULL);
636 g_return_if_fail(ui != NULL);
637 g_return_if_fail(name != NULL);
638
639 setting = g_new0(GaimAccountSetting, 1);
640
641 setting->type = GAIM_PREF_INT;
642 setting->ui = g_strdup(ui);
643 setting->value.integer = value;
644
645 table = get_ui_settings_table(account, ui);
646
647 g_hash_table_insert(table, g_strdup(name), setting);
648
649 schedule_accounts_save();
650 }
651
652 void
653 gaim_account_set_ui_string(GaimAccount *account, const char *ui,
654 const char *name, const char *value)
655 {
656 GaimAccountSetting *setting;
657 GHashTable *table;
658
659 g_return_if_fail(account != NULL);
660 g_return_if_fail(ui != NULL);
661 g_return_if_fail(name != NULL);
662
663 setting = g_new0(GaimAccountSetting, 1);
664
665 setting->type = GAIM_PREF_STRING;
666 setting->ui = g_strdup(ui);
667 setting->value.string = g_strdup(value);
668
669 table = get_ui_settings_table(account, ui);
670
671 g_hash_table_insert(table, g_strdup(name), setting);
672
673 schedule_accounts_save();
674 }
675
676 void
677 gaim_account_set_ui_bool(GaimAccount *account, const char *ui,
678 const char *name, gboolean value)
679 {
680 GaimAccountSetting *setting;
681 GHashTable *table;
682
683 g_return_if_fail(account != NULL);
684 g_return_if_fail(ui != NULL);
685 g_return_if_fail(name != NULL);
686
687 setting = g_new0(GaimAccountSetting, 1);
688
689 setting->type = GAIM_PREF_BOOLEAN;
690 setting->ui = g_strdup(ui);
691 setting->value.bool = value;
692
693 table = get_ui_settings_table(account, ui);
694
695 g_hash_table_insert(table, g_strdup(name), setting);
696
697 schedule_accounts_save();
698 }
699
700 gboolean
701 gaim_account_is_connected(const GaimAccount *account)
702 {
703 GaimConnection *gc;
704
705 g_return_val_if_fail(account != NULL, FALSE);
706
707 gc = gaim_account_get_connection(account);
708
709 /* XXX - The first way is better... but it doesn't work quite right yet */
710 /* return ((gc != NULL) && GAIM_CONNECTION_IS_CONNECTED(gc)); */
711 return ((gc != NULL) && gaim_connection_get_state(gc) != GAIM_DISCONNECTED);
712 }
713
714 const char *
715 gaim_account_get_username(const GaimAccount *account)
716 {
717 g_return_val_if_fail(account != NULL, NULL);
718
719 return account->username;
720 }
721
722 const char *
723 gaim_account_get_password(const GaimAccount *account)
724 {
725 g_return_val_if_fail(account != NULL, NULL);
726
727 return account->password;
728 }
729
730 const char *
731 gaim_account_get_alias(const GaimAccount *account)
732 {
733 g_return_val_if_fail(account != NULL, NULL);
734
735 return account->alias;
736 }
737
738 const char *
739 gaim_account_get_user_info(const GaimAccount *account)
740 {
741 g_return_val_if_fail(account != NULL, NULL);
742
743 return account->user_info;
744 }
745
746 const char *
747 gaim_account_get_buddy_icon(const GaimAccount *account)
748 {
749 g_return_val_if_fail(account != NULL, NULL);
750
751 return account->buddy_icon;
752 }
753
754 const char *
755 gaim_account_get_protocol_id(const GaimAccount *account)
756 {
757 g_return_val_if_fail(account != NULL, NULL);
758
759 return account->protocol_id;
760 }
761
762 const char *
763 gaim_account_get_protocol_name(const GaimAccount *account)
764 {
765 GaimPlugin *p;
766
767 g_return_val_if_fail(account != NULL, NULL);
768
769 p = gaim_find_prpl(gaim_account_get_protocol_id(account));
770
771 return ((p && p->info->name) ? _(p->info->name) : _("Unknown"));
772 }
773
774 GaimConnection *
775 gaim_account_get_connection(const GaimAccount *account)
776 {
777 g_return_val_if_fail(account != NULL, NULL);
778
779 return account->gc;
780 }
781
782 gboolean
783 gaim_account_get_remember_password(const GaimAccount *account)
784 {
785 g_return_val_if_fail(account != NULL, FALSE);
786
787 return account->remember_pass;
788 }
789
790 gboolean
791 gaim_account_get_check_mail(const GaimAccount *account)
792 {
793 g_return_val_if_fail(account != NULL, FALSE);
794
795 return gaim_account_get_bool(account, "check-mail", FALSE);
796 }
797
798 gboolean
799 gaim_account_get_enabled(const GaimAccount *account, const char *ui)
800 {
801 g_return_val_if_fail(account != NULL, FALSE);
802 g_return_val_if_fail(ui != NULL, FALSE);
803
804 return gaim_account_get_ui_bool(account, ui, "auto-login", FALSE);
805 }
806
807 GaimProxyInfo *
808 gaim_account_get_proxy_info(const GaimAccount *account)
809 {
810 g_return_val_if_fail(account != NULL, NULL);
811
812 return account->proxy_info;
813 }
814
815 GaimStatus *
816 gaim_account_get_status(const GaimAccount *account, const char *status_id)
817 {
818 g_return_val_if_fail(account != NULL, NULL);
819 g_return_val_if_fail(status_id != NULL, NULL);
820
821 return gaim_presence_get_status(account->presence, status_id);
822 }
823
824 GaimStatusType *
825 gaim_account_get_status_type(const GaimAccount *account, const char *id)
826 {
827 const GList *l;
828
829 g_return_val_if_fail(account != NULL, NULL);
830 g_return_val_if_fail(id != NULL, NULL);
831
832 for (l = gaim_account_get_status_types(account); l != NULL; l = l->next)
833 {
834 GaimStatusType *status_type = (GaimStatusType *)l->data;
835
836 if (!strcmp(gaim_status_type_get_id(status_type), id))
837 return status_type;
838 }
839
840 return NULL;
841 }
842
843 GaimPresence *
844 gaim_account_get_presence(const GaimAccount *account)
845 {
846 g_return_val_if_fail(account != NULL, NULL);
847
848 return account->presence;
849 }
850
851 gboolean
852 gaim_account_is_status_active(const GaimAccount *account,
853 const char *status_id)
854 {
855 g_return_val_if_fail(account != NULL, FALSE);
856 g_return_val_if_fail(status_id != NULL, FALSE);
857
858 return gaim_presence_is_status_active(account->presence, status_id);
859 }
860
861 const GList *
862 gaim_account_get_status_types(const GaimAccount *account)
863 {
864 g_return_val_if_fail(account != NULL, NULL);
865
866 return account->status_types;
867 }
868
869 int
870 gaim_account_get_int(const GaimAccount *account, const char *name,
871 int default_value)
872 {
873 GaimAccountSetting *setting;
874
875 g_return_val_if_fail(account != NULL, default_value);
876 g_return_val_if_fail(name != NULL, default_value);
877
878 setting = g_hash_table_lookup(account->settings, name);
879
880 if (setting == NULL)
881 return default_value;
882
883 g_return_val_if_fail(setting->type == GAIM_PREF_INT, default_value);
884
885 return setting->value.integer;
886 }
887
888 const char *
889 gaim_account_get_string(const GaimAccount *account, const char *name,
890 const char *default_value)
891 {
892 GaimAccountSetting *setting;
893
894 g_return_val_if_fail(account != NULL, default_value);
895 g_return_val_if_fail(name != NULL, default_value);
896
897 setting = g_hash_table_lookup(account->settings, name);
898
899 if (setting == NULL)
900 return default_value;
901
902 g_return_val_if_fail(setting->type == GAIM_PREF_STRING, default_value);
903
904 return setting->value.string;
905 }
906
907 gboolean
908 gaim_account_get_bool(const GaimAccount *account, const char *name,
909 gboolean default_value)
910 {
911 GaimAccountSetting *setting;
912
913 g_return_val_if_fail(account != NULL, default_value);
914 g_return_val_if_fail(name != NULL, default_value);
915
916 setting = g_hash_table_lookup(account->settings, name);
917
918 if (setting == NULL)
919 return default_value;
920
921 g_return_val_if_fail(setting->type == GAIM_PREF_BOOLEAN, default_value);
922
923 return setting->value.bool;
924 }
925
926 int
927 gaim_account_get_ui_int(const GaimAccount *account, const char *ui,
928 const char *name, int default_value)
929 {
930 GaimAccountSetting *setting;
931 GHashTable *table;
932
933 g_return_val_if_fail(account != NULL, default_value);
934 g_return_val_if_fail(ui != NULL, default_value);
935 g_return_val_if_fail(name != NULL, default_value);
936
937 if ((table = g_hash_table_lookup(account->ui_settings, ui)) == NULL)
938 return default_value;
939
940 if ((setting = g_hash_table_lookup(table, name)) == NULL)
941 return default_value;
942
943 g_return_val_if_fail(setting->type == GAIM_PREF_INT, default_value);
944
945 return setting->value.integer;
946 }
947
948 const char *
949 gaim_account_get_ui_string(const GaimAccount *account, const char *ui,
950 const char *name, const char *default_value)
951 {
952 GaimAccountSetting *setting;
953 GHashTable *table;
954
955 g_return_val_if_fail(account != NULL, default_value);
956 g_return_val_if_fail(ui != NULL, default_value);
957 g_return_val_if_fail(name != NULL, default_value);
958
959 if ((table = g_hash_table_lookup(account->ui_settings, ui)) == NULL)
960 return default_value;
961
962 if ((setting = g_hash_table_lookup(table, name)) == NULL)
963 return default_value;
964
965 g_return_val_if_fail(setting->type == GAIM_PREF_STRING, default_value);
966
967 return setting->value.string;
968 }
969
970 gboolean
971 gaim_account_get_ui_bool(const GaimAccount *account, const char *ui,
972 const char *name, gboolean default_value)
973 {
974 GaimAccountSetting *setting;
975 GHashTable *table;
976
977 g_return_val_if_fail(account != NULL, default_value);
978 g_return_val_if_fail(ui != NULL, default_value);
979 g_return_val_if_fail(name != NULL, default_value);
980
981 if ((table = g_hash_table_lookup(account->ui_settings, ui)) == NULL)
982 return default_value;
983
984 if ((setting = g_hash_table_lookup(table, name)) == NULL)
985 return default_value;
986
987 g_return_val_if_fail(setting->type == GAIM_PREF_BOOLEAN, default_value);
988
989 return setting->value.bool;
990 }
991
992 GaimLog *
993 gaim_account_get_log(GaimAccount *account)
994 {
995 g_return_val_if_fail(account != NULL, NULL);
996
997 if(!account->system_log){
998 GaimConnection *gc;
999
1000 gc = gaim_account_get_connection(account);
1001
1002 account->system_log = gaim_log_new(GAIM_LOG_SYSTEM,
1003 gaim_account_get_username(account), account,
1004 gc != NULL ? gc->login_time : time(NULL));
1005 }
1006
1007 return account->system_log;
1008 }
1009
1010 void
1011 gaim_account_destroy_log(GaimAccount *account)
1012 {
1013 g_return_if_fail(account != NULL);
1014
1015 if(account->system_log){
1016 gaim_log_free(account->system_log);
1017 account->system_log = NULL;
1018 }
1019 }
1020 288
1021 static void 289 static void
1022 parse_settings(xmlnode *node, GaimAccount *account) 290 parse_settings(xmlnode *node, GaimAccount *account)
1023 { 291 {
1024 const char *ui; 292 const char *ui;
1266 new = parse_account(child); 534 new = parse_account(child);
1267 gaim_accounts_add(new); 535 gaim_accounts_add(new);
1268 } 536 }
1269 } 537 }
1270 538
539
1271 static void 540 static void
1272 setting_to_xmlnode(gpointer key, gpointer value, gpointer user_data) 541 delete_setting(void *data)
1273 { 542 {
1274 const char *name; 543 GaimAccountSetting *setting = (GaimAccountSetting *)data;
544
545 if (setting->ui != NULL)
546 g_free(setting->ui);
547
548 if (setting->type == GAIM_PREF_STRING)
549 g_free(setting->value.string);
550
551 g_free(setting);
552 }
553
554 GaimAccount *
555 gaim_account_new(const char *username, const char *protocol_id)
556 {
557 GaimAccount *account = NULL;
558 GaimPlugin *prpl = NULL;
559 GaimPluginProtocolInfo *prpl_info = NULL;
560
561 g_return_val_if_fail(username != NULL, NULL);
562 g_return_val_if_fail(protocol_id != NULL, NULL);
563
564 account = gaim_accounts_find(username, protocol_id);
565
566 if (account != NULL)
567 return account;
568
569 account = g_new0(GaimAccount, 1);
570
571 gaim_account_set_username(account, username);
572
573 gaim_account_set_protocol_id(account, protocol_id);
574
575 account->settings = g_hash_table_new_full(g_str_hash, g_str_equal,
576 g_free, delete_setting);
577 account->ui_settings = g_hash_table_new_full(g_str_hash, g_str_equal,
578 g_free, (GDestroyNotify)g_hash_table_destroy);
579 account->system_log = NULL;
580
581 account->presence = gaim_presence_new_for_account(account);
582
583 prpl = gaim_find_prpl(gaim_account_get_protocol_id(account));
584
585 if (prpl == NULL)
586 return account;
587
588 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl);
589 if ( prpl_info != NULL && prpl_info->status_types != NULL )
590 gaim_account_set_status_types(account, prpl_info->status_types(account));
591
592 gaim_presence_set_status_active(account->presence, "offline", TRUE);
593
594 return account;
595 }
596
597 void
598 gaim_account_destroy(GaimAccount *account)
599 {
600 GList *l;
601
602 g_return_if_fail(account != NULL);
603
604 gaim_debug_info("account", "Destroying account %p\n", account);
605
606 if (account->gc != NULL)
607 gaim_connection_destroy(account->gc);
608
609 gaim_debug_info("account", "Continuing to destroy account %p\n", account);
610
611 for (l = gaim_get_conversations(); l != NULL; l = l->next)
612 {
613 GaimConversation *conv = (GaimConversation *)l->data;
614
615 if (gaim_conversation_get_account(conv) == account)
616 gaim_conversation_set_account(conv, NULL);
617 }
618
619 if (account->username != NULL) g_free(account->username);
620 if (account->alias != NULL) g_free(account->alias);
621 if (account->password != NULL) g_free(account->password);
622 if (account->user_info != NULL) g_free(account->user_info);
623 if (account->protocol_id != NULL) g_free(account->protocol_id);
624
625 g_hash_table_destroy(account->settings);
626 g_hash_table_destroy(account->ui_settings);
627
628 gaim_account_set_status_types(account, NULL);
629
630 gaim_presence_destroy(account->presence);
631
632 if(account->system_log)
633 gaim_log_free(account->system_log);
634
635 g_free(account);
636 }
637
638 GaimConnection *
639 gaim_account_register(GaimAccount *account)
640 {
641 GaimConnection *gc;
642
643 g_return_val_if_fail(account != NULL, NULL);
644
645 if (gaim_account_get_connection(account) != NULL)
646 return NULL;
647
648 gc = gaim_connection_new(account);
649
650 gaim_debug_info("account", "Registering account %p. gc = %p\n",
651 account, gc);
652
653 gaim_connection_register(gc);
654
655 return gc;
656 }
657
658 GaimConnection *
659 gaim_account_connect(GaimAccount *account, GaimStatus *status)
660 {
661 GaimConnection *gc;
662
663 g_return_val_if_fail(account != NULL, NULL);
664
665 if (gaim_account_get_connection(account) != NULL)
666 return NULL;
667
668 gc = gaim_connection_new(account);
669
670 gaim_debug_info("account", "Connecting to account %p. gc = %p\n",
671 account, gc);
672
673 gaim_connection_connect(gc, status);
674
675 return gc;
676 }
677
678 void
679 gaim_account_disconnect(GaimAccount *account)
680 {
681 GaimConnection *gc;
682
683 g_return_if_fail(account != NULL);
684 g_return_if_fail(gaim_account_is_connected(account));
685
686 gaim_debug_info("account", "Disconnecting account %p\n", account);
687
688 account->disconnecting = TRUE;
689 gc = gaim_account_get_connection(account);
690
691 gaim_connection_disconnect(gc);
692
693 gaim_account_set_connection(account, NULL);
694 account->disconnecting = FALSE;
695 }
696
697 void
698 gaim_account_notify_added(GaimAccount *account, const char *id,
699 const char *remote_user, const char *alias,
700 const char *message)
701 {
702 GaimAccountUiOps *ui_ops;
703
704 g_return_if_fail(account != NULL);
705 g_return_if_fail(remote_user != NULL);
706
707 ui_ops = gaim_accounts_get_ui_ops();
708
709 if (ui_ops != NULL && ui_ops->notify_added != NULL)
710 ui_ops->notify_added(account, remote_user, id, alias, message);
711 }
712
713 static void
714 change_password_cb(GaimAccount *account, GaimRequestFields *fields)
715 {
716 const char *orig_pass, *new_pass_1, *new_pass_2;
717
718 orig_pass = gaim_request_fields_get_string(fields, "password");
719 new_pass_1 = gaim_request_fields_get_string(fields, "new_password_1");
720 new_pass_2 = gaim_request_fields_get_string(fields, "new_password_2");
721
722 if (g_utf8_collate(new_pass_1, new_pass_2))
723 {
724 gaim_notify_error(NULL, NULL,
725 _("New passwords do not match."), NULL);
726
727 return;
728 }
729
730 if (orig_pass == NULL || new_pass_1 == NULL || new_pass_2 == NULL ||
731 *orig_pass == '\0' || *new_pass_1 == '\0' || *new_pass_2 == '\0')
732 {
733 gaim_notify_error(NULL, NULL,
734 _("Fill out all fields completely."), NULL);
735 return;
736 }
737
738 serv_change_passwd(gaim_account_get_connection(account),
739 orig_pass, new_pass_1);
740 gaim_account_set_password(account, new_pass_1);
741 }
742
743 void
744 gaim_account_request_change_password(GaimAccount *account)
745 {
746 GaimRequestFields *fields;
747 GaimRequestFieldGroup *group;
748 GaimRequestField *field;
749 char primary[256];
750
751 g_return_if_fail(account != NULL);
752 g_return_if_fail(gaim_account_is_connected(account));
753
754 fields = gaim_request_fields_new();
755
756 group = gaim_request_field_group_new(NULL);
757 gaim_request_fields_add_group(fields, group);
758
759 field = gaim_request_field_string_new("password", _("Original password"),
760 NULL, FALSE);
761 gaim_request_field_string_set_masked(field, TRUE);
762 gaim_request_field_set_required(field, TRUE);
763 gaim_request_field_group_add_field(group, field);
764
765 field = gaim_request_field_string_new("new_password_1",
766 _("New password"),
767 NULL, FALSE);
768 gaim_request_field_string_set_masked(field, TRUE);
769 gaim_request_field_set_required(field, TRUE);
770 gaim_request_field_group_add_field(group, field);
771
772 field = gaim_request_field_string_new("new_password_2",
773 _("New password (again)"),
774 NULL, FALSE);
775 gaim_request_field_string_set_masked(field, TRUE);
776 gaim_request_field_set_required(field, TRUE);
777 gaim_request_field_group_add_field(group, field);
778
779 g_snprintf(primary, sizeof(primary), _("Change password for %s"),
780 gaim_account_get_username(account));
781
782 /* I'm sticking this somewhere in the code: bologna */
783
784 gaim_request_fields(gaim_account_get_connection(account),
785 NULL,
786 primary,
787 _("Please enter your current password and your "
788 "new password."),
789 fields,
790 _("OK"), G_CALLBACK(change_password_cb),
791 _("Cancel"), NULL,
792 account);
793 }
794
795 static void
796 set_user_info_cb(GaimAccount *account, const char *user_info)
797 {
798 GaimConnection *gc;
799
800 gaim_account_set_user_info(account, user_info);
801
802 gc = gaim_account_get_connection(account);
803
804 if (gc != NULL)
805 serv_set_info(gaim_account_get_connection(account), user_info);
806 }
807
808 void
809 gaim_account_request_change_user_info(GaimAccount *account)
810 {
811 GaimConnection *gc;
812 char primary[256];
813
814 g_return_if_fail(account != NULL);
815 g_return_if_fail(gaim_account_is_connected(account));
816
817 gc = gaim_account_get_connection(account);
818
819 g_snprintf(primary, sizeof(primary),
820 _("Change user information for %s"),
821 gaim_account_get_username(account));
822
823 gaim_request_input(gaim_account_get_connection(account),
824 NULL, primary, NULL,
825 gaim_account_get_user_info(account),
826 TRUE, FALSE, ((gc != NULL) &&
827 (gc->flags & GAIM_CONNECTION_HTML) ? "html" : NULL),
828 _("Save"), G_CALLBACK(set_user_info_cb),
829 _("Cancel"), NULL, account);
830 }
831
832 void
833 gaim_account_set_username(GaimAccount *account, const char *username)
834 {
835 g_return_if_fail(account != NULL);
836
837 if (account->username != NULL)
838 g_free(account->username);
839
840 account->username = (username == NULL ? NULL : g_strdup(username));
841
842 schedule_accounts_save();
843 }
844
845 void
846 gaim_account_set_password(GaimAccount *account, const char *password)
847 {
848 g_return_if_fail(account != NULL);
849
850 if (account->password != NULL)
851 g_free(account->password);
852
853 account->password = (password == NULL ? NULL : g_strdup(password));
854
855 schedule_accounts_save();
856 }
857
858 void
859 gaim_account_set_alias(GaimAccount *account, const char *alias)
860 {
861 g_return_if_fail(account != NULL);
862
863 if (account->alias != NULL)
864 g_free(account->alias);
865
866 account->alias = (alias == NULL ? NULL : g_strdup(alias));
867
868 schedule_accounts_save();
869 }
870
871 void
872 gaim_account_set_user_info(GaimAccount *account, const char *user_info)
873 {
874 g_return_if_fail(account != NULL);
875
876 if (account->user_info != NULL)
877 g_free(account->user_info);
878
879 account->user_info = (user_info == NULL ? NULL : g_strdup(user_info));
880
881 schedule_accounts_save();
882 }
883
884 void
885 gaim_account_set_buddy_icon(GaimAccount *account, const char *icon)
886 {
887 g_return_if_fail(account != NULL);
888
889 if (account->buddy_icon != NULL)
890 g_free(account->buddy_icon);
891
892 account->buddy_icon = (icon == NULL ? NULL : g_strdup(icon));
893 if (account->gc)
894 serv_set_buddyicon(account->gc, icon);
895
896 schedule_accounts_save();
897 }
898
899 void
900 gaim_account_set_protocol_id(GaimAccount *account, const char *protocol_id)
901 {
902 g_return_if_fail(account != NULL);
903 g_return_if_fail(protocol_id != NULL);
904
905 if (account->protocol_id != NULL)
906 g_free(account->protocol_id);
907
908 account->protocol_id = g_strdup(protocol_id);
909
910 schedule_accounts_save();
911 }
912
913 void
914 gaim_account_set_connection(GaimAccount *account, GaimConnection *gc)
915 {
916 g_return_if_fail(account != NULL);
917
918 account->gc = gc;
919 }
920
921 void
922 gaim_account_set_remember_password(GaimAccount *account, gboolean value)
923 {
924 g_return_if_fail(account != NULL);
925
926 account->remember_pass = value;
927
928 schedule_accounts_save();
929 }
930
931 void
932 gaim_account_set_check_mail(GaimAccount *account, gboolean value)
933 {
934 g_return_if_fail(account != NULL);
935
936 gaim_account_set_bool(account, "check-mail", value);
937 }
938
939 void
940 gaim_account_set_enabled(GaimAccount *account, const char *ui,
941 gboolean value)
942 {
943 g_return_if_fail(account != NULL);
944 g_return_if_fail(ui != NULL);
945
946 gaim_account_set_ui_bool(account, ui, "auto-login", value);
947 }
948
949 void
950 gaim_account_set_proxy_info(GaimAccount *account, GaimProxyInfo *info)
951 {
952 g_return_if_fail(account != NULL);
953
954 if (account->proxy_info != NULL)
955 gaim_proxy_info_destroy(account->proxy_info);
956
957 account->proxy_info = info;
958
959 schedule_accounts_save();
960 }
961
962 void
963 gaim_account_set_status_types(GaimAccount *account, GList *status_types)
964 {
965 g_return_if_fail(account != NULL);
966
967 /* Old with the old... */
968 if (account->status_types != NULL)
969 {
970 GList *l;
971
972 for (l = account->status_types; l != NULL; l = l->next)
973 gaim_status_type_destroy((GaimStatusType *)l->data);
974
975 g_list_free(account->status_types);
976 }
977
978 /* In with the new... */
979 account->status_types = status_types;
980 }
981
982 void
983 gaim_account_set_status(GaimAccount *account, const char *status_id,
984 gboolean active, ...)
985 {
986 GaimStatus *status;
987 va_list args;
988
989 g_return_if_fail(account != NULL);
990 g_return_if_fail(status_id != NULL);
991
992 status = gaim_account_get_status(account, status_id);
993
994 if (status == NULL)
995 {
996 gaim_debug_error("accounts",
997 "Invalid status ID %s for account %s (%s)\n",
998 status_id, gaim_account_get_username(account),
999 gaim_account_get_protocol_id(account));
1000 return;
1001 }
1002
1003 va_start(args, active);
1004 gaim_status_set_active_with_attrs(status, active, args);
1005 va_end(args);
1006 }
1007
1008 void
1009 gaim_account_clear_settings(GaimAccount *account)
1010 {
1011 g_return_if_fail(account != NULL);
1012
1013 g_hash_table_destroy(account->settings);
1014
1015 account->settings = g_hash_table_new_full(g_str_hash, g_str_equal,
1016 g_free, delete_setting);
1017 }
1018
1019 void
1020 gaim_account_set_int(GaimAccount *account, const char *name, int value)
1021 {
1275 GaimAccountSetting *setting; 1022 GaimAccountSetting *setting;
1276 xmlnode *node, *child; 1023
1277 char buf[20]; 1024 g_return_if_fail(account != NULL);
1278 1025 g_return_if_fail(name != NULL);
1279 name = (const char *)key; 1026
1280 setting = (GaimAccountSetting *)value; 1027 setting = g_new0(GaimAccountSetting, 1);
1281 node = (xmlnode *)user_data; 1028
1282 1029 setting->type = GAIM_PREF_INT;
1283 child = xmlnode_new_child(node, "setting"); 1030 setting->value.integer = value;
1284 xmlnode_set_attrib(child, "name", name); 1031
1285 1032 g_hash_table_insert(account->settings, g_strdup(name), setting);
1286 if (setting->type == GAIM_PREF_INT) { 1033
1287 xmlnode_set_attrib(child, "type", "int"); 1034 schedule_accounts_save();
1288 snprintf(buf, sizeof(buf), "%d", setting->value.integer); 1035 }
1289 xmlnode_insert_data(child, buf, -1); 1036
1290 } 1037 void
1291 else if (setting->type == GAIM_PREF_STRING && setting->value.string != NULL) { 1038 gaim_account_set_string(GaimAccount *account, const char *name,
1292 xmlnode_set_attrib(child, "type", "string"); 1039 const char *value)
1293 xmlnode_insert_data(child, setting->value.string, -1); 1040 {
1294 } 1041 GaimAccountSetting *setting;
1295 else if (setting->type == GAIM_PREF_BOOLEAN) { 1042
1296 xmlnode_set_attrib(child, "type", "bool"); 1043 g_return_if_fail(account != NULL);
1297 snprintf(buf, sizeof(buf), "%d", setting->value.bool); 1044 g_return_if_fail(name != NULL);
1298 xmlnode_insert_data(child, buf, -1); 1045
1299 } 1046 setting = g_new0(GaimAccountSetting, 1);
1300 } 1047
1301 1048 setting->type = GAIM_PREF_STRING;
1302 static void 1049 setting->value.string = g_strdup(value);
1303 ui_setting_to_xmlnode(gpointer key, gpointer value, gpointer user_data) 1050
1304 { 1051 g_hash_table_insert(account->settings, g_strdup(name), setting);
1305 const char *ui; 1052
1053 schedule_accounts_save();
1054 }
1055
1056 void
1057 gaim_account_set_bool(GaimAccount *account, const char *name, gboolean value)
1058 {
1059 GaimAccountSetting *setting;
1060
1061 g_return_if_fail(account != NULL);
1062 g_return_if_fail(name != NULL);
1063
1064 setting = g_new0(GaimAccountSetting, 1);
1065
1066 setting->type = GAIM_PREF_BOOLEAN;
1067 setting->value.bool = value;
1068
1069 g_hash_table_insert(account->settings, g_strdup(name), setting);
1070
1071 schedule_accounts_save();
1072 }
1073
1074 static GHashTable *
1075 get_ui_settings_table(GaimAccount *account, const char *ui)
1076 {
1306 GHashTable *table; 1077 GHashTable *table;
1307 xmlnode *node, *child; 1078
1308 1079 table = g_hash_table_lookup(account->ui_settings, ui);
1309 ui = (const char *)key; 1080
1310 table = (GHashTable *)value; 1081 if (table == NULL) {
1311 node = (xmlnode *)user_data; 1082 table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
1312 1083 delete_setting);
1313 if (g_hash_table_size(table) > 0) 1084 g_hash_table_insert(account->ui_settings, g_strdup(ui), table);
1314 { 1085 }
1315 child = xmlnode_new_child(node, "settings"); 1086
1316 xmlnode_set_attrib(child, "ui", ui); 1087 return table;
1317 g_hash_table_foreach(table, setting_to_xmlnode, child); 1088 }
1318 } 1089
1319 } 1090 void
1320 1091 gaim_account_set_ui_int(GaimAccount *account, const char *ui,
1321 static xmlnode * 1092 const char *name, int value)
1322 proxy_settings_to_xmlnode(GaimProxyInfo *proxy_info) 1093 {
1323 { 1094 GaimAccountSetting *setting;
1324 xmlnode *node, *child; 1095 GHashTable *table;
1325 GaimProxyType proxy_type; 1096
1326 const char *value; 1097 g_return_if_fail(account != NULL);
1327 int int_value; 1098 g_return_if_fail(ui != NULL);
1328 char buf[20]; 1099 g_return_if_fail(name != NULL);
1329 1100
1330 proxy_type = gaim_proxy_info_get_type(proxy_info); 1101 setting = g_new0(GaimAccountSetting, 1);
1331 1102
1332 node = xmlnode_new("proxy"); 1103 setting->type = GAIM_PREF_INT;
1333 1104 setting->ui = g_strdup(ui);
1334 child = xmlnode_new_child(node, "type"); 1105 setting->value.integer = value;
1335 xmlnode_insert_data(child, 1106
1336 (proxy_type == GAIM_PROXY_USE_GLOBAL ? "global" : 1107 table = get_ui_settings_table(account, ui);
1337 proxy_type == GAIM_PROXY_NONE ? "none" : 1108
1338 proxy_type == GAIM_PROXY_HTTP ? "http" : 1109 g_hash_table_insert(table, g_strdup(name), setting);
1339 proxy_type == GAIM_PROXY_SOCKS4 ? "socks4" : 1110
1340 proxy_type == GAIM_PROXY_SOCKS5 ? "socks5" : 1111 schedule_accounts_save();
1341 proxy_type == GAIM_PROXY_USE_ENVVAR ? "envvar" : "unknown"), -1); 1112 }
1342 1113
1343 if (proxy_type != GAIM_PROXY_USE_GLOBAL && 1114 void
1344 proxy_type != GAIM_PROXY_NONE && 1115 gaim_account_set_ui_string(GaimAccount *account, const char *ui,
1345 proxy_type != GAIM_PROXY_USE_ENVVAR) 1116 const char *name, const char *value)
1346 { 1117 {
1347 if ((value = gaim_proxy_info_get_host(proxy_info)) != NULL) 1118 GaimAccountSetting *setting;
1348 { 1119 GHashTable *table;
1349 child = xmlnode_new_child(node, "host"); 1120
1350 xmlnode_insert_data(child, value, -1); 1121 g_return_if_fail(account != NULL);
1351 } 1122 g_return_if_fail(ui != NULL);
1352 1123 g_return_if_fail(name != NULL);
1353 if ((int_value = gaim_proxy_info_get_port(proxy_info)) != 0) 1124
1354 { 1125 setting = g_new0(GaimAccountSetting, 1);
1355 snprintf(buf, sizeof(buf), "%d", int_value); 1126
1356 child = xmlnode_new_child(node, "port"); 1127 setting->type = GAIM_PREF_STRING;
1357 xmlnode_insert_data(child, buf, -1); 1128 setting->ui = g_strdup(ui);
1358 } 1129 setting->value.string = g_strdup(value);
1359 1130
1360 if ((value = gaim_proxy_info_get_username(proxy_info)) != NULL) 1131 table = get_ui_settings_table(account, ui);
1361 { 1132
1362 child = xmlnode_new_child(node, "username"); 1133 g_hash_table_insert(table, g_strdup(name), setting);
1363 xmlnode_insert_data(child, value, -1); 1134
1364 } 1135 schedule_accounts_save();
1365 1136 }
1366 if ((value = gaim_proxy_info_get_password(proxy_info)) != NULL) 1137
1367 { 1138 void
1368 child = xmlnode_new_child(node, "password"); 1139 gaim_account_set_ui_bool(GaimAccount *account, const char *ui,
1369 xmlnode_insert_data(child, value, -1); 1140 const char *name, gboolean value)
1370 } 1141 {
1371 } 1142 GaimAccountSetting *setting;
1372 1143 GHashTable *table;
1373 return node; 1144
1374 } 1145 g_return_if_fail(account != NULL);
1375 1146 g_return_if_fail(ui != NULL);
1376 static xmlnode * 1147 g_return_if_fail(name != NULL);
1377 account_to_xmlnode(GaimAccount *account) 1148
1378 { 1149 setting = g_new0(GaimAccountSetting, 1);
1379 xmlnode *node, *child; 1150
1380 const char *tmp; 1151 setting->type = GAIM_PREF_BOOLEAN;
1381 GaimProxyInfo *proxy_info; 1152 setting->ui = g_strdup(ui);
1382 1153 setting->value.bool = value;
1383 node = xmlnode_new("account"); 1154
1384 1155 table = get_ui_settings_table(account, ui);
1385 child = xmlnode_new_child(node, "protocol"); 1156
1386 xmlnode_insert_data(child, gaim_account_get_protocol_id(account), -1); 1157 g_hash_table_insert(table, g_strdup(name), setting);
1387 1158
1388 child = xmlnode_new_child(node, "name"); 1159 schedule_accounts_save();
1389 xmlnode_insert_data(child, gaim_account_get_username(account), -1); 1160 }
1390 1161
1391 if (gaim_account_get_remember_password(account) && 1162 gboolean
1392 ((tmp = gaim_account_get_password(account)) != NULL)) 1163 gaim_account_is_connected(const GaimAccount *account)
1393 { 1164 {
1394 child = xmlnode_new_child(node, "password"); 1165 GaimConnection *gc;
1395 xmlnode_insert_data(child, tmp, -1); 1166
1396 } 1167 g_return_val_if_fail(account != NULL, FALSE);
1397 1168
1398 if ((tmp = gaim_account_get_alias(account)) != NULL) 1169 gc = gaim_account_get_connection(account);
1399 { 1170
1400 child = xmlnode_new_child(node, "alias"); 1171 /* XXX - The first way is better... but it doesn't work quite right yet */
1401 xmlnode_insert_data(child, tmp, -1); 1172 /* return ((gc != NULL) && GAIM_CONNECTION_IS_CONNECTED(gc)); */
1402 } 1173 return ((gc != NULL) && gaim_connection_get_state(gc) != GAIM_DISCONNECTED);
1403 1174 }
1404 if ((tmp = gaim_account_get_user_info(account)) != NULL) 1175
1405 { 1176 const char *
1406 /* TODO: Do we need to call gaim_str_strip_cr(tmp) here? */ 1177 gaim_account_get_username(const GaimAccount *account)
1407 child = xmlnode_new_child(node, "userinfo"); 1178 {
1408 xmlnode_insert_data(child, tmp, -1); 1179 g_return_val_if_fail(account != NULL, NULL);
1409 } 1180
1410 1181 return account->username;
1411 if ((tmp = gaim_account_get_buddy_icon(account)) != NULL) 1182 }
1412 { 1183
1413 child = xmlnode_new_child(node, "buddyicon"); 1184 const char *
1414 xmlnode_insert_data(child, tmp, -1); 1185 gaim_account_get_password(const GaimAccount *account)
1415 } 1186 {
1416 1187 g_return_val_if_fail(account != NULL, NULL);
1417 if (g_hash_table_size(account->settings) > 0) 1188
1418 { 1189 return account->password;
1419 child = xmlnode_new_child(node, "settings"); 1190 }
1420 g_hash_table_foreach(account->settings, setting_to_xmlnode, child); 1191
1421 } 1192 const char *
1422 1193 gaim_account_get_alias(const GaimAccount *account)
1423 if (g_hash_table_size(account->ui_settings) > 0) 1194 {
1424 { 1195 g_return_val_if_fail(account != NULL, NULL);
1425 g_hash_table_foreach(account->ui_settings, ui_setting_to_xmlnode, node); 1196
1426 } 1197 return account->alias;
1427 1198 }
1428 if ((proxy_info = gaim_account_get_proxy_info(account)) != NULL) 1199
1429 { 1200 const char *
1430 child = proxy_settings_to_xmlnode(proxy_info); 1201 gaim_account_get_user_info(const GaimAccount *account)
1431 xmlnode_insert_child(node, child); 1202 {
1432 } 1203 g_return_val_if_fail(account != NULL, NULL);
1433 1204
1434 return node; 1205 return account->user_info;
1435 } 1206 }
1436 1207
1437 static xmlnode * 1208 const char *
1438 accounts_to_xmlnode(void) 1209 gaim_account_get_buddy_icon(const GaimAccount *account)
1439 { 1210 {
1440 xmlnode *node, *child; 1211 g_return_val_if_fail(account != NULL, NULL);
1441 GList *cur; 1212
1442 1213 return account->buddy_icon;
1443 node = xmlnode_new("accounts"); 1214 }
1444 xmlnode_set_attrib(node, "version", "1.0"); 1215
1445 1216 const char *
1446 for (cur = gaim_accounts_get_all(); cur != NULL; cur = cur->next) 1217 gaim_account_get_protocol_id(const GaimAccount *account)
1447 { 1218 {
1448 child = account_to_xmlnode(cur->data); 1219 g_return_val_if_fail(account != NULL, NULL);
1449 xmlnode_insert_child(node, child); 1220
1450 } 1221 return account->protocol_id;
1451 1222 }
1452 return node; 1223
1453 } 1224 const char *
1454 1225 gaim_account_get_protocol_name(const GaimAccount *account)
1455 void 1226 {
1456 gaim_accounts_sync(void) 1227 GaimPlugin *p;
1457 { 1228
1458 xmlnode *node; 1229 g_return_val_if_fail(account != NULL, NULL);
1459 char *data; 1230
1460 1231 p = gaim_find_prpl(gaim_account_get_protocol_id(account));
1461 if (!accounts_loaded) { 1232
1462 gaim_debug_error("accounts", "Attempted to save accounts before they " 1233 return ((p && p->info->name) ? _(p->info->name) : _("Unknown"));
1463 "were read!\n"); 1234 }
1464 } 1235
1465 1236 GaimConnection *
1466 node = accounts_to_xmlnode(); 1237 gaim_account_get_connection(const GaimAccount *account)
1467 data = xmlnode_to_formatted_str(node, NULL); 1238 {
1468 gaim_util_write_data_to_file("accounts.xml", data, -1); 1239 g_return_val_if_fail(account != NULL, NULL);
1469 g_free(data); 1240
1470 xmlnode_free(node); 1241 return account->gc;
1242 }
1243
1244 gboolean
1245 gaim_account_get_remember_password(const GaimAccount *account)
1246 {
1247 g_return_val_if_fail(account != NULL, FALSE);
1248
1249 return account->remember_pass;
1250 }
1251
1252 gboolean
1253 gaim_account_get_check_mail(const GaimAccount *account)
1254 {
1255 g_return_val_if_fail(account != NULL, FALSE);
1256
1257 return gaim_account_get_bool(account, "check-mail", FALSE);
1258 }
1259
1260 gboolean
1261 gaim_account_get_enabled(const GaimAccount *account, const char *ui)
1262 {
1263 g_return_val_if_fail(account != NULL, FALSE);
1264 g_return_val_if_fail(ui != NULL, FALSE);
1265
1266 return gaim_account_get_ui_bool(account, ui, "auto-login", FALSE);
1267 }
1268
1269 GaimProxyInfo *
1270 gaim_account_get_proxy_info(const GaimAccount *account)
1271 {
1272 g_return_val_if_fail(account != NULL, NULL);
1273
1274 return account->proxy_info;
1275 }
1276
1277 GaimStatus *
1278 gaim_account_get_status(const GaimAccount *account, const char *status_id)
1279 {
1280 g_return_val_if_fail(account != NULL, NULL);
1281 g_return_val_if_fail(status_id != NULL, NULL);
1282
1283 return gaim_presence_get_status(account->presence, status_id);
1284 }
1285
1286 GaimStatusType *
1287 gaim_account_get_status_type(const GaimAccount *account, const char *id)
1288 {
1289 const GList *l;
1290
1291 g_return_val_if_fail(account != NULL, NULL);
1292 g_return_val_if_fail(id != NULL, NULL);
1293
1294 for (l = gaim_account_get_status_types(account); l != NULL; l = l->next)
1295 {
1296 GaimStatusType *status_type = (GaimStatusType *)l->data;
1297
1298 if (!strcmp(gaim_status_type_get_id(status_type), id))
1299 return status_type;
1300 }
1301
1302 return NULL;
1303 }
1304
1305 GaimPresence *
1306 gaim_account_get_presence(const GaimAccount *account)
1307 {
1308 g_return_val_if_fail(account != NULL, NULL);
1309
1310 return account->presence;
1311 }
1312
1313 gboolean
1314 gaim_account_is_status_active(const GaimAccount *account,
1315 const char *status_id)
1316 {
1317 g_return_val_if_fail(account != NULL, FALSE);
1318 g_return_val_if_fail(status_id != NULL, FALSE);
1319
1320 return gaim_presence_is_status_active(account->presence, status_id);
1321 }
1322
1323 const GList *
1324 gaim_account_get_status_types(const GaimAccount *account)
1325 {
1326 g_return_val_if_fail(account != NULL, NULL);
1327
1328 return account->status_types;
1329 }
1330
1331 int
1332 gaim_account_get_int(const GaimAccount *account, const char *name,
1333 int default_value)
1334 {
1335 GaimAccountSetting *setting;
1336
1337 g_return_val_if_fail(account != NULL, default_value);
1338 g_return_val_if_fail(name != NULL, default_value);
1339
1340 setting = g_hash_table_lookup(account->settings, name);
1341
1342 if (setting == NULL)
1343 return default_value;
1344
1345 g_return_val_if_fail(setting->type == GAIM_PREF_INT, default_value);
1346
1347 return setting->value.integer;
1348 }
1349
1350 const char *
1351 gaim_account_get_string(const GaimAccount *account, const char *name,
1352 const char *default_value)
1353 {
1354 GaimAccountSetting *setting;
1355
1356 g_return_val_if_fail(account != NULL, default_value);
1357 g_return_val_if_fail(name != NULL, default_value);
1358
1359 setting = g_hash_table_lookup(account->settings, name);
1360
1361 if (setting == NULL)
1362 return default_value;
1363
1364 g_return_val_if_fail(setting->type == GAIM_PREF_STRING, default_value);
1365
1366 return setting->value.string;
1367 }
1368
1369 gboolean
1370 gaim_account_get_bool(const GaimAccount *account, const char *name,
1371 gboolean default_value)
1372 {
1373 GaimAccountSetting *setting;
1374
1375 g_return_val_if_fail(account != NULL, default_value);
1376 g_return_val_if_fail(name != NULL, default_value);
1377
1378 setting = g_hash_table_lookup(account->settings, name);
1379
1380 if (setting == NULL)
1381 return default_value;
1382
1383 g_return_val_if_fail(setting->type == GAIM_PREF_BOOLEAN, default_value);
1384
1385 return setting->value.bool;
1386 }
1387
1388 int
1389 gaim_account_get_ui_int(const GaimAccount *account, const char *ui,
1390 const char *name, int default_value)
1391 {
1392 GaimAccountSetting *setting;
1393 GHashTable *table;
1394
1395 g_return_val_if_fail(account != NULL, default_value);
1396 g_return_val_if_fail(ui != NULL, default_value);
1397 g_return_val_if_fail(name != NULL, default_value);
1398
1399 if ((table = g_hash_table_lookup(account->ui_settings, ui)) == NULL)
1400 return default_value;
1401
1402 if ((setting = g_hash_table_lookup(table, name)) == NULL)
1403 return default_value;
1404
1405 g_return_val_if_fail(setting->type == GAIM_PREF_INT, default_value);
1406
1407 return setting->value.integer;
1408 }
1409
1410 const char *
1411 gaim_account_get_ui_string(const GaimAccount *account, const char *ui,
1412 const char *name, const char *default_value)
1413 {
1414 GaimAccountSetting *setting;
1415 GHashTable *table;
1416
1417 g_return_val_if_fail(account != NULL, default_value);
1418 g_return_val_if_fail(ui != NULL, default_value);
1419 g_return_val_if_fail(name != NULL, default_value);
1420
1421 if ((table = g_hash_table_lookup(account->ui_settings, ui)) == NULL)
1422 return default_value;
1423
1424 if ((setting = g_hash_table_lookup(table, name)) == NULL)
1425 return default_value;
1426
1427 g_return_val_if_fail(setting->type == GAIM_PREF_STRING, default_value);
1428
1429 return setting->value.string;
1430 }
1431
1432 gboolean
1433 gaim_account_get_ui_bool(const GaimAccount *account, const char *ui,
1434 const char *name, gboolean default_value)
1435 {
1436 GaimAccountSetting *setting;
1437 GHashTable *table;
1438
1439 g_return_val_if_fail(account != NULL, default_value);
1440 g_return_val_if_fail(ui != NULL, default_value);
1441 g_return_val_if_fail(name != NULL, default_value);
1442
1443 if ((table = g_hash_table_lookup(account->ui_settings, ui)) == NULL)
1444 return default_value;
1445
1446 if ((setting = g_hash_table_lookup(table, name)) == NULL)
1447 return default_value;
1448
1449 g_return_val_if_fail(setting->type == GAIM_PREF_BOOLEAN, default_value);
1450
1451 return setting->value.bool;
1452 }
1453
1454 GaimLog *
1455 gaim_account_get_log(GaimAccount *account)
1456 {
1457 g_return_val_if_fail(account != NULL, NULL);
1458
1459 if(!account->system_log){
1460 GaimConnection *gc;
1461
1462 gc = gaim_account_get_connection(account);
1463
1464 account->system_log = gaim_log_new(GAIM_LOG_SYSTEM,
1465 gaim_account_get_username(account), account,
1466 gc != NULL ? gc->login_time : time(NULL));
1467 }
1468
1469 return account->system_log;
1470 }
1471
1472 void
1473 gaim_account_destroy_log(GaimAccount *account)
1474 {
1475 g_return_if_fail(account != NULL);
1476
1477 if(account->system_log){
1478 gaim_log_free(account->system_log);
1479 account->system_log = NULL;
1480 }
1471 } 1481 }
1472 1482
1473 void 1483 void
1474 gaim_accounts_add(GaimAccount *account) 1484 gaim_accounts_add(GaimAccount *account)
1475 { 1485 {
1695 } 1705 }
1696 1706
1697 void 1707 void
1698 gaim_accounts_uninit(void) 1708 gaim_accounts_uninit(void)
1699 { 1709 {
1700 if (accounts_save_timer != 0) { 1710 if (accounts_save_timer != 0)
1711 {
1701 gaim_timeout_remove(accounts_save_timer); 1712 gaim_timeout_remove(accounts_save_timer);
1702 accounts_save_timer = 0; 1713 accounts_save_timer = 0;
1703 gaim_accounts_sync(); 1714 sync_accounts();
1704 } 1715 }
1705 1716
1706 gaim_signals_unregister_by_instance(gaim_accounts_get_handle()); 1717 gaim_signals_unregister_by_instance(gaim_accounts_get_handle());
1707 } 1718 }