aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheJackiMonster <thejackimonster@gmail.com>2022-02-13 17:35:32 +0100
committerTheJackiMonster <thejackimonster@gmail.com>2022-02-13 17:35:32 +0100
commitccdeafaf88627aa274c2d6090e4231ed51b56c63 (patch)
tree6bd037bd2d01626e35fc2f573e9d424da5d49673
parentffbadef904ae1e32eb54671647527b99e70d2266 (diff)
downloadlibgnunetchat-ccdeafaf88627aa274c2d6090e4231ed51b56c63.tar.gz
libgnunetchat-ccdeafaf88627aa274c2d6090e4231ed51b56c63.zip
Established accounts as selectable identities to use
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-rw-r--r--Makefile3
-rw-r--r--include/gnunet_chat_lib.h88
-rw-r--r--src/gnunet_chat_account.c50
-rw-r--r--src/gnunet_chat_account.h45
-rw-r--r--src/gnunet_chat_handle.c185
-rw-r--r--src/gnunet_chat_handle.h24
-rw-r--r--src/gnunet_chat_handle_intern.c18
-rw-r--r--src/gnunet_chat_lib.c76
-rw-r--r--src/gnunet_chat_message.h5
9 files changed, 383 insertions, 111 deletions
diff --git a/Makefile b/Makefile
index 577b83c..d1ae23c 100644
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,8 @@ INSTALL_DIR ?= /usr/local/
7 7
8LIBRARY = lib$(TARGET_NAME).so 8LIBRARY = lib$(TARGET_NAME).so
9SOURCES = gnunet_chat_lib.c\ 9SOURCES = gnunet_chat_lib.c\
10 gnunet_chat_contact.c\ 10 gnunet_chat_account.c\
11 gnunet_chat_contact.c\
11 gnunet_chat_context.c\ 12 gnunet_chat_context.c\
12 gnunet_chat_file.c\ 13 gnunet_chat_file.c\
13 gnunet_chat_group.c\ 14 gnunet_chat_group.c\
diff --git a/include/gnunet_chat_lib.h b/include/gnunet_chat_lib.h
index 7675ad1..0d2a848 100644
--- a/include/gnunet_chat_lib.h
+++ b/include/gnunet_chat_lib.h
@@ -50,49 +50,54 @@ enum GNUNET_CHAT_MessageKind
50 GNUNET_CHAT_KIND_WARNING = 1, /**< GNUNET_CHAT_KIND_WARNING */ 50 GNUNET_CHAT_KIND_WARNING = 1, /**< GNUNET_CHAT_KIND_WARNING */
51 51
52 /** 52 /**
53 * The kind to inform that the list of accounts was refreshed.
54 */
55 GNUNET_CHAT_KIND_REFRESH = 2, /**< GNUNET_CHAT_KIND_REFRESH */
56
57 /**
53 * The kind to inform that the application can be used. 58 * The kind to inform that the application can be used.
54 */ 59 */
55 GNUNET_CHAT_KIND_LOGIN = 2, /**< GNUNET_CHAT_KIND_LOGIN */ 60 GNUNET_CHAT_KIND_LOGIN = 3, /**< GNUNET_CHAT_KIND_LOGIN */
56 61
57 /** 62 /**
58 * The kind to inform that a context was updated. 63 * The kind to inform that a context was updated.
59 */ 64 */
60 GNUNET_CHAT_KIND_UPDATE = 3, /**< GNUNET_CHAT_KIND_UPDATE */ 65 GNUNET_CHAT_KIND_UPDATE = 4, /**< GNUNET_CHAT_KIND_UPDATE */
61 66
62 /** 67 /**
63 * The kind to inform that a contact has joined a chat. 68 * The kind to inform that a contact has joined a chat.
64 */ 69 */
65 GNUNET_CHAT_KIND_JOIN = 4, /**< GNUNET_CHAT_KIND_JOIN */ 70 GNUNET_CHAT_KIND_JOIN = 5, /**< GNUNET_CHAT_KIND_JOIN */
66 71
67 /** 72 /**
68 * The kind to inform that a contact has left a chat. 73 * The kind to inform that a contact has left a chat.
69 */ 74 */
70 GNUNET_CHAT_KIND_LEAVE = 5, /**< GNUNET_CHAT_KIND_LEAVE */ 75 GNUNET_CHAT_KIND_LEAVE = 6, /**< GNUNET_CHAT_KIND_LEAVE */
71 76
72 /** 77 /**
73 * The kind to inform that a contact has changed. 78 * The kind to inform that a contact has changed.
74 */ 79 */
75 GNUNET_CHAT_KIND_CONTACT = 6, /**< GNUNET_CHAT_KIND_CONTACT */ 80 GNUNET_CHAT_KIND_CONTACT = 7, /**< GNUNET_CHAT_KIND_CONTACT */
76 81
77 /** 82 /**
78 * The kind to describe an invitation to a different chat. 83 * The kind to describe an invitation to a different chat.
79 */ 84 */
80 GNUNET_CHAT_KIND_INVITATION = 7, /**< GNUNET_CHAT_KIND_INVITATION */ 85 GNUNET_CHAT_KIND_INVITATION = 8, /**< GNUNET_CHAT_KIND_INVITATION */
81 86
82 /** 87 /**
83 * The kind to describe a text message. 88 * The kind to describe a text message.
84 */ 89 */
85 GNUNET_CHAT_KIND_TEXT = 8, /**< GNUNET_CHAT_KIND_TEXT */ 90 GNUNET_CHAT_KIND_TEXT = 9, /**< GNUNET_CHAT_KIND_TEXT */
86 91
87 /** 92 /**
88 * The kind to describe a shared file. 93 * The kind to describe a shared file.
89 */ 94 */
90 GNUNET_CHAT_KIND_FILE = 9, /**< GNUNET_CHAT_KIND_FILE */ 95 GNUNET_CHAT_KIND_FILE = 10, /**< GNUNET_CHAT_KIND_FILE */
91 96
92 /** 97 /**
93 * The kind to inform about a deletion of a previous message. 98 * The kind to inform about a deletion of a previous message.
94 */ 99 */
95 GNUNET_CHAT_KIND_DELETION = 10, /**< GNUNET_CHAT_KIND_DELETION */ 100 GNUNET_CHAT_KIND_DELETION = 11, /**< GNUNET_CHAT_KIND_DELETION */
96 101
97 /** 102 /**
98 * An unknown kind of message. 103 * An unknown kind of message.
@@ -106,6 +111,11 @@ enum GNUNET_CHAT_MessageKind
106struct GNUNET_CHAT_Handle; 111struct GNUNET_CHAT_Handle;
107 112
108/** 113/**
114 * Struct of a chat account.
115 */
116struct GNUNET_CHAT_Account;
117
118/**
109 * Struct of a chat contact. 119 * Struct of a chat contact.
110 */ 120 */
111struct GNUNET_CHAT_Contact; 121struct GNUNET_CHAT_Contact;
@@ -136,6 +146,19 @@ struct GNUNET_CHAT_File;
136struct GNUNET_CHAT_Invitation; 146struct GNUNET_CHAT_Invitation;
137 147
138/** 148/**
149 * Iterator over chat accounts of a specific chat handle.
150 *
151 * @param[in,out] cls Closure from #GNUNET_CHAT_iterate_accounts
152 * @param[in] handle Chat handle
153 * @param[in] account Chat account
154 * @return #GNUNET_YES if we should continue to iterate, #GNUNET_NO otherwise.
155 */
156typedef int
157(*GNUNET_CHAT_AccountCallback) (void *cls,
158 const struct GNUNET_CHAT_Handle *handle,
159 const struct GNUNET_CHAT_Account *account);
160
161/**
139 * Iterator over chat contacts of a specific chat handle. 162 * Iterator over chat contacts of a specific chat handle.
140 * 163 *
141 * @param[in,out] cls Closure from #GNUNET_CHAT_iterate_contacts 164 * @param[in,out] cls Closure from #GNUNET_CHAT_iterate_contacts
@@ -261,15 +284,14 @@ typedef void
261 uint64_t size); 284 uint64_t size);
262 285
263/** 286/**
264 * Start a chat handle with a certain configuration, an application <i>directory</i> 287 * Start a chat handle with a certain configuration and a selected application
265 * and a selected user <i>name</i>. 288 * <i>directory</i>.
266 * 289 *
267 * A custom callback for warnings and message events can be provided optionally 290 * A custom callback for warnings and message events can be provided optionally
268 * together with their respective closures. 291 * together with their respective closures.
269 * 292 *
270 * @param[in] cfg Configuration 293 * @param[in] cfg Configuration
271 * @param[in] directory Application directory path (optional) 294 * @param[in] directory Application directory path (optional)
272 * @param[in] name User name (optional)
273 * @param[in] msg_cb Callback for message events (optional) 295 * @param[in] msg_cb Callback for message events (optional)
274 * @param[in,out] msg_cls Closure for message events (optional) 296 * @param[in,out] msg_cls Closure for message events (optional)
275 * @return Chat handle 297 * @return Chat handle
@@ -277,7 +299,6 @@ typedef void
277struct GNUNET_CHAT_Handle* 299struct GNUNET_CHAT_Handle*
278GNUNET_CHAT_start (const struct GNUNET_CONFIGURATION_Handle *cfg, 300GNUNET_CHAT_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
279 const char *directory, 301 const char *directory,
280 const char *name,
281 GNUNET_CHAT_ContextMessageCallback msg_cb, void *msg_cls); 302 GNUNET_CHAT_ContextMessageCallback msg_cb, void *msg_cls);
282 303
283/** 304/**
@@ -290,6 +311,47 @@ void
290GNUNET_CHAT_stop (struct GNUNET_CHAT_Handle *handle); 311GNUNET_CHAT_stop (struct GNUNET_CHAT_Handle *handle);
291 312
292/** 313/**
314 * Iterates through the accounts of a given chat <i>handle</i> with a selected
315 * callback and custom closure.
316 *
317 * @param[in] handle Chat handle
318 * @param[in] callback Callback for account iteration (optional)
319 * @param[in,out] cls Closure for account iteration (optional)
320 * @return Amount of accounts iterated or #GNUNET_SYSERR on failure
321 */
322int
323GNUNET_CHAT_iterate_accounts(const struct GNUNET_CHAT_Handle *handle,
324 GNUNET_CHAT_AccountCallback callback,
325 void *cls);
326
327/**
328 * Connects a chat <i>handle</i> to a selected chat <i>account</i>.
329 *
330 * @param[in] account Chat account
331 */
332void
333GNUNET_CHAT_connect (struct GNUNET_CHAT_Handle *handle,
334 const struct GNUNET_CHAT_Account *account);
335
336/**
337 * Disconnects a chat <i>handle</i> from the current chat account.
338 *
339 * @param[in,out] handle Chat handle
340 */
341void
342GNUNET_CHAT_disconnect (struct GNUNET_CHAT_Handle *handle);
343
344/**
345 * Returns the connected account of a chat <i>handle</i> for related
346 * communication or NULL if no account is set yet.
347 *
348 * @param handle Chat handle
349 * @return Account used by the handle or NULL
350 */
351const struct GNUNET_CHAT_Account*
352GNUNET_CHAT_get_connected(const struct GNUNET_CHAT_Handle *handle);
353
354/**
293 * Updates a chat handle to renew the used ego to sign sent messages in active 355 * Updates a chat handle to renew the used ego to sign sent messages in active
294 * chats. 356 * chats.
295 * 357 *
diff --git a/src/gnunet_chat_account.c b/src/gnunet_chat_account.c
new file mode 100644
index 0000000..049536b
--- /dev/null
+++ b/src/gnunet_chat_account.c
@@ -0,0 +1,50 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/*
21 * @author Tobias Frisch
22 * @file gnunet_chat_account.c
23 */
24
25#include "gnunet_chat_account.h"
26
27struct GNUNET_CHAT_Account*
28account_create_from_ego(struct GNUNET_IDENTITY_Ego *ego,
29 const char *name)
30{
31 GNUNET_assert((ego) && (name));
32
33 struct GNUNET_CHAT_Account *account = GNUNET_new(struct GNUNET_CHAT_Account);
34
35 account->ego = ego;
36 account->name = GNUNET_strdup(name);
37
38 return account;
39}
40
41void
42account_destroy(struct GNUNET_CHAT_Account *account)
43{
44 GNUNET_assert(account);
45
46 if (account->name)
47 GNUNET_free(account->name);
48
49 GNUNET_free(account);
50}
diff --git a/src/gnunet_chat_account.h b/src/gnunet_chat_account.h
new file mode 100644
index 0000000..dc41f25
--- /dev/null
+++ b/src/gnunet_chat_account.h
@@ -0,0 +1,45 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/*
21 * @author Tobias Frisch
22 * @file gnunet_chat_account.h
23 */
24
25#ifndef GNUNET_CHAT_ACCOUNT_H_
26#define GNUNET_CHAT_ACCOUNT_H_
27
28#include <gnunet/platform.h>
29#include <gnunet/gnunet_common.h>
30#include <gnunet/gnunet_identity_service.h>
31
32struct GNUNET_CHAT_Account
33{
34 struct GNUNET_IDENTITY_Ego *ego;
35 char *name;
36};
37
38struct GNUNET_CHAT_Account*
39account_create_from_ego(struct GNUNET_IDENTITY_Ego *ego,
40 const char *name);
41
42void
43account_destroy(struct GNUNET_CHAT_Account *account);
44
45#endif /* GNUNET_CHAT_ACCOUNT_H_ */
diff --git a/src/gnunet_chat_handle.c b/src/gnunet_chat_handle.c
index f4e86b2..57e0043 100644
--- a/src/gnunet_chat_handle.c
+++ b/src/gnunet_chat_handle.c
@@ -29,7 +29,6 @@
29struct GNUNET_CHAT_Handle* 29struct GNUNET_CHAT_Handle*
30handle_create_from_config (const struct GNUNET_CONFIGURATION_Handle* cfg, 30handle_create_from_config (const struct GNUNET_CONFIGURATION_Handle* cfg,
31 const char *directory, 31 const char *directory,
32 const char *name,
33 GNUNET_CHAT_ContextMessageCallback msg_cb, 32 GNUNET_CHAT_ContextMessageCallback msg_cb,
34 void *msg_cls) 33 void *msg_cls)
35{ 34{
@@ -54,13 +53,15 @@ handle_create_from_config (const struct GNUNET_CONFIGURATION_Handle* cfg,
54 handle->msg_cb = msg_cb; 53 handle->msg_cb = msg_cb;
55 handle->msg_cls = msg_cls; 54 handle->msg_cls = msg_cls;
56 55
57 handle->identities_head = NULL; 56 handle->accounts_head = NULL;
58 handle->identities_tail = NULL; 57 handle->accounts_tail = NULL;
59 58
60 handle->files = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); 59 handle->current = NULL;
61 handle->contexts = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); 60
62 handle->contacts = GNUNET_CONTAINER_multishortmap_create(8, GNUNET_NO); 61 handle->files = NULL;
63 handle->groups = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); 62 handle->contexts = NULL;
63 handle->contacts = NULL;
64 handle->groups = NULL;
64 65
65 handle->arm = GNUNET_ARM_connect( 66 handle->arm = GNUNET_ARM_connect(
66 handle->cfg, 67 handle->cfg,
@@ -70,39 +71,17 @@ handle_create_from_config (const struct GNUNET_CONFIGURATION_Handle* cfg,
70 if (handle->arm) 71 if (handle->arm)
71 on_handle_arm_connection(handle, GNUNET_NO); 72 on_handle_arm_connection(handle, GNUNET_NO);
72 73
73 char* fs_client_name = NULL;
74 GNUNET_asprintf (
75 &fs_client_name,
76 "GNUNET_CHAT_%s%s",
77 name? "_" : "anonymous",
78 name? name : ""
79 );
80
81 handle->fs = GNUNET_FS_start(
82 handle->cfg, fs_client_name,
83 notify_handle_fs_progress, handle,
84 GNUNET_FS_FLAGS_NONE,
85 GNUNET_FS_OPTIONS_END
86 );
87
88 GNUNET_free(fs_client_name);
89
90 handle->identity = GNUNET_IDENTITY_connect( 74 handle->identity = GNUNET_IDENTITY_connect(
91 handle->cfg, 75 handle->cfg,
92 on_handle_gnunet_identity, 76 on_handle_gnunet_identity,
93 handle 77 handle
94 ); 78 );
95 79
96 handle->messenger = GNUNET_MESSENGER_connect( 80 handle->fs = NULL;
97 handle->cfg, name, 81 handle->messenger = NULL;
98 on_handle_identity, handle,
99 on_handle_message, handle
100 );
101 82
102 handle->public_key = NULL; 83 handle->public_key = NULL;
103 handle->user_pointer = NULL; 84 handle->user_pointer = NULL;
104
105 handle_update_key(handle);
106 return handle; 85 return handle;
107} 86}
108 87
@@ -129,66 +108,35 @@ handle_update_key (struct GNUNET_CHAT_Handle *handle)
129void 108void
130handle_destroy (struct GNUNET_CHAT_Handle *handle) 109handle_destroy (struct GNUNET_CHAT_Handle *handle)
131{ 110{
132 GNUNET_assert((handle) && 111 GNUNET_assert(handle);
133 (handle->groups) &&
134 (handle->contacts) &&
135 (handle->contexts) &&
136 (handle->files));
137 112
138 if (handle->shutdown_hook) 113 if (handle->shutdown_hook)
139 GNUNET_SCHEDULER_cancel(handle->shutdown_hook); 114 GNUNET_SCHEDULER_cancel(handle->shutdown_hook);
140 115
141 GNUNET_CONTAINER_multihashmap_iterate( 116 if (handle->current)
142 handle->groups, it_destroy_handle_groups, NULL 117 handle_disconnect(handle);
143 );
144
145 GNUNET_CONTAINER_multishortmap_iterate(
146 handle->contacts, it_destroy_handle_contacts, NULL
147 );
148
149 GNUNET_CONTAINER_multihashmap_iterate(
150 handle->contexts, it_destroy_handle_contexts, NULL
151 );
152
153 if (handle->public_key)
154 GNUNET_free(handle->public_key);
155
156 if (handle->messenger)
157 GNUNET_MESSENGER_disconnect(handle->messenger);
158 118
159 if (handle->identity) 119 if (handle->identity)
160 GNUNET_IDENTITY_disconnect(handle->identity); 120 GNUNET_IDENTITY_disconnect(handle->identity);
161 121
162 if (handle->fs)
163 GNUNET_FS_stop(handle->fs);
164
165 if (handle->arm) 122 if (handle->arm)
166 GNUNET_ARM_disconnect(handle->arm); 123 GNUNET_ARM_disconnect(handle->arm);
167 124
168 GNUNET_CONTAINER_multihashmap_iterate( 125 struct GNUNET_CHAT_InternalAccounts *accounts;
169 handle->files, it_destroy_handle_files, NULL 126 while (handle->accounts_head)
170 );
171
172 GNUNET_CONTAINER_multihashmap_destroy(handle->groups);
173 GNUNET_CONTAINER_multishortmap_destroy(handle->contacts);
174 GNUNET_CONTAINER_multihashmap_destroy(handle->contexts);
175 GNUNET_CONTAINER_multihashmap_destroy(handle->files);
176
177 struct GNUNET_CHAT_InternalIdentities *identities;
178 while (handle->identities_head)
179 { 127 {
180 identities = handle->identities_head; 128 accounts = handle->accounts_head;
181 129
182 if (identities->name) 130 if (accounts->account)
183 GNUNET_free(identities->name); 131 account_destroy(accounts->account);
184 132
185 GNUNET_CONTAINER_DLL_remove( 133 GNUNET_CONTAINER_DLL_remove(
186 handle->identities_head, 134 handle->accounts_head,
187 handle->identities_tail, 135 handle->accounts_tail,
188 identities 136 accounts
189 ); 137 );
190 138
191 GNUNET_free(identities); 139 GNUNET_free(accounts);
192 } 140 }
193 141
194 if (handle->directory) 142 if (handle->directory)
@@ -215,6 +163,95 @@ handle_destroy (struct GNUNET_CHAT_Handle *handle)
215} 163}
216 164
217void 165void
166handle_connect (struct GNUNET_CHAT_Handle *handle,
167 const struct GNUNET_CHAT_Account *account)
168{
169 GNUNET_assert((handle) && (account) &&
170 (!(handle->current)) &&
171 (!(handle->groups)) &&
172 (!(handle->contacts)) &&
173 (!(handle->contexts)) &&
174 (!(handle->files)));
175
176 handle->files = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO);
177 handle->contexts = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO);
178 handle->contacts = GNUNET_CONTAINER_multishortmap_create(8, GNUNET_NO);
179 handle->groups = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO);
180
181 const char *name = account->name;
182
183 char* fs_client_name = NULL;
184 GNUNET_asprintf (
185 &fs_client_name,
186 "GNUNET_CHAT_%s%s",
187 name? "_" : "anonymous",
188 name? name : ""
189 );
190
191 handle->fs = GNUNET_FS_start(
192 handle->cfg, fs_client_name,
193 notify_handle_fs_progress, handle,
194 GNUNET_FS_FLAGS_NONE,
195 GNUNET_FS_OPTIONS_END
196 );
197
198 GNUNET_free(fs_client_name);
199
200 handle->messenger = GNUNET_MESSENGER_connect(
201 handle->cfg, name,
202 on_handle_identity, handle,
203 on_handle_message, handle
204 );
205
206 handle->current = account;
207 handle_update_key(handle);
208}
209
210void
211handle_disconnect (struct GNUNET_CHAT_Handle *handle)
212{
213 GNUNET_assert((handle) &&
214 (handle->current) &&
215 (handle->groups) &&
216 (handle->contacts) &&
217 (handle->contexts) &&
218 (handle->files));
219
220 GNUNET_CONTAINER_multihashmap_iterate(
221 handle->groups, it_destroy_handle_groups, NULL
222 );
223
224 GNUNET_CONTAINER_multishortmap_iterate(
225 handle->contacts, it_destroy_handle_contacts, NULL
226 );
227
228 GNUNET_CONTAINER_multihashmap_iterate(
229 handle->contexts, it_destroy_handle_contexts, NULL
230 );
231
232 if (handle->messenger)
233 GNUNET_MESSENGER_disconnect(handle->messenger);
234
235 if (handle->fs)
236 GNUNET_FS_stop(handle->fs);
237
238 GNUNET_CONTAINER_multihashmap_iterate(
239 handle->files, it_destroy_handle_files, NULL
240 );
241
242 handle->fs = NULL;
243 handle->messenger = NULL;
244
245 GNUNET_CONTAINER_multihashmap_destroy(handle->groups);
246 GNUNET_CONTAINER_multishortmap_destroy(handle->contacts);
247 GNUNET_CONTAINER_multihashmap_destroy(handle->contexts);
248 GNUNET_CONTAINER_multihashmap_destroy(handle->files);
249
250 handle->current = NULL;
251 handle_update_key(handle);
252}
253
254void
218handle_send_internal_message (struct GNUNET_CHAT_Handle *handle, 255handle_send_internal_message (struct GNUNET_CHAT_Handle *handle,
219 struct GNUNET_CHAT_Context *context, 256 struct GNUNET_CHAT_Context *context,
220 enum GNUNET_CHAT_MessageFlag flag, 257 enum GNUNET_CHAT_MessageFlag flag,
diff --git a/src/gnunet_chat_handle.h b/src/gnunet_chat_handle.h
index 047afab..569a62f 100644
--- a/src/gnunet_chat_handle.h
+++ b/src/gnunet_chat_handle.h
@@ -37,6 +37,7 @@
37#include <gnunet/gnunet_util_lib.h> 37#include <gnunet/gnunet_util_lib.h>
38 38
39#include "gnunet_chat_lib.h" 39#include "gnunet_chat_lib.h"
40#include "gnunet_chat_account.h"
40#include "gnunet_chat_message.h" 41#include "gnunet_chat_message.h"
41 42
42struct GNUNET_CHAT_InternalMessages 43struct GNUNET_CHAT_InternalMessages
@@ -46,12 +47,11 @@ struct GNUNET_CHAT_InternalMessages
46 struct GNUNET_CHAT_InternalMessages *prev; 47 struct GNUNET_CHAT_InternalMessages *prev;
47}; 48};
48 49
49struct GNUNET_CHAT_InternalIdentities 50struct GNUNET_CHAT_InternalAccounts
50{ 51{
51 char *name; 52 struct GNUNET_CHAT_Account *account;
52 struct GNUNET_IDENTITY_Ego *ego; 53 struct GNUNET_CHAT_InternalAccounts *next;
53 struct GNUNET_CHAT_InternalIdentities *next; 54 struct GNUNET_CHAT_InternalAccounts *prev;
54 struct GNUNET_CHAT_InternalIdentities *prev;
55}; 55};
56 56
57struct GNUNET_CHAT_Handle 57struct GNUNET_CHAT_Handle
@@ -67,8 +67,10 @@ struct GNUNET_CHAT_Handle
67 GNUNET_CHAT_ContextMessageCallback msg_cb; 67 GNUNET_CHAT_ContextMessageCallback msg_cb;
68 void *msg_cls; 68 void *msg_cls;
69 69
70 struct GNUNET_CHAT_InternalIdentities *identities_head; 70 struct GNUNET_CHAT_InternalAccounts *accounts_head;
71 struct GNUNET_CHAT_InternalIdentities *identities_tail; 71 struct GNUNET_CHAT_InternalAccounts *accounts_tail;
72
73 const struct GNUNET_CHAT_Account *current;
72 74
73 struct GNUNET_CONTAINER_MultiHashMap *files; 75 struct GNUNET_CONTAINER_MultiHashMap *files;
74 struct GNUNET_CONTAINER_MultiHashMap *contexts; 76 struct GNUNET_CONTAINER_MultiHashMap *contexts;
@@ -87,7 +89,6 @@ struct GNUNET_CHAT_Handle
87struct GNUNET_CHAT_Handle* 89struct GNUNET_CHAT_Handle*
88handle_create_from_config (const struct GNUNET_CONFIGURATION_Handle* cfg, 90handle_create_from_config (const struct GNUNET_CONFIGURATION_Handle* cfg,
89 const char *directory, 91 const char *directory,
90 const char *name,
91 GNUNET_CHAT_ContextMessageCallback msg_cb, 92 GNUNET_CHAT_ContextMessageCallback msg_cb,
92 void *msg_cls); 93 void *msg_cls);
93 94
@@ -98,6 +99,13 @@ void
98handle_destroy (struct GNUNET_CHAT_Handle *handle); 99handle_destroy (struct GNUNET_CHAT_Handle *handle);
99 100
100void 101void
102handle_connect (struct GNUNET_CHAT_Handle *handle,
103 const struct GNUNET_CHAT_Account *account);
104
105void
106handle_disconnect (struct GNUNET_CHAT_Handle *handle);
107
108void
101handle_send_internal_message (struct GNUNET_CHAT_Handle *handle, 109handle_send_internal_message (struct GNUNET_CHAT_Handle *handle,
102 struct GNUNET_CHAT_Context *context, 110 struct GNUNET_CHAT_Context *context,
103 enum GNUNET_CHAT_MessageFlag flag, 111 enum GNUNET_CHAT_MessageFlag flag,
diff --git a/src/gnunet_chat_handle_intern.c b/src/gnunet_chat_handle_intern.c
index 5b11876..bb4c107 100644
--- a/src/gnunet_chat_handle_intern.c
+++ b/src/gnunet_chat_handle_intern.c
@@ -206,20 +206,22 @@ on_handle_gnunet_identity(void *cls,
206{ 206{
207 struct GNUNET_CHAT_Handle* handle = cls; 207 struct GNUNET_CHAT_Handle* handle = cls;
208 208
209 if (!name) 209 if ((!name) || (!ego))
210 {
211 handle_send_internal_message(handle, NULL, GNUNET_CHAT_FLAG_REFRESH, NULL);
210 return; 212 return;
213 }
211 214
212 struct GNUNET_CHAT_InternalIdentities *identities = GNUNET_new( 215 struct GNUNET_CHAT_InternalAccounts *accounts = GNUNET_new(
213 struct GNUNET_CHAT_InternalIdentities 216 struct GNUNET_CHAT_InternalAccounts
214 ); 217 );
215 218
216 identities->name = GNUNET_strdup(name); 219 accounts->account = account_create_from_ego(ego, name);
217 identities->ego = ego;
218 220
219 GNUNET_CONTAINER_DLL_insert_tail( 221 GNUNET_CONTAINER_DLL_insert_tail(
220 handle->identities_head, 222 handle->accounts_head,
221 handle->identities_tail, 223 handle->accounts_tail,
222 identities 224 accounts
223 ); 225 );
224} 226}
225 227
diff --git a/src/gnunet_chat_lib.c b/src/gnunet_chat_lib.c
index be07f85..e40ef0c 100644
--- a/src/gnunet_chat_lib.c
+++ b/src/gnunet_chat_lib.c
@@ -40,14 +40,13 @@
40struct GNUNET_CHAT_Handle* 40struct GNUNET_CHAT_Handle*
41GNUNET_CHAT_start (const struct GNUNET_CONFIGURATION_Handle *cfg, 41GNUNET_CHAT_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
42 const char *directory, 42 const char *directory,
43 const char *name,
44 GNUNET_CHAT_ContextMessageCallback msg_cb, void *msg_cls) 43 GNUNET_CHAT_ContextMessageCallback msg_cb, void *msg_cls)
45{ 44{
46 if (!cfg) 45 if (!cfg)
47 return NULL; 46 return NULL;
48 47
49 return handle_create_from_config( 48 return handle_create_from_config(
50 cfg, directory, name, 49 cfg, directory,
51 msg_cb, msg_cls 50 msg_cb, msg_cls
52 ); 51 );
53} 52}
@@ -64,6 +63,71 @@ GNUNET_CHAT_stop (struct GNUNET_CHAT_Handle *handle)
64 63
65 64
66int 65int
66GNUNET_CHAT_iterate_accounts(const struct GNUNET_CHAT_Handle *handle,
67 GNUNET_CHAT_AccountCallback callback,
68 void *cls)
69{
70 if (!handle)
71 return GNUNET_SYSERR;
72
73 int result = 0;
74
75 struct GNUNET_CHAT_InternalAccounts *accounts = handle->accounts_head;
76 while (accounts)
77 {
78 if (!(accounts->account))
79 return GNUNET_SYSERR;
80
81 result++;
82
83 if ((!callback) && (GNUNET_YES != callback(cls, handle, accounts->account)))
84 break;
85
86 accounts = accounts->next;
87 }
88
89 return result;
90}
91
92
93void
94GNUNET_CHAT_connect (struct GNUNET_CHAT_Handle *handle,
95 const struct GNUNET_CHAT_Account *account)
96{
97 if (!handle)
98 return;
99
100 if (handle->current)
101 handle_disconnect(handle);
102
103 if (!account)
104 return;
105
106 handle_connect(handle, account);
107}
108
109
110void
111GNUNET_CHAT_disconnect (struct GNUNET_CHAT_Handle *handle)
112{
113 if ((!handle) || (!(handle->current)))
114 return;
115
116 handle_disconnect(handle);
117}
118
119
120const struct GNUNET_CHAT_Account*
121GNUNET_CHAT_get_connected(const struct GNUNET_CHAT_Handle *handle)
122{
123 if (!handle)
124 return NULL;
125
126 return handle->current;
127}
128
129
130int
67GNUNET_CHAT_update (struct GNUNET_CHAT_Handle *handle) 131GNUNET_CHAT_update (struct GNUNET_CHAT_Handle *handle)
68{ 132{
69 if (!handle) 133 if (!handle)
@@ -133,7 +197,7 @@ GNUNET_CHAT_iterate_contacts (struct GNUNET_CHAT_Handle *handle,
133 GNUNET_CHAT_ContactCallback callback, 197 GNUNET_CHAT_ContactCallback callback,
134 void *cls) 198 void *cls)
135{ 199{
136 if (!handle) 200 if ((!handle) || (!(handle->contacts)))
137 return GNUNET_SYSERR; 201 return GNUNET_SYSERR;
138 202
139 struct GNUNET_CHAT_HandleIterateContacts it; 203 struct GNUNET_CHAT_HandleIterateContacts it;
@@ -151,7 +215,7 @@ struct GNUNET_CHAT_Group *
151GNUNET_CHAT_group_create (struct GNUNET_CHAT_Handle *handle, 215GNUNET_CHAT_group_create (struct GNUNET_CHAT_Handle *handle,
152 const char* topic) 216 const char* topic)
153{ 217{
154 if (!handle) 218 if ((!handle) || (!(handle->groups)) || (!(handle->contexts)))
155 return NULL; 219 return NULL;
156 220
157 struct GNUNET_HashCode key; 221 struct GNUNET_HashCode key;
@@ -210,7 +274,7 @@ GNUNET_CHAT_iterate_groups (struct GNUNET_CHAT_Handle *handle,
210 GNUNET_CHAT_GroupCallback callback, 274 GNUNET_CHAT_GroupCallback callback,
211 void *cls) 275 void *cls)
212{ 276{
213 if (!handle) 277 if ((!handle) || (!(handle->groups)))
214 return GNUNET_SYSERR; 278 return GNUNET_SYSERR;
215 279
216 struct GNUNET_CHAT_HandleIterateGroups it; 280 struct GNUNET_CHAT_HandleIterateGroups it;
@@ -784,6 +848,8 @@ GNUNET_CHAT_message_get_kind (const struct GNUNET_CHAT_Message *message)
784 { 848 {
785 case GNUNET_CHAT_FLAG_WARNING: 849 case GNUNET_CHAT_FLAG_WARNING:
786 return GNUNET_CHAT_KIND_WARNING; 850 return GNUNET_CHAT_KIND_WARNING;
851 case GNUNET_CHAT_FLAG_REFRESH:
852 return GNUNET_CHAT_KIND_REFRESH;
787 case GNUNET_CHAT_FLAG_LOGIN: 853 case GNUNET_CHAT_FLAG_LOGIN:
788 return GNUNET_CHAT_KIND_LOGIN; 854 return GNUNET_CHAT_KIND_LOGIN;
789 case GNUNET_CHAT_FLAG_UPDATE: 855 case GNUNET_CHAT_FLAG_UPDATE:
diff --git a/src/gnunet_chat_message.h b/src/gnunet_chat_message.h
index 9df2b67..59737ac 100644
--- a/src/gnunet_chat_message.h
+++ b/src/gnunet_chat_message.h
@@ -45,8 +45,9 @@ enum GNUNET_CHAT_MessageFlag
45{ 45{
46 GNUNET_CHAT_FLAG_NONE = 0, 46 GNUNET_CHAT_FLAG_NONE = 0,
47 GNUNET_CHAT_FLAG_WARNING = 1, 47 GNUNET_CHAT_FLAG_WARNING = 1,
48 GNUNET_CHAT_FLAG_LOGIN = 2, 48 GNUNET_CHAT_FLAG_REFRESH = 2,
49 GNUNET_CHAT_FLAG_UPDATE = 3 49 GNUNET_CHAT_FLAG_LOGIN = 3,
50 GNUNET_CHAT_FLAG_UPDATE = 4
50}; 51};
51 52
52struct GNUNET_CHAT_Message 53struct GNUNET_CHAT_Message