+
+/* Generates the session detachment data. This data can be used later
+ to resume back to the server. */
+
+SilcBuffer silc_client_get_detach_data(SilcClient client,
+ SilcClientConnection conn)
+{
+ SilcBuffer detach;
+ SilcHashTableList htl;
+ SilcChannelUser chu;
+ int ret, ch_count;
+
+ SILC_LOG_DEBUG(("Creating detachment data"));
+
+ ch_count = silc_hash_table_count(conn->local_entry->channels);
+
+ /* Save the nickname, Client ID and user mode in SILC network */
+ detach = silc_buffer_alloc(0);
+ if (!detach)
+ return NULL;
+ ret =
+ silc_buffer_format(detach,
+ SILC_STR_ADVANCE,
+ SILC_STR_UI_SHORT(strlen(conn->local_entry->nickname)),
+ SILC_STR_DATA(conn->local_entry->nickname,
+ strlen(conn->local_entry->nickname)),
+ SILC_STR_UI_SHORT(silc_buffer_len(conn->internal->
+ local_idp)),
+ SILC_STR_DATA(silc_buffer_data(conn->internal->
+ local_idp),
+ silc_buffer_len(conn->internal->
+ local_idp)),
+ SILC_STR_UI_INT(conn->local_entry->mode),
+ SILC_STR_UI_INT(ch_count),
+ SILC_STR_END);
+ if (ret < 0) {
+ silc_buffer_free(detach);
+ return NULL;
+ }
+
+ /* Save all joined channels */
+ silc_hash_table_list(conn->local_entry->channels, &htl);
+ while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
+ unsigned char chid[32];
+ SilcUInt32 chid_len;
+
+ silc_id_id2str(&chu->channel->id, SILC_ID_CHANNEL, chid, sizeof(chid),
+ &chid_len);
+ silc_buffer_format(detach,
+ SILC_STR_ADVANCE,
+ SILC_STR_UI_SHORT(strlen(chu->channel->channel_name)),
+ SILC_STR_DATA(chu->channel->channel_name,
+ strlen(chu->channel->channel_name)),
+ SILC_STR_UI_SHORT(chid_len),
+ SILC_STR_DATA(chid, chid_len),
+ SILC_STR_UI_INT(chu->channel->mode),
+ SILC_STR_END);
+ silc_free(chid);
+ }
+ silc_hash_table_list_reset(&htl);
+
+ silc_buffer_start(detach);
+ SILC_LOG_HEXDUMP(("Detach data"), silc_buffer_data(detach),
+ silc_buffer_len(detach));
+
+ return detach;
+}