clsync
Loading...
Searching...
No Matches
control.c
Go to the documentation of this file.
1
/*
2
clsync - file tree sync utility based on inotify
3
4
Copyright (C) 2013 Dmitry Yu Okunev <dyokunev@ut.mephi.ru> 0x8E30679C
5
6
This program is free software: you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation, either version 3 of the License, or
9
(at your option) any later version.
10
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
15
16
You should have received a copy of the GNU General Public License
17
along with this program. If not, see <http://www.gnu.org/licenses/>.
18
*/
19
20
#include "
common.h
"
21
22
#include <sys/un.h>
// for "struct sockaddr_un"
23
#include <sys/stat.h>
// mkdir()
24
#include <sys/types.h>
// mkdir()
25
#include <fcntl.h>
// mkdirat()
26
#include <glib.h>
// g_hash_table_foreach()
27
28
29
#include "
indexes.h
"
30
#include "
main.h
"
31
#include "
ctx.h
"
32
#include "
error.h
"
33
#include "
sync.h
"
34
#include "
control.h
"
35
#include "
socket.h
"
36
37
static
pthread_t
pthread_control
;
38
39
40
static
inline
int
control_error
(
clsyncsock_t
*clsyncsock_p,
sockcmd_t
*sockcmd_p,
const
char
*
const
funct,
const
char
*
const
args )
41
{
42
debug
( 3,
"%s(%s): %u: %s"
, funct, args, errno, strerror ( errno ) );
43
return
socket_reply
( clsyncsock_p, sockcmd_p,
SOCKCMD_REPLY_ECUSTOM
, funct, args, errno, strerror ( errno ) );
44
}
45
46
47
int
control_dump
(
ctx_t
*
ctx_p
,
clsyncsock_t
*clsyncsock_p,
sockcmd_t
*sockcmd_p )
48
{
49
sockcmd_dat_dump_t
*dat = sockcmd_p->
data
;
50
debug
( 3,
"%s"
, dat->
dir_path
);
51
return
(
sync_dump
(
ctx_p
, dat->
dir_path
) ) ?
52
control_error
( clsyncsock_p, sockcmd_p,
"sync_dump"
, dat->
dir_path
) :
53
socket_reply
( clsyncsock_p, sockcmd_p,
SOCKCMD_REPLY_DUMP
);
54
}
55
56
int
control_procclsyncsock
(
socket_sockthreaddata_t
*arg,
sockcmd_t
*sockcmd_p )
57
{
58
int
rc;
59
clsyncsock_t
*clsyncsock_p = arg->
clsyncsock_p
;
60
ctx_t
*
ctx_p
= (
ctx_t
* ) arg->
arg
;
61
62
switch
( sockcmd_p->
cmd_id
) {
63
case
SOCKCMD_REQUEST_DUMP
:
64
rc =
control_dump
(
ctx_p
, clsyncsock_p, sockcmd_p );
65
break
;
66
67
case
SOCKCMD_REQUEST_INFO
:
68
rc =
socket_reply
( clsyncsock_p, sockcmd_p,
SOCKCMD_REPLY_INFO
,
ctx_p
->
config_block
,
ctx_p
->
label
,
ctx_p
->
flags
,
ctx_p
->
flags_set
);
69
break
;
70
71
case
SOCKCMD_REQUEST_SET
: {
72
sockcmd_dat_set_t
*dat = sockcmd_p->
data
;
73
rc =
ctx_set
(
ctx_p
, dat->
key
, dat->
value
);
74
75
if
( rc ) {
76
control_error
( clsyncsock_p, sockcmd_p,
"ctx_set"
, dat->
key
);
77
break
;
78
}
79
80
rc =
socket_reply
( clsyncsock_p, sockcmd_p,
SOCKCMD_REPLY_SET
);
81
break
;
82
}
83
84
case
SOCKCMD_REQUEST_DIE
:
85
rc =
sync_term
( SIGTERM );
86
break
;
87
88
default
:
89
return
EINVAL;
90
}
91
92
debug
( 3,
"rc == %u"
, rc );
93
return
rc;
94
}
95
96
static
inline
void
closecontrol
(
ctx_t
*
ctx_p
)
97
{
98
if
(
ctx_p
->
socket
) {
99
close (
ctx_p
->
socket
);
100
ctx_p
->
socket
= 0;
101
}
102
}
103
104
int
control_loop
(
ctx_t
*
ctx_p
)
105
{
106
// Starting
107
debug
( 1,
"started (ctx_p->socket == %u)"
,
ctx_p
->
socket
);
108
int
s;
109
110
while
( ( s =
ctx_p
->
socket
) ) {
111
// Check if the socket is still alive
112
if
(
socket_check_bysock
( s ) ) {
113
error
(
"Control socket closed [case 0]"
);
114
closecontrol
(
ctx_p
);
115
continue
;
116
}
117
118
// Waiting for event
119
debug
( 3,
"waiting for events on the socket"
);
120
fd_set rfds;
121
FD_ZERO ( &rfds );
122
FD_SET ( s, &rfds );
123
int
count = select ( s + 1, &rfds, NULL, NULL, NULL );
124
// Processing the events
125
debug
( 2,
"got %i events with select()"
, count );
126
127
// Processing the events: checks
128
if
( count == 0 ) {
129
debug
( 2,
"select() timed out."
);
130
continue
;
131
}
132
133
if
( count < 0 ) {
134
debug
( 1,
"Got negative events count. Closing the socket."
);
135
closecontrol
(
ctx_p
);
136
continue
;
137
}
138
139
if
( !FD_ISSET ( s, &rfds ) ) {
140
error
(
"Got event, but not on the control socket. Closing the socket (cannot use \"select()\")."
);
141
closecontrol
(
ctx_p
);
142
continue
;
143
}
144
145
// Processing the events: accepting new clsyncsock
146
clsyncsock_t
*clsyncsock_p =
socket_accept
( s );
147
148
if
( clsyncsock_p == NULL ) {
149
if
( errno == EUSERS )
// Too many connections. Just ignoring the new one.
150
continue
;
151
152
// Got unknown error. Closing control socket just in case.
153
error
(
"Cannot socket_accept()"
);
154
closecontrol
(
ctx_p
);
155
continue
;
156
}
157
158
debug
( 2,
"Starting new thread for new connection."
);
159
socket_sockthreaddata_t
*threaddata_p =
socket_thread_attach
( clsyncsock_p );
160
161
if
( threaddata_p == NULL ) {
162
error
(
"Cannot create a thread for connection"
);
163
closecontrol
(
ctx_p
);
164
continue
;
165
}
166
167
threaddata_p->
procfunct
=
control_procclsyncsock
;
168
threaddata_p->
clsyncsock_p
= clsyncsock_p;
169
threaddata_p->
arg
=
ctx_p
;
170
threaddata_p->
running
= &
ctx_p
->
socket
;
171
threaddata_p->
authtype
=
ctx_p
->
flags
[
SOCKETAUTH
];
172
threaddata_p->
flags
= 0;
173
174
if
(
socket_thread_start
( threaddata_p ) ) {
175
error
(
"Cannot start a thread for connection"
);
176
closecontrol
(
ctx_p
);
177
continue
;
178
}
179
180
#ifdef DEBUG
181
// To prevent too often connections
182
sleep ( 1 );
183
#endif
184
}
185
186
// Cleanup
187
debug
( 1,
"control_loop() finished"
);
188
return
0;
189
}
190
191
int
control_run
(
ctx_t
*
ctx_p
)
192
{
193
if
(
ctx_p
->
socketpath
!= NULL ) {
194
int
ret = 0;
195
int
s = -1;
196
197
// initializing clsync-socket subsystem
198
if
( ( ret =
socket_init
() ) )
199
error
(
"Cannot init clsync-sockets subsystem."
);
200
201
if
( !ret ) {
202
clsyncsock_t
*
clsyncsock
=
socket_listen_unix
(
ctx_p
->
socketpath
);
203
204
if
(
clsyncsock
== NULL ) {
205
ret = errno;
206
}
else
{
207
s =
clsyncsock
->
sock
;
208
socket_cleanup
(
clsyncsock
);
209
}
210
}
211
212
// fixing privileges
213
if
( !ret ) {
214
if
(
ctx_p
->
flags
[
SOCKETMOD
] )
215
if
( chmod (
ctx_p
->
socketpath
,
ctx_p
->
socketmod
) ) {
216
error
(
"Error, Cannot chmod(\"%s\", %o)"
,
217
ctx_p
->
socketpath
,
ctx_p
->
socketmod
);
218
ret = errno;
219
}
220
221
if
(
ctx_p
->
flags
[
SOCKETOWN
] )
222
if
( chown (
ctx_p
->
socketpath
,
ctx_p
->
socketuid
,
ctx_p
->
socketgid
) ) {
223
error
(
"Error, Cannot chown(\"%s\", %u, %u)"
,
224
ctx_p
->
socketpath
,
ctx_p
->
socketuid
,
ctx_p
->
socketgid
);
225
ret = errno;
226
}
227
}
228
229
// finish
230
if
( ret ) {
231
close ( s );
232
return
ret;
233
}
234
235
ctx_p
->
socket
= s;
236
debug
( 2,
"ctx_p->socket = %u"
,
ctx_p
->
socket
);
237
ret = pthread_create ( &
pthread_control
, NULL, (
void
* ( * ) (
void
* ) )
control_loop
,
ctx_p
);
238
}
239
240
return
0;
241
}
242
243
int
control_cleanup
(
ctx_t
*
ctx_p
)
244
{
245
if
(
ctx_p
->
socketpath
!= NULL ) {
246
unlink (
ctx_p
->
socketpath
);
247
closecontrol
(
ctx_p
);
248
// TODO: kill pthread_control and join
249
// pthread_join(pthread_control, NULL);
250
socket_deinit
();
251
}
252
253
return
0;
254
}
255
common.h
control_dump
int control_dump(ctx_t *ctx_p, clsyncsock_t *clsyncsock_p, sockcmd_t *sockcmd_p)
Definition
control.c:47
control_error
static int control_error(clsyncsock_t *clsyncsock_p, sockcmd_t *sockcmd_p, const char *const funct, const char *const args)
Definition
control.c:40
pthread_control
static pthread_t pthread_control
Definition
control.c:37
control_procclsyncsock
int control_procclsyncsock(socket_sockthreaddata_t *arg, sockcmd_t *sockcmd_p)
Definition
control.c:56
control_loop
int control_loop(ctx_t *ctx_p)
Definition
control.c:104
closecontrol
static void closecontrol(ctx_t *ctx_p)
Definition
control.c:96
control_run
int control_run(ctx_t *ctx_p)
Definition
control.c:191
control_cleanup
int control_cleanup(ctx_t *ctx_p)
Definition
control.c:243
control.h
ctx.h
SOCKETAUTH
@ SOCKETAUTH
Definition
ctx.h:97
SOCKETOWN
@ SOCKETOWN
Definition
ctx.h:99
SOCKETMOD
@ SOCKETMOD
Definition
ctx.h:98
error.h
error
#define error(...)
Definition
error.h:36
debug
#define debug(debug_level,...)
Definition
error.h:50
indexes.h
ctx_set
int ctx_set(ctx_t *ctx_p, const char *const parameter_name, const char *const parameter_value)
Definition
main.c:2560
main.h
ctx_p
ctx_t * ctx_p
Definition
mon_kqueue.c:85
socket_init
int socket_init()
Definition
socket.c:818
socket_listen_unix
clsyncsock_t * socket_listen_unix(const char *const socket_path)
Definition
socket.c:192
socket_thread_attach
socket_sockthreaddata_t * socket_thread_attach(clsyncsock_t *clsyncsock_p)
Definition
socket.c:797
socket_check_bysock
int socket_check_bysock(int sock)
Definition
socket.c:108
socket_deinit
int socket_deinit()
Definition
socket.c:823
socket_reply
int socket_reply(clsyncsock_t *clsyncsock_p, sockcmd_t *sockcmd_p, sockcmd_id_t cmd_id,...)
Definition
socket.c:331
socket_accept
clsyncsock_t * socket_accept(int sock)
Definition
socket.c:177
socket_thread_start
int socket_thread_start(socket_sockthreaddata_t *threaddata_p)
Definition
socket.c:808
socket_cleanup
int socket_cleanup(clsyncsock_t *clsyncsock_p)
Definition
socket.c:140
socket.h
SOCKCMD_REPLY_INFO
@ SOCKCMD_REPLY_INFO
Definition
socket.h:118
SOCKCMD_REPLY_ECUSTOM
@ SOCKCMD_REPLY_ECUSTOM
Definition
socket.h:109
SOCKCMD_REQUEST_SET
@ SOCKCMD_REQUEST_SET
Definition
socket.h:114
SOCKCMD_REPLY_SET
@ SOCKCMD_REPLY_SET
Definition
socket.h:121
SOCKCMD_REQUEST_DIE
@ SOCKCMD_REQUEST_DIE
Definition
socket.h:115
SOCKCMD_REPLY_DUMP
@ SOCKCMD_REPLY_DUMP
Definition
socket.h:119
SOCKCMD_REQUEST_INFO
@ SOCKCMD_REQUEST_INFO
Definition
socket.h:111
SOCKCMD_REQUEST_DUMP
@ SOCKCMD_REQUEST_DUMP
Definition
socket.h:112
clsyncsock
Definition
socket.h:65
clsyncsock::sock
int sock
Definition
socket.h:66
ctx
Definition
ctx.h:315
ctx::flags_set
int flags_set[(1<< 10)]
Definition
ctx.h:339
ctx::socket
int socket
Definition
ctx.h:360
ctx::socketmod
mode_t socketmod
Definition
ctx.h:361
ctx::socketuid
uid_t socketuid
Definition
ctx.h:362
ctx::config_block
const char * config_block
Definition
ctx.h:342
ctx::socketpath
char * socketpath
Definition
ctx.h:355
ctx::label
char * label
Definition
ctx.h:344
ctx::socketgid
gid_t socketgid
Definition
ctx.h:363
ctx::flags
int flags[(1<< 10)]
Definition
ctx.h:338
sockcmd_dat_dump
Definition
socket.h:165
sockcmd_dat_dump::dir_path
char dir_path[PATH_MAX]
Definition
socket.h:166
sockcmd_dat_set
Definition
socket.h:180
sockcmd_dat_set::key
char key[BUFSIZ]
Definition
socket.h:181
sockcmd_dat_set::value
char value[BUFSIZ]
Definition
socket.h:182
sockcmd
Definition
socket.h:186
sockcmd::cmd_id
uint16_t cmd_id
Definition
socket.h:188
sockcmd::data
void * data
Definition
socket.h:190
socket_sockthreaddata
Definition
socket.h:209
socket_sockthreaddata::clsyncsock_p
clsyncsock_t * clsyncsock_p
Definition
socket.h:213
socket_sockthreaddata::procfunct
clsyncsock_procfunct_t procfunct
Definition
socket.h:211
socket_sockthreaddata::authtype
sockauth_id_t authtype
Definition
socket.h:216
socket_sockthreaddata::flags
sockprocflags_t flags
Definition
socket.h:218
socket_sockthreaddata::running
int * running
Definition
socket.h:217
socket_sockthreaddata::arg
void * arg
Definition
socket.h:214
sync_term
int sync_term(int exitcode)
Definition
sync.c:3991
sync_dump
int sync_dump(ctx_t *ctx_p, const char *const dir_path)
Definition
sync.c:3773
sync.h
Generated on Wed Nov 15 2023 13:38:28 for clsync by
1.12.0