Merge branch 'master' into support-secret-chats
Conflicts: Makefile.in telegram-base.c telegram-base.h telegram-purple.c telegram-purple.h
|
@ -15,8 +15,7 @@ OBJ=objs
|
|||
LIB=libs
|
||||
DIR_LIST=${DEP} ${AUTO} ${EXE} ${OBJ} ${LIB} ${DEP}/auto ${OBJ}/auto
|
||||
|
||||
|
||||
PLUGIN_OBJECTS=${OBJ}/tgp-net.o ${OBJ}/tgp-timers.o ${OBJ}/msglog.o ${OBJ}/telegram-base.o ${OBJ}/telegram-purple.o ${OBJ}/tgp-2prpl.o ${OBJ}/lodepng.o
|
||||
PLUGIN_OBJECTS=${OBJ}/tgp-net.o ${OBJ}/tgp-timers.o ${OBJ}/msglog.o ${OBJ}/telegram-base.o ${OBJ}/telegram-purple.o ${OBJ}/tgp-2prpl.o ${OBJ}/tgp-structs.o ${OBJ}/lodepng.o
|
||||
ALL_OBJS=${PLUGIN_OBJECTS}
|
||||
|
||||
.SUFFIXES:
|
||||
|
|
|
@ -18,7 +18,7 @@ When encountering a crash or some other bugs, please report it to us, preferably
|
|||
- Support changing own profile picture
|
||||
- Support adding new contacts
|
||||
- Display service messages
|
||||
|
||||
- Works with libpurple proxy settings
|
||||
|
||||
## Version 0.4
|
||||
|
||||
|
@ -45,7 +45,6 @@ The following features are currently planned and will probably be added in the f
|
|||
- File transfers
|
||||
- Geo-locations
|
||||
- Multiple accounts on one client
|
||||
- Respect libpurple proxy settings (implemented but untested)
|
||||
|
||||
|
||||
## Platform Support
|
||||
|
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 671 B After Width: | Height: | Size: 432 B |
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 943 B |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2 KiB |
12
msglog.c
|
@ -38,15 +38,9 @@
|
|||
#define COLOR_NORMAL ""
|
||||
#endif
|
||||
|
||||
void hexdump (int *in_ptr, int *in_end) {
|
||||
// TODO: figure out how to log hexdumps to purple log
|
||||
int *ptr = in_ptr;
|
||||
while (ptr < in_end) {
|
||||
++ ptr;
|
||||
//printf (" %08x", *(ptr ++));
|
||||
}
|
||||
//printf ("\n");
|
||||
}
|
||||
/*
|
||||
msglog.c: Convenience methods for logging to libpurple log
|
||||
*/
|
||||
|
||||
void log_level_printf (const char* format, va_list ap, int level, char *color) {
|
||||
char buffer[256];
|
||||
|
|
2
msglog.h
|
@ -19,8 +19,6 @@
|
|||
*/
|
||||
#include <stdarg.h>
|
||||
|
||||
void hexdump (int *in_ptr, int *in_end);
|
||||
|
||||
void debug(const char* format, ...);
|
||||
void info(const char* format, ...);
|
||||
void warning(const char* format, ...);
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <telegram-purple.h>
|
||||
#include <msglog.h>
|
||||
#include <tgp-2prpl.h>
|
||||
#include "tgp-structs.h"
|
||||
#include "lodepng.h"
|
||||
|
||||
#define DC_SERIALIZED_MAGIC 0x868aa81d
|
||||
|
@ -164,6 +165,15 @@ void read_dc (struct tgl_state *TLS, int auth_file_fd, int id, unsigned ver) {
|
|||
bl_do_dc_signed (TLS, id);
|
||||
}
|
||||
|
||||
int error_if_val_false (struct tgl_state *TLS, int val, const char *msg) {
|
||||
if (!val) {
|
||||
connection_data *conn = TLS->ev_base;
|
||||
purple_connection_error_reason (conn->gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, msg);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void empty_auth_file (struct tgl_state *TLS) {
|
||||
if (TLS->test_mode) {
|
||||
bl_do_dc_option (TLS, 1, 0, "", strlen (TG_SERVER_TEST_1), TG_SERVER_TEST_1, 443);
|
||||
|
@ -226,8 +236,9 @@ void read_auth_file (struct tgl_state *TLS) {
|
|||
|
||||
void telegram_export_authorization (struct tgl_state *TLS);
|
||||
void export_auth_callback (struct tgl_state *TLS, void *extra, int success) {
|
||||
assert (success);
|
||||
telegram_export_authorization (TLS);
|
||||
if (!error_if_val_false(TLS, success, "Authentication Export failed.")) {
|
||||
telegram_export_authorization (TLS);
|
||||
}
|
||||
}
|
||||
|
||||
void telegram_export_authorization (struct tgl_state *TLS) {
|
||||
|
@ -262,21 +273,21 @@ static void code_auth_receive_result (struct tgl_state *TLS, void *extra, int su
|
|||
|
||||
void request_code_entered (gpointer data, const gchar *code) {
|
||||
struct tgl_state *TLS = data;
|
||||
telegram_conn *conn = TLS->ev_base;
|
||||
connection_data *conn = TLS->ev_base;
|
||||
char const *username = purple_account_get_username(conn->pa);
|
||||
tgl_do_send_code_result (TLS, username, conn->hash, code, code_receive_result, 0) ;
|
||||
}
|
||||
|
||||
static void request_code_canceled (gpointer data) {
|
||||
struct tgl_state *TLS = data;
|
||||
telegram_conn *conn = TLS->ev_base;
|
||||
connection_data *conn = TLS->ev_base;
|
||||
|
||||
purple_connection_error_reason(conn->gc,
|
||||
PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, "registration canceled");
|
||||
}
|
||||
|
||||
static void request_name_code_entered (PurpleConnection* gc, PurpleRequestFields* fields) {
|
||||
telegram_conn *conn = purple_connection_get_protocol_data(gc);
|
||||
connection_data *conn = purple_connection_get_protocol_data(gc);
|
||||
struct tgl_state *TLS = conn->TLS;
|
||||
char const *username = purple_account_get_username(conn->pa);
|
||||
|
||||
|
@ -293,7 +304,7 @@ static void request_name_code_entered (PurpleConnection* gc, PurpleRequestFields
|
|||
|
||||
static void request_code (struct tgl_state *TLS) {
|
||||
debug ("Client is not registered, registering...\n");
|
||||
telegram_conn *conn = TLS->ev_base;
|
||||
connection_data *conn = TLS->ev_base;
|
||||
int compat = purple_account_get_bool (tg_get_acc(TLS), "compat-verification", 0);
|
||||
|
||||
if (compat || ! purple_request_input (conn->gc, "Telegram Code", "Enter Telegram Code",
|
||||
|
@ -315,7 +326,7 @@ static void request_code (struct tgl_state *TLS) {
|
|||
static void request_name_and_code (struct tgl_state *TLS) {
|
||||
debug ("Phone is not registered, registering...\n");
|
||||
|
||||
telegram_conn *conn = TLS->ev_base;
|
||||
connection_data *conn = TLS->ev_base;
|
||||
|
||||
PurpleRequestFields* fields = purple_request_fields_new();
|
||||
PurpleRequestField* field = 0;
|
||||
|
@ -342,14 +353,14 @@ static void request_name_and_code (struct tgl_state *TLS) {
|
|||
}
|
||||
|
||||
static void sign_in_callback (struct tgl_state *TLS, void *extra, int success, int registered, const char *mhash) {
|
||||
assert (success); // TODO proper error handle
|
||||
telegram_conn *conn = TLS->ev_base;
|
||||
conn->hash = strdup (mhash);
|
||||
|
||||
if (registered) {
|
||||
request_code (TLS);
|
||||
} else {
|
||||
request_name_and_code (TLS);
|
||||
connection_data *conn = TLS->ev_base;
|
||||
if (!error_if_val_false (TLS, success, "Invalid or non-existing phone number.")) {
|
||||
conn->hash = strdup (mhash);
|
||||
if (registered) {
|
||||
request_code (TLS);
|
||||
} else {
|
||||
request_name_and_code (TLS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -358,7 +369,7 @@ static void telegram_send_sms (struct tgl_state *TLS) {
|
|||
telegram_export_authorization (TLS);
|
||||
return;
|
||||
}
|
||||
telegram_conn *conn = TLS->ev_base;
|
||||
connection_data *conn = TLS->ev_base;
|
||||
char const *username = purple_account_get_username(conn->pa);
|
||||
tgl_do_send_code (TLS, username, sign_in_callback, 0);
|
||||
}
|
||||
|
@ -395,7 +406,7 @@ void telegram_login (struct tgl_state *TLS) {
|
|||
|
||||
PurpleConversation *chat_show (PurpleConnection *gc, int id) {
|
||||
debug ("show chat");
|
||||
telegram_conn *conn = purple_connection_get_protocol_data(gc);
|
||||
connection_data *conn = purple_connection_get_protocol_data(gc);
|
||||
|
||||
PurpleConversation *convo = purple_find_chat(gc, id);
|
||||
if (! convo) {
|
||||
|
@ -411,17 +422,20 @@ PurpleConversation *chat_show (PurpleConnection *gc, int id) {
|
|||
}
|
||||
|
||||
int chat_add_message (struct tgl_state *TLS, struct tgl_message *M, char *text) {
|
||||
telegram_conn *conn = TLS->ev_base;
|
||||
connection_data *conn = TLS->ev_base;
|
||||
|
||||
if (chat_show (conn->gc, tgl_get_peer_id (M->to_id))) {
|
||||
p2tgl_got_chat_in(TLS, M->to_id, M->from_id, text ? text : M->message,
|
||||
M->service ? PURPLE_MESSAGE_SYSTEM : PURPLE_MESSAGE_RECV, M->date);
|
||||
|
||||
pending_reads_add (conn->pending_reads, M->to_id);
|
||||
if (p2tgl_status_is_present(purple_account_get_active_status(conn->pa))) {
|
||||
pending_reads_send_all (conn->pending_reads, conn->TLS);
|
||||
}
|
||||
return 1;
|
||||
} else {
|
||||
// add message once the chat was initialised
|
||||
struct message_text *mt = malloc (sizeof (*mt));
|
||||
mt->M = M;
|
||||
mt->text = text ? g_strdup (text) : text;
|
||||
struct message_text *mt = message_text_init (M, text);
|
||||
g_queue_push_tail (conn->new_messages, mt);
|
||||
return 0;
|
||||
}
|
||||
|
@ -442,6 +456,9 @@ void chat_add_all_users (PurpleConversation *pc, struct tgl_chat *chat) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function generates a png image to visulize the sha1 key from an encrypted chat.
|
||||
*/
|
||||
int generate_ident_icon (unsigned char* sha1_key)
|
||||
{
|
||||
int colors[4] = {
|
||||
|
@ -490,4 +507,4 @@ int generate_ident_icon (unsigned char* sha1_key)
|
|||
g_free(image);
|
||||
g_free(png);
|
||||
return imgStoreId;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
*/
|
||||
#ifndef __TELEGRAM_BASE_H__
|
||||
#define __TELEGRAM_BASE_H__
|
||||
|
||||
#include "telegram-purple.h"
|
||||
|
||||
void read_state_file (struct tgl_state *TLS);
|
||||
void read_auth_file (struct tgl_state *TLS);
|
||||
void write_auth_file (struct tgl_state *TLS);
|
||||
|
@ -30,4 +33,5 @@ int chat_add_message (struct tgl_state *TLS, struct tgl_message *M, char *text);
|
|||
void chat_add_all_users (PurpleConversation *pc, struct tgl_chat *chat);
|
||||
void request_code_entered (gpointer data, const gchar *code);
|
||||
int generate_ident_icon(unsigned char* sha1_key);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "request.h"
|
||||
|
||||
#include <tgl.h>
|
||||
#include "tgp-structs.h"
|
||||
#include "tgp-2prpl.h"
|
||||
#include "tgp-net.h"
|
||||
#include "tgp-timers.h"
|
||||
|
@ -65,8 +66,8 @@ const char *pk_path = "/etc/telegram-purple/server.pub";
|
|||
void tgprpl_login_on_connected();
|
||||
void on_user_get_info (struct tgl_state *TLS, void *show_info, int success, struct tgl_user *U);
|
||||
|
||||
static telegram_conn *get_conn_from_buddy (PurpleBuddy *buddy) {
|
||||
telegram_conn *c = purple_connection_get_protocol_data (
|
||||
static connection_data *get_conn_from_buddy (PurpleBuddy *buddy) {
|
||||
connection_data *c = purple_connection_get_protocol_data (
|
||||
purple_account_get_connection (purple_buddy_get_account (buddy)));
|
||||
return c;
|
||||
}
|
||||
|
@ -181,12 +182,17 @@ static char *format_service_msg (struct tgl_state *TLS, struct tgl_message *M)
|
|||
|
||||
static int our_msg (struct tgl_state *TLS, struct tgl_message *M) {
|
||||
//return tgl_get_peer_id(M->from_id) == TLS->our_id;
|
||||
//return M->out;
|
||||
return (M->flags & FLAG_SESSION_OUTBOUND) != 0;
|
||||
}
|
||||
|
||||
static int out_msg (struct tgl_state *TLS, struct tgl_message *M) {
|
||||
return M->out;
|
||||
}
|
||||
|
||||
static gboolean queries_timerfunc (gpointer data) {
|
||||
debug ("queries_timerfunc()\n");
|
||||
telegram_conn *conn = data;
|
||||
connection_data *conn = data;
|
||||
|
||||
if (conn->updated) {
|
||||
conn->updated = 0;
|
||||
|
@ -230,25 +236,28 @@ struct tgl_update_callback tgp_callback = {
|
|||
};
|
||||
|
||||
void on_message_load_photo (struct tgl_state *TLS, void *extra, int success, char *filename) {
|
||||
connection_data *conn = TLS->ev_base;
|
||||
|
||||
gchar *data = NULL;
|
||||
size_t len;
|
||||
GError *err = NULL;
|
||||
g_file_get_contents (filename, &data, &len, &err);
|
||||
int imgStoreId = purple_imgstore_add_with_id (g_memdup(data, (guint)len), len, NULL);
|
||||
|
||||
char *image = format_img_full(imgStoreId);
|
||||
used_images_add (conn, imgStoreId);
|
||||
|
||||
char *image = format_img_full (imgStoreId);
|
||||
struct tgl_message *M = extra;
|
||||
switch (tgl_get_peer_type (M->to_id)) {
|
||||
case TGL_PEER_CHAT:
|
||||
debug ("PEER_CHAT\n");
|
||||
if (! our_msg(TLS, M)) {
|
||||
if (!our_msg(TLS, M)) {
|
||||
chat_add_message (TLS, M, image);
|
||||
}
|
||||
break;
|
||||
|
||||
case TGL_PEER_USER:
|
||||
debug ("PEER_USER\n");
|
||||
if (our_msg(TLS, M)) {
|
||||
if (out_msg(TLS, M)) {
|
||||
p2tgl_got_im (TLS, M->to_id, image, PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_IMAGES, M->date);
|
||||
} else {
|
||||
p2tgl_got_im (TLS, M->from_id, image, PURPLE_MESSAGE_RECV | PURPLE_MESSAGE_IMAGES, M->date);
|
||||
|
@ -267,13 +276,13 @@ void on_message_load_photo (struct tgl_state *TLS, void *extra, int success, cha
|
|||
}
|
||||
|
||||
g_free (image);
|
||||
telegram_conn *conn = TLS->ev_base;
|
||||
conn = TLS->ev_base;
|
||||
conn->updated = 1;
|
||||
}
|
||||
|
||||
static void update_message_received (struct tgl_state *TLS, struct tgl_message *M) {
|
||||
debug ("received message\n");
|
||||
telegram_conn *conn = TLS->ev_base;
|
||||
connection_data *conn = TLS->ev_base;
|
||||
conn->updated = 1;
|
||||
|
||||
if (M->service) {
|
||||
|
@ -316,7 +325,7 @@ static void update_message_received (struct tgl_state *TLS, struct tgl_message *
|
|||
switch (tgl_get_peer_type (M->to_id)) {
|
||||
case TGL_PEER_CHAT:
|
||||
debug ("PEER_CHAT\n");
|
||||
if (! our_msg(TLS, M)) {
|
||||
if (!our_msg(TLS, M)) {
|
||||
chat_add_message (TLS, M, text);
|
||||
}
|
||||
break;
|
||||
|
@ -326,8 +335,17 @@ static void update_message_received (struct tgl_state *TLS, struct tgl_message *
|
|||
|
||||
// p2tgl_got_im (TLS, M->to_id, text, PURPLE_MESSAGE_SEND, M->date);
|
||||
// :TODO: figure out how to add messages from different devices to history
|
||||
if (! our_msg(TLS, M)) {
|
||||
p2tgl_got_im (TLS, M->from_id, text, PURPLE_MESSAGE_RECV, M->date);
|
||||
if (!our_msg(TLS, M)) {
|
||||
if (out_msg(TLS, M)) {
|
||||
p2tgl_got_im (TLS, M->to_id, text, PURPLE_MESSAGE_SEND, M->date);
|
||||
} else {
|
||||
p2tgl_got_im (TLS, M->from_id, text, PURPLE_MESSAGE_RECV, M->date);
|
||||
|
||||
pending_reads_add (conn->pending_reads, M->from_id);
|
||||
if (p2tgl_status_is_present(purple_account_get_active_status(conn->pa))) {
|
||||
pending_reads_send_all (conn->pending_reads, conn->TLS);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -362,9 +380,6 @@ static void update_user_handler (struct tgl_state *TLS, struct tgl_user *user, u
|
|||
p2tgl_prpl_got_user_status (TLS, user->id, &user->status);
|
||||
p2tgl_buddy_update (TLS, (tgl_peer_t *)user, flags);
|
||||
}
|
||||
if (flags & (TGL_UPDATE_NAME | TGL_UPDATE_REAL_NAME | TGL_UPDATE_USERNAME) && buddy) {
|
||||
p2tgl_blist_alias_buddy (buddy, user);
|
||||
}
|
||||
if (flags & TGL_UPDATE_PHOTO) {
|
||||
tgl_do_get_user_info (TLS, user->id, 0, on_user_get_info, 0);
|
||||
}
|
||||
|
@ -449,13 +464,15 @@ static void on_userpic_loaded (struct tgl_state *TLS, void *extra, int success,
|
|||
struct tgl_user *U = dld->data;
|
||||
warning ("Can not load userpic for user %s %s\n", U->first_name, U->last_name);
|
||||
}
|
||||
telegram_conn *conn = TLS->ev_base;
|
||||
connection_data *conn = TLS->ev_base;
|
||||
|
||||
gchar *data = NULL;
|
||||
size_t len;
|
||||
GError *err = NULL;
|
||||
g_file_get_contents (filename, &data, &len, &err);
|
||||
|
||||
int imgStoreId = purple_imgstore_add_with_id (g_memdup(data, (guint)len), len, NULL);
|
||||
used_images_add (conn, imgStoreId);
|
||||
|
||||
struct download_desc *dld = extra;
|
||||
struct tgl_user *U = dld->data;
|
||||
|
@ -482,7 +499,7 @@ static void on_userpic_loaded (struct tgl_state *TLS, void *extra, int success,
|
|||
purple_notify_userinfo (conn->gc, who, info, NULL, NULL);
|
||||
g_free (profile_image);
|
||||
}
|
||||
purple_buddy_icons_set_for_user(conn->pa, who, g_memdup(data, (guint)len), len, NULL);
|
||||
purple_buddy_icons_set_for_user(conn->pa, who, data, len, NULL);
|
||||
g_free(who);
|
||||
}
|
||||
|
||||
|
@ -507,7 +524,7 @@ void on_chat_get_info (struct tgl_state *TLS, void *extra, int success, struct t
|
|||
assert (success);
|
||||
|
||||
debug ("on_chat_joined(%d)\n", tgl_get_peer_id (C->id));
|
||||
telegram_conn *conn = TLS->ev_base;
|
||||
connection_data *conn = TLS->ev_base;
|
||||
|
||||
PurpleConversation *conv;
|
||||
if (!(conv = purple_find_chat(conn->gc, tgl_get_peer_id(C->id)))) {
|
||||
|
@ -534,13 +551,9 @@ void on_chat_get_info (struct tgl_state *TLS, void *extra, int success, struct t
|
|||
g_free (name);
|
||||
}
|
||||
|
||||
// This function generates a png image to visulize the sha1 key from an encrypted chat.
|
||||
|
||||
|
||||
|
||||
void on_ready (struct tgl_state *TLS) {
|
||||
debug ("on_ready().\n");
|
||||
telegram_conn *conn = TLS->ev_base;
|
||||
connection_data *conn = TLS->ev_base;
|
||||
|
||||
purple_connection_set_state(conn->gc, PURPLE_CONNECTED);
|
||||
purple_connection_set_display_name(conn->gc, purple_account_get_username(conn->pa));
|
||||
|
@ -585,16 +598,25 @@ static GList *tgprpl_status_types (PurpleAccount * acct) {
|
|||
debug ("tgprpl_status_types()\n");
|
||||
GList *types = NULL;
|
||||
PurpleStatusType *type;
|
||||
type = purple_status_type_new_with_attrs (PURPLE_STATUS_AVAILABLE, NULL, NULL,
|
||||
1, 1, 0, "last online", "last online", purple_value_new (PURPLE_TYPE_STRING), NULL);
|
||||
|
||||
type = purple_status_type_new_full(PURPLE_STATUS_AVAILABLE, NULL, NULL, FALSE, TRUE, FALSE);
|
||||
types = g_list_prepend (types, type);
|
||||
|
||||
type = purple_status_type_new_with_attrs (PURPLE_STATUS_MOBILE, NULL, NULL, 1,
|
||||
1, 0, "last online", "last online", purple_value_new (PURPLE_TYPE_STRING), NULL);
|
||||
type = purple_status_type_new_full(PURPLE_STATUS_MOBILE, NULL, NULL, FALSE, TRUE, FALSE);
|
||||
types = g_list_prepend (types, type);
|
||||
|
||||
type = purple_status_type_new_full(PURPLE_STATUS_OFFLINE, NULL, NULL, FALSE, TRUE, FALSE);
|
||||
types = g_list_prepend (types, type);
|
||||
|
||||
type = purple_status_type_new (PURPLE_STATUS_OFFLINE, NULL, NULL, 1);
|
||||
types = g_list_append (types, type);
|
||||
/*
|
||||
The states below are only registered internally so that we get notified about
|
||||
state changes to away and unavailable. This is useful for deciding when to send
|
||||
No other peer should ever have those states.
|
||||
*/
|
||||
type = purple_status_type_new_full(PURPLE_STATUS_AWAY, NULL, NULL, FALSE, TRUE, FALSE);
|
||||
types = g_list_prepend (types, type);
|
||||
type = purple_status_type_new_full(PURPLE_STATUS_UNAVAILABLE, NULL, NULL, FALSE, TRUE, FALSE);
|
||||
types = g_list_prepend (types, type);
|
||||
|
||||
return g_list_reverse (types);
|
||||
}
|
||||
|
@ -637,12 +659,7 @@ static void tgprpl_login (PurpleAccount * acct) {
|
|||
|
||||
// create handle to store additional info for libpurple in
|
||||
// the new telegram instance
|
||||
telegram_conn *conn = g_new0(telegram_conn, 1);
|
||||
conn->TLS = TLS;
|
||||
conn->gc = gc;
|
||||
conn->pa = acct;
|
||||
conn->new_messages = g_queue_new ();
|
||||
conn->joining_chats = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
|
||||
connection_data *conn = connection_data_init (TLS, gc, acct);
|
||||
purple_connection_set_protocol_data (gc, conn);
|
||||
|
||||
tgl_set_ev_base (TLS, conn);
|
||||
|
@ -659,15 +676,16 @@ static void tgprpl_login (PurpleAccount * acct) {
|
|||
|
||||
static void tgprpl_close (PurpleConnection * gc) {
|
||||
debug ("tgprpl_close()\n");
|
||||
telegram_conn *conn = purple_connection_get_protocol_data(gc);
|
||||
purple_timeout_remove(conn->timer);
|
||||
tgl_free_all (conn->TLS);
|
||||
connection_data *conn = purple_connection_get_protocol_data (gc);
|
||||
purple_timeout_remove (conn->timer);
|
||||
|
||||
connection_data_free (conn);
|
||||
}
|
||||
|
||||
static int tgprpl_send_im (PurpleConnection * gc, const char *who, const char *message, PurpleMessageFlags flags) {
|
||||
debug ("tgprpl_send_im()\n");
|
||||
|
||||
telegram_conn *conn = purple_connection_get_protocol_data(gc);
|
||||
connection_data *conn = purple_connection_get_protocol_data(gc);
|
||||
PurpleAccount *pa = conn->pa;
|
||||
|
||||
// this is part of a workaround to support clients without
|
||||
|
@ -698,7 +716,7 @@ static int tgprpl_send_im (PurpleConnection * gc, const char *who, const char *m
|
|||
static unsigned int tgprpl_send_typing (PurpleConnection * gc, const char *who, PurpleTypingState typing) {
|
||||
debug ("tgprpl_send_typing()\n");
|
||||
int id = atoi (who);
|
||||
telegram_conn *conn = purple_connection_get_protocol_data(gc);
|
||||
connection_data *conn = purple_connection_get_protocol_data(gc);
|
||||
tgl_peer_t *U = tgl_peer_get (conn->TLS, TGL_MK_USER (id));
|
||||
if (U) {
|
||||
if (typing == PURPLE_TYPING) {
|
||||
|
@ -712,41 +730,42 @@ static unsigned int tgprpl_send_typing (PurpleConnection * gc, const char *who,
|
|||
|
||||
static void tgprpl_get_info (PurpleConnection * gc, const char *username) {
|
||||
debug ("tgprpl_get_info()\n");
|
||||
telegram_conn *conn = purple_connection_get_protocol_data(gc);
|
||||
connection_data *conn = purple_connection_get_protocol_data(gc);
|
||||
tgl_peer_id_t u = TGL_MK_USER(atoi(username));
|
||||
tgl_do_get_user_info (conn->TLS, u, 0, on_user_get_info, (void *)1l);
|
||||
}
|
||||
|
||||
static void tgprpl_set_status (PurpleAccount * acct, PurpleStatus * status) {
|
||||
debug ("tgprpl_set_status()\n");
|
||||
debug ("tgprpl_set_status(%s)\n", purple_status_get_name (status));
|
||||
debug ("tgprpl_set_status(currstatus=%s)\n", purple_status_get_name(purple_account_get_active_status(acct)));
|
||||
|
||||
PurpleConnection *gc = purple_account_get_connection(acct);
|
||||
if (!gc) { return; }
|
||||
connection_data *conn = purple_connection_get_protocol_data (gc);
|
||||
|
||||
if (p2tgl_status_is_present(status)) {
|
||||
pending_reads_send_all (conn->pending_reads, conn->TLS);
|
||||
}
|
||||
}
|
||||
|
||||
static void tgprpl_add_buddy (PurpleConnection * gc, PurpleBuddy * buddy, PurpleGroup * group) {
|
||||
telegram_conn *conn = purple_connection_get_protocol_data(gc);
|
||||
connection_data *conn = purple_connection_get_protocol_data(gc);
|
||||
const char* first = buddy->alias ? buddy->alias : "";
|
||||
|
||||
tgl_do_add_contact (conn->TLS, buddy->name, (int)strlen (buddy->name), first, (int)strlen (first), "", 0, 0, on_contact_added, buddy);
|
||||
}
|
||||
|
||||
static void tgprpl_add_buddies (PurpleConnection * gc, GList * buddies, GList * groups) {
|
||||
debug ("tgprpl_add_buddies()\n");
|
||||
}
|
||||
|
||||
static void tgprpl_remove_buddy (PurpleConnection * gc, PurpleBuddy * buddy, PurpleGroup * group) {
|
||||
debug ("tgprpl_remove_buddy()\n");
|
||||
if (!buddy) { return; }
|
||||
|
||||
telegram_conn *conn = purple_connection_get_protocol_data (gc);
|
||||
connection_data *conn = purple_connection_get_protocol_data (gc);
|
||||
struct tgl_user *user = purple_buddy_get_protocol_data (buddy);
|
||||
if (!user) { warning ("cannot remove buddy '%s', no protocol data found\n", buddy->name); return; }
|
||||
|
||||
tgl_do_del_contact (conn->TLS, user->id, NULL, NULL);
|
||||
}
|
||||
|
||||
static void tgprpl_remove_buddies (PurpleConnection * gc, GList * buddies, GList * groups){
|
||||
debug ("tgprpl_remove_buddies()\n");
|
||||
}
|
||||
|
||||
static void tgprpl_add_deny (PurpleConnection * gc, const char *name){
|
||||
debug ("tgprpl_add_deny()\n");
|
||||
}
|
||||
|
@ -758,7 +777,7 @@ static void tgprpl_rem_deny (PurpleConnection * gc, const char *name){
|
|||
static void tgprpl_chat_join (PurpleConnection * gc, GHashTable * data) {
|
||||
debug ("tgprpl_chat_join()\n");
|
||||
|
||||
telegram_conn *conn = purple_connection_get_protocol_data (gc);
|
||||
connection_data *conn = purple_connection_get_protocol_data (gc);
|
||||
const char *groupname = g_hash_table_lookup (data, "subject");
|
||||
|
||||
char *id = g_hash_table_lookup(data, "id");
|
||||
|
@ -795,7 +814,7 @@ static GHashTable *tgprpl_chat_info_deflt (PurpleConnection * gc, const char *ch
|
|||
static void tgprpl_chat_invite (PurpleConnection * gc, int id, const char *message, const char *name) {
|
||||
debug ("tgprpl_chat_invite()\n");
|
||||
|
||||
telegram_conn *conn = purple_connection_get_protocol_data (gc);
|
||||
connection_data *conn = purple_connection_get_protocol_data (gc);
|
||||
tgl_peer_t *chat = tgl_peer_get(conn->TLS, TGL_MK_CHAT (id));
|
||||
tgl_peer_t *user = tgl_peer_get(conn->TLS, TGL_MK_USER (atoi(name)));
|
||||
|
||||
|
@ -809,14 +828,20 @@ static void tgprpl_chat_invite (PurpleConnection * gc, int id, const char *messa
|
|||
|
||||
static int tgprpl_send_chat (PurpleConnection * gc, int id, const char *message, PurpleMessageFlags flags) {
|
||||
debug ("tgprpl_send_chat()\n");
|
||||
telegram_conn *conn = purple_connection_get_protocol_data (gc);
|
||||
connection_data *conn = purple_connection_get_protocol_data (gc);
|
||||
|
||||
gchar *raw = purple_unescape_html(message);
|
||||
tgl_do_send_message (conn->TLS, TGL_MK_CHAT(id), raw, (int)strlen (raw), 0, 0);
|
||||
g_free (raw);
|
||||
|
||||
/* Pidgin won't display the written message if we don't call this, Adium will display it twice
|
||||
if we call it, so we don't do it for the adium Plugin.
|
||||
TODO: there has to be a better way to do this, figure out how.
|
||||
*/
|
||||
#ifndef __ADIUM_
|
||||
p2tgl_got_chat_in(conn->TLS, TGL_MK_CHAT(id), TGL_MK_USER(conn->TLS->our_id), message,
|
||||
PURPLE_MESSAGE_RECV, time(NULL));
|
||||
PURPLE_MESSAGE_RECV, time(NULL));
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -835,7 +860,7 @@ static void tgprpl_convo_closed (PurpleConnection * gc, const char *who){
|
|||
static void tgprpl_set_buddy_icon (PurpleConnection * gc, PurpleStoredImage * img) {
|
||||
debug ("tgprpl_set_buddy_icon()\n");
|
||||
|
||||
telegram_conn *conn = purple_connection_get_protocol_data (gc);
|
||||
connection_data *conn = purple_connection_get_protocol_data (gc);
|
||||
if (purple_imgstore_get_filename (img)) {
|
||||
char* filename = g_strdup_printf ("%s/icons/%s", purple_user_dir(), purple_imgstore_get_filename (img));
|
||||
debug (filename);
|
||||
|
@ -906,9 +931,9 @@ static PurplePluginProtocolInfo prpl_info = {
|
|||
NULL, // set_idle
|
||||
NULL, // change_passwd
|
||||
tgprpl_add_buddy,
|
||||
tgprpl_add_buddies,
|
||||
NULL, // add_buddies
|
||||
tgprpl_remove_buddy,
|
||||
tgprpl_remove_buddies,
|
||||
NULL, // remove_buddies
|
||||
NULL, // add_permit
|
||||
tgprpl_add_deny,
|
||||
NULL, // rem_permit
|
||||
|
@ -964,8 +989,7 @@ static PurplePluginProtocolInfo prpl_info = {
|
|||
static void tgprpl_init (PurplePlugin *plugin) {
|
||||
PurpleAccountOption *opt;
|
||||
|
||||
opt = purple_account_option_bool_new("Compatibility Mode (read SMS code from settings)",
|
||||
"compat-verification", 0);
|
||||
opt = purple_account_option_bool_new("Fallback SMS verification", "compat-verification", 0);
|
||||
prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, opt);
|
||||
|
||||
_telegram_protocol = plugin;
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#define TG_VERSION "0.5"
|
||||
#define TG_BUILD "10"
|
||||
|
||||
#include <glib.h>
|
||||
#include <notify.h>
|
||||
#include <plugin.h>
|
||||
#include <version.h>
|
||||
|
@ -38,28 +37,6 @@
|
|||
#define TGP_APP_HASH "99428c722d0ed59b9cd844e4577cb4bb"
|
||||
#define TGP_APP_ID 16154
|
||||
|
||||
typedef struct {
|
||||
struct tgl_state *TLS;
|
||||
char *hash;
|
||||
PurpleAccount *pa;
|
||||
PurpleConnection *gc;
|
||||
int updated;
|
||||
GQueue *new_messages;
|
||||
GHashTable *joining_chats;
|
||||
guint timer;
|
||||
int in_fallback_chat;
|
||||
} telegram_conn;
|
||||
|
||||
struct download_desc {
|
||||
int type;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct message_text {
|
||||
struct tgl_message *M;
|
||||
char *text;
|
||||
};
|
||||
|
||||
void on_chat_get_info (struct tgl_state *TLS, void *extra, int success, struct tgl_chat *C);
|
||||
void on_ready (struct tgl_state *TLS);
|
||||
extern const char *pk_path;
|
||||
|
|
2
tgl
|
@ -1 +1 @@
|
|||
Subproject commit d78ebeb6c61b63755052ef6d0f08113396173657
|
||||
Subproject commit cebe2822a2620961692ac45b0ea2ee99d396c5fb
|
27
tgp-2prpl.c
|
@ -19,12 +19,17 @@
|
|||
*/
|
||||
#include "telegram-purple.h"
|
||||
#include "tgp-2prpl.h"
|
||||
#include "tgp-structs.h"
|
||||
|
||||
#include <server.h>
|
||||
#include <tgl.h>
|
||||
#include <msglog.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
tgp-2prpl.c: Libpurple functions that can be called with tgl data types
|
||||
*/
|
||||
|
||||
static void sanitize_alias(char *buffer) {
|
||||
size_t len = strlen(buffer);
|
||||
gchar *curr;
|
||||
|
@ -56,11 +61,11 @@ static int user_get_alias (tgl_peer_t *user, char *buffer, int maxlen) {
|
|||
}
|
||||
|
||||
PurpleAccount *tg_get_acc (struct tgl_state *TLS) {
|
||||
return (PurpleAccount *) ((telegram_conn *)TLS->ev_base)->pa;
|
||||
return (PurpleAccount *) ((connection_data *)TLS->ev_base)->pa;
|
||||
}
|
||||
|
||||
PurpleConnection *tg_get_conn (struct tgl_state *TLS) {
|
||||
return (PurpleConnection *) ((telegram_conn *)TLS->ev_base)->gc;
|
||||
return (PurpleConnection *) ((connection_data *)TLS->ev_base)->gc;
|
||||
}
|
||||
|
||||
static char *peer_strdup_id(tgl_peer_id_t user) {
|
||||
|
@ -85,6 +90,12 @@ char *p2tgl_strdup_alias(tgl_peer_t *user) {
|
|||
return g_alias;
|
||||
}
|
||||
|
||||
int p2tgl_status_is_present (PurpleStatus *status)
|
||||
{
|
||||
const char *name = purple_status_get_id (status);
|
||||
return !(strcmp (name, "unavailable") == 0 || strcmp (name, "away") == 0);
|
||||
}
|
||||
|
||||
static PurpleChat *blist_find_chat_by_hasht_cond(PurpleConnection *gc,
|
||||
int (*fn)(GHashTable *hasht, void *data), void *data) {
|
||||
PurpleAccount *account = purple_connection_get_account(gc);
|
||||
|
@ -105,12 +116,16 @@ static PurpleChat *blist_find_chat_by_hasht_cond(PurpleConnection *gc,
|
|||
}
|
||||
|
||||
static int hasht_cmp_id(GHashTable *hasht, void *data) {
|
||||
return !strcmp(g_hash_table_lookup(hasht, "id"), *((char **)data));
|
||||
gpointer id = g_hash_table_lookup(hasht, "id");
|
||||
if (!id || !data) {
|
||||
return 0;
|
||||
}
|
||||
return !strcmp(id, ((char *)data));
|
||||
}
|
||||
|
||||
|
||||
PurpleConversation *p2tgl_got_joined_chat (struct tgl_state *TLS, struct tgl_chat *chat) {
|
||||
telegram_conn *conn = TLS->ev_base;
|
||||
connection_data *conn = TLS->ev_base;
|
||||
gchar *alias = p2tgl_strdup_alias((tgl_peer_t *)chat);
|
||||
|
||||
PurpleConversation *conv = serv_got_joined_chat(conn->gc, tgl_get_peer_id(chat->id), alias);
|
||||
|
@ -181,7 +196,7 @@ PurpleBuddy *p2tgl_buddy_update (struct tgl_state *TLS, tgl_peer_t *user, unsign
|
|||
if (!b) {
|
||||
b = p2tgl_buddy_new (TLS, user);
|
||||
}
|
||||
if (flags & TGL_UPDATE_NAME) {
|
||||
if (flags & (TGL_UPDATE_NAME | TGL_UPDATE_REAL_NAME | TGL_UPDATE_USERNAME)) {
|
||||
debug ("Update username for id%d (name %s %s)\n", tgl_get_peer_id (user->id), user->user.first_name, user->user.last_name);
|
||||
char *alias = p2tgl_strdup_alias (user);
|
||||
purple_blist_alias_buddy(b, alias);
|
||||
|
@ -248,7 +263,7 @@ PurpleChat *p2tgl_chat_new (struct tgl_state *TLS, struct tgl_chat *chat) {
|
|||
|
||||
PurpleChat *p2tgl_chat_find (struct tgl_state *TLS, tgl_peer_id_t id) {
|
||||
char *name = peer_strdup_id(id);
|
||||
PurpleChat *c = blist_find_chat_by_hasht_cond(tg_get_conn(TLS), hasht_cmp_id, &name);
|
||||
PurpleChat *c = blist_find_chat_by_hasht_cond(tg_get_conn(TLS), hasht_cmp_id, name);
|
||||
g_free(name);
|
||||
return c;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ tgl_peer_t *p2tgl_get_peer (tgl_peer_id_t peer);
|
|||
tgl_peer_t *p2tgl_get_peer_by_id (int id);
|
||||
char *p2tgl_strdup_alias(tgl_peer_t *user);
|
||||
|
||||
int p2tgl_status_is_present (PurpleStatus *status);
|
||||
|
||||
PurpleConversation *p2tgl_got_joined_chat (struct tgl_state *TLS, struct tgl_chat *chat);
|
||||
void p2tgl_got_chat_invite (PurpleConnection *gc, tgl_peer_t *chat, tgl_peer_id_t inviter, const char *message);
|
||||
|
|
16
tgp-net.c
|
@ -42,6 +42,7 @@
|
|||
#include <time.h>
|
||||
|
||||
#include "tgp-net.h"
|
||||
#include "tgp-structs.h"
|
||||
#include <tgl.h>
|
||||
#include <tgl-inner.h>
|
||||
|
||||
|
@ -83,6 +84,7 @@ static int ping_alarm (gpointer arg) {
|
|||
|
||||
static void stop_ping_timer (struct connection *c) {
|
||||
purple_timeout_remove (c->ping_ev);
|
||||
c->ping_ev = -1;
|
||||
}
|
||||
|
||||
static void start_ping_timer (struct connection *c) {
|
||||
|
@ -333,7 +335,7 @@ struct connection *tgln_create_connection (struct tgl_state *TLS, const char *ho
|
|||
|
||||
c->conn_timeout = MIN_EXP_TIMEOUT;
|
||||
|
||||
telegram_conn *conn = TLS->ev_base;
|
||||
connection_data *conn = TLS->ev_base;
|
||||
c->prpl_data = purple_proxy_connect (conn->gc, conn->pa, host, port, net_on_connected, c);
|
||||
|
||||
return c;
|
||||
|
@ -346,8 +348,9 @@ static void restart_connection (struct connection *c) {
|
|||
return;
|
||||
}
|
||||
|
||||
telegram_conn *conn = TLS->ev_base;
|
||||
c->prpl_data = purple_proxy_connect (conn->gc, conn->pa, c->ip, c->port, net_on_connected, c);
|
||||
connection_data *conn = TLS->ev_base;
|
||||
purple_connection_error_reason (conn->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, "Lost connection with server");
|
||||
// c->prpl_data = purple_proxy_connect (conn->gc, conn->pa, c->ip, c->port, net_on_connected, c);
|
||||
}
|
||||
|
||||
static void fail_connection (struct connection *c) {
|
||||
|
@ -383,7 +386,7 @@ static void fail_connection (struct connection *c) {
|
|||
c->out_bytes = c->in_bytes = 0;
|
||||
|
||||
if (c->state == conn_ready) {
|
||||
telegram_conn *conn = TLS->ev_base;
|
||||
connection_data *conn = TLS->ev_base;
|
||||
purple_connection_error_reason(conn->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, "connection fail");
|
||||
}
|
||||
c->prpl_data = NULL; // Did not find any destroy code. What should be done here?
|
||||
|
@ -457,7 +460,9 @@ static void try_rpc_read (struct connection *c) {
|
|||
len *= 4;
|
||||
int op;
|
||||
assert (tgln_read_in_lookup (c, &op, 4) == 4);
|
||||
c->methods->execute (TLS, c, op, len);
|
||||
if (c->methods->execute (TLS, c, op, len) < 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -593,6 +598,7 @@ static void tgln_free (struct connection *c) {
|
|||
purple_input_remove (c->write_ev);
|
||||
}
|
||||
|
||||
if (c->fd >= 0) { close (c->fd); }
|
||||
c->fd = -1;
|
||||
}
|
||||
|
||||
|
|
122
tgp-structs.c
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
This file is part of telegram-purple
|
||||
|
||||
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 2 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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
|
||||
Copyright Matthias Jentsch 2014
|
||||
*/
|
||||
|
||||
#include "tgp-structs.h"
|
||||
#include "purple.h"
|
||||
#include "msglog.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <tgl.h>
|
||||
|
||||
/*
|
||||
tgp-structs.c: Structs that are only used internally by the protocol plugin
|
||||
*/
|
||||
|
||||
void pending_reads_free_cb (gpointer data)
|
||||
{
|
||||
free (data);
|
||||
}
|
||||
|
||||
static void pending_reads_cb (struct tgl_state *TLS, void *extra, int success)
|
||||
{
|
||||
debug ("ack state: %d", success);
|
||||
}
|
||||
|
||||
static gint pending_reads_compare (gconstpointer a, gconstpointer b)
|
||||
{
|
||||
return !memcmp ((tgl_peer_id_t *)a, (tgl_peer_id_t *)b, sizeof(tgl_peer_id_t));
|
||||
}
|
||||
|
||||
void pending_reads_send_all (GQueue *queue, struct tgl_state *TLS)
|
||||
{
|
||||
debug ("send all pending ack");
|
||||
|
||||
tgl_peer_id_t *pending;
|
||||
|
||||
while ((pending = (tgl_peer_id_t*) g_queue_pop_head(queue))) {
|
||||
tgl_do_mark_read (TLS, *pending, pending_reads_cb, queue);
|
||||
debug ("tgl_do_mark_read (%d)", pending->id);
|
||||
free (pending);
|
||||
}
|
||||
}
|
||||
|
||||
void pending_reads_add (GQueue *queue, tgl_peer_id_t id)
|
||||
{
|
||||
tgl_peer_id_t *copy = malloc (sizeof(tgl_peer_id_t));
|
||||
*copy = id;
|
||||
if (! g_queue_find_custom (queue, copy, pending_reads_compare)) {
|
||||
g_queue_push_tail (queue, copy);
|
||||
}
|
||||
}
|
||||
|
||||
struct message_text *message_text_init (struct tgl_message *M, gchar *text)
|
||||
{
|
||||
struct message_text *mt = malloc (sizeof (struct message_text));
|
||||
mt->M = M;
|
||||
mt->text = text ? g_strdup (text) : text;
|
||||
return mt;
|
||||
}
|
||||
|
||||
void message_text_free (gpointer data)
|
||||
{
|
||||
struct message_text *mt = (struct message_text*)data;
|
||||
if (mt->text) {
|
||||
g_free (mt->text);
|
||||
}
|
||||
free (mt);
|
||||
}
|
||||
|
||||
static void used_image_free (gpointer data)
|
||||
{
|
||||
int id = GPOINTER_TO_INT(data);
|
||||
purple_imgstore_unref_by_id (id);
|
||||
debug ("used_image: unref %d", id);
|
||||
}
|
||||
|
||||
void used_images_add (connection_data *data, gint imgid)
|
||||
{
|
||||
data->used_images = g_list_append (data->used_images, GINT_TO_POINTER(imgid));
|
||||
debug ("used_image: add %d", imgid);
|
||||
}
|
||||
|
||||
connection_data *connection_data_init (struct tgl_state *TLS, PurpleConnection *gc, PurpleAccount *pa)
|
||||
{
|
||||
connection_data *conn = g_new0 (connection_data, 1);
|
||||
conn->TLS = TLS;
|
||||
conn->gc = gc;
|
||||
conn->pa = pa;
|
||||
conn->new_messages = g_queue_new ();
|
||||
conn->pending_reads = g_queue_new ();
|
||||
conn->joining_chats = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
||||
return conn;
|
||||
}
|
||||
|
||||
void *connection_data_free (connection_data *conn)
|
||||
{
|
||||
purple_timeout_remove(conn->timer);
|
||||
g_queue_free_full (conn->pending_reads, pending_reads_free_cb);
|
||||
g_queue_free_full (conn->new_messages, message_text_free);
|
||||
g_hash_table_destroy (conn->joining_chats);
|
||||
g_list_free_full (conn->used_images, used_image_free);
|
||||
tgl_free_all (conn->TLS);
|
||||
free (conn);
|
||||
return NULL;
|
||||
}
|
||||
|
64
tgp-structs.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
This file is part of telegram-purple
|
||||
|
||||
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 2 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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
|
||||
Copyright Matthias Jentsch 2014
|
||||
*/
|
||||
|
||||
#ifndef __telegram_adium__tgp_data__
|
||||
#define __telegram_adium__tgp_data__
|
||||
|
||||
#include "purple.h"
|
||||
|
||||
#include <tgl.h>
|
||||
#include <glib.h>
|
||||
|
||||
typedef struct {
|
||||
struct tgl_state *TLS;
|
||||
char *hash;
|
||||
PurpleAccount *pa;
|
||||
PurpleConnection *gc;
|
||||
int updated;
|
||||
GQueue *new_messages;
|
||||
GQueue *pending_reads;
|
||||
GList *used_images;
|
||||
GHashTable *joining_chats;
|
||||
guint timer;
|
||||
int in_fallback_chat;
|
||||
} connection_data;
|
||||
|
||||
struct download_desc {
|
||||
int type;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct message_text {
|
||||
struct tgl_message *M;
|
||||
char *text;
|
||||
};
|
||||
|
||||
void pending_reads_send_all (GQueue *queue, struct tgl_state *TLS);
|
||||
void pending_reads_add (GQueue *queue, tgl_peer_id_t id);
|
||||
|
||||
struct message_text *message_text_init (struct tgl_message *M, gchar *text);
|
||||
void message_text_free (gpointer data);
|
||||
|
||||
void used_images_add (connection_data *data, gint imgid);
|
||||
|
||||
void *connection_data_free (connection_data *conn);
|
||||
connection_data *connection_data_init (struct tgl_state *TLS, PurpleConnection *gc, PurpleAccount *pa);
|
||||
|
||||
#endif
|