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,101 +130,100 @@ 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);
ProcessRequest *pr = NULL; dc_context_t *mailbox = conn->mailbox;
uintptr_t out = 0; dc_event_emitter_t* emitter = dc_get_event_emitter(mailbox);
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; dc_event_t* event;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
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: // FIXME: do we still need runthreads?
pr = delta_build_process_request(conn); while (conn->runthreads && (event = dc_get_next_event(emitter)) != NULL) {
purple_timeout_add(0, delta_process_fresh_messages, pr); ProcessRequest *pr = NULL;
break; int event_id = dc_event_get_id(event);
case DC_EVENT_INCOMING_MSG: purple_debug_info(PLUGIN_ID, "Event %d received from Delta.\n", event_id);
// 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;
// These are all to do with sending & receiving messages. The real meat of switch (event_id) {
// the event loop case DC_EVENT_SMTP_MESSAGE_SENT:
case DC_EVENT_MSG_DELIVERED: case DC_EVENT_IMAP_CONNECTED:
case DC_EVENT_MSG_READ: case DC_EVENT_SMTP_CONNECTED:
case DC_EVENT_CHAT_MODIFIED: case DC_EVENT_IMAP_MESSAGE_DELETED:
case DC_EVENT_CONTACTS_CHANGED: case DC_EVENT_IMAP_MESSAGE_MOVED:
purple_debug_info(PLUGIN_ID, "Event %d is TODO\n", event); case DC_EVENT_INFO: {
break; char *info = dc_event_get_data2_str(event);
purple_debug_info(PLUGIN_ID, "INFO from Delta: %s\n", info);
case DC_EVENT_CONFIGURE_PROGRESS: dc_str_unref(info);
pr = delta_build_process_request(conn); break;
pr->connection_state = (int)data1; }
purple_timeout_add(0, delta_process_connection_state, pr); case DC_EVENT_WARNING: {
break; char *warn = dc_event_get_data2_str(event);
purple_debug_info(PLUGIN_ID, "WARNING from Delta: %s\n", warn);
case DC_EVENT_HTTP_GET: dc_str_unref(warn);
purple_debug_info(PLUGIN_ID, "HTTP GET requested: %s\n", (char *)data1); break;
}
pthread_mutex_lock(&mutex); case DC_EVENT_ERROR:
case DC_EVENT_ERROR_NETWORK: {
pr = delta_build_process_request(conn); int errcode = dc_event_get_data1_int(event);
g_assert(pr != NULL); char *err = dc_event_get_data2_str(event);
purple_debug_info(PLUGIN_ID, "ERROR from Delta: %d: %s\n", errcode, err);
pr->http_url = (char *)data1; dc_str_unref(err);
pr->http_wait = &cond; break;
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:
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 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.