commit cdb69d11f86721dc5d003bff5b478223b80aae0c
parent 0643c99b65df3e2ca2bf63b9b664b07c84de4f39
Author: Jacki <jacki@thejackimonster.de>
Date: Thu, 18 Apr 2024 18:28:45 +0200
Implement function to upload file and get uri from file handle
Signed-off-by: Jacki <jacki@thejackimonster.de>
Diffstat:
3 files changed, 146 insertions(+), 1 deletion(-)
diff --git a/include/gnunet/gnunet_chat_lib.h b/include/gnunet/gnunet_chat_lib.h
@@ -691,12 +691,29 @@ GNUNET_CHAT_lobby_join (struct GNUNET_CHAT_Handle *handle,
*
* @param[in,out] handle Chat handle
* @param[in] uri Chat URI
+ * @return File handle on success, NULL on failure
*/
struct GNUNET_CHAT_File*
GNUNET_CHAT_request_file (struct GNUNET_CHAT_Handle *handle,
const struct GNUNET_CHAT_Uri *uri);
/**
+ * Uploads a local file specified via its <i>path</i> to share its uri
+ * with others afterwards.
+ *
+ * @param[in,out] handle Chat handle
+ * @param[in] path Local file path
+ * @param[in] callback Callback for file uploading (optional)
+ * @param[in,out] cls Closure for file uploading (optional)
+ * @return The file handle on success, NULL on failure
+ */
+struct GNUNET_CHAT_File*
+GNUNET_CHAT_upload_file (struct GNUNET_CHAT_Handle *handle,
+ const char *path,
+ GNUNET_CHAT_FileUploadCallback callback,
+ void *cls);
+
+/**
* Sets a custom <i>user pointer</i> to a given chat <i>handle</i> so it can
* be accessed in all handle related callbacks.
*
@@ -1433,6 +1450,16 @@ uint64_t
GNUNET_CHAT_file_get_local_size (const struct GNUNET_CHAT_File *file);
/**
+ * Returns a new allocated uri to access the content of a given
+ * <i>file</i> handle.
+ *
+ * @param[in] file File handle
+ * @return URI on success, NULL on error
+ */
+struct GNUNET_CHAT_Uri*
+GNUNET_CHAT_file_get_uri (const struct GNUNET_CHAT_File *file);
+
+/**
* Returns if a given <i>file</i> handle is currently uploading.
*
* @param[in] file File handle
diff --git a/src/gnunet_chat_file.c b/src/gnunet_chat_file.c
@@ -305,7 +305,8 @@ file_update_upload (struct GNUNET_CHAT_File *file,
{
upload = file->upload_head;
- GNUNET_MESSENGER_send_message(upload->context->room, &msg, NULL);
+ if (upload->context)
+ GNUNET_MESSENGER_send_message(upload->context->room, &msg, NULL);
GNUNET_CONTAINER_DLL_remove(
file->upload_head,
diff --git a/src/gnunet_chat_lib.c b/src/gnunet_chat_lib.c
@@ -782,6 +782,111 @@ GNUNET_CHAT_request_file (struct GNUNET_CHAT_Handle *handle,
}
+struct GNUNET_CHAT_File*
+GNUNET_CHAT_upload_file (struct GNUNET_CHAT_Handle *handle,
+ const char *path,
+ GNUNET_CHAT_FileUploadCallback callback,
+ void *cls)
+{
+ GNUNET_CHAT_VERSION_ASSERT();
+
+ if ((!handle) || (handle->destruction) ||
+ (!path))
+ return NULL;
+
+ struct GNUNET_HashCode hash;
+ if (GNUNET_OK != util_hash_file(path, &hash))
+ return NULL;
+
+ char *filename = handle_create_file_path(
+ handle, &hash
+ );
+
+ if (!filename)
+ return NULL;
+
+ struct GNUNET_CHAT_File *file = GNUNET_CONTAINER_multihashmap_get(
+ handle->files,
+ &hash
+ );
+
+ if (file)
+ goto file_binding;
+
+ if ((GNUNET_YES == GNUNET_DISK_file_test(filename)) ||
+ (GNUNET_OK != GNUNET_DISK_directory_create_for_file(filename)) ||
+ (GNUNET_OK != GNUNET_DISK_file_copy(path, filename)))
+ {
+ GNUNET_free(filename);
+ return NULL;
+ }
+
+ struct GNUNET_CRYPTO_SymmetricSessionKey key;
+ GNUNET_CRYPTO_symmetric_create_session_key(&key);
+
+ if (GNUNET_OK != util_encrypt_file(filename, &hash, &key))
+ {
+ GNUNET_free(filename);
+ return NULL;
+ }
+
+ char* p = GNUNET_strdup(path);
+
+ file = file_create_from_disk(
+ handle,
+ basename(p),
+ &hash,
+ &key
+ );
+
+ GNUNET_free(p);
+
+ if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(
+ handle->files, &hash, file,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
+ {
+ file_destroy(file);
+ GNUNET_free(filename);
+ return NULL;
+ }
+
+ struct GNUNET_FS_BlockOptions bo;
+
+ bo.anonymity_level = block_anonymity_level;
+ bo.content_priority = block_content_priority;
+ bo.replication_level = block_replication_level;
+
+ bo.expiration_time = GNUNET_TIME_absolute_add(
+ GNUNET_TIME_absolute_get(), GNUNET_TIME_relative_get_hour_()
+ );
+
+ struct GNUNET_FS_FileInformation* fi = GNUNET_FS_file_information_create_from_file(
+ handle->fs,
+ file,
+ filename,
+ NULL,
+ file->meta,
+ GNUNET_YES,
+ &bo
+ );
+
+ file->publish = GNUNET_FS_publish_start(
+ handle->fs, fi,
+ NULL, NULL, NULL,
+ GNUNET_FS_PUBLISH_OPTION_NONE
+ );
+
+ if (file->publish)
+ file->status |= GNUNET_CHAT_FILE_STATUS_PUBLISH;
+
+ GNUNET_free(filename);
+
+file_binding:
+ file_bind_upload(file, NULL, callback, cls);
+ return file;
+}
+
+
void
GNUNET_CHAT_set_user_pointer (struct GNUNET_CHAT_Handle *handle,
void *user_pointer)
@@ -2203,6 +2308,18 @@ GNUNET_CHAT_file_get_local_size (const struct GNUNET_CHAT_File *file)
}
+struct GNUNET_CHAT_Uri*
+GNUNET_CHAT_file_get_uri (const struct GNUNET_CHAT_File *file)
+{
+ GNUNET_CHAT_VERSION_ASSERT();
+
+ if ((!file) || (!(file->uri)))
+ return NULL;
+
+ return uri_create_file(file->uri);
+}
+
+
enum GNUNET_GenericReturnValue
GNUNET_CHAT_file_is_uploading (const struct GNUNET_CHAT_File *file)
{