Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
T
tg
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
tg
Commits
c04a0f5d
Commit
c04a0f5d
authored
Nov 08, 2013
by
vysheng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added libconfig to parse config. Something fixed in net
parent
a0645402
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
162 additions
and
102 deletions
+162
-102
Makefile
Makefile
+1
-1
loop.c
loop.c
+2
-1
main.c
main.c
+127
-62
mtproto-client.c
mtproto-client.c
+4
-3
net.c
net.c
+3
-2
net.h
net.h
+1
-1
queries.c
queries.c
+24
-32
No files found.
Makefile
View file @
c04a0f5d
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
...
...
loop.c
View file @
c04a0f5d
...
...
@@ -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
;
...
...
main.c
View file @
c04a0f5d
...
...
@@ -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
(
"
\n
Running "
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:N
c: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
();
...
...
mtproto-client.c
View file @
c04a0f5d
...
...
@@ -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
);
...
...
net.c
View file @
c04a0f5d
...
...
@@ -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
);
}
...
...
net.h
View file @
c04a0f5d
...
...
@@ -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"
...
...
queries.c
View file @
c04a0f5d
...
...
@@ -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
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment