Upgrade to deltachat v1.50.0

This commit is contained in:
2021-01-10 15:56:07 +00:00
parent 25af2f6b49
commit 6da5908686
5 changed files with 101 additions and 202 deletions

View File

@@ -7,7 +7,7 @@ email - which is to say, SMTP+IMAP.
Delta has:
* A mature [core library](https://github.com/deltachat/deltachat-core)
* A mature [core library](https://github.com/deltachat/deltachat-core-rust)
* A mature [Android application](https://github.com/deltachat/deltachat-android)
* An experimental [iOS application](https://github.com/deltachat/deltachat-ios)
* An electron [desktop application](https://github.com/deltachat/deltachat-desktop)
@@ -22,22 +22,21 @@ Current status is probably best described as "skunkworks", although connecting
to an account and sending / receiving text messages should work reliably. You
can view specific progress on [the issue board](https://gitlab.com/lupine/purple-plugin-delta/boards).
We currrently build against deltachat v1.50.0. You'll need to build and install
deltachat-ffi separately and ensure that it's available via `pkg-config` for
deltachat to install.
## Build
There are some licensing issues at present, so you shouldn't build this plugin.
`deltachat-core` vendors openssl, unconditionally links it, and is MPL-licensed.
`deltachat-core-rust` uses a vendored openssl 1, unconditionally links it, and
is MPL-licensed.
`purple-plugin-delta` is GPLv3 without the [OpenSSL exemption](https://people.gnome.org/~markmc/openssl-and-the-gpl.html)
`libpurple` itself is GPLv2 without the OpenSSL exemption.
`deltachat-core-rust` may make OpenSSL optional, so linking against that version
would be fine.
Linking against a patched / changed `deltachat-core` that disregards vendored
OpenSSL and uses GnuTLS instead would also be fine.
There's no point to `purple-plugin-delta` adding the OpenSSL exemption because
`libpurple` lacks it, and in any event, it will be unnecessary with the next
major version of OpenSSL. So, time should resolve this for us one way or another.

View File

@@ -14,38 +14,6 @@
void delta_recv_im(DeltaConnectionData *conn, uint32_t msg_id);
void *imap_thread_func(void *delta_connection_data)
{
DeltaConnectionData *conn = (DeltaConnectionData *)delta_connection_data;
g_assert(conn != NULL);
dc_context_t *mailbox = conn->mailbox;
g_assert(mailbox != NULL);
while (conn->runthreads) {
dc_perform_imap_jobs(mailbox);
dc_perform_imap_fetch(mailbox);
dc_perform_imap_idle(mailbox);
}
return NULL;
}
void *smtp_thread_func(void *delta_connection_data)
{
DeltaConnectionData *conn = (DeltaConnectionData *)delta_connection_data;
g_assert(conn != NULL);
dc_context_t *mailbox = conn->mailbox;
g_assert(mailbox != NULL);
while (conn->runthreads) {
dc_perform_smtp_jobs(mailbox);
dc_perform_smtp_idle(mailbox);
}
return NULL;
}
void
_transpose_config(dc_context_t *mailbox, PurpleAccount *acct)
{
@@ -84,11 +52,6 @@ typedef struct {
// Used by delta_process_connection_state
int connection_state;
// Used by delta_process_http_get
char *http_url;
char *http_response;
pthread_cond_t *http_wait;
} ProcessRequest;
gboolean
@@ -151,56 +114,6 @@ delta_process_fresh_messages(void *data)
return FALSE;
}
void
delta_process_http_get_cb(
PurpleUtilFetchUrlData *url_data,
gpointer user_data,
const gchar *url_text,
gsize len,
const gchar *error_message
)
{
UNUSED(url_data);
ProcessRequest *pr = (ProcessRequest *)user_data;
g_assert(pr != NULL);
g_assert(pr->http_wait != NULL);
if (len == 0) {
purple_debug_info("Failed to GET %s: %s\n", pr->http_url, error_message);
pr->http_response = NULL;
goto out;
}
pr->http_response = g_malloc(len);
g_assert(pr->http_response != NULL);
strncpy(pr->http_response, url_text, len);
out:
pthread_cond_broadcast(pr->http_wait);
return;
}
gboolean
delta_process_http_get(void *data)
{
ProcessRequest *pr = (ProcessRequest *)data;
g_assert(pr != NULL);
g_assert(pr->http_url != NULL);
purple_util_fetch_url(
pr->http_url,
TRUE,
NULL,
TRUE,
delta_process_http_get_cb,
data
);
return FALSE;
}
ProcessRequest *
delta_build_process_request(DeltaConnectionData *conn)
{
@@ -217,101 +130,100 @@ delta_build_process_request(DeltaConnectionData *conn)
// Do not call any libpurple or delta functions in here, as it is not
// thread-safe and events may be dispatched from any delta thread. Use
// purple_timeout_add(0, callback, data) to run on the main thread instead
uintptr_t
my_delta_handler(dc_context_t* mailbox, int event, uintptr_t data1, uintptr_t data2)
void *
delta_event_handler(void *context)
{
DeltaConnectionData *conn = (DeltaConnectionData *)dc_get_userdata(mailbox);
DeltaConnectionData *conn = (DeltaConnectionData *)context;
g_assert(conn != NULL);
ProcessRequest *pr = NULL;
uintptr_t out = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
dc_context_t *mailbox = conn->mailbox;
dc_event_emitter_t* emitter = dc_get_event_emitter(mailbox);
dc_event_t* event;
purple_debug_info(PLUGIN_ID, "Event %d received from Delta. Args: %" PRIuPTR ", %" PRIuPTR "\n", event, data1, data2);
switch (event) {
case DC_EVENT_SMTP_MESSAGE_SENT:
case DC_EVENT_IMAP_CONNECTED:
case DC_EVENT_SMTP_CONNECTED:
case DC_EVENT_INFO:
purple_debug_info(PLUGIN_ID, "INFO from Delta: %s\n", (char *)data2);
break;
case DC_EVENT_WARNING:
purple_debug_info(PLUGIN_ID, "WARNING from Delta: %s\n", (char *)data2);
break;
case DC_EVENT_ERROR:
case DC_EVENT_ERROR_NETWORK:
purple_debug_info(PLUGIN_ID, "ERROR from Delta: %d: %s\n", (int)data1, (char *)data2);
break;
case DC_EVENT_MSGS_CHANGED:
pr = delta_build_process_request(conn);
purple_timeout_add(0, delta_process_fresh_messages, pr);
break;
// FIXME: do we still need runthreads?
while (conn->runthreads && (event = dc_get_next_event(emitter)) != NULL) {
ProcessRequest *pr = NULL;
int event_id = dc_event_get_id(event);
case DC_EVENT_INCOMING_MSG:
// data1 is chat_id, which we don't seem to need yet.
// TODO: It may be needed for group chats
pr = delta_build_process_request(conn);
pr->msg_id = (uint32_t)data2;
purple_timeout_add(0, delta_process_incoming_message, pr);
break;
purple_debug_info(PLUGIN_ID, "Event %d received from Delta.\n", event_id);
// These are all to do with sending & receiving messages. The real meat of
// the event loop
case DC_EVENT_MSG_DELIVERED:
case DC_EVENT_MSG_READ:
case DC_EVENT_CHAT_MODIFIED:
case DC_EVENT_CONTACTS_CHANGED:
purple_debug_info(PLUGIN_ID, "Event %d is TODO\n", event);
break;
case DC_EVENT_CONFIGURE_PROGRESS:
pr = delta_build_process_request(conn);
pr->connection_state = (int)data1;
purple_timeout_add(0, delta_process_connection_state, pr);
break;
case DC_EVENT_HTTP_GET:
purple_debug_info(PLUGIN_ID, "HTTP GET requested: %s\n", (char *)data1);
pthread_mutex_lock(&mutex);
pr = delta_build_process_request(conn);
g_assert(pr != NULL);
pr->http_url = (char *)data1;
pr->http_wait = &cond;
purple_timeout_add(0, delta_process_http_get, pr);
// Wait patiently for the HTTP GET to complete
pthread_cond_wait(pr->http_wait, &mutex);
out = (uintptr_t)pr->http_response;
pthread_mutex_unlock(&mutex);
pthread_cond_destroy(&cond);
pthread_mutex_destroy(&mutex);
g_free(pr);
break;
case DC_EVENT_IS_OFFLINE:
if ( conn->pc == NULL || !PURPLE_CONNECTION_IS_CONNECTED(conn->pc) ) {
purple_debug_info(PLUGIN_ID, "Telling Delta we are offline\n");
out = 1;
} else {
purple_debug_info(PLUGIN_ID, "Telling Delta we are online\n");
switch (event_id) {
case DC_EVENT_SMTP_MESSAGE_SENT:
case DC_EVENT_IMAP_CONNECTED:
case DC_EVENT_SMTP_CONNECTED:
case DC_EVENT_IMAP_MESSAGE_DELETED:
case DC_EVENT_IMAP_MESSAGE_MOVED:
case DC_EVENT_INFO: {
char *info = dc_event_get_data2_str(event);
purple_debug_info(PLUGIN_ID, "INFO from Delta: %s\n", info);
dc_str_unref(info);
break;
}
case DC_EVENT_WARNING: {
char *warn = dc_event_get_data2_str(event);
purple_debug_info(PLUGIN_ID, "WARNING from Delta: %s\n", warn);
dc_str_unref(warn);
break;
}
case DC_EVENT_ERROR:
case DC_EVENT_ERROR_NETWORK: {
int errcode = dc_event_get_data1_int(event);
char *err = dc_event_get_data2_str(event);
purple_debug_info(PLUGIN_ID, "ERROR from Delta: %d: %s\n", errcode, err);
dc_str_unref(err);
break;
}
break;
case DC_EVENT_GET_STRING:
break;
default:
purple_debug_info(PLUGIN_ID, "Unknown Delta event: %d\n", event);
}
return out;
case DC_EVENT_MSGS_CHANGED:
pr = delta_build_process_request(conn);
purple_timeout_add(0, delta_process_fresh_messages, pr);
break;
case DC_EVENT_INCOMING_MSG:
// data1 is chat_id, which we don't seem to need yet.
// TODO: It may be needed for group chats
pr = delta_build_process_request(conn);
pr->msg_id = (uint32_t)dc_event_get_data2_int(event);
purple_timeout_add(0, delta_process_incoming_message, pr);
break;
// Things left to do
case DC_EVENT_CHAT_EPHEMERAL_TIMER_MODIFIED:
case DC_EVENT_NEW_BLOB_FILE:
case DC_EVENT_DELETED_BLOB_FILE:
case DC_EVENT_MSG_DELIVERED:
case DC_EVENT_MSG_READ:
case DC_EVENT_MSG_FAILED:
case DC_EVENT_CHAT_MODIFIED:
case DC_EVENT_CONTACTS_CHANGED:
case DC_EVENT_ERROR_SELF_NOT_IN_GROUP:
case DC_EVENT_IMEX_FILE_WRITTEN:
case DC_EVENT_IMEX_PROGRESS:
case DC_EVENT_LOCATION_CHANGED:
case DC_EVENT_MSGS_NOTICED:
case DC_EVENT_SECUREJOIN_INVITER_PROGRESS:
case DC_EVENT_SECUREJOIN_JOINER_PROGRESS:
purple_debug_info(PLUGIN_ID, "Event %d is TODO\n", event_id);
break;
case DC_EVENT_CONFIGURE_PROGRESS:
pr = delta_build_process_request(conn);
pr->connection_state = dc_event_get_data1_int(event);
purple_timeout_add(0, delta_process_connection_state, pr);
break;
default:
purple_debug_info(PLUGIN_ID, "Unknown Delta event: %d\n", event_id);
}
dc_event_unref(event);
}
dc_event_emitter_unref(emitter);
return NULL;
}
void
@@ -336,18 +248,15 @@ delta_connection_free(PurpleConnection *pc)
conn->runthreads = 0;
if (conn->mailbox != NULL) {
dc_maybe_network(conn->mailbox);
dc_stop_ongoing_process(conn->mailbox);
dc_stop_io(conn->mailbox);
// TODO: correctly handle join failing
if (pthread_join(conn->imap_thread, NULL) != 0) {
purple_debug_info(PLUGIN_ID, "joining imap thread failed\n");
}
if (pthread_join(conn->smtp_thread, NULL) != 0) {
purple_debug_info(PLUGIN_ID, "joining smtp thread failed\n");
purple_debug_info(PLUGIN_ID, "Joining event thread\n");
if (pthread_join(conn->event_thread, NULL) != 0) {
purple_debug_info(PLUGIN_ID, "joining event thread failed\n");
}
dc_stop_ongoing_process(conn->mailbox);
dc_close(conn->mailbox);
dc_context_unref(conn->mailbox);
}
@@ -366,25 +275,23 @@ delta_connection_start_login(PurpleConnection *pc)
char dbname[1024];
PurpleAccount *acct = pc->account;
DeltaConnectionData *conn = purple_connection_get_protocol_data(pc);
dc_context_t *mailbox = dc_context_new(my_delta_handler, conn, NULL);
dc_context_t *mailbox = NULL;
g_snprintf(
dbname, 1024, "%s%sdelta_db-%s",
purple_user_dir(), G_DIR_SEPARATOR_S, acct->username
);
if (!dc_open(mailbox, dbname, NULL)) {
purple_debug_info(PLUGIN_ID, "dc_open returned false...?\n");
}
mailbox = dc_context_new(PLUGIN_ID, dbname, NULL);
conn->mailbox = mailbox;
_transpose_config(mailbox, acct);
conn->runthreads = 1;
pthread_create(&conn->imap_thread, NULL, imap_thread_func, conn);
pthread_create(&conn->smtp_thread, NULL, smtp_thread_func, conn);
pthread_create(&conn->event_thread, NULL, delta_event_handler, conn);
dc_configure(mailbox);
dc_start_io(mailbox);
dc_maybe_network(mailbox);
return;

View File

@@ -14,8 +14,7 @@ typedef struct _DeltaConnectionData {
// Set to 0 to convince threads to exit
int runthreads;
pthread_t imap_thread;
pthread_t smtp_thread;
pthread_t event_thread;
} DeltaConnectionData;
#define MAX_DELTA_CONFIGURE 1000

BIN
vendor/deltachat-core-0.41.0.tar.gz (Stored with Git LFS) vendored

Binary file not shown.

BIN
vendor/libetpan-1.8.tar.gz (Stored with Git LFS) vendored

Binary file not shown.