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: 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) * A mature [Android application](https://github.com/deltachat/deltachat-android)
* An experimental [iOS application](https://github.com/deltachat/deltachat-ios) * An experimental [iOS application](https://github.com/deltachat/deltachat-ios)
* An electron [desktop application](https://github.com/deltachat/deltachat-desktop) * 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 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). 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 ## Build
There are some licensing issues at present, so you shouldn't build this plugin. 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) `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. `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 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 `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. 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 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 void
_transpose_config(dc_context_t *mailbox, PurpleAccount *acct) _transpose_config(dc_context_t *mailbox, PurpleAccount *acct)
{ {
@@ -84,11 +52,6 @@ typedef struct {
// Used by delta_process_connection_state // Used by delta_process_connection_state
int connection_state; int connection_state;
// Used by delta_process_http_get
char *http_url;
char *http_response;
pthread_cond_t *http_wait;
} ProcessRequest; } ProcessRequest;
gboolean gboolean
@@ -151,56 +114,6 @@ delta_process_fresh_messages(void *data)
return FALSE; 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 * ProcessRequest *
delta_build_process_request(DeltaConnectionData *conn) delta_build_process_request(DeltaConnectionData *conn)
{ {
@@ -217,33 +130,52 @@ delta_build_process_request(DeltaConnectionData *conn)
// Do not call any libpurple or delta functions in here, as it is not // 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 // 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 // purple_timeout_add(0, callback, data) to run on the main thread instead
uintptr_t void *
my_delta_handler(dc_context_t* mailbox, int event, uintptr_t data1, uintptr_t data2) delta_event_handler(void *context)
{ {
DeltaConnectionData *conn = (DeltaConnectionData *)dc_get_userdata(mailbox); DeltaConnectionData *conn = (DeltaConnectionData *)context;
g_assert(conn != NULL); g_assert(conn != NULL);
dc_context_t *mailbox = conn->mailbox;
dc_event_emitter_t* emitter = dc_get_event_emitter(mailbox);
dc_event_t* event;
// FIXME: do we still need runthreads?
while (conn->runthreads && (event = dc_get_next_event(emitter)) != NULL) {
ProcessRequest *pr = NULL; ProcessRequest *pr = NULL;
uintptr_t out = 0; int event_id = dc_event_get_id(event);
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
purple_debug_info(PLUGIN_ID, "Event %d received from Delta. Args: %" PRIuPTR ", %" PRIuPTR "\n", event, data1, data2); purple_debug_info(PLUGIN_ID, "Event %d received from Delta.\n", event_id);
switch (event) { switch (event_id) {
case DC_EVENT_SMTP_MESSAGE_SENT: case DC_EVENT_SMTP_MESSAGE_SENT:
case DC_EVENT_IMAP_CONNECTED: case DC_EVENT_IMAP_CONNECTED:
case DC_EVENT_SMTP_CONNECTED: case DC_EVENT_SMTP_CONNECTED:
case DC_EVENT_INFO: case DC_EVENT_IMAP_MESSAGE_DELETED:
purple_debug_info(PLUGIN_ID, "INFO from Delta: %s\n", (char *)data2); 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; break;
case DC_EVENT_WARNING: }
purple_debug_info(PLUGIN_ID, "WARNING from Delta: %s\n", (char *)data2); 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; break;
}
case DC_EVENT_ERROR: case DC_EVENT_ERROR:
case DC_EVENT_ERROR_NETWORK: case DC_EVENT_ERROR_NETWORK: {
purple_debug_info(PLUGIN_ID, "ERROR from Delta: %d: %s\n", (int)data1, (char *)data2); 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_MSGS_CHANGED: case DC_EVENT_MSGS_CHANGED:
pr = delta_build_process_request(conn); pr = delta_build_process_request(conn);
@@ -254,64 +186,44 @@ my_delta_handler(dc_context_t* mailbox, int event, uintptr_t data1, uintptr_t da
// data1 is chat_id, which we don't seem to need yet. // data1 is chat_id, which we don't seem to need yet.
// TODO: It may be needed for group chats // TODO: It may be needed for group chats
pr = delta_build_process_request(conn); pr = delta_build_process_request(conn);
pr->msg_id = (uint32_t)data2; pr->msg_id = (uint32_t)dc_event_get_data2_int(event);
purple_timeout_add(0, delta_process_incoming_message, pr); purple_timeout_add(0, delta_process_incoming_message, pr);
break; break;
// These are all to do with sending & receiving messages. The real meat of // Things left to do
// the event loop 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_DELIVERED:
case DC_EVENT_MSG_READ: case DC_EVENT_MSG_READ:
case DC_EVENT_MSG_FAILED:
case DC_EVENT_CHAT_MODIFIED: case DC_EVENT_CHAT_MODIFIED:
case DC_EVENT_CONTACTS_CHANGED: case DC_EVENT_CONTACTS_CHANGED:
purple_debug_info(PLUGIN_ID, "Event %d is TODO\n", event); 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; break;
case DC_EVENT_CONFIGURE_PROGRESS: case DC_EVENT_CONFIGURE_PROGRESS:
pr = delta_build_process_request(conn); pr = delta_build_process_request(conn);
pr->connection_state = (int)data1; pr->connection_state = dc_event_get_data1_int(event);
purple_timeout_add(0, delta_process_connection_state, pr); purple_timeout_add(0, delta_process_connection_state, pr);
break; 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");
}
break;
case DC_EVENT_GET_STRING:
break;
default: default:
purple_debug_info(PLUGIN_ID, "Unknown Delta event: %d\n", event); purple_debug_info(PLUGIN_ID, "Unknown Delta event: %d\n", event_id);
} }
return out; dc_event_unref(event);
}
dc_event_emitter_unref(emitter);
return NULL;
} }
void void
@@ -336,18 +248,15 @@ delta_connection_free(PurpleConnection *pc)
conn->runthreads = 0; conn->runthreads = 0;
if (conn->mailbox != NULL) { 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 // TODO: correctly handle join failing
if (pthread_join(conn->imap_thread, NULL) != 0) { purple_debug_info(PLUGIN_ID, "Joining event thread\n");
purple_debug_info(PLUGIN_ID, "joining imap thread failed\n"); if (pthread_join(conn->event_thread, NULL) != 0) {
} purple_debug_info(PLUGIN_ID, "joining event thread failed\n");
if (pthread_join(conn->smtp_thread, NULL) != 0) {
purple_debug_info(PLUGIN_ID, "joining smtp thread failed\n");
} }
dc_stop_ongoing_process(conn->mailbox);
dc_close(conn->mailbox);
dc_context_unref(conn->mailbox); dc_context_unref(conn->mailbox);
} }
@@ -366,25 +275,23 @@ delta_connection_start_login(PurpleConnection *pc)
char dbname[1024]; char dbname[1024];
PurpleAccount *acct = pc->account; PurpleAccount *acct = pc->account;
DeltaConnectionData *conn = purple_connection_get_protocol_data(pc); 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( g_snprintf(
dbname, 1024, "%s%sdelta_db-%s", dbname, 1024, "%s%sdelta_db-%s",
purple_user_dir(), G_DIR_SEPARATOR_S, acct->username purple_user_dir(), G_DIR_SEPARATOR_S, acct->username
); );
if (!dc_open(mailbox, dbname, NULL)) { mailbox = dc_context_new(PLUGIN_ID, dbname, NULL);
purple_debug_info(PLUGIN_ID, "dc_open returned false...?\n");
}
conn->mailbox = mailbox; conn->mailbox = mailbox;
_transpose_config(mailbox, acct); _transpose_config(mailbox, acct);
conn->runthreads = 1; conn->runthreads = 1;
pthread_create(&conn->imap_thread, NULL, imap_thread_func, conn); pthread_create(&conn->event_thread, NULL, delta_event_handler, conn);
pthread_create(&conn->smtp_thread, NULL, smtp_thread_func, conn);
dc_configure(mailbox); dc_configure(mailbox);
dc_start_io(mailbox);
dc_maybe_network(mailbox); dc_maybe_network(mailbox);
return; return;

View File

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