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
37static pthread_t pthread_control;
38
39
40static 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
47int 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
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 ) {
64 rc = control_dump ( ctx_p, clsyncsock_p, sockcmd_p );
65 break;
66
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
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
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
96static 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
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]" );
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." );
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()\")." );
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()" );
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" );
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" );
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
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 ) {
203
204 if ( clsyncsock == NULL ) {
205 ret = errno;
206 } else {
207 s = clsyncsock->sock;
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)",
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)",
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
244{
245 if ( ctx_p->socketpath != NULL ) {
246 unlink ( ctx_p->socketpath );
248 // TODO: kill pthread_control and join
249// pthread_join(pthread_control, NULL);
251 }
252
253 return 0;
254}
255
int control_dump(ctx_t *ctx_p, clsyncsock_t *clsyncsock_p, sockcmd_t *sockcmd_p)
Definition control.c:47
static int control_error(clsyncsock_t *clsyncsock_p, sockcmd_t *sockcmd_p, const char *const funct, const char *const args)
Definition control.c:40
static pthread_t pthread_control
Definition control.c:37
int control_procclsyncsock(socket_sockthreaddata_t *arg, sockcmd_t *sockcmd_p)
Definition control.c:56
int control_loop(ctx_t *ctx_p)
Definition control.c:104
static void closecontrol(ctx_t *ctx_p)
Definition control.c:96
int control_run(ctx_t *ctx_p)
Definition control.c:191
int control_cleanup(ctx_t *ctx_p)
Definition control.c:243
@ SOCKETAUTH
Definition ctx.h:97
@ SOCKETOWN
Definition ctx.h:99
@ SOCKETMOD
Definition ctx.h:98
#define error(...)
Definition error.h:36
#define debug(debug_level,...)
Definition error.h:50
int ctx_set(ctx_t *ctx_p, const char *const parameter_name, const char *const parameter_value)
Definition main.c:2560
ctx_t * ctx_p
Definition mon_kqueue.c:85
int socket_init()
Definition socket.c:818
clsyncsock_t * socket_listen_unix(const char *const socket_path)
Definition socket.c:192
socket_sockthreaddata_t * socket_thread_attach(clsyncsock_t *clsyncsock_p)
Definition socket.c:797
int socket_check_bysock(int sock)
Definition socket.c:108
int socket_deinit()
Definition socket.c:823
int socket_reply(clsyncsock_t *clsyncsock_p, sockcmd_t *sockcmd_p, sockcmd_id_t cmd_id,...)
Definition socket.c:331
clsyncsock_t * socket_accept(int sock)
Definition socket.c:177
int socket_thread_start(socket_sockthreaddata_t *threaddata_p)
Definition socket.c:808
int socket_cleanup(clsyncsock_t *clsyncsock_p)
Definition socket.c:140
@ SOCKCMD_REPLY_INFO
Definition socket.h:118
@ SOCKCMD_REPLY_ECUSTOM
Definition socket.h:109
@ SOCKCMD_REQUEST_SET
Definition socket.h:114
@ SOCKCMD_REPLY_SET
Definition socket.h:121
@ SOCKCMD_REQUEST_DIE
Definition socket.h:115
@ SOCKCMD_REPLY_DUMP
Definition socket.h:119
@ SOCKCMD_REQUEST_INFO
Definition socket.h:111
@ SOCKCMD_REQUEST_DUMP
Definition socket.h:112
int sock
Definition socket.h:66
Definition ctx.h:315
int flags_set[(1<< 10)]
Definition ctx.h:339
int socket
Definition ctx.h:360
mode_t socketmod
Definition ctx.h:361
uid_t socketuid
Definition ctx.h:362
const char * config_block
Definition ctx.h:342
char * socketpath
Definition ctx.h:355
char * label
Definition ctx.h:344
gid_t socketgid
Definition ctx.h:363
int flags[(1<< 10)]
Definition ctx.h:338
char dir_path[PATH_MAX]
Definition socket.h:166
char key[BUFSIZ]
Definition socket.h:181
char value[BUFSIZ]
Definition socket.h:182
uint16_t cmd_id
Definition socket.h:188
void * data
Definition socket.h:190
clsyncsock_t * clsyncsock_p
Definition socket.h:213
clsyncsock_procfunct_t procfunct
Definition socket.h:211
sockauth_id_t authtype
Definition socket.h:216
sockprocflags_t flags
Definition socket.h:218
int sync_term(int exitcode)
Definition sync.c:3991
int sync_dump(ctx_t *ctx_p, const char *const dir_path)
Definition sync.c:3773