/**
- * Possible states of the program.
+ * Possible states of the phone.
*/
-enum ConversationState
+enum PhoneState
{
/**
* We're waiting for our own idenitty.
*/
- CS_LOOKUP_EGO,
+ PS_LOOKUP_EGO,
/**
* We're listening for calls
*/
- CS_LISTEN,
+ PS_LISTEN,
/**
- * Our phone is ringing.
+ * We accepted an incoming phone call.
*/
- CS_RING,
+ PS_ACCEPTED,
/**
- * We accepted an incoming phone call.
+ * Internal error
*/
- CS_ACCEPTED,
+ PS_ERROR
+};
+
+/**
+ * States for current outgoing call.
+ */
+enum CallState
+{
/**
* We are looking up some other participant.
*/
CS_CONNECTED,
/**
- * Internal error
+ * The call is currently suspended (by us).
+ */
+ CS_SUSPENDED
+
+};
+
+
+
+/**
+ * List of incoming calls
+ */
+struct CallList
+{
+
+ /**
+ * A DLL.
+ */
+ struct CallList *prev;
+
+ /**
+ * A DLL.
+ */
+ struct CallList *next;
+
+ /**
+ * Handle to hang up or activate.
+ */
+ struct GNUNET_CONVERSATION_Caller *caller;
+
+ /**
+ * String identifying the caller.
+ */
+ char *caller_id;
+
+ /**
+ * Unique number of the call.
*/
- CS_ERROR
+ unsigned int caller_num;
};
+
/**
* Phone handle
*/
static struct GNUNET_CONVERSATION_Phone *phone;
/**
- * Call handle
+ * Call handle (for active outgoing call).
*/
static struct GNUNET_CONVERSATION_Call *call;
+/**
+ * Caller handle (for active incoming call).
+ */
+static struct CallList *cl_active;
+
+/**
+ * Head of calls waiting to be accepted.
+ */
+static struct CallList *cl_head;
+
+/**
+ * Tail of calls waiting to be accepted.
+ */
+static struct CallList *cl_tail;
+
/**
* Desired phone line.
*/
static struct GNUNET_DISK_FileHandle *stdin_fh;
/**
- * Our current state.
+ * Our phone's current state.
+ */
+static enum PhoneState phone_state;
+
+/**
+ * Our call's current state.
*/
-static enum ConversationState state;
+static enum CallState call_state;
+
+/**
+ * Counts the number of incoming calls we have had so far.
+ */
+static unsigned int caller_num_gen;
/**
* GNS address for this phone.
* Function called with an event emitted by a phone.
*
* @param cls closure
- * @param code type of the event on the phone
- * @param ... additional information, depends on @a code
+ * @param code type of the event
+ * @param caller handle for the caller
+ * @param caller_id name of the caller in GNS
*/
static void
phone_event_handler (void *cls,
- enum GNUNET_CONVERSATION_EventCode code,
- ...)
+ enum GNUNET_CONVERSATION_PhoneEventCode code,
+ struct GNUNET_CONVERSATION_Caller *caller,
+ const char *caller_id)
{
- va_list va;
+ struct CallList *cl;
- va_start (va, code);
switch (code)
{
- case GNUNET_CONVERSATION_EC_RING:
- GNUNET_break (CS_LISTEN == state);
- GNUNET_free_non_null (peer_name);
- peer_name = GNUNET_strdup (va_arg (va, const char *));
+ case GNUNET_CONVERSATION_EC_PHONE_RING:
FPRINTF (stdout,
- _("Incoming call from `%s'.\nPlease /accept or /cancel the call.\n"),
- peer_name);
- state = CS_RING;
- break;
- case GNUNET_CONVERSATION_EC_RINGING:
- GNUNET_break (0);
- break;
- case GNUNET_CONVERSATION_EC_READY:
- GNUNET_break (0);
+ _("Incoming call from `%s'. Please /accept #%u or /cancel %u the call.\n"),
+ caller_id,
+ caller_num_gen,
+ caller_num_gen);
+ cl = GNUNET_new (struct CallList);
+ cl->caller = caller;
+ cl->caller_id = GNUNET_strdup (caller_id);
+ cl->caller_num = caller_num_gen++;
+ GNUNET_CONTAINER_DLL_insert (cl_head,
+ cl_tail,
+ cl);
break;
- case GNUNET_CONVERSATION_EC_GNS_FAIL:
- GNUNET_break (0);
+ case GNUNET_CONVERSATION_EC_PHONE_HUNG_UP:
+ for (cl = cl_head; NULL != cl; cl = cl->next)
+ if (caller == cl->caller)
+ break;
+ if (NULL == cl)
+ {
+ GNUNET_break (0);
+ return;
+ }
+ FPRINTF (stdout,
+ _("Call from `%s' terminated\n"),
+ cl->caller_id);
+ GNUNET_CONTAINER_DLL_remove (cl_head,
+ cl_tail,
+ cl);
+ GNUNET_free (cl->caller_id);
+ if (cl == cl_active)
+ {
+ cl_active = NULL;
+ phone_state = PS_LISTEN;
+ }
+ GNUNET_free (cl);
break;
- case GNUNET_CONVERSATION_EC_BUSY:
- GNUNET_break (0);
+ }
+}
+
+
+/**
+ * Function called with an event emitted by a caller.
+ *
+ * @param cls closure with the `struct CallList` of the caller
+ * @param code type of the event issued by the caller
+ */
+static void
+caller_event_handler (void *cls,
+ enum GNUNET_CONVERSATION_CallerEventCode code)
+{
+ struct CallList *cl = cls;
+
+ switch (code)
+ {
+ case GNUNET_CONVERSATION_EC_CALLER_SUSPEND:
+ FPRINTF (stdout,
+ _("Call from `%s' suspended by other user\n"),
+ cl->caller_id);
break;
- case GNUNET_CONVERSATION_EC_TERMINATED:
- GNUNET_break ( (CS_RING == state) ||
- (CS_ACCEPTED == state) );
+ case GNUNET_CONVERSATION_EC_CALLER_RESUME:
FPRINTF (stdout,
- _("Call terminated: %s\n"),
- va_arg (va, const char *));
- state = CS_LISTEN;
+ _("Call from `%s' resumed by other user\n"),
+ cl->caller_id);
break;
}
- va_end (va);
}
static void
start_phone ()
{
- struct GNUNET_NAMESTORE_RecordData rd;
+ struct GNUNET_GNSRECORD_Data rd;
if (NULL == caller_id)
{
FPRINTF (stderr,
_("Ego `%s' no longer available, phone is now down.\n"),
ego_name);
- state = CS_LOOKUP_EGO;
+ phone_state = PS_LOOKUP_EGO;
return;
}
+ GNUNET_assert (NULL == phone);
phone = GNUNET_CONVERSATION_phone_create (cfg,
caller_id,
&phone_event_handler, NULL);
FPRINTF (stderr,
"%s",
_("Failed to setup phone (internal error)\n"));
- state = CS_ERROR;
+ phone_state = PS_ERROR;
}
else
{
FPRINTF (stdout,
_("Phone active on line %u\n"),
(unsigned int) line);
- state = CS_LISTEN;
+ phone_state = PS_LISTEN;
}
}
/**
- * Function called with an event emitted by a phone.
+ * Function called with an event emitted by a call.
*
- * @param cls closure
- * @param code type of the event on the phone
- * @param ... additional information, depends on @a code
+ * @param cls closure, NULL
+ * @param code type of the event on the call
*/
static void
call_event_handler (void *cls,
- enum GNUNET_CONVERSATION_EventCode code,
- ...)
+ enum GNUNET_CONVERSATION_CallEventCode code)
{
- va_list va;
-
- va_start (va, code);
switch (code)
{
- case GNUNET_CONVERSATION_EC_RING:
- GNUNET_break (0);
- break;
- case GNUNET_CONVERSATION_EC_RINGING:
- GNUNET_break (CS_RESOLVING == state);
- if (verbose)
- FPRINTF (stdout,
- "%s",
- _("Resolved address. Now ringing other party.\n"));
- state = CS_RINGING;
+ case GNUNET_CONVERSATION_EC_CALL_RINGING:
+ GNUNET_break (CS_RESOLVING == call_state);
+ FPRINTF (stdout,
+ _("Resolved address of `%s'. Now ringing other party.\n"),
+ peer_name);
+ call_state = CS_RINGING;
break;
- case GNUNET_CONVERSATION_EC_READY:
- GNUNET_break (CS_RINGING == state);
+ case GNUNET_CONVERSATION_EC_CALL_PICKED_UP:
+ GNUNET_break (CS_RINGING == call_state);
FPRINTF (stdout,
- _("Connection established to `%s': %s\n"),
- peer_name,
- va_arg (va, const char *));
- state = CS_CONNECTED;
+ _("Connection established to `%s'\n"),
+ peer_name);
+ call_state = CS_CONNECTED;
break;
- case GNUNET_CONVERSATION_EC_GNS_FAIL:
- GNUNET_break (CS_RESOLVING == state);
+ case GNUNET_CONVERSATION_EC_CALL_GNS_FAIL:
+ GNUNET_break (CS_RESOLVING == call_state);
FPRINTF (stdout,
_("Failed to resolve `%s'\n"),
ego_name);
call = NULL;
- start_phone ();
break;
- case GNUNET_CONVERSATION_EC_BUSY:
- GNUNET_break (CS_RINGING == state);
+ case GNUNET_CONVERSATION_EC_CALL_HUNG_UP:
FPRINTF (stdout,
"%s",
- _("Line busy\n"));
+ _("Call terminated\n"));
call = NULL;
- start_phone ();
break;
- case GNUNET_CONVERSATION_EC_TERMINATED:
- GNUNET_break ( (CS_RINGING == state) ||
- (CS_CONNECTED == state) );
+ case GNUNET_CONVERSATION_EC_CALL_SUSPENDED:
+ GNUNET_break (CS_CONNECTED == call_state);
FPRINTF (stdout,
- _("Call terminated: %s\n"),
- va_arg (va, const char *));
- call = NULL;
- start_phone ();
+ _("Connection to `%s' suspended (by other user)\n"),
+ peer_name);
+ break;
+ case GNUNET_CONVERSATION_EC_CALL_RESUMED:
+ GNUNET_break (CS_CONNECTED == call_state);
+ FPRINTF (stdout,
+ _("Connection to `%s' resumed (by other user)\n"),
+ peer_name);
break;
}
- va_end (va);
}
ego_name);
return;
}
- switch (state)
+ if (NULL != call)
+ {
+ FPRINTF (stderr,
+ _("You are calling someone else already, hang up first!\n"));
+ return;
+ }
+ switch (phone_state)
{
- case CS_LOOKUP_EGO:
+ case PS_LOOKUP_EGO:
FPRINTF (stderr,
_("Ego `%s' not available\n"),
ego_name);
return;
- case CS_LISTEN:
+ case PS_LISTEN:
/* ok to call! */
break;
- case CS_RING:
- FPRINTF (stdout,
- _("Hanging up on incoming phone call from `%s' to call `%s'.\n"),
- peer_name,
- arg);
- GNUNET_CONVERSATION_phone_hang_up (phone, NULL);
- break;
- case CS_ACCEPTED:
+ case PS_ACCEPTED:
FPRINTF (stderr,
- _("You are already in a conversation with `%s', refusing to call `%s'.\n"),
- peer_name,
- arg);
- return;
- case CS_RESOLVING:
- case CS_RINGING:
- FPRINTF (stderr,
- _("Aborting call to `%s'\n"),
+ _("You are answering call from `%s', hang up or suspend that call first!\n"),
peer_name);
- GNUNET_CONVERSATION_call_stop (call, NULL);
- call = NULL;
- break;
- case CS_CONNECTED:
- FPRINTF (stderr,
- _("You are already in a conversation with `%s', refusing to call `%s'.\n"),
- peer_name,
- arg);
return;
- case CS_ERROR:
+ case PS_ERROR:
/* ok to call */
break;
}
- GNUNET_assert (NULL == call);
- if (NULL != phone)
- {
- GNUNET_CONVERSATION_phone_destroy (phone);
- phone = NULL;
- }
GNUNET_free_non_null (peer_name);
peer_name = GNUNET_strdup (arg);
+ call_state = CS_RESOLVING;
+ GNUNET_assert (NULL == call);
call = GNUNET_CONVERSATION_call_start (cfg,
caller_id,
arg,
speaker,
mic,
&call_event_handler, NULL);
- state = CS_RESOLVING;
}
static void
do_accept (const char *args)
{
- switch (state)
+ struct CallList *cl;
+ char buf[32];
+
+ if ( (NULL != call) &&
+ (CS_SUSPENDED != call_state) )
{
- case CS_LOOKUP_EGO:
- case CS_LISTEN:
- case CS_ERROR:
FPRINTF (stderr,
- _("There is no incoming call to be accepted!\n"));
+ _("You are calling someone else already, hang up first!\n"));
return;
- case CS_RING:
+ }
+ switch (phone_state)
+ {
+ case PS_LOOKUP_EGO:
+ GNUNET_break (0);
+ break;
+ case PS_LISTEN:
/* this is the expected state */
break;
- case CS_ACCEPTED:
+ case PS_ACCEPTED:
FPRINTF (stderr,
- _("You are already in a conversation with `%s'.\n"),
+ _("You are answering call from `%s', hang up or suspend that call first!\n"),
peer_name);
return;
- case CS_RESOLVING:
- case CS_RINGING:
+ case PS_ERROR:
+ GNUNET_break (0);
+ break;
+ }
+ cl = cl_head;
+ if (NULL == cl)
+ {
FPRINTF (stderr,
- _("You are trying to call `%s', cannot accept incoming calls right now.\n"),
- peer_name);
+ _("There is no incoming call to accept here!\n"));
return;
- case CS_CONNECTED:
+ }
+ if ( (NULL != cl->next) || (NULL != args) )
+ {
+ for (cl = cl_head; NULL != cl; cl = cl->next)
+ {
+ GNUNET_snprintf (buf, sizeof (buf),
+ "%u",
+ cl->caller_num);
+ if (0 == strcmp (buf, args))
+ break;
+ }
+ }
+ if (NULL == cl)
+ {
FPRINTF (stderr,
- _("You are already in a conversation with `%s'.\n"),
- peer_name);
+ _("There is no incoming call `%s' to accept right now!\n"),
+ args);
return;
}
- GNUNET_assert (NULL != phone);
- GNUNET_CONVERSATION_phone_pick_up (phone,
- args,
- speaker,
- mic);
- state = CS_ACCEPTED;
+ cl_active = cl;
+ GNUNET_free_non_null (peer_name);
+ peer_name = GNUNET_strdup (cl->caller_id);
+ phone_state = PS_ACCEPTED;
+ GNUNET_CONVERSATION_caller_pick_up (cl->caller,
+ &caller_event_handler,
+ cl,
+ speaker,
+ mic);
}
static void
do_status (const char *args)
{
- switch (state)
+ struct CallList *cl;
+
+ switch (phone_state)
{
- case CS_LOOKUP_EGO:
+ case PS_LOOKUP_EGO:
FPRINTF (stdout,
_("We are currently trying to locate the private key for the ego `%s'.\n"),
ego_name);
break;
- case CS_LISTEN:
+ case PS_LISTEN:
FPRINTF (stdout,
_("We are listening for incoming calls for ego `%s' on line %u.\n"),
ego_name,
line);
break;
- case CS_RING:
- FPRINTF (stdout,
- _("The phone is rining. `%s' is trying to call us.\n"),
- peer_name);
- break;
- case CS_ACCEPTED:
- case CS_CONNECTED:
+ case PS_ACCEPTED:
FPRINTF (stdout,
_("You are having a conversation with `%s'.\n"),
peer_name);
break;
- case CS_RESOLVING:
+ case PS_ERROR:
FPRINTF (stdout,
- _("We are trying to find the network address to call `%s'.\n"),
- peer_name);
+ _("We had an internal error setting up our phone line. You can still make calls.\n"));
break;
- case CS_RINGING:
+ }
+ if (NULL != call)
+ {
+ switch (call_state)
+ {
+ case CS_RESOLVING:
+ FPRINTF (stdout,
+ _("We are trying to find the network address to call `%s'.\n"),
+ peer_name);
+ break;
+ case CS_RINGING:
+ FPRINTF (stdout,
+ _("We are calling `%s', his phone should be ringing.\n"),
+ peer_name);
+ break;
+ case CS_CONNECTED:
+ FPRINTF (stdout,
+ _("You are having a conversation with `%s'.\n"),
+ peer_name);
+ break;
+ case CS_SUSPENDED:
+ /* ok to accept incoming call right now */
+ break;
+ }
+ }
+ if ( (NULL != cl_head) &&
+ ( (cl_head != cl_active) ||
+ (cl_head != cl_tail) ) )
+ {
FPRINTF (stdout,
- _("We are calling `%s', his phone should be ringing.\n"),
- peer_name);
- break;
- case CS_ERROR:
+ "%s",
+ _("Calls waiting:\n"));
+ for (cl = cl_head; NULL != cl; cl = cl->next)
+ {
+ if (cl == cl_active)
+ continue;
+ FPRINTF (stdout,
+ _("#%u: `%s'\n"),
+ cl->caller_num,
+ cl->caller_id);
+ }
FPRINTF (stdout,
- _("We had an internal error setting up our phone line. You can still make calls.\n"));
- break;
+ "%s",
+ "\n");
}
}
/**
- * Rejecting a call
+ * Suspending a call
*
* @param args arguments given to the command
*/
static void
-do_reject (const char *args)
+do_suspend (const char *args)
{
- switch (state)
+ if (NULL != call)
{
- case CS_LOOKUP_EGO:
- case CS_LISTEN:
- case CS_ERROR:
+ switch (call_state)
+ {
+ case CS_RESOLVING:
+ case CS_RINGING:
+ case CS_SUSPENDED:
+ FPRINTF (stderr,
+ "%s",
+ _("There is no call that could be suspended right now.\n"));
+ return;
+ case CS_CONNECTED:
+ call_state = CS_SUSPENDED;
+ GNUNET_CONVERSATION_call_suspend (call);
+ return;
+ }
+ }
+ switch (phone_state)
+ {
+ case PS_LOOKUP_EGO:
+ case PS_LISTEN:
+ case PS_ERROR:
FPRINTF (stderr,
"%s",
- _("There is no call that could be cancelled right now.\n"));
+ _("There is no call that could be suspended right now.\n"));
return;
- case CS_RING:
- case CS_ACCEPTED:
- case CS_RESOLVING:
- case CS_RINGING:
- case CS_CONNECTED:
+ case PS_ACCEPTED:
/* expected state, do rejection logic */
break;
}
- if (NULL == call)
+ GNUNET_assert (NULL != cl_active);
+ GNUNET_CONVERSATION_caller_suspend (cl_active->caller);
+ cl_active = NULL;
+ phone_state = PS_LISTEN;
+}
+
+
+/**
+ * Resuming a call
+ *
+ * @param args arguments given to the command
+ */
+static void
+do_resume (const char *args)
+{
+ struct CallList *cl;
+ char buf[32];
+
+ if (NULL != call)
{
- GNUNET_assert (NULL != phone);
- GNUNET_CONVERSATION_phone_hang_up (phone,
- args);
- state = CS_LISTEN;
+ switch (call_state)
+ {
+ case CS_RESOLVING:
+ case CS_RINGING:
+ case CS_CONNECTED:
+ FPRINTF (stderr,
+ "%s",
+ _("There is no call that could be resumed right now.\n"));
+ return;
+ case CS_SUSPENDED:
+ call_state = CS_CONNECTED;
+ GNUNET_CONVERSATION_call_resume (call,
+ speaker,
+ mic);
+ return;
+ }
}
- else
+ switch (phone_state)
+ {
+ case PS_LOOKUP_EGO:
+ case PS_ERROR:
+ FPRINTF (stderr,
+ "%s",
+ _("There is no call that could be resumed right now.\n"));
+ return;
+ case PS_LISTEN:
+ /* expected state, do resume logic */
+ break;
+ case PS_ACCEPTED:
+ FPRINTF (stderr,
+ _("Already talking with `%s', cannot resume a call right now.\n"),
+ peer_name);
+ return;
+ }
+ GNUNET_assert (NULL == cl_active);
+ cl = cl_head;
+ if (NULL == cl)
+ {
+ FPRINTF (stderr,
+ _("There is no incoming call to resume here!\n"));
+ return;
+ }
+ if ( (NULL != cl->next) || (NULL != args) )
{
- GNUNET_CONVERSATION_call_stop (call, args);
+ for (cl = cl_head; NULL != cl; cl = cl->next)
+ {
+ GNUNET_snprintf (buf, sizeof (buf),
+ "%u",
+ cl->caller_num);
+ if (0 == strcmp (buf, args))
+ break;
+ }
+ }
+ if (NULL == cl)
+ {
+ FPRINTF (stderr,
+ _("There is no incoming call `%s' to resume right now!\n"),
+ args);
+ return;
+ }
+ cl_active = cl;
+ GNUNET_CONVERSATION_caller_resume (cl_active->caller,
+ speaker,
+ mic);
+ phone_state = PS_ACCEPTED;
+}
+
+
+/**
+ * Rejecting a call
+ *
+ * @param args arguments given to the command
+ */
+static void
+do_reject (const char *args)
+{
+ struct CallList *cl;
+ char buf[32];
+
+ if (NULL != call)
+ {
+ GNUNET_CONVERSATION_call_stop (call);
call = NULL;
- start_phone ();
+ return;
+ }
+ switch (phone_state)
+ {
+ case PS_LOOKUP_EGO:
+ case PS_ERROR:
+ FPRINTF (stderr,
+ "%s",
+ _("There is no call that could be cancelled right now.\n"));
+ return;
+ case PS_LISTEN:
+ /* look for active incoming calls to refuse */
+ cl = cl_head;
+ if (NULL == cl)
+ {
+ FPRINTF (stderr,
+ _("There is no incoming call to refuse here!\n"));
+ return;
+ }
+ if ( (NULL != cl->next) || (NULL != args) )
+ {
+ for (cl = cl_head; NULL != cl; cl = cl->next)
+ {
+ GNUNET_snprintf (buf, sizeof (buf),
+ "%u",
+ cl->caller_num);
+ if (0 == strcmp (buf, args))
+ break;
+ }
+ }
+ if (NULL == cl)
+ {
+ FPRINTF (stderr,
+ _("There is no incoming call `%s' to refuse right now!\n"),
+ args);
+ return;
+ }
+ GNUNET_CONVERSATION_caller_hang_up (cl->caller);
+ GNUNET_CONTAINER_DLL_remove (cl_head,
+ cl_tail,
+ cl);
+ GNUNET_free (cl->caller_id);
+ GNUNET_free (cl);
+ break;
+ case PS_ACCEPTED:
+ /* expected state, do rejection logic */
+ GNUNET_assert (NULL != cl_active);
+ GNUNET_CONVERSATION_caller_hang_up (cl_active->caller);
+ cl_active = NULL;
+ phone_state = PS_LISTEN;
+ break;
}
}
{"/call", &do_call,
gettext_noop ("Use `/call USER.gnu' to call USER")},
{"/accept", &do_accept,
- gettext_noop ("Use `/accept MESSAGE' to accept an incoming call")},
+ gettext_noop ("Use `/accept #NUM' to accept incoming call #NUM")},
+ {"/suspend", &do_suspend,
+ gettext_noop ("Use `/suspend' to suspend the active call")},
+ {"/resume", &do_resume,
+ gettext_noop ("Use `/resume [#NUM]' to resume a call, #NUM is needed to resume incoming calls, no argument is needed to resume the current outgoing call.")},
{"/cancel", &do_reject,
- gettext_noop ("Use `/cancel MESSAGE' to reject or terminate a call")},
+ gettext_noop ("Use `/cancel' to reject or terminate a call")},
{"/status", &do_status,
gettext_noop ("Use `/status' to print status information")},
{"/quit", &do_quit,
/**
* Action function to print help for the command shell.
*
- * @param arguments arguments given to the command
+ * @param args arguments given to the command
*/
static void
do_help (const char *args)
{
if (NULL != call)
{
- GNUNET_CONVERSATION_call_stop (call, NULL);
+ GNUNET_CONVERSATION_call_stop (call);
call = NULL;
}
if (NULL != phone)
mic = NULL;
GNUNET_free (ego_name);
ego_name = NULL;
- GNUNET_CONFIGURATION_destroy (cfg);
- cfg = NULL;
GNUNET_free_non_null (peer_name);
- state = CS_ERROR;
+ phone_state = PS_ERROR;
}
ptr = &message[strlen (commands[i].command)];
while (isspace ((int) *ptr))
ptr++;
+ if ('\0' == *ptr)
+ ptr = NULL;
commands[i].Action (ptr);
}
gettext_noop ("Enables having a conversation with other GNUnet users."),
options, &run, NULL);
GNUNET_free ((void *) argv);
+ if (NULL != cfg)
+ {
+ GNUNET_CONFIGURATION_destroy (cfg);
+ cfg = NULL;
+ }
return (GNUNET_OK == ret) ? 0 : 1;
}