123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924 |
- /*
- * Email plugin for libpurple
- * Copyright (C) 2017 Alyssa Rosenzweig
- * Copyright (C) 2016 Eion Robb
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #ifdef __GNUC__
- #include <unistd.h>
- #endif
- #include <errno.h>
- #ifdef ENABLE_NLS
- # define GETTEXT_PACKAGE "purple-email"
- # include <glib/gi18n-lib.h>
- # ifdef _WIN32
- # ifdef LOCALEDIR
- # unset LOCALEDIR
- # endif
- # define LOCALEDIR wpurple_locale_dir()
- # endif
- #else
- # define _(a) (a)
- # define N_(a) (a)
- #endif
- #include <glib.h>
- #include "purplecompat.h"
- #include "purple2compat/purple-socket.h"
- #define EMAIL_PLUGIN_ID "prpl-alyssa-mail"
- #ifndef EMAIL_PLUGIN_VERSION
- #define EMAIL_PLUGIN_VERSION "0.1"
- #endif
- #define EMAIL_PLUGIN_WEBSITE "https://notabug.org/alyssa/purple-email"
- #define SMTP_PORT 587
- #define SMTPS_PORT 465
- #define IMAP_PORT 143
- #define IMAPS_PORT 993
- enum IMAPState {
- IMAP_ANONYMOUS = 0,
- IMAP_AUTHENTICATING,
- IMAP_AUTHENTICATED,
- IMAP_SELECT,
- IMAP_IDLING,
- IMAP_FETCHING
- };
- typedef struct {
- PurpleAccount *account;
- PurpleConnection *pc;
- gchar *domain;
- PurpleSocket *imap;
- enum IMAPState imap_state;
- int imap_id;
- } EmailAccount;
- static gboolean
- plugin_load(PurplePlugin *plugin, GError **error)
- {
- return TRUE;
- }
- static gboolean
- plugin_unload(PurplePlugin *plugin, GError **error)
- {
- purple_signals_disconnect_by_handle(plugin);
- return TRUE;
- }
- /* Purple2 Plugin Load Functions */
- #if !PURPLE_VERSION_CHECK(3, 0, 0)
- static gboolean
- libpurple2_plugin_load(PurplePlugin *plugin)
- {
- return plugin_load(plugin, NULL);
- }
- static gboolean
- libpurple2_plugin_unload(PurplePlugin *plugin)
- {
- return plugin_unload(plugin, NULL);
- }
- static GHashTable *
- email_get_account_text_table(PurpleAccount *unused)
- {
- GHashTable *table;
- table = g_hash_table_new(g_str_hash, g_str_equal);
- g_hash_table_insert(table, "login_label", (gpointer) _("Email address..."));
- return table;
- }
- static GList *
- email_chat_info(PurpleConnection *pc)
- {
- GList *m = NULL;
- PurpleProtocolChatEntry *pce;
- pce = g_new0(PurpleProtocolChatEntry, 1);
- pce->label = _("ID");
- pce->identifier = "id";
- m = g_list_append(m, pce);
- pce = g_new0(PurpleProtocolChatEntry, 1);
- pce->label = _("Name");
- pce->identifier = "name";
- m = g_list_append(m, pce);
- return m;
- }
- static GHashTable *
- email_chat_info_defaults(PurpleConnection *pc, const char *chatname)
- {
- GHashTable *defaults = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free);
- return defaults;
- }
- #define COMPONENT_USER 0
- #define COMPONENT_DOMAIN 1
- gchar *
- email_address_component(const gchar *address, int component)
- {
- gchar **components = g_strsplit(address, "@", 2);
- gchar *out = g_strdup(components[component]);
- g_strfreev(components);
- return out;
- }
- void
- email_imap_login(EmailAccount *acc)
- {
- gchar *username = email_address_component(purple_account_get_username(acc->account), COMPONENT_USER);
- gchar *q = g_strdup_printf("a%d LOGIN %s %s\r\n", acc->imap_id++, username, purple_account_get_password(acc->account));
- purple_socket_write(acc->imap, (guchar *) q, strlen(q));
- g_free(q);
- g_free(username);
- acc->imap_state = IMAP_AUTHENTICATING;
- }
- void email_imap_select(EmailAccount *acc, const char *inbox)
- {
- gchar *q = g_strdup_printf("a%d SELECT %s\r\n", acc->imap_id++, inbox);
- purple_socket_write(acc->imap, (guchar *) q, strlen(q));
- g_free(q);
- }
- void email_imap_idle(EmailAccount *acc)
- {
- gchar *q = g_strdup_printf("a%d IDLE\r\n", acc->imap_id++);
- purple_socket_write(acc->imap, (guchar *) q, strlen(q));
- g_free(q);
- }
- void email_imap_fetch(EmailAccount *acc, const gchar *msg)
- {
- gchar *q = g_strdup_printf("a%d FETCH %s (BODY[HEADER] BODY[TEXT])\r\n", acc->imap_id++, msg);
- purple_socket_write(acc->imap, (guchar *) q, strlen(q));
- g_free(q);
- }
- typedef struct {
- gchar *body;
- gchar *sender;
- } IncomingMessage;
- gchar *
- email_parse_section(gchar *fetch, const gchar *section) {
- gchar *start = g_strrstr(fetch, section);
-
- if(!start) {
- return NULL;
- }
- gchar *end;
- int len = g_ascii_strtoull(start + strlen(section) + 2, &end, 10);
- return g_strndup(end + 3, len - 2);
- }
- gboolean
- email_parse_fetch(gchar *fetch, IncomingMessage *msg)
- {
- msg->body = email_parse_section(fetch, "BODY[TEXT]");
-
- if (!msg->body) {
- printf("No body parsed\n");
- return FALSE;
- }
- gchar *headers = email_parse_section(fetch, "BODY[HEADER]");
- if (!headers) {
- printf("No headers\n");
- return FALSE;
- }
- GRegex *from_regex = g_regex_new("(^|\r|\n|\r\n)From: (.*)\r\n", 0, 0, NULL);
- GRegex *brackets = g_regex_new("<(.*)>", 0, 0, NULL);
- GMatchInfo *match;
- if (!g_regex_match(from_regex, headers, 0, &match)) {
- printf("No from\n");
- return FALSE;
- }
-
- gchar *from = g_match_info_fetch(match, 2);
- GMatchInfo *fm;
- if (g_regex_match(brackets, from, 0, &fm)) {
- g_free(from);
- from = g_match_info_fetch(fm, 1);
- g_match_info_free(fm);
- }
- msg->sender = from;
- g_match_info_free(match);
- g_regex_unref(from_regex);
- g_regex_unref(brackets);
- return TRUE;
- }
- void
- email_got_imap_line(EmailAccount *acc, gchar *buffer) {
- if (!buffer || !strlen(buffer))
- return;
- printf("Line: %s\n", buffer);
- if (acc->imap_state == IMAP_ANONYMOUS) {
- /* Handshake received, login */
- email_imap_login(acc);
- } else if (acc->imap_state == IMAP_AUTHENTICATING) {
- /* Login response received */
- gchar **response = g_strsplit(buffer, " ", 3);
- gchar *code = response[1];
- if (!code) {
- printf("Uh oh\n");
- printf("%s\n", buffer);
- return;
- }
- if (purple_strequal(code, "OK")) {
- purple_connection_set_state(acc->pc, PURPLE_CONNECTION_CONNECTED);
- acc->imap_state = IMAP_SELECT;
- email_imap_select(acc, "Inbox");
- } else if (purple_strequal(code, "BAD")) {
- purple_connection_error(acc->pc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Bad username/password"));
- acc->imap_state = IMAP_ANONYMOUS;
- } else {
- /* RIP the spec */
- }
- g_strfreev(response);
- } else if (acc->imap_state == IMAP_SELECT) {
- /* Mailbox selected TODO vet response */
- if (buffer[0] == '*') {
- puts(buffer);
- } else if (buffer[0] == 'a') {
- /* TODO: Is ok? */
- email_imap_idle(acc);
- acc->imap_state = IMAP_IDLING;
- }
- } else if (acc->imap_state == IMAP_IDLING) {
- if (buffer[0] == '*') {
- gchar **words = g_strsplit(buffer, " ", 3);
- if (words[0] && words[1] && words[2] && purple_strequal(words[2], "EXISTS")) {
- gchar *new_message = words[1];
- /* End IDLE to fetch message */
- gchar *q = "DONE\r\n";
- purple_socket_write(acc->imap, (guchar *) q, strlen(q));
- /* and fetch it */
- email_imap_fetch(acc, new_message);
- acc->imap_state = IMAP_FETCHING;
- }
- g_strfreev(words);
- }
- }
- }
- void
- email_got_imap(gpointer user_data, gint fd, PurpleInputCondition condition)
- {
- EmailAccount *acc = user_data;
- PurpleSocket *imap = acc->imap;
- guchar buffer[65536];
- gsize sz = purple_socket_read(imap, buffer, sizeof(buffer) - 1);
- if (sz > 0) {
- buffer[sz] = 0;
-
- if (acc->imap_state == IMAP_FETCHING) {
- /* TODO: Parse message correctly :p */
- IncomingMessage msg;
- if (buffer[0] == '*') {
- if (email_parse_fetch((gchar *) buffer, &msg)) {
- purple_serv_got_im(acc->pc, msg.sender, msg.body, PURPLE_MESSAGE_RECV, time(NULL));
- printf("Incoming: %s from %s\n", msg.body, msg.sender);
- email_imap_idle(acc);
- acc->imap_state = IMAP_IDLING;
- } else {
- printf("Ruh-roh, couldn't parse %s", (gchar *) buffer);
- }
- }
- } else {
- gchar **lines = g_strsplit((gchar *) buffer, "\r\n", 0);
- for (int i = 0; lines[i]; ++i) {
- email_got_imap_line(acc, lines[i]);
- }
- g_strfreev(lines);
- }
- }
- }
- void
- email_imap_connected(PurpleSocket *ps, const gchar *error, gpointer user_data)
- {
- if (error) {
- printf("Error connecting %s\n", error);
- return;
- }
- printf("Connected\n");
- purple_socket_watch(ps, PURPLE_INPUT_READ, email_got_imap, user_data);
- }
- void
- email_login(PurpleAccount *account)
- {
- EmailAccount *da;
- PurpleConnection *pc = purple_account_get_connection(account);
- PurpleConnectionFlags pc_flags;
- if (!strchr(purple_account_get_username(account), '@')) {
- purple_connection_error(pc, PURPLE_CONNECTION_ERROR_INVALID_USERNAME, _("Username needs to be an email address"));
- return;
- }
- pc_flags = purple_connection_get_flags(pc);
- pc_flags |= PURPLE_CONNECTION_FLAG_HTML;
- purple_connection_set_flags(pc, pc_flags);
- da = g_new0(EmailAccount, 1);
- purple_connection_set_protocol_data(pc, da);
- da->account = account;
- da->pc = pc;
- purple_connection_set_state(pc, PURPLE_CONNECTION_CONNECTING);
- /* Do IMAP login */
- printf("Connecting to IMAP...\n");
- da->imap_state = IMAP_ANONYMOUS;
- da->domain = email_address_component(purple_account_get_username(da->account), COMPONENT_DOMAIN);
- da->imap = purple_socket_new(pc);
- purple_socket_set_tls(da->imap, TRUE);
- purple_socket_set_host(da->imap, purple_account_get_string(da->account, "imap_server", da->domain));
- purple_socket_set_port(da->imap, IMAPS_PORT);
- purple_socket_connect(da->imap, email_imap_connected, da);
- }
- static GList *
- email_status_types(PurpleAccount *account)
- {
- GList *types = NULL;
- PurpleStatusType *status;
- status = purple_status_type_new_full(PURPLE_STATUS_AVAILABLE, "set-online", _("Online"), TRUE, TRUE, FALSE);
- types = g_list_append(types, status);
- status = purple_status_type_new_full(PURPLE_STATUS_OFFLINE, "set-offline", _("Offline"), TRUE, TRUE, FALSE);
- types = g_list_append(types, status);
- return types;
- }
- static void
- email_close(PurpleConnection *pc)
- {
- EmailAccount *da = purple_connection_get_protocol_data(pc);
- g_return_if_fail(da != NULL);
- g_free(da);
- }
- /* Hacky SMTP implementation ¯\_(ツ)_/¯ */
- typedef enum {
- SMTP_ANONYMOUS = 0,
- SMTP_HELLO,
- SMTP_AUTH,
- SMTP_FROM,
- SMTP_RCPT,
- SMTP_DATA,
- SMTP_XFER,
- SMTP_QUIT
- } SMTPState;
- typedef struct {
- EmailAccount *account;
- SMTPState state;
- PurpleSocket *socket;
- /* email addresses + aliases */
- gchar *sender;
- gchar *sender_alias;
- gchar *recipient;
- gchar *recipient_alias;
- gchar *subject;
- gchar *body;
- } OutgoingMessage;
- void
- email_got_smtp(gpointer user_data, gint fd, PurpleInputCondition condition)
- {
- OutgoingMessage *msg = user_data;
- guchar buffer[2048];
- gsize sz = purple_socket_read(msg->socket, buffer, sizeof(buffer) - 1);
- if (sz > 0) {
- if (msg->state == SMTP_ANONYMOUS) {
- if (buffer[0] == '2' && buffer[1] == '2' && buffer[2] == '0') {
- /* Greetings, server! */
- gchar *ehlo = g_strdup_printf("EHLO %s\r\n", msg->account->domain); /* TODO */
- purple_socket_write(msg->socket, (guchar *) ehlo, strlen(ehlo));
- msg->state++;
- } else {
- goto error;
- }
- } else if (msg->state == SMTP_HELLO) {
- if (buffer[0] == '2' && buffer[1] == '5' && buffer[2] == '0') {
- /* Authenticate with plain */
- gchar *username = email_address_component(purple_account_get_username(msg->account->account), COMPONENT_USER);
- const gchar *password = purple_account_get_password(msg->account->account);
- size_t sz = strlen(username) + strlen(password) + 2;
- guchar *buffer = g_malloc(sz);
- buffer[0] = '\0';
- memcpy(buffer + 1, (guchar*) username, strlen(username));
- buffer[1 + strlen(username)] = '\0';
- memcpy(buffer + 1 + strlen(username) + 1, (guchar *) password, strlen(password));
- gchar *base64 = g_base64_encode(buffer, sz);
- g_free(buffer);
- g_free(username);
- gchar *cmd = g_strdup_printf("AUTH PLAIN %s\r\n", base64);
- purple_socket_write(msg->socket, (guchar *) cmd, strlen(cmd));
- msg->state++;
- g_free(base64);
- } else {
- goto error;
- }
- } else if (msg->state >= (SMTP_FROM - 1) && msg->state <= (SMTP_DATA - 1)) {
- if (buffer[0] == '2') {
- /* Send the next piece of information */
- msg->state++;
- gchar *resp;
- switch (msg->state) {
- case SMTP_FROM:
- resp = g_strdup_printf("MAIL FROM: <%s>\r\n", msg->sender);
- break;
- case SMTP_RCPT:
- resp = g_strdup_printf("RCPT TO: <%s>\r\n", msg->recipient);
- break;
- case SMTP_DATA:
- resp = g_strdup_printf("DATA\r\n");
- break;
- default:
- resp = g_strdup("QUIT");
- break;
- }
- purple_socket_write(msg->socket, (guchar *) resp, strlen(resp));
- g_free(resp);
- } else {
- goto error;
- }
- } else if (msg->state == SMTP_DATA) {
- if (buffer[0] == '3' && buffer[1] == '5' && buffer[2] == '4') {
- /* TODO: Escape */
- /* TODO: Date */
- /* TODO: Randomise */
- gchar *boundary = "laescuchdabushdetodoslosescuchdabush";
- gchar *plain = purple_markup_strip_html(msg->body);
- gchar *html = msg->body;
- gchar *data = g_strdup_printf(
- "From: %s <%s>\r\n"
- "To: %s <%s>\r\n"
- "Subject: %s\r\n"
- "Content-Type: multipart/alternative; boundary=%s\r\n"
- //"Date: Tue, 15 January 2008 16:02:43 -0500"
- "\r\n"
- "--%s\r\n"
- "Content-Type: text/plain\r\n"
- "\r\n"
- "%s\r\n"
- "--%s\r\n"
- "Content-Type: text/html\r\n"
- "\r\n"
- "%s\r\n"
- "--%s--\r\n"
- ".\r\n",
- msg->sender_alias, msg->sender,
- msg->recipient_alias, msg->recipient,
- msg->subject, boundary,
- boundary, plain,
- boundary, html,
- boundary);
- purple_socket_write(msg->socket, (guchar *) data, strlen(data));
- msg->state++;
- g_free(data);
- g_free(plain);
- } else {
- goto error;
- }
- } else if (msg->state == SMTP_XFER) {
- if (buffer[0] == '2' && buffer[1] == '5' && buffer[2] == '0') {
- gchar *quit = "QUIT\r\n";
- purple_socket_write(msg->socket, (guchar *) quit, strlen(quit));
- msg->state++;
- } else {
- goto error;
- }
- } else if (msg->state == SMTP_QUIT) {
- g_free(msg->sender);
- g_free(msg->sender_alias);
- g_free(msg->recipient_alias);
- g_free(msg->subject);
- g_free(msg->body);
- purple_socket_destroy(msg->socket);
- g_free(msg);
- }
- goto not_err;
- error:
- printf("Error!\n");
- not_err:
- buffer[sz] = 0;
- puts((gchar *) buffer);
- printf("(state %d)\n", msg->state);
- return;
- }
- }
- void
- email_smtp_connected(PurpleSocket *ps, const gchar *error, gpointer user_data)
- {
- if (error) {
- printf("Error SMTP connecting %s\n", error);
- return;
- }
- printf("SMTP Connected\n");
- purple_socket_watch(ps, PURPLE_INPUT_READ, email_got_smtp, user_data);
- }
- void
- email_send_smtp(EmailAccount *account, OutgoingMessage *msg)
- {
- msg->socket = purple_socket_new(account->pc);
- purple_socket_set_tls(msg->socket, TRUE);
- purple_socket_set_host(msg->socket, purple_account_get_string(account->account, "smtp_server", account->domain));
- purple_socket_set_port(msg->socket, SMTPS_PORT);
- purple_socket_connect(msg->socket, email_smtp_connected, msg);
- }
- static int
- email_send_im(PurpleConnection *pc,
- #if PURPLE_VERSION_CHECK(3, 0, 0)
- PurpleMessage *msg)
- {
- const gchar *who = purple_message_get_recipient(msg);
- const gchar *message = purple_message_get_contents(msg);
- #else
- const gchar *who, const gchar *message, PurpleMessageFlags flags)
- {
- #endif
- EmailAccount *da = purple_connection_get_protocol_data(pc);
- OutgoingMessage *outgoing = g_new0(OutgoingMessage, 1);
- outgoing->account = da;
- outgoing->sender = g_strdup(purple_account_get_username(da->account));
- outgoing->recipient = g_strdup(who);
- PurpleBuddy *buddy = purple_blist_find_buddy(da->account, who);
- if (purple_account_get_private_alias(da->account)) {
- outgoing->sender_alias = g_strdup(purple_account_get_private_alias(da->account));
- } else {
- outgoing->sender_alias = g_strdup(who);
- }
- if (buddy && purple_buddy_get_alias(buddy)) {
- outgoing->recipient_alias = g_strdup(purple_buddy_get_alias(buddy));
- } else {
- outgoing->recipient_alias = g_strdup(who);
- }
- outgoing->subject = g_strdup("Pidgin message");
- outgoing->body = g_strdup(message);
- outgoing->state = SMTP_ANONYMOUS;
- email_send_smtp(da, outgoing);
- return 1;
- }
- static GList *
- email_add_account_options(GList *account_options)
- {
- PurpleAccountOption *option;
-
- option = purple_account_option_string_new(_("SMTP server"), "smtp_server", "");
- account_options = g_list_append(account_options, option);
- option = purple_account_option_string_new(_("IMAP server"), "imap_server", "");
- account_options = g_list_append(account_options, option);
- return account_options;
- }
- static const char *
- email_list_icon(PurpleAccount *account, PurpleBuddy *buddy)
- {
- return "email";
- }
- static void
- plugin_init(PurplePlugin *plugin)
- {
- #ifdef ENABLE_NLS
- bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
- bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
- #endif
- PurplePluginInfo *info;
- PurplePluginProtocolInfo *prpl_info = g_new0(PurplePluginProtocolInfo, 1);
- info = plugin->info;
- if (info == NULL) {
- plugin->info = info = g_new0(PurplePluginInfo, 1);
- }
- info->extra_info = prpl_info;
- #if PURPLE_MINOR_VERSION >= 5
- prpl_info->struct_size = sizeof(PurplePluginProtocolInfo);
- #endif
- prpl_info->options = OPT_PROTO_CHAT_TOPIC | OPT_PROTO_SLASH_COMMANDS_NATIVE | OPT_PROTO_UNIQUE_CHATNAME;
- prpl_info->protocol_options = email_add_account_options(prpl_info->protocol_options);
- prpl_info->icon_spec.format = "png,gif,jpeg";
- prpl_info->icon_spec.min_width = 0;
- prpl_info->icon_spec.min_height = 0;
- prpl_info->icon_spec.max_width = 96;
- prpl_info->icon_spec.max_height = 96;
- prpl_info->icon_spec.max_filesize = 0;
- prpl_info->icon_spec.scale_rules = PURPLE_ICON_SCALE_DISPLAY;
- prpl_info->get_account_text_table = email_get_account_text_table;
- prpl_info->status_types = email_status_types;
- prpl_info->list_icon = email_list_icon;
- prpl_info->chat_info = email_chat_info;
- prpl_info->chat_info_defaults = email_chat_info_defaults;
- prpl_info->login = email_login;
- prpl_info->close = email_close;
- prpl_info->send_im = email_send_im;
- // prpl_info->join_chat = email_join_chat;
- // prpl_info->get_chat_name = email_get_chat_name;
- // prpl_info->chat_invite = email_chat_invite;
- // prpl_info->chat_send = email_chat_send;
- // prpl_info->set_chat_topic = email_chat_set_topic;
- // prpl_info->roomlist_get_list = email_roomlist_get_list;
- // prpl_info->roomlist_room_serialize = email_roomlist_serialize;
- }
- static PurplePluginInfo info = {
- PURPLE_PLUGIN_MAGIC,
- /* PURPLE_MAJOR_VERSION,
- PURPLE_MINOR_VERSION,
- */
- 2, 1,
- PURPLE_PLUGIN_PROTOCOL, /* type */
- NULL, /* ui_requirement */
- 0, /* flags */
- NULL, /* dependencies */
- PURPLE_PRIORITY_DEFAULT, /* priority */
- EMAIL_PLUGIN_ID, /* id */
- "Email", /* name */
- EMAIL_PLUGIN_VERSION, /* version */
- "", /* summary */
- "", /* description */
- "Alyssa Rosenzweig <alyssa@rosenzweig.io>", /* author */
- EMAIL_PLUGIN_WEBSITE, /* homepage */
- libpurple2_plugin_load, /* load */
- libpurple2_plugin_unload, /* unload */
- NULL, /* destroy */
- NULL, /* ui_info */
- NULL, /* extra_info */
- NULL, /* prefs_info */
- /*email_actions*/ NULL, /* actions */
- NULL, /* padding */
- NULL,
- NULL,
- NULL
- };
- PURPLE_INIT_PLUGIN(email, plugin_init, info);
- #else
- /* Purple 3 plugin load functions */
- G_MODULE_EXPORT GType email_protocol_get_type(void);
- #define EMAIL_TYPE_PROTOCOL (email_protocol_get_type())
- #define EMAIL_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), EMAIL_TYPE_PROTOCOL, EmailProtocol))
- #define EMAIL_PROTOCOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EMAIL_TYPE_PROTOCOL, EmailProtocolClass))
- #define EMAIL_IS_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), EMAIL_TYPE_PROTOCOL))
- #define EMAIL_IS_PROTOCOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EMAIL_TYPE_PROTOCOL))
- #define EMAIL_PROTOCOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EMAIL_TYPE_PROTOCOL, EmailProtocolClass))
- typedef struct _EmailProtocol {
- PurpleProtocol parent;
- } EmailProtocol;
- typedef struct _EmailProtocolClass {
- PurpleProtocolClass parent_class;
- } EmailProtocolClass;
- static void
- email_protocol_init(PurpleProtocol *prpl_info)
- {
- PurpleProtocol *info = prpl_info;
- info->id = EMAIL_PLUGIN_ID;
- info->name = "Email";
- info->options = OPT_PROTO_CHAT_TOPIC | OPT_PROTO_SLASH_COMMANDS_NATIVE | OPT_PROTO_UNIQUE_CHATNAME;
- info->account_options = email_add_account_options(info->account_options);
- }
- static void
- email_protocol_class_init(PurpleProtocolClass *prpl_info)
- {
- prpl_info->login = email_login;
- prpl_info->close = email_close;
- prpl_info->list_icon = email_list_icon;
- prpl_info->status_type = email_status_types;
- }
- static void
- email_protocol_im_iface_init(PurpleProtocolIMIface *prpl_info)
- {
- prpl_info->send = email_send_im;
- }
- static void
- email_protocol_chat_iface_init(PurpleProtocolChatIface *prpl_info)
- {
- prpl_info->send = email_chat_send;
- prpl_info->info = email_chat_info;
- prpl_info->info_defaults = email_chat_info_defaults;
- // prpl_info->join = email_join_chat;
- // prpl_info->get_name = email_get_chat_name;
- // prpl_info->invite = email_chat_invite;
- // prpl_info->set_topic = email_chat_set_topic;
- }
- static void
- email_protocol_server_iface_init(PurpleProtocolServerIface *prpl_info)
- {
- }
- static void
- email_protocol_client_iface_init(PurpleProtocolClientIface *prpl_info)
- {
- prpl_info->get_account_text_table = email_get_account_text_table;
- // prpl_info->get_actions = email_actions;
- // prpl_info->tooltip_text = email_tooltip_text;
- }
- static void
- email_protocol_privacy_iface_init(PurpleProtocolPrivacyIface *prpl_info)
- {
- // prpl_info->add_deny = email_block_user;
- // prpl_info->rem_deny = email_unblock_user;
- }
- static void
- email_protocol_roomlist_iface_init(PurpleProtocolRoomlistIface *prpl_info)
- {
- // prpl_info->get_list = email_roomlist_get_list;
- // prpl_info->room_serialize = email_roomlist_serialize;
- }
- static PurpleProtocol *email_protocol;
- PURPLE_DEFINE_TYPE_EXTENDED(
- EmailProtocol, email_protocol, PURPLE_TYPE_PROTOCOL, 0,
- PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_IM_IFACE,
- email_protocol_im_iface_init)
- PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_CHAT_IFACE,
- email_protocol_chat_iface_init)
- PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_SERVER_IFACE,
- email_protocol_server_iface_init)
- PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_CLIENT_IFACE,
- email_protocol_client_iface_init)
-
- PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_PRIVACY_IFACE,
- email_protocol_privacy_iface_init)
- PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_ROOMLIST_IFACE,
- email_protocol_roomlist_iface_init)
- );
- static gboolean
- libpurple3_plugin_load(PurplePlugin *plugin, GError **error)
- {
- email_protocol_register_type(plugin);
- email_protocol = purple_protocols_add(EMAIL_TYPE_PROTOCOL, error);
- if (!email_protocol) {
- return FALSE;
- }
- return plugin_load(plugin, error);
- }
- static gboolean
- libpurple3_plugin_unload(PurplePlugin *plugin, GError **error)
- {
- if (!plugin_unload(plugin, error)) {
- return FALSE;
- }
- if (!purple_protocols_remove(email_protocol, error)) {
- return FALSE;
- }
- return TRUE;
- }
- static PurplePluginInfo *
- plugin_query(GError **error)
- {
- #ifdef ENABLE_NLS
- bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
- bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
- #endif
-
- return purple_plugin_info_new(
- "id", EMAIL_PLUGIN_ID,
- "name", "Email",
- "version", EMAIL_PLUGIN_VERSION,
- "category", _("Protocol"),
- "summary", _("Email Protocol Plugins."),
- "description", _("Adds Email protocol support to libpurple."),
- "website", EMAIL_PLUGIN_WEBSITE,
- "abi-version", PURPLE_ABI_VERSION,
- "flags", PURPLE_PLUGIN_INFO_FLAGS_INTERNAL |
- PURPLE_PLUGIN_INFO_FLAGS_AUTO_LOAD,
- NULL);
- }
- PURPLE_PLUGIN_INIT(email, plugin_query, libpurple3_plugin_load, libpurple3_plugin_unload);
- #endif
|