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 
21 #ifndef __CLSYNC_COMMON_H
22 #define __CLSYNC_COMMON_H
23 
24 #ifndef __linux__
25 #	ifdef HAVE_CAPABILITIES
26 #		undef HAVE_CAPABILITIES
27 #		warning Capabilities support can be built only on Linux
28 #	endif
29 #endif
30 
31 #define _GNU_SOURCE
32 //#define _XOPEN_SOURCE 700
33 #define _LARGEFILE64_SOURCE
34 
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stdint.h>
38 #include <string.h>
39 #include <strings.h>
40 #include <unistd.h>
41 #include <getopt.h>
42 #include <limits.h>
43 #include <stdarg.h>
44 #include <sys/types.h>
45 #include <sys/stat.h>
46 #include <fcntl.h>
47 #include <sys/mman.h>
48 #include <errno.h>
49 #include <ctype.h>
50 #include <signal.h>
51 #ifdef KQUEUE_SUPPORT
52 #	include <sys/event.h>
53 #endif
54 #ifdef INOTIFY_SUPPORT
55 #	include <sys/inotify.h>
56 #endif
57 #ifdef FANOTIFY_SUPPORT
58 #	include <sys/fanotify.h>
59 #endif
60 #include <sys/wait.h>
61 #include <fts.h>
62 #include <sys/time.h>
63 #include <dirent.h>
64 #include <sys/utsname.h>
65 #include <sys/socket.h>
66 #include <arpa/inet.h>
67 #include <netinet/in.h>
68 #include <libgen.h>
69 #include <pthread.h>
70 #include <glib.h>
71 
72 #ifdef HAVE_CAPABILITIES
73 #	include <sys/capability.h>	// for capset()/capget() for --preserve-file-access
74 #	include <sys/prctl.h>		// for prctl() for --preserve-fil-access
75 #endif
76 
77 #include "configuration.h"
78 #ifdef HAVE_CONFIG_H
79 #	include "config.h"
80 #endif
81 
82 #include "clsync.h"
83 #include "ctx.h"
84 #include "program.h"
85 
86 #include <sys/param.h>
87 
88 #ifndef IN_CREATE_SELF
89 #	define IN_CREATE_SELF IN_CREATE
90 #endif
91 
92 #ifdef _DEBUG
93 #	define DEBUGV(...) __VA_ARGS__
94 #else
95 #	define DEBUGV(...)
96 #endif
97 
98 #ifdef PARANOID
99 #	define PARANOIDV(...) __VA_ARGS__
100 #else
101 #	define PARANOIDV(...)
102 #endif
103 
104 #ifdef _GNU_SOURCE
105 #	ifndef likely
106 #		define likely(x)    __builtin_expect(!!(x), 1)
107 #	endif
108 #	ifndef unlikely
109 #		define unlikely(x)  __builtin_expect(!!(x), 0)
110 #	endif
111 #else
112 #	ifndef likely
113 #		define likely(x)   (x)
114 #	endif
115 #	ifndef unlikely
116 #		define unlikely(x) (x)
117 #	endif
118 #endif
119 
120 
121 #define TOSTR(a) # a
122 #define XTOSTR(a) TOSTR(a)
123 
124 #define COLLECTDELAY_INSTANT ((unsigned int)~0)
125 
126 #define require_strlen_le(str, limit) \
127 	if (strlen(str) >= limit)\
128 		critical("length of "TOSTR(str)" (\"%s\") >= "TOSTR(limit));\
129 
130 enum paramsource_enum {
131 	PS_UNKNOWN	 = 0,
132 	PS_ARGUMENT,
133 	PS_CONFIG
134 };
135 typedef enum paramsource_enum paramsource_t;
136 
137 
138 enum notifyengine_enum {
139 	NE_UNDEFINED = 0,
140 	NE_FANOTIFY,
141 	NE_INOTIFY,
142 	NE_KQUEUE,
143 	NE_BSM,
144 	NE_DTRACEPIPE,
145 };
146 typedef enum notifyengine_enum notifyengine_t;
147 
148 #define STATE_STARTING(state_p) (state_p == NULL)
149 enum state_enum {
150 	STATE_EXIT 	= 0,
151 	STATE_STARTING,
152 	STATE_RUNNING,
153 	STATE_REHASH,
154 	STATE_TERM,
155 	STATE_THREAD_GC,
156 	STATE_INITSYNC,
157 	STATE_UNKNOWN
158 };
159 typedef enum state_enum state_t;
160 
161 enum threadingmode {
162 	PM_OFF	= 0,
163 	PM_SAFE,
164 	PM_FULL
165 };
166 typedef enum threadingmode threadingmode_t;
167 
168 /*
169 struct excludeinfo {
170 	unsigned int	seqid_min;
171 	unsigned int	seqid_max;
172 	eventobjtype_t	objtype_old;
173 	eventobjtype_t	objtype_new;
174 	uint32_t	flags;
175 };
176 typedef struct eventinfo eventinfo_t;
177 */
178 struct eventinfo {
179 	uint32_t	evmask;
180 	unsigned int	seqid_min;
181 	unsigned int	seqid_max;
182 	eventobjtype_t	objtype_old;
183 	eventobjtype_t	objtype_new;
184 	int		wd;
185 	size_t		fsize;
186 	uint32_t	flags;
187 };
188 typedef struct eventinfo eventinfo_t;
189 
190 
191 typedef int (*thread_callbackfunct_t)(ctx_t *ctx_p, char **argv);
192 struct threadinfo {
193 	int			  thread_num;
194 	uint32_t		  iteration;
195 	thread_callbackfunct_t 	  callback;
196 	char 			**argv;
197 	pthread_t		  pthread;
198 	int			  exitcode;
199 	int			  errcode;
200 	state_t			  state;
201 	ctx_t			 *ctx_p;
202 	time_t			  starttime;
203 	time_t			  expiretime;
204 	int			  child_pid;
205 
206 	GHashTable		 *fpath2ei_ht;		// file path -> event information
207 
208 	int			  try_n;
209 
210 	// for so-synchandler
211 	int			  n;
212 	api_eventinfo_t		 *ei;
213 };
214 typedef struct threadinfo threadinfo_t;
215 
216 enum pthread_mutex_id {
217 	PTHREAD_MUTEX_STATE,
218 	PTHREAD_MUTEX_SELECT,
219 	PTHREAD_MUTEX_THREADSINFO,
220 	PTHREAD_MUTEX_MAX
221 };
222 
223 
224 struct threadsinfo {
225 	pthread_mutex_t		  mutex[PTHREAD_MUTEX_MAX];
226 	pthread_cond_t		  cond [PTHREAD_MUTEX_MAX];
227 	char			  mutex_init;
228 	int			  allocated;
229 	int			  used;
230 	threadinfo_t 		 *threads;
231 	threadinfo_t 		**threadsstack;	// stack of threadinfo_t to be used on thread_new()
232 	int			  stacklen;
233 };
234 typedef struct threadsinfo threadsinfo_t;
235 
236 struct dosync_arg {
237 	int evcount;
238 	char excf_path[PATH_MAX+1];
239 	char outf_path[PATH_MAX+1];
240 	FILE *outf;
241 	ctx_t *ctx_p;
242 	struct indexes *indexes_p;
243 	void *data;
244 	int linescount;
245 	api_eventinfo_t *api_ei;
246 	int api_ei_count;
247 	char buf[BUFSIZ+1];
248 };
249 
250 struct doubleentry {
251 	size_t  size0;
252 	size_t  size1;
253 	size_t  alloc0;
254 	size_t  alloc1;
255 	void   *dat0;
256 	void   *dat1;
257 };
258 
259 struct pushdoubleentry_arg {
260 	int			 allocated;
261 	int			 total;
262 	size_t			 size;
263 	struct doubleentry	*entry;
264 };
265 
266 struct myentry {
267 	size_t  size;
268 	size_t  alloc;
269 	void   *dat;
270 };
271 
272 struct pushentry_arg {
273 	int		 allocated;
274 	int		 total;
275 	size_t		 size;
276 	struct myentry	*entry;
277 };
278 
279 enum initsync {
280 	INITSYNC_UNKNOWN = 0,
281 	INITSYNC_FULL,
282 	INITSYNC_SUBDIR
283 };
284 typedef enum initsync initsync_t;
285 
286 struct sighandler_arg {
287 	ctx_t     *ctx_p;
288 //	indexes_t *indexes_p;
289 	pthread_t  pthread_parent;
290 	int	  *exitcode_p;
291 	sigset_t  *sigset_p;
292 };
293 typedef struct sighandler_arg sighandler_arg_t;
294 
295 #endif
296 
297