Commit 923845d6 authored by vysheng's avatar vysheng

Partial support for encrypted chats.

parent 9dd3627a
......@@ -48,9 +48,8 @@ long long cur_downloading_bytes;
long long cur_downloaded_bytes;
char *line_ptr;
extern int user_num;
extern int chat_num;
extern peer_t *Peers[];
extern int peer_num;
int is_same_word (const char *s, size_t l, const char *word) {
return s && word && strlen (word) == l && !memcmp (s, word, l);
......@@ -106,10 +105,10 @@ peer_id_t next_token_user (void) {
}
int index = 0;
while (index < user_num + chat_num && (!is_same_word (s, l, Peers[index]->print_name) || get_peer_type (Peers[index]->id) != PEER_USER)) {
while (index < peer_num && (!is_same_word (s, l, Peers[index]->print_name) || get_peer_type (Peers[index]->id) != PEER_USER)) {
index ++;
}
if (index < user_num + chat_num) {
if (index < peer_num) {
return Peers[index]->id;
} else {
return PEER_NOT_FOUND;
......@@ -130,10 +129,10 @@ peer_id_t next_token_chat (void) {
}
int index = 0;
while (index < user_num + chat_num && (!is_same_word (s, l, Peers[index]->print_name) || get_peer_type (Peers[index]->id) != PEER_CHAT)) {
while (index < peer_num && (!is_same_word (s, l, Peers[index]->print_name) || get_peer_type (Peers[index]->id) != PEER_CHAT)) {
index ++;
}
if (index < user_num + chat_num) {
if (index < peer_num) {
return Peers[index]->id;
} else {
return PEER_NOT_FOUND;
......@@ -161,10 +160,10 @@ peer_id_t next_token_peer (void) {
}
int index = 0;
while (index < user_num + chat_num && (!is_same_word (s, l, Peers[index]->print_name))) {
while (index < peer_num && (!is_same_word (s, l, Peers[index]->print_name))) {
index ++;
}
if (index < user_num + chat_num) {
if (index < peer_num) {
return Peers[index]->id;
} else {
return PEER_NOT_FOUND;
......@@ -232,6 +231,7 @@ char *commands[] = {
"rename_contact",
"show_license",
"search",
"mark_read",
0 };
int commands_flags[] = {
......@@ -258,6 +258,7 @@ int commands_flags[] = {
071,
07,
072,
072,
};
int get_complete_mode (void) {
......@@ -297,10 +298,10 @@ int get_complete_mode (void) {
int complete_user_list (int index, const char *text, int len, char **R) {
index ++;
while (index < user_num + chat_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len) || get_peer_type (Peers[index]->id) != PEER_USER)) {
while (index < peer_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len) || get_peer_type (Peers[index]->id) != PEER_USER)) {
index ++;
}
if (index < user_num + chat_num) {
if (index < peer_num) {
*R = strdup (Peers[index]->print_name);
return index;
} else {
......@@ -310,10 +311,10 @@ int complete_user_list (int index, const char *text, int len, char **R) {
int complete_chat_list (int index, const char *text, int len, char **R) {
index ++;
while (index < user_num + chat_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len) || get_peer_type (Peers[index]->id) != PEER_CHAT)) {
while (index < peer_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len) || get_peer_type (Peers[index]->id) != PEER_CHAT)) {
index ++;
}
if (index < user_num + chat_num) {
if (index < peer_num) {
*R = strdup (Peers[index]->print_name);
return index;
} else {
......@@ -323,10 +324,10 @@ int complete_chat_list (int index, const char *text, int len, char **R) {
int complete_user_chat_list (int index, const char *text, int len, char **R) {
index ++;
while (index < user_num + chat_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len))) {
while (index < peer_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len))) {
index ++;
}
if (index < user_num + chat_num) {
if (index < peer_num) {
*R = strdup (Peers[index]->print_name);
return index;
} else {
......@@ -663,6 +664,8 @@ void interpreter (char *line UU) {
"load_photo/load_video/load_video_thumb <msg-seqno> - loads photo/video to download dir\n"
"view_photo/view_video/view_video_thumb <msg-seqno> - loads photo/video to download dir and starts system default viewer\n"
"show_license - prints contents of GPLv2\n"
"search <peer> pattern - searches pattern in messages with peer\n"
"mark_read <peer> - mark read all received messages with peer\n"
);
pop_color ();
rl_on_new_line ();
......@@ -685,6 +688,9 @@ void interpreter (char *line UU) {
RET;
}
do_msg_search (id, from, to, limit, s);
} else if (IS_WORD ("mark_read")) {
GET_PEER;
do_mark_read (id);
}
#undef IS_WORD
#undef RET
......@@ -796,30 +802,6 @@ void logprintf (const char *format, ...) {
}
}
const char *message_media_type_str (struct message_media *M) {
static char buf[1000];
switch (M->type) {
case CODE_message_media_empty:
return "";
case CODE_message_media_photo:
return "[photo]";
case CODE_message_media_video:
return "[video]";
case CODE_message_media_geo:
sprintf (buf, "[geo] https://maps.google.com/maps?ll=%.6lf,%.6lf", M->geo.latitude, M->geo.longitude);
return buf;
case CODE_message_media_contact:
snprintf (buf, 999, "[contact] " COLOR_RED "%s %s" COLOR_NORMAL " %s", M->first_name, M->last_name, M->phone);
return buf;
case CODE_message_media_unsupported:
return "[unsupported]";
default:
assert (0);
return "";
}
}
int color_stack_pos;
const char *color_stack[10];
......@@ -853,6 +835,12 @@ void print_media (struct message_media *M) {
case CODE_message_media_video:
printf ("[video]");
return;
case CODE_decrypted_message_media_photo:
printf ("[photo]");
return;
case CODE_decrypted_message_media_video:
printf ("[video]");
return;
case CODE_message_media_geo:
printf ("[geo] https://maps.google.com/?q=%.6lf,%.6lf", M->geo.latitude, M->geo.longitude);
return;
......@@ -1009,6 +997,9 @@ peer_id_t last_from_id;
peer_id_t last_to_id;
void print_message (struct message *M) {
if (M->flags & (FLAG_EMPTY | FLAG_DELETED)) {
return;
}
if (M->service) {
print_service_message (M);
return;
......@@ -1050,7 +1041,42 @@ void print_message (struct message *M) {
printf (" »»» ");
}
}
} else if (get_peer_type (M->to_id) == PEER_ENCR_CHAT) {
peer_t *P = user_chat_get (M->to_id);
assert (P);
if (M->out) {
push_color (COLOR_GREEN);
if (msg_num_mode) {
printf ("%lld ", M->id);
}
print_date (M->date);
printf (" ");
push_color (COLOR_CYAN);
printf (" %s", P->print_name);
pop_color ();
if (M->unread) {
printf (" <<< ");
} else {
printf (" ««« ");
}
} else {
push_color (COLOR_BLUE);
if (msg_num_mode) {
printf ("%lld ", M->id);
}
print_date (M->date);
push_color (COLOR_CYAN);
printf (" %s", P->print_name);
pop_color ();
if (M->unread) {
printf (" >>> ");
} else {
printf (" »»» ");
}
}
} else {
assert (get_peer_type (M->to_id) == PEER_CHAT);
push_color (COLOR_MAGENTA);
if (msg_num_mode) {
printf ("%lld ", M->id);
......
......@@ -28,7 +28,7 @@
#define COLOR_YELLOW "\033[33;1m"
#define COLOR_BLUE "\033[34;1m"
#define COLOR_MAGENTA "\033[35;1m"
#define COLOR_CYAN "\033[36;1m"
char *get_default_prompt (void);
char *complete_none (const char *text, int state);
......
......@@ -39,6 +39,7 @@
#include "mtproto-common.h"
#include "queries.h"
#include "telegram.h"
#include "loop.h"
extern char *default_username;
extern char *auth_token;
......@@ -59,6 +60,7 @@ void net_loop (int flags, int (*is_end)(void)) {
cc ++;
}
write_state_file ();
int x = connections_make_poll_array (fds + cc, 101 - cc) + cc;
double timer = next_timer_in ();
if (timer > 1000) { timer = 1000; }
......@@ -116,6 +118,8 @@ struct dc *DC_working;
int dc_working_num;
int auth_state;
char *get_auth_key_filename (void);
char *get_state_filename (void);
char *get_secret_chat_filename (void);
int zero[512];
......@@ -231,11 +235,157 @@ void read_auth_file (void) {
}
}
int pts, qts, seq, last_date;
void read_state_file (void) {
int state_file_fd = open (get_state_filename (), O_CREAT | O_RDWR, 0600);
if (state_file_fd < 0) {
return;
}
int version, magic;
if (read (state_file_fd, &magic, 4) < 4) { close (state_file_fd); return; }
if (magic != (int)STATE_FILE_MAGIC) { close (state_file_fd); return; }
if (read (state_file_fd, &version, 4) < 4) { close (state_file_fd); return; }
assert (version >= 0);
int x[4];
if (read (state_file_fd, x, 16) < 16) {
close (state_file_fd);
return;
}
pts = x[0];
qts = x[1];
seq = x[2];
last_date = x[3];
close (state_file_fd);
}
void write_state_file (void) {
static int wseq;
static int wpts;
static int wqts;
static int wdate;
if (wseq >= seq && wpts >= pts && wqts >= qts && wdate >= last_date) { return; }
int state_file_fd = open (get_state_filename (), O_CREAT | O_RDWR, 0600);
if (state_file_fd < 0) {
return;
}
int x[6];
x[0] = STATE_FILE_MAGIC;
x[1] = 0;
x[2] = pts;
x[3] = qts;
x[4] = seq;
x[5] = last_date;
assert (write (state_file_fd, x, 24) == 24);
close (state_file_fd);
wseq = seq; wpts = pts; wqts = qts; wdate = last_date;
}
extern peer_t *Peers[];
extern int peer_num;
void read_secret_chat_file (void) {
int fd = open (get_secret_chat_filename (), O_CREAT | O_RDWR, 0600);
if (fd < 0) {
return;
}
int x[2];
if (read (fd, x, 8) < 8) {
close (fd); return;
}
if (x[0] != (int)SECRET_CHAT_FILE_MAGIC) { close (fd); return; }
int version = x[1];
assert (version >= 0);
int cc;
assert (read (fd, &cc, 4) == 4);
int i;
for (i = 0; i < cc; i++) {
peer_t *P = malloc (sizeof (*P));
memset (P, 0, sizeof (*P));
struct secret_chat *E = &P->encr_chat;
int t;
assert (read (fd, &t, 4) == 4);
P->id = MK_ENCR_CHAT (t);
assert (read (fd, &P->flags, 4) == 4);
assert (read (fd, &t, 4) == 4);
assert (t > 0);
P->print_name = malloc (t + 1);
assert (read (fd, P->print_name, t) == t);
P->print_name[t] = 0;
assert (read (fd, &E->state, 4) == 4);
assert (read (fd, &E->user_id, 4) == 4);
assert (read (fd, &E->admin_id, 4) == 4);
assert (read (fd, &E->ttl, 4) == 4);
assert (read (fd, &E->access_hash, 8) == 8);
if (E->state != sc_waiting) {
E->g_key = malloc (256);
assert (read (fd, E->g_key, 256) == 256);
}
E->nonce = malloc (256);
assert (read (fd, E->nonce, 256) == 256);
assert (read (fd, E->key, 256) == 256);
assert (read (fd, &E->key_fingerprint, 8) == 8);
insert_encrypted_chat (P);
}
close (fd);
}
void write_secret_chat_file (void) {
int fd = open (get_secret_chat_filename (), O_CREAT | O_RDWR, 0600);
if (fd < 0) {
return;
}
int x[2];
x[0] = SECRET_CHAT_FILE_MAGIC;
x[1] = 0;
assert (write (fd, x, 8) == 8);
int i;
int cc = 0;
for (i = 0; i < peer_num; i++) if (get_peer_type (Peers[i]->id) == PEER_ENCR_CHAT) {
if (Peers[i]->encr_chat.state != sc_none && Peers[i]->encr_chat.state != sc_deleted) {
cc ++;
}
}
assert (write (fd, &cc, 4) == 4);
for (i = 0; i < peer_num; i++) if (get_peer_type (Peers[i]->id) == PEER_ENCR_CHAT) {
if (Peers[i]->encr_chat.state != sc_none && Peers[i]->encr_chat.state != sc_deleted) {
int t = get_peer_id (Peers[i]->id);
assert (write (fd, &t, 4) == 4);
t = Peers[i]->flags;
assert (write (fd, &t, 4) == 4);
t = strlen (Peers[i]->print_name);
assert (write (fd, &t, 4) == 4);
assert (write (fd, Peers[i]->print_name, t) == t);
assert (write (fd, &Peers[i]->encr_chat.state, 4) == 4);
assert (write (fd, &Peers[i]->encr_chat.user_id, 4) == 4);
assert (write (fd, &Peers[i]->encr_chat.admin_id, 4) == 4);
assert (write (fd, &Peers[i]->encr_chat.ttl, 4) == 4);
assert (write (fd, &Peers[i]->encr_chat.access_hash, 8) == 8);
if (Peers[i]->encr_chat.state != sc_waiting) {
assert (write (fd, Peers[i]->encr_chat.g_key, 256) == 256);
}
assert (write (fd, Peers[i]->encr_chat.nonce, 256) == 256);
assert (write (fd, Peers[i]->encr_chat.key, 256) == 256);
assert (write (fd, &Peers[i]->encr_chat.key_fingerprint, 8) == 8);
}
}
close (fd);
}
extern int max_chat_size;
int mcs (void) {
return max_chat_size;
}
extern int difference_got;
int dgot (void) {
return !difference_got;
}
int readline_active;
int new_dc_num;
int loop (void) {
......@@ -368,7 +518,11 @@ int loop (void) {
rl_attempted_completion_function = (CPPFunction *) complete_text;
rl_completion_entry_function = complete_none;
do_get_dialog_list_ex ();
read_state_file ();
read_secret_chat_file ();
do_get_difference ();
net_loop (0, dgot);
do_get_dialog_list ();
return main_loop ();
}
......
......@@ -21,4 +21,6 @@
int loop (void);
void net_loop (int flags, int (*end)(void));
void write_auth_file (void);
void write_state_file (void);
void write_secret_chat_file (void);
#endif
......@@ -41,6 +41,8 @@
#define CONFIG_DIRECTORY ".telegram/"
#define CONFIG_FILE CONFIG_DIRECTORY "config"
#define AUTH_KEY_FILE CONFIG_DIRECTORY "auth"
#define STATE_FILE CONFIG_DIRECTORY "state"
#define SECRET_CHAT_FILE CONFIG_DIRECTORY "secret"
#define DOWNLOADS_DIRECTORY "downloads/"
#define CONFIG_DIRECTORY_MODE 0700
......@@ -130,6 +132,24 @@ char *get_auth_key_filename (void) {
return auth_key_filename;
}
char *get_state_filename (void) {
char *state_filename;
int length = strlen (get_home_directory ()) + strlen (STATE_FILE) + 2;
state_filename = (char *) calloc (length, sizeof (char));
sprintf (state_filename, "%s/" STATE_FILE, get_home_directory ());
return state_filename;
}
char *get_secret_chat_filename (void) {
char *secret_chat_filename;
int length = strlen (get_home_directory ()) + strlen (SECRET_CHAT_FILE) + 2;
secret_chat_filename = (char *) calloc (length, sizeof (char));
sprintf (secret_chat_filename, "%s/" SECRET_CHAT_FILE, get_home_directory ());
return secret_chat_filename;
}
char *get_downloads_directory (void)
{
char *downloads_directory;
......
......@@ -637,14 +637,18 @@ int unread_messages;
int our_id;
int pts;
int qts;
int last_date;
int seq;
void fetch_pts (void) {
int p = fetch_int ();
if (p <= pts) { return; }
if (p != pts + 1) {
if (pts) {
logprintf ("Hole in pts p = %d, pts = %d\n", p, pts);
//logprintf ("Hole in pts p = %d, pts = %d\n", p, pts);
// get difference should be here
pts = p;
} else {
pts = p;
}
......@@ -655,10 +659,12 @@ void fetch_pts (void) {
void fetch_qts (void) {
int p = fetch_int ();
if (p <= qts) { return; }
if (p != qts + 1) {
if (qts) {
logprintf ("Hole in qts\n");
//logprintf ("Hole in qts\n");
// get difference should be here
qts = p;
} else {
qts = p;
}
......@@ -667,6 +673,24 @@ void fetch_qts (void) {
}
}
void fetch_date (void) {
int p = fetch_int ();
if (p > last_date) {
last_date = p;
}
}
void fetch_seq (void) {
int x = fetch_int ();
if (x > seq + 1) {
logprintf ("Hole in seq: seq = %d, x = %d\n", seq, x);
//do_get_difference ();
seq = x;
} else if (x >= seq + 1) {
seq = x;
}
}
void work_update (struct connection *c UU, long long msg_id UU) {
unsigned op = fetch_int ();
switch (op) {
......@@ -993,9 +1017,11 @@ void work_update (struct connection *c UU, long long msg_id UU) {
printf (" is now in deleted state\n");
break;
}
/*if (E->state == state_requested) {
pop_color ();
print_end ();
if (E->state == sc_request) {
do_accept_encr_chat_request (E);
}*/
}
fetch_int (); // date
}
break;
......@@ -1041,7 +1067,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
void work_update_short (struct connection *c, long long msg_id) {
assert (fetch_int () == CODE_update_short);
work_update (c, msg_id);
fetch_int (); // date
fetch_date ();
}
void work_updates (struct connection *c, long long msg_id) {
......@@ -1062,9 +1088,8 @@ void work_updates (struct connection *c, long long msg_id) {
for (i = 0; i < n; i++) {
fetch_alloc_chat ();
}
fetch_int (); // date
fetch_int (); // seq
fetch_date (); // date
fetch_seq (); // seq
}
void work_update_short_message (struct connection *c UU, long long msg_id UU) {
......@@ -1073,6 +1098,9 @@ void work_update_short_message (struct connection *c UU, long long msg_id UU) {
unread_messages ++;
print_message (M);
update_prompt ();
if (M->date > last_date) {
last_date = M->date;
}
}
void work_update_short_chat_message (struct connection *c UU, long long msg_id UU) {
......@@ -1081,6 +1109,9 @@ void work_update_short_chat_message (struct connection *c UU, long long msg_id U
unread_messages ++;
print_message (M);
update_prompt ();
if (M->date > last_date) {
last_date = M->date;
}
}
void work_container (struct connection *c, long long msg_id UU) {
......@@ -1211,6 +1242,10 @@ void work_detained_info (struct connection *c UU, long long msg_id UU) {
fetch_int (); // status
}
void work_updates_to_long (struct connection *c UU, long long msg_id UU) {
assert (fetch_int () == (int)CODE_updates_too_long);
do_get_difference ();
}
void rpc_execute_answer (struct connection *c, long long msg_id UU) {
if (verbosity >= 5) {
logprintf ("rpc_execute_answer: fd=%d\n", c->fd);
......@@ -1254,6 +1289,9 @@ void rpc_execute_answer (struct connection *c, long long msg_id UU) {
case CODE_msg_detained_info:
work_detained_info (c, msg_id);
return;
case CODE_updates_too_long:
work_updates_to_long (c, msg_id);
return;
}
logprintf ( "Unknown message: \n");
hexdump_in ();
......
......@@ -23,4 +23,5 @@
void on_start (void);
long long encrypt_send_message (struct connection *c, int *msg, int msg_ints, int useful);
void dc_authorize (struct dc *DC);
void work_update (struct connection *c, long long msg_id);
#endif
......@@ -37,6 +37,9 @@
#include "mtproto-common.h"
#include "interface.h"
int __packet_buffer[PACKET_BUFFER_SIZE], *packet_ptr;
int *packet_buffer = __packet_buffer + 16;
long long rsa_encrypted_chunks, rsa_decrypted_chunks;
BN_CTX *BN_ctx;
......
......@@ -83,6 +83,7 @@
#define MAX_MESSAGE_INTS 1048576
#define MAX_PROTO_MESSAGE_INTS 1048576
#define PACKET_BUFFER_SIZE (16384 * 100 + 16) // temp fix
#pragma pack(push,4)
struct encrypted_message {
// unencrypted header
......@@ -219,8 +220,8 @@ void prng_seed (const char *password_filename, int password_length);
int serialize_bignum (BIGNUM *b, char *buffer, int maxlen);
long long compute_rsa_key_fingerprint (RSA *key);
#define PACKET_BUFFER_SIZE (16384 * 100) // temp fix
int packet_buffer[PACKET_BUFFER_SIZE], *packet_ptr;
extern int *packet_buffer;
extern int *packet_ptr;
static inline void out_ints (int *what, int len) {
assert (packet_ptr + len <= packet_buffer + PACKET_BUFFER_SIZE);
......@@ -262,6 +263,9 @@ static inline void out_bignum (BIGNUM *n) {
extern int *in_ptr, *in_end;
void fetch_pts (void);
void fetch_qts (void);
void fetch_date (void);
void fetch_seq (void);
static inline int prefetch_strlen (void) {
if (in_ptr >= in_end) {
return -1;
......
......@@ -26,7 +26,7 @@ struct dc;
//#define TG_SERVER "95.142.192.66"
#define TG_APP_HASH "36722c72256a24c1225de00eb6a1ca74"
#define TG_APP_ID 2899
#define TG_BUILD "200"
#define TG_BUILD "203"
#define TG_VERSION "0.01-beta"
......@@ -79,6 +79,9 @@ struct dc {
#define DC_SERIALIZED_MAGIC 0x64582faa
#define DC_SERIALIZED_MAGIC_V2 0x94032abb
#define STATE_FILE_MAGIC 0x84217a0d
#define SECRET_CHAT_FILE_MAGIC 0xa9840add
struct dc_serialized {
int magic;
int port;
......
This diff is collapsed.
......@@ -94,5 +94,8 @@ void do_import_auth (int num);
void do_export_auth (int num);
void do_add_contact (const char *phone, int phone_len, const char *first_name, int first_name_len, const char *last_name, int last_name_len, int force);
void do_msg_search (peer_id_t id, int from, int to, int limit, const char *s);
void do_accept_encr_chat_request (struct secret_chat *E);
void do_get_difference (void);
void do_mark_read (peer_id_t id);
#endif
This diff is collapsed.
......@@ -20,7 +20,7 @@
#define __STRUCTURES_H__
#include <assert.h>
typedef struct { int id; } peer_id_t;
typedef struct { int type; int id; } peer_id_t;
#define FLAG_EMPTY 1
#define FLAG_DELETED 2
......@@ -111,6 +111,7 @@ struct user_status {
struct user {
peer_id_t id;
int flags;
struct message *last;
char *print_name;
struct file_location photo_big;
struct file_location photo_small;
......@@ -134,6 +135,7 @@ struct chat_user {
struct chat {
peer_id_t id;
int flags;
struct message *last;
char *print_title;
struct file_location photo_big;
struct file_location photo_small;
......@@ -157,6 +159,7 @@ enum secret_chat_state {
struct secret_chat {
peer_id_t id;
int flags;
struct message *last;
char *print_name;
struct file_location photo_big;
struct file_location photo_small;
......@@ -178,6 +181,7 @@ typedef union peer {
struct {
peer_id_t id;
int flags;
struct message *last;
char *print_name;
struct file_location photo_big;
struct file_location photo_small;
......@@ -237,6 +241,7 @@ struct message_media {
struct message {
struct message *next_use, *prev_use;
struct message *next, *prev;
long long id;
int flags;
peer_id_t fwd_from_id;
......@@ -283,6 +288,7 @@ void update_message_id (struct message *M, long long id);
void message_insert (struct message *M);
void free_photo (struct photo *P);
void fetch_photo (struct photo *P);
void insert_encrypted_chat (peer_t *P);
#define PEER_USER 1
#define PEER_CHAT 2
......@@ -296,55 +302,18 @@ void fetch_photo (struct photo *P);
#define MK_ENCR_CHAT(id) set_peer_id (PEER_ENCR_CHAT,id)
static inline int get_peer_type (peer_id_t id) {
if (id.id > 1000000000) {
return PEER_ENCR_CHAT;
}
if (id.id > 0) {
return PEER_USER;
}
if (id.id < -1000000000) {
return PEER_GEO_CHAT;
}
if (id.id < 0) {
return PEER_CHAT;
}
return PEER_UNKNOWN;
return id.type;
}
static inline int get_peer_id (peer_id_t id) {
switch (get_peer_type (id)) {
case PEER_USER:
return id.id;
case PEER_CHAT:
return -id.id;
case PEER_GEO_CHAT:
return -id.id - 1000000000;
case PEER_ENCR_CHAT:
return id.id - 1000000000;
default:
return 0;
}
return id.id;
}
static inline peer_id_t set_peer_id (int type, int id) {
peer_id_t ID;
switch (type) {
case PEER_USER:
ID.id = id;
return ID;
case PEER_CHAT:
ID.id = -id;
return ID;
case PEER_GEO_CHAT:
ID.id = -id - 1000000000;
return ID;
case PEER_ENCR_CHAT:
ID.id = id + 1000000000;
return ID;
default:
assert (0);
return ID;
}
ID.id = id;
ID.type = type;
return ID;
}
static inline int cmp_peer_id (peer_id_t a, peer_id_t b) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment