Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
Synchronet
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Main
Synchronet
Commits
f53412f2
Commit
f53412f2
authored
1 year ago
by
Deucе
Browse files
Options
Downloads
Patches
Plain Diff
Add a mutex to protect the client.
parent
eff862f8
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/sftp/sftp.h
+3
-0
3 additions, 0 deletions
src/sftp/sftp.h
src/sftp/sftp_client.c
+117
-76
117 additions, 76 deletions
src/sftp/sftp_client.c
with
120 additions
and
76 deletions
src/sftp/sftp.h
+
3
−
0
View file @
f53412f2
...
...
@@ -100,9 +100,12 @@ typedef struct sftp_client_state {
void
*
cb_data
;
sftp_str_t
err_msg
;
sftp_str_t
err_lang
;
pthread_mutex_t
mtx
;
uint32_t
running
;
uint32_t
id
;
uint32_t
err_id
;
uint32_t
err_code
;
bool
terminating
;
}
*
sftpc_state_t
;
enum
sftp_handle_type
{
...
...
This diff is collapsed.
Click to expand it.
src/sftp/sftp_client.c
+
117
−
76
View file @
f53412f2
...
...
@@ -69,6 +69,9 @@ sftpc_finish(sftpc_state_t state)
assert
(
state
);
if
(
state
==
NULL
)
return
;
pthread_mutex_lock
(
&
state
->
mtx
);
state
->
terminating
=
true
;
pthread_mutex_unlock
(
&
state
->
mtx
);
// TODO: Close all open handles
while
(
!
CloseEvent
(
state
->
recv_event
))
{
assert
(
errno
==
EBUSY
);
...
...
@@ -77,8 +80,16 @@ sftpc_finish(sftpc_state_t state)
SetEvent
(
state
->
recv_event
);
SLEEP
(
1
);
}
pthread_mutex_lock
(
&
state
->
mtx
);
while
(
state
->
running
)
{
pthread_mutex_unlock
(
&
state
->
mtx
);
SLEEP
(
1
);
pthread_mutex_lock
(
&
state
->
mtx
);
}
sftp_free_rx_pkt
(
state
->
rxp
);
sftp_free_tx_pkt
(
state
->
txp
);
pthread_mutex_unlock
(
&
state
->
mtx
);
pthread_mutex_destroy
(
&
state
->
mtx
);
free
(
state
);
}
...
...
@@ -100,6 +111,9 @@ sftpc_begin(bool (*send_cb)(uint8_t *buf, size_t len, void *cb_data), void *cb_d
ret
->
id
=
0
;
ret
->
err_lang
=
NULL
;
ret
->
err_msg
=
NULL
;
ret
->
running
=
0
;
pthread_mutex_init
(
&
ret
->
mtx
,
NULL
);
ret
->
terminating
=
false
;
return
ret
;
}
...
...
@@ -162,8 +176,12 @@ get_result(sftpc_state_t state)
return
false
;
if
(
!
state
->
send_cb
(
txbuf
,
txsz
,
state
->
cb_data
))
return
false
;
if
(
WaitForEvent
(
state
->
recv_event
,
INFINITE
)
!=
WAIT_OBJECT_0
)
pthread_mutex_unlock
(
&
state
->
mtx
);
if
(
WaitForEvent
(
state
->
recv_event
,
INFINITE
)
!=
WAIT_OBJECT_0
)
{
pthread_mutex_lock
(
&
state
->
mtx
);
return
false
;
}
pthread_mutex_lock
(
&
state
->
mtx
);
if
(
state
->
rxp
==
NULL
)
return
false
;
if
(
state
->
rxp
->
type
!=
SSH_FXP_VERSION
)
{
...
...
@@ -192,201 +210,224 @@ handle_error(sftpc_state_t state)
response_handled
(
state
);
}
static
bool
parse_handle
(
sftpc_state_t
state
,
sftp_str_t
*
handle
)
{
assert
(
state
->
rxp
);
if
(
state
->
rxp
==
NULL
)
return
false
;
assert
(
state
->
rxp
->
type
==
SSH_FXP_HANDLE
);
if
(
state
->
rxp
->
type
!=
SSH_FXP_HANDLE
)
return
false
;
assert
(
handle
);
if
(
handle
==
NULL
)
return
false
;
*
handle
=
getstring
(
state
);
if
(
*
handle
==
NULL
)
return
false
;
return
true
;
}
static
bool
enter_function
(
sftpc_state_t
state
)
{
if
(
!
check_state
(
state
))
return
false
;
if
(
pthread_mutex_lock
(
&
state
->
mtx
))
return
false
;
if
(
state
->
terminating
)
{
pthread_mutex_unlock
(
&
state
->
mtx
);
return
false
;
}
state
->
running
++
;
}
static
bool
exit_function
(
sftpc_state_t
state
,
bool
retval
)
{
assert
(
state
->
running
>
0
);
state
->
running
--
;
pthread_mutex_unlock
(
&
state
->
mtx
);
return
retval
;
}
bool
sftpc_init
(
sftpc_state_t
state
)
{
if
(
!
check_state
(
state
))
if
(
!
enter_function
(
state
))
return
false
;
if
(
!
appendheader
(
state
,
SSH_FXP_INIT
))
return
false
;
return
exit_function
(
state
,
false
)
;
if
(
!
append32
(
state
,
SFTP_VERSION
))
return
false
;
return
exit_function
(
state
,
false
)
;
if
(
!
get_result
(
state
))
return
false
;
return
exit_function
(
state
,
false
)
;
if
(
state
->
rxp
->
type
!=
SSH_FXP_VERSION
)
return
false
;
return
exit_function
(
state
,
false
)
;
if
(
get32
(
state
)
!=
SFTP_VERSION
)
{
response_handled
(
state
);
return
false
;
return
exit_function
(
state
,
false
)
;
}
response_handled
(
state
);
state
->
id
=
0
;
return
true
;
return
exit_function
(
state
,
true
)
;
}
bool
sftpc_recv
(
sftpc_state_t
state
,
uint8_t
*
buf
,
uint32_t
sz
)
{
if
(
!
check_state
(
state
))
if
(
!
enter_function
(
state
))
return
false
;
if
(
!
sftp_rx_pkt_append
(
&
state
->
rxp
,
buf
,
sz
))
return
false
;
return
exit_function
(
state
,
false
)
;
if
(
sftp_have_full_pkt
(
state
->
rxp
))
SetEvent
(
state
->
recv_event
);
return
true
;
return
exit_function
(
state
,
true
)
;
}
bool
sftpc_realpath
(
sftpc_state_t
state
,
char
*
path
,
sftp_str_t
*
ret
)
{
if
(
!
check_state
(
state
))
if
(
!
enter_function
(
state
))
return
false
;
assert
(
ret
);
if
(
ret
==
NULL
)
return
false
;
return
exit_function
(
state
,
false
)
;
if
(
*
ret
!=
NULL
)
return
false
;
return
exit_function
(
state
,
false
)
;
if
(
!
appendheader
(
state
,
SSH_FXP_REALPATH
))
return
false
;
return
exit_function
(
state
,
false
)
;
sftp_str_t
pstr
=
sftp_strdup
(
path
);
if
(
!
appendandfreestring
(
state
,
&
pstr
))
return
false
;
return
exit_function
(
state
,
false
)
;
if
(
!
get_result
(
state
))
return
false
;
return
exit_function
(
state
,
false
)
;
if
(
state
->
rxp
->
type
==
SSH_FXP_NAME
)
{
if
(
get32
(
state
)
!=
1
)
{
response_handled
(
state
);
return
false
;
return
exit_function
(
state
,
false
)
;
}
*
ret
=
getstring
(
state
);
response_handled
(
state
);
return
true
;
return
exit_function
(
state
,
true
)
;
}
handle_error
(
state
);
return
false
;
}
static
bool
parse_handle
(
sftpc_state_t
state
,
sftp_str_t
*
handle
)
{
assert
(
state
->
rxp
);
if
(
state
->
rxp
==
NULL
)
return
false
;
assert
(
state
->
rxp
->
type
==
SSH_FXP_HANDLE
);
if
(
state
->
rxp
->
type
!=
SSH_FXP_HANDLE
)
return
false
;
assert
(
handle
);
if
(
handle
==
NULL
)
return
false
;
*
handle
=
getstring
(
state
);
if
(
*
handle
==
NULL
)
return
false
;
return
true
;
return
exit_function
(
state
,
false
);
}
bool
sftpc_open
(
sftpc_state_t
state
,
char
*
path
,
uint32_t
flags
,
sftp_file_attr_t
attr
,
sftp_dirhandle_t
*
handle
)
{
if
(
!
check_state
(
state
))
return
false
;
if
(
!
enter_function
(
state
))
return
exit_function
(
state
,
false
)
;
assert
(
path
);
if
(
path
==
NULL
)
return
false
;
return
exit_function
(
state
,
false
)
;
assert
(
handle
);
if
(
handle
==
NULL
)
return
false
;
return
exit_function
(
state
,
false
)
;
assert
(
!*
handle
);
if
(
*
handle
!=
NULL
)
return
false
;
return
exit_function
(
state
,
false
)
;
if
(
!
appendheader
(
state
,
SSH_FXP_OPEN
))
return
false
;
return
exit_function
(
state
,
false
)
;
sftp_str_t
pstr
=
sftp_strdup
(
path
);
if
(
!
appendandfreestring
(
state
,
&
pstr
))
return
false
;
return
exit_function
(
state
,
false
)
;
if
(
!
append32
(
state
,
flags
))
return
false
;
return
exit_function
(
state
,
false
)
;
sftp_file_attr_t
a
=
attr
;
if
(
a
==
NULL
)
{
a
=
sftp_fattr_alloc
();
if
(
a
==
NULL
)
return
false
;
return
exit_function
(
state
,
false
)
;
}
if
(
!
appendfattr
(
state
,
a
))
{
if
(
a
!=
attr
)
sftp_fattr_free
(
a
);
return
false
;
return
exit_function
(
state
,
false
)
;
}
if
(
a
!=
attr
)
sftp_fattr_free
(
a
);
if
(
!
get_result
(
state
))
return
false
;
return
exit_function
(
state
,
false
)
;
if
(
state
->
rxp
->
type
==
SSH_FXP_HANDLE
)
{
if
(
!
parse_handle
(
state
,
(
sftp_str_t
*
)
handle
))
{
response_handled
(
state
);
return
false
;
return
exit_function
(
state
,
false
)
;
}
response_handled
(
state
);
return
true
;
return
exit_function
(
state
,
true
)
;
}
handle_error
(
state
);
return
false
;
return
exit_function
(
state
,
false
)
;
}
bool
sftpc_close
(
sftpc_state_t
state
,
sftp_filehandle_t
*
handle
)
{
if
(
!
check_state
(
state
))
if
(
!
enter_function
(
state
))
return
false
;
if
(
!
appendheader
(
state
,
SSH_FXP_CLOSE
))
return
false
;
return
exit_function
(
state
,
false
)
;
if
(
!
appendfhandle
(
state
,
*
handle
))
return
false
;
return
exit_function
(
state
,
false
)
;
if
(
!
get_result
(
state
))
return
false
;
return
exit_function
(
state
,
false
)
;
handle_error
(
state
);
free_sftp_str
(
*
handle
);
*
handle
=
NULL
;
return
state
->
err_code
==
SSH_FX_OK
;
return
exit_function
(
state
,
state
->
err_code
==
SSH_FX_OK
)
;
}
bool
sftpc_read
(
sftpc_state_t
state
,
sftp_filehandle_t
handle
,
uint64_t
offset
,
uint32_t
len
,
sftp_str_t
*
ret
)
{
if
(
!
check_state
(
state
))
return
false
;
if
(
!
enter_function
(
state
))
return
exit_function
(
state
,
false
)
;
assert
(
ret
);
if
(
ret
==
NULL
)
return
false
;
return
exit_function
(
state
,
false
)
;
assert
(
*
ret
==
NULL
);
if
(
*
ret
!=
NULL
)
return
false
;
return
exit_function
(
state
,
false
)
;
if
(
!
appendheader
(
state
,
SSH_FXP_READ
))
return
false
;
return
exit_function
(
state
,
false
)
;
if
(
!
appendfhandle
(
state
,
handle
))
return
false
;
return
exit_function
(
state
,
false
)
;
if
(
!
append64
(
state
,
offset
))
return
false
;
return
exit_function
(
state
,
false
)
;
if
(
!
append32
(
state
,
len
))
return
false
;
return
exit_function
(
state
,
false
)
;
if
(
!
get_result
(
state
))
return
false
;
return
exit_function
(
state
,
false
)
;
if
(
state
->
rxp
->
type
==
SSH_FXP_DATA
)
{
*
ret
=
getstring
(
state
);
response_handled
(
state
);
return
*
ret
!=
NULL
;
return
exit_function
(
state
,
*
ret
!=
NULL
)
;
}
handle_error
(
state
);
return
false
;
return
exit_function
(
state
,
false
)
;
}
bool
sftpc_write
(
sftpc_state_t
state
,
sftp_filehandle_t
handle
,
uint64_t
offset
,
sftp_str_t
data
)
{
if
(
!
check_state
(
state
))
if
(
!
enter_function
(
state
))
return
false
;
assert
(
data
);
if
(
data
==
NULL
)
return
false
;
return
exit_function
(
state
,
false
)
;
if
(
!
appendheader
(
state
,
SSH_FXP_WRITE
))
return
false
;
return
exit_function
(
state
,
false
)
;
if
(
!
appendfhandle
(
state
,
handle
))
return
false
;
return
exit_function
(
state
,
false
)
;
if
(
!
append64
(
state
,
offset
))
return
false
;
return
exit_function
(
state
,
false
)
;
if
(
!
appendstring
(
state
,
data
))
return
false
;
return
exit_function
(
state
,
false
)
;
if
(
!
get_result
(
state
))
return
false
;
return
exit_function
(
state
,
false
)
;
handle_error
(
state
);
return
state
->
err_code
==
SSH_FX_OK
;
return
exit_function
(
state
,
state
->
err_code
==
SSH_FX_OK
)
;
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment