Added libconfig to parse config. Something fixed in net
This commit is contained in:
parent
a064540223
commit
c04a0f5d6a
2
Makefile
2
Makefile
@ -1,6 +1,6 @@
|
||||
CC=cc
|
||||
CFLAGS=-c -Wall -Wextra -Werror -fPIC -ggdb -O2 -fno-omit-frame-pointer -fno-strict-aliasing -rdynamic
|
||||
LDFLAGS=-lreadline -lssl -lcrypto -lrt -lz -ggdb -rdynamic
|
||||
LDFLAGS=-lreadline -lssl -lcrypto -lrt -lz -lconfig -ggdb -rdynamic
|
||||
LD=cc
|
||||
|
||||
SRC=main.c loop.c interface.c net.c mtproto-common.c mtproto-client.c queries.c structures.c
|
||||
|
3
loop.c
3
loop.c
@ -43,6 +43,7 @@
|
||||
|
||||
extern char *default_username;
|
||||
extern char *auth_token;
|
||||
extern int test_dc;
|
||||
void set_default_username (const char *s);
|
||||
int default_dc_num;
|
||||
|
||||
@ -188,7 +189,7 @@ void read_dc (int auth_file_fd, int id, unsigned ver) {
|
||||
}
|
||||
|
||||
void empty_auth_file (void) {
|
||||
struct dc *DC = alloc_dc (1, strdup (TG_SERVER), 443);
|
||||
struct dc *DC = alloc_dc (1, strdup (test_dc ? TG_SERVER_TEST : TG_SERVER), 443);
|
||||
assert (DC);
|
||||
dc_working_num = 1;
|
||||
auth_state = 0;
|
||||
|
187
main.c
187
main.c
@ -16,6 +16,7 @@
|
||||
|
||||
Copyright Vitaly Valtman 2013
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
@ -31,6 +32,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <execinfo.h>
|
||||
#include <signal.h>
|
||||
#include <libconfig.h>
|
||||
|
||||
#include "loop.h"
|
||||
#include "mtproto-client.h"
|
||||
@ -38,12 +40,12 @@
|
||||
#define PROGNAME "telegram-client"
|
||||
#define VERSION "0.01"
|
||||
|
||||
#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 ".telegram"
|
||||
#define CONFIG_FILE "config"
|
||||
#define AUTH_KEY_FILE "auth"
|
||||
#define STATE_FILE "state"
|
||||
#define SECRET_CHAT_FILE "secret"
|
||||
#define DOWNLOADS_DIRECTORY "downloads"
|
||||
|
||||
#define CONFIG_DIRECTORY_MODE 0700
|
||||
|
||||
@ -52,9 +54,16 @@
|
||||
"# Feel free to put something here\n"
|
||||
|
||||
char *default_username;
|
||||
int setup_mode;
|
||||
char *auth_token;
|
||||
int msg_num_mode;
|
||||
char *config_filename;
|
||||
char *prefix;
|
||||
int test_dc;
|
||||
char *auth_file_name;
|
||||
char *state_file_name;
|
||||
char *secret_chat_file_name;
|
||||
char *downloads_directory;
|
||||
char *config_directory;
|
||||
|
||||
void set_default_username (const char *s) {
|
||||
if (default_username) {
|
||||
@ -63,11 +72,6 @@ void set_default_username (const char *s) {
|
||||
default_username = strdup (s);
|
||||
}
|
||||
|
||||
void set_setup_mode (void) {
|
||||
setup_mode = 1;
|
||||
}
|
||||
|
||||
|
||||
/* {{{ TERMINAL */
|
||||
tcflag_t old_lflag;
|
||||
cc_t old_vtime;
|
||||
@ -100,7 +104,7 @@ char *get_home_directory (void) {
|
||||
return current_passwd->pw_dir;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return "";
|
||||
}
|
||||
|
||||
char *get_config_directory (void) {
|
||||
@ -115,63 +119,47 @@ char *get_config_directory (void) {
|
||||
}
|
||||
|
||||
char *get_config_filename (void) {
|
||||
char *config_filename;
|
||||
int length = strlen (get_home_directory ()) + strlen (CONFIG_FILE) + 2;
|
||||
|
||||
config_filename = (char *) calloc (length, sizeof (char));
|
||||
sprintf (config_filename, "%s/" CONFIG_FILE, get_home_directory ());
|
||||
return config_filename;
|
||||
}
|
||||
|
||||
char *get_auth_key_filename (void) {
|
||||
char *auth_key_filename;
|
||||
int length = strlen (get_home_directory ()) + strlen (AUTH_KEY_FILE) + 2;
|
||||
|
||||
auth_key_filename = (char *) calloc (length, sizeof (char));
|
||||
sprintf (auth_key_filename, "%s/" AUTH_KEY_FILE, get_home_directory ());
|
||||
return auth_key_filename;
|
||||
return auth_file_name;
|
||||
}
|
||||
|
||||
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;
|
||||
return state_file_name;
|
||||
}
|
||||
|
||||
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;
|
||||
return secret_chat_file_name;
|
||||
}
|
||||
|
||||
char *get_downloads_directory (void)
|
||||
{
|
||||
char *downloads_directory;
|
||||
int length = strlen (get_config_directory ()) + strlen (DOWNLOADS_DIRECTORY) + 2;
|
||||
|
||||
downloads_directory = (char *) calloc (length, sizeof (char));
|
||||
sprintf (downloads_directory, "%s/" DOWNLOADS_DIRECTORY, get_config_directory ());
|
||||
|
||||
char *get_downloads_directory (void) {
|
||||
return downloads_directory;
|
||||
}
|
||||
|
||||
char *make_full_path (char *s) {
|
||||
if (*s != '/') {
|
||||
char *t = s;
|
||||
assert (asprintf (&s, "%s/%s", get_home_directory (), s) >= 0);
|
||||
free (t);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void running_for_first_time (void) {
|
||||
if (config_filename) {
|
||||
return; // Do not create custom config file
|
||||
}
|
||||
assert (asprintf (&config_filename, "%s/%s/%s", get_home_directory (), CONFIG_DIRECTORY, CONFIG_FILE) >= 0);
|
||||
config_filename = make_full_path (config_filename);
|
||||
|
||||
struct stat *config_file_stat = NULL;
|
||||
int config_file_fd;
|
||||
char *config_directory = get_config_directory ();
|
||||
char *config_filename = get_config_filename ();
|
||||
char *downloads_directory = get_downloads_directory ();
|
||||
//char *downloads_directory = get_downloads_directory ();
|
||||
|
||||
if (mkdir (config_directory, CONFIG_DIRECTORY_MODE) != 0) {
|
||||
return;
|
||||
} else {
|
||||
printf ("\nRunning " PROGNAME " for first time!!\n");
|
||||
if (!mkdir (config_directory, CONFIG_DIRECTORY_MODE)) {
|
||||
printf ("[%s] created\n", config_directory);
|
||||
}
|
||||
|
||||
@ -192,21 +180,92 @@ void running_for_first_time (void) {
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
close (config_file_fd);
|
||||
int auth_file_fd = open (get_auth_key_filename (), O_CREAT | O_RDWR, 0600);
|
||||
/*int auth_file_fd = open (get_auth_key_filename (), O_CREAT | O_RDWR, 0600);
|
||||
int x = -1;
|
||||
assert (write (auth_file_fd, &x, 4) == 4);
|
||||
close (auth_file_fd);
|
||||
|
||||
printf ("[%s] created\n", config_filename);
|
||||
printf ("[%s] created\n", config_filename);*/
|
||||
|
||||
/* create downloads directory */
|
||||
if (mkdir (downloads_directory, 0755) !=0) {
|
||||
/*if (mkdir (downloads_directory, 0755) !=0) {
|
||||
perror ("creating download directory");
|
||||
exit (EXIT_FAILURE);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
void parse_config_val (config_t *conf, char **s, char *param_name, const char *default_name, const char *path) {
|
||||
static char buf[1000];
|
||||
int l = 0;
|
||||
if (prefix) {
|
||||
l = strlen (prefix);
|
||||
memcpy (buf, prefix, l);
|
||||
buf[l ++] = '.';
|
||||
}
|
||||
*s = 0;
|
||||
const char *r = 0;
|
||||
strcpy (buf + l, param_name);
|
||||
config_lookup_string (conf, buf, &r);
|
||||
if (r) {
|
||||
if (path) {
|
||||
assert (asprintf (s, "%s/%s", path, r) >= 0);
|
||||
} else {
|
||||
*s = strdup (r);
|
||||
}
|
||||
} else {
|
||||
if (path) {
|
||||
assert (asprintf (s, "%s/%s", path, default_name) >= 0);
|
||||
} else {
|
||||
*s = strdup (default_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set_setup_mode ();
|
||||
void parse_config (void) {
|
||||
config_filename = make_full_path (config_filename);
|
||||
|
||||
config_t conf;
|
||||
config_init (&conf);
|
||||
if (config_read_file (&conf, config_filename) != CONFIG_TRUE) {
|
||||
fprintf (stderr, "Can not read config '%s': error '%s' on the line %d\n", config_filename, config_error_text (&conf), config_error_line (&conf));
|
||||
exit (2);
|
||||
}
|
||||
|
||||
if (!prefix) {
|
||||
config_lookup_string (&conf, "default_profile", (void *)&prefix);
|
||||
}
|
||||
|
||||
static char buf[1000];
|
||||
int l = 0;
|
||||
if (prefix) {
|
||||
l = strlen (prefix);
|
||||
memcpy (buf, prefix, l);
|
||||
buf[l ++] = '.';
|
||||
}
|
||||
test_dc = 0;
|
||||
strcpy (buf + l, "test");
|
||||
config_lookup_bool (&conf, buf, &test_dc);
|
||||
|
||||
if (!msg_num_mode) {
|
||||
strcpy (buf + l, "msg_num");
|
||||
config_lookup_bool (&conf, buf, &msg_num_mode);
|
||||
}
|
||||
|
||||
parse_config_val (&conf, &config_directory, "config_directory", CONFIG_DIRECTORY, 0);
|
||||
config_directory = make_full_path (config_directory);
|
||||
|
||||
parse_config_val (&conf, &auth_file_name, "auth_file", AUTH_KEY_FILE, config_directory);
|
||||
parse_config_val (&conf, &state_file_name, "state_file", STATE_FILE, config_directory);
|
||||
parse_config_val (&conf, &secret_chat_file_name, "secret", SECRET_CHAT_FILE, config_directory);
|
||||
parse_config_val (&conf, &downloads_directory, "downloads", DOWNLOADS_DIRECTORY, config_directory);
|
||||
|
||||
if (!mkdir (config_directory, CONFIG_DIRECTORY_MODE)) {
|
||||
printf ("[%s] created\n", config_directory);
|
||||
}
|
||||
if (!mkdir (downloads_directory, CONFIG_DIRECTORY_MODE)) {
|
||||
printf ("[%s] created\n", downloads_directory);
|
||||
}
|
||||
}
|
||||
|
||||
void inner_main (void) {
|
||||
@ -214,7 +273,7 @@ void inner_main (void) {
|
||||
}
|
||||
|
||||
void usage (void) {
|
||||
printf ("%s [-u username] [-h] [-k public key name]\n", PROGNAME);
|
||||
printf ("%s [-u username] [-h] [-k public key name] [-N] [-v]\n", PROGNAME);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
@ -224,7 +283,7 @@ extern int default_dc_num;
|
||||
|
||||
void args_parse (int argc, char **argv) {
|
||||
int opt = 0;
|
||||
while ((opt = getopt (argc, argv, "u:hk:vn:N")) != -1) {
|
||||
while ((opt = getopt (argc, argv, "u:hk:vn:Nc:p:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'u':
|
||||
set_default_username (optarg);
|
||||
@ -235,12 +294,16 @@ void args_parse (int argc, char **argv) {
|
||||
case 'v':
|
||||
verbosity ++;
|
||||
break;
|
||||
case 'n':
|
||||
default_dc_num = atoi (optarg);
|
||||
break;
|
||||
case 'N':
|
||||
msg_num_mode ++;
|
||||
break;
|
||||
case 'c':
|
||||
config_filename = strdup (optarg);
|
||||
break;
|
||||
case 'p':
|
||||
prefix = strdup (optarg);
|
||||
assert (strlen (prefix) <= 100);
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
usage ();
|
||||
@ -266,18 +329,20 @@ void sig_handler (int signum) {
|
||||
int main (int argc, char **argv) {
|
||||
signal (SIGSEGV, sig_handler);
|
||||
signal (SIGABRT, sig_handler);
|
||||
running_for_first_time ();
|
||||
|
||||
args_parse (argc, argv);
|
||||
printf (
|
||||
"Telegram-client version " TG_VERSION ", Copyright (C) 2013 Vitaly Valtman\n"
|
||||
"Telegram-client comes with ABSOLUTELY NO WARRANTY; for details type `show_license'.\n"
|
||||
"This is free software, and you are welcome to redistribute it\n"
|
||||
"under certain conditions; type `show_license' for details.\n"
|
||||
);
|
||||
running_for_first_time ();
|
||||
parse_config ();
|
||||
|
||||
|
||||
get_terminal_attributes ();
|
||||
|
||||
args_parse (argc, argv);
|
||||
|
||||
inner_main ();
|
||||
|
||||
|
@ -1361,8 +1361,9 @@ int process_rpc_message (struct connection *c UU, struct encrypted_message *enc,
|
||||
double st = get_server_time (DC);
|
||||
assert (this_server_time >= st - 300 && this_server_time <= st + 30);
|
||||
//assert (enc->msg_id > server_last_msg_id && (enc->msg_id & 3) == 1);
|
||||
if (verbosity >= 2) {
|
||||
if (verbosity >= 1) {
|
||||
logprintf ( "received mesage id %016llx\n", enc->msg_id);
|
||||
hexdump_in ();
|
||||
}
|
||||
server_last_msg_id = enc->msg_id;
|
||||
|
||||
@ -1390,10 +1391,10 @@ int rpc_execute (struct connection *c, int op, int len) {
|
||||
if (verbosity) {
|
||||
logprintf ( "outbound rpc connection #%d : received rpc answer %d with %d content bytes\n", c->fd, op, len);
|
||||
}
|
||||
if (op < 0) {
|
||||
/* if (op < 0) {
|
||||
assert (read_in (c, Response, Response_len) == Response_len);
|
||||
return 0;
|
||||
}
|
||||
}*/
|
||||
|
||||
if (len >= MAX_RESPONSE_SIZE/* - 12*/ || len < 0/*12*/) {
|
||||
logprintf ( "answer too long (%d bytes), skipping\n", len);
|
||||
|
5
net.c
5
net.c
@ -146,7 +146,7 @@ int read_in (struct connection *c, void *data, int len) {
|
||||
int x = 0;
|
||||
while (len) {
|
||||
int y = c->in_head->wptr - c->in_head->rptr;
|
||||
if (y >= len) {
|
||||
if (y > len) {
|
||||
memcpy (data, c->in_head->rptr, len);
|
||||
c->in_head->rptr += len;
|
||||
c->in_bytes -= len;
|
||||
@ -185,6 +185,7 @@ int read_in_lookup (struct connection *c, void *data, int len) {
|
||||
memcpy (data, b->rptr, y);
|
||||
x += y;
|
||||
data += y;
|
||||
len -= y;
|
||||
b = b->next;
|
||||
}
|
||||
}
|
||||
@ -405,7 +406,7 @@ void hexdump_buf (struct connection_buffer *b) {
|
||||
|
||||
void try_rpc_read (struct connection *c) {
|
||||
assert (c->in_head);
|
||||
if (verbosity >= 4) {
|
||||
if (verbosity >= 1) {
|
||||
hexdump_buf (c->in_head);
|
||||
}
|
||||
|
||||
|
2
net.h
2
net.h
@ -23,7 +23,7 @@
|
||||
struct dc;
|
||||
#include "queries.h"
|
||||
#define TG_SERVER "173.240.5.1"
|
||||
//#define TG_SERVER "95.142.192.66"
|
||||
#define TG_SERVER_TEST "173.240.5.253"
|
||||
#define TG_APP_HASH "36722c72256a24c1225de00eb6a1ca74"
|
||||
#define TG_APP_ID 2899
|
||||
#define TG_BUILD "203"
|
||||
|
56
queries.c
56
queries.c
@ -1159,6 +1159,9 @@ int send_file_on_answer (struct query *q UU) {
|
||||
}
|
||||
|
||||
int send_encr_file_on_answer (struct query *q UU) {
|
||||
if (prefetch_int () != (int)CODE_messages_sent_encrypted_file) {
|
||||
hexdump_in ();
|
||||
}
|
||||
assert (fetch_int () == (int)CODE_messages_sent_encrypted_file);
|
||||
struct message *M = q->extra;
|
||||
M->date = fetch_int ();
|
||||
@ -1649,40 +1652,9 @@ void load_next_part (struct download *D);
|
||||
int download_on_answer (struct query *q) {
|
||||
assert (fetch_int () == (int)CODE_upload_file);
|
||||
unsigned x = fetch_int ();
|
||||
assert (x);
|
||||
struct download *D = q->extra;
|
||||
if (D->fd == -1) {
|
||||
static char buf[100];
|
||||
sprintf (buf, "%s/tmp_%ld_%ld", get_downloads_directory (), lrand48 (), lrand48 ());
|
||||
int l = strlen (buf);
|
||||
switch (x) {
|
||||
case CODE_storage_file_unknown:
|
||||
break;
|
||||
case CODE_storage_file_jpeg:
|
||||
sprintf (buf + l, "%s", ".jpg");
|
||||
break;
|
||||
case CODE_storage_file_gif:
|
||||
sprintf (buf + l, "%s", ".gif");
|
||||
break;
|
||||
case CODE_storage_file_png:
|
||||
sprintf (buf + l, "%s", ".png");
|
||||
break;
|
||||
case CODE_storage_file_mp3:
|
||||
sprintf (buf + l, "%s", ".mp3");
|
||||
break;
|
||||
case CODE_storage_file_mov:
|
||||
sprintf (buf + l, "%s", ".mov");
|
||||
break;
|
||||
case CODE_storage_file_partial:
|
||||
sprintf (buf + l, "%s", ".part");
|
||||
break;
|
||||
case CODE_storage_file_mp4:
|
||||
sprintf (buf + l, "%s", ".mp4");
|
||||
break;
|
||||
case CODE_storage_file_webp:
|
||||
sprintf (buf + l, "%s", ".webp");
|
||||
break;
|
||||
}
|
||||
D->name = strdup (buf);
|
||||
D->fd = open (D->name, O_CREAT | O_WRONLY, 0640);
|
||||
}
|
||||
fetch_int (); // mtime
|
||||
@ -1719,7 +1691,27 @@ struct query_methods download_methods = {
|
||||
|
||||
void load_next_part (struct download *D) {
|
||||
if (!D->offset) {
|
||||
static char buf[1000];
|
||||
if (!D->id) {
|
||||
sprintf (buf, "%s/download_%lld_%d", get_downloads_directory (), D->volume, D->local_id);
|
||||
} else {
|
||||
sprintf (buf, "%s/download_%lld", get_downloads_directory (), D->id);
|
||||
}
|
||||
D->name = strdup (buf);
|
||||
struct stat st;
|
||||
if (stat (buf, &st) >= 0) {
|
||||
D->offset = st.st_size;
|
||||
if (D->offset >= D->size) {
|
||||
cur_downloading_bytes += D->size;
|
||||
cur_downloaded_bytes += D->offset;
|
||||
rprintf ("Already downloaded\n");
|
||||
end_load (D);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
cur_downloading_bytes += D->size;
|
||||
cur_downloaded_bytes += D->offset;
|
||||
update_prompt ();
|
||||
}
|
||||
clear_packet ();
|
||||
|
Loading…
Reference in New Issue
Block a user