Showing
10 changed files
with
267 additions
and
28 deletions
@@ -17,6 +17,9 @@ | @@ -17,6 +17,9 @@ | ||
17 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 17 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
18 | */ | 18 | */ |
19 | 19 | ||
20 | +#ifndef __CLSYNC_CLSYNC_H | ||
21 | +#define __CLSYNC_CLSYNC_H | ||
22 | + | ||
20 | #include <stdio.h> | 23 | #include <stdio.h> |
21 | #include <stdint.h> | 24 | #include <stdint.h> |
22 | #include <sys/types.h> | 25 | #include <sys/types.h> |
@@ -89,3 +92,5 @@ extern int clsyncapi_getapiversion(); | @@ -89,3 +92,5 @@ extern int clsyncapi_getapiversion(); | ||
89 | */ | 92 | */ |
90 | extern pid_t clsyncapi_fork(struct ctx *ctx_p); | 93 | extern pid_t clsyncapi_fork(struct ctx *ctx_p); |
91 | 94 | ||
95 | +#endif | ||
96 | + |
@@ -182,6 +182,7 @@ typedef struct eventinfo eventinfo_t; | @@ -182,6 +182,7 @@ typedef struct eventinfo eventinfo_t; | ||
182 | typedef int (*thread_callbackfunct_t)(ctx_t *ctx_p, char **argv); | 182 | typedef int (*thread_callbackfunct_t)(ctx_t *ctx_p, char **argv); |
183 | struct threadinfo { | 183 | struct threadinfo { |
184 | int thread_num; | 184 | int thread_num; |
185 | + uint32_t iteration; | ||
185 | thread_callbackfunct_t callback; | 186 | thread_callbackfunct_t callback; |
186 | char **argv; | 187 | char **argv; |
187 | pthread_t pthread; | 188 | pthread_t pthread; |
@@ -71,3 +71,5 @@ | @@ -71,3 +71,5 @@ | ||
71 | #define CONFIG_PATHS { ".clsync.conf", "/etc/clsync/clsync.conf", NULL } /* "~/.clsync.conf" and "/etc/clsync/clsync.conf" */ | 71 | #define CONFIG_PATHS { ".clsync.conf", "/etc/clsync/clsync.conf", NULL } /* "~/.clsync.conf" and "/etc/clsync/clsync.conf" */ |
72 | 72 | ||
73 | #define API_PREFIX "clsyncapi_" | 73 | #define API_PREFIX "clsyncapi_" |
74 | + | ||
75 | +#define DUMP_DIRMODE 0700 |
@@ -20,7 +20,14 @@ | @@ -20,7 +20,14 @@ | ||
20 | #include "common.h" | 20 | #include "common.h" |
21 | 21 | ||
22 | #include <sys/un.h> // for "struct sockaddr_un" | 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() | ||
23 | 27 | ||
28 | + | ||
29 | +#include "indexes.h" | ||
30 | +#include "ctx.h" | ||
24 | #include "error.h" | 31 | #include "error.h" |
25 | #include "sync.h" | 32 | #include "sync.h" |
26 | #include "control.h" | 33 | #include "control.h" |
@@ -28,19 +35,195 @@ | @@ -28,19 +35,195 @@ | ||
28 | 35 | ||
29 | static pthread_t pthread_control; | 36 | static pthread_t pthread_control; |
30 | 37 | ||
38 | + | ||
39 | +static inline int control_error(clsyncsock_t *clsyncsock_p, const char *const funct, const char *const args) { | ||
40 | + return socket_send(clsyncsock_p, SOCKCMD_REPLY_ECUSTOM, funct, args, errno, strerror(errno)); | ||
41 | +} | ||
42 | + | ||
43 | +enum dump_dirfd_obj { | ||
44 | + DUMP_DIRFD_ROOT = 0, | ||
45 | + DUMP_DIRFD_QUEUE, | ||
46 | + DUMP_DIRFD_THREAD, | ||
47 | + | ||
48 | + DUMP_DIRFD_MAX | ||
49 | +}; | ||
50 | + | ||
51 | +enum dump_ltype { | ||
52 | + DUMP_LTYPE_INCLUDE, | ||
53 | + DUMP_LTYPE_EXCLUDE, | ||
54 | + DUMP_LTYPE_EVINFO, | ||
55 | +}; | ||
56 | + | ||
57 | +struct control_dump_arg { | ||
58 | + clsyncsock_t *clsyncsock_p; | ||
59 | + ctx_t *ctx_p; | ||
60 | + int dirfd[DUMP_DIRFD_MAX]; | ||
61 | + int fd_out; | ||
62 | + int data; | ||
63 | +}; | ||
64 | + | ||
65 | +void control_dump_liststep(gpointer fpath_gp, gpointer evinfo_gp, gpointer arg_gp) { | ||
66 | + char *fpath = (char *)fpath_gp; | ||
67 | + eventinfo_t *evinfo = (eventinfo_t *)evinfo_gp; | ||
68 | + struct control_dump_arg *arg = arg_gp; | ||
69 | + char act, num; | ||
70 | + | ||
71 | + switch (arg->data) { | ||
72 | + case DUMP_LTYPE_INCLUDE: | ||
73 | + act = '+'; | ||
74 | + num = '1'; | ||
75 | + break; | ||
76 | + case DUMP_LTYPE_EXCLUDE: | ||
77 | + act = '-'; | ||
78 | + num = '1'; | ||
79 | + break; | ||
80 | + case DUMP_LTYPE_EVINFO: | ||
81 | + act = '+'; | ||
82 | + num = evinfo->flags&EVIF_RECURSIVELY ? '*' : | ||
83 | + (evinfo->flags&EVIF_CONTENTRECURSIVELY ? '/' : '1'); | ||
84 | + break; | ||
85 | + default: | ||
86 | + act = '?'; | ||
87 | + num = '?'; | ||
88 | + } | ||
89 | + | ||
90 | + dprintf(arg->fd_out, "%c%c %s\n", act, num, fpath); | ||
91 | + | ||
92 | + return; | ||
93 | +} | ||
94 | + | ||
95 | +int control_dump_thread(threadinfo_t *threadinfo_p, void *_arg) { | ||
96 | + struct control_dump_arg *arg = _arg; | ||
97 | + char buf[BUFSIZ]; | ||
98 | + | ||
99 | + snprintf(buf, BUFSIZ, "%u-%u-%lx", threadinfo_p->iteration, threadinfo_p->thread_num, (long)threadinfo_p->pthread); | ||
100 | + | ||
101 | + arg->fd_out = openat(arg->dirfd[DUMP_DIRFD_THREAD], buf, O_WRONLY); | ||
102 | + if (arg->fd_out == -1) | ||
103 | + return errno; | ||
104 | + | ||
105 | + { | ||
106 | + char **argv; | ||
107 | + | ||
108 | + dprintf(arg->fd_out, | ||
109 | + "thread:\n\titeration == %u;\n\tnum == %u;\n\tpthread == %lx;\n\tstarttime == %lu\n\texpiretime == %lu\n\tchild_pid == %u\n\ttry_n == %u\nCommand:", | ||
110 | + threadinfo_p->iteration, | ||
111 | + threadinfo_p->thread_num, | ||
112 | + (long)threadinfo_p->pthread, | ||
113 | + threadinfo_p->starttime, | ||
114 | + threadinfo_p->expiretime, | ||
115 | + threadinfo_p->child_pid, | ||
116 | + threadinfo_p->try_n | ||
117 | + ); | ||
118 | + | ||
119 | + argv = threadinfo_p->argv; | ||
120 | + while (argv != NULL) | ||
121 | + dprintf(arg->fd_out, " \"%s\"", *(argv++)); | ||
122 | + | ||
123 | + dprintf(arg->fd_out, "\n"); | ||
124 | + } | ||
125 | + | ||
126 | + arg->data = DUMP_LTYPE_EVINFO; | ||
127 | + g_hash_table_foreach(threadinfo_p->fpath2ei_ht, control_dump_liststep, arg); | ||
128 | + | ||
129 | + close(arg->fd_out); | ||
130 | + | ||
131 | + return 0; | ||
132 | +} | ||
133 | + | ||
134 | +int control_mkdir_open(clsyncsock_t *clsyncsock_p, const char *const dir_path) { | ||
135 | + int dirfd; | ||
136 | + | ||
137 | + if (mkdir(dir_path, DUMP_DIRMODE)) { | ||
138 | + control_error(clsyncsock_p, "mkdir", dir_path); | ||
139 | + return -1; | ||
140 | + } | ||
141 | + | ||
142 | + dirfd = open(dir_path, O_RDWR); | ||
143 | + if (dirfd == -1) { | ||
144 | + control_error(clsyncsock_p, "open", dir_path); | ||
145 | + return -1; | ||
146 | + } | ||
147 | + | ||
148 | + return dirfd; | ||
149 | +} | ||
150 | + | ||
151 | +int control_dump(ctx_t *ctx_p, clsyncsock_t *clsyncsock_p, sockcmd_t *sockcmd_p) { | ||
152 | + indexes_t *indexes_p = ctx_p->indexes_p; | ||
153 | + sockcmd_dat_dump_t *dat = sockcmd_p->data; | ||
154 | + int rootfd; | ||
155 | + struct control_dump_arg arg; | ||
156 | + enum dump_dirfd_obj dirfd_obj; | ||
157 | + | ||
158 | + static const char *const subdirs[] = { | ||
159 | + [DUMP_DIRFD_QUEUE] = "queue", | ||
160 | + [DUMP_DIRFD_THREAD] = "threads" | ||
161 | + }; | ||
162 | + | ||
163 | + rootfd = control_mkdir_open(clsyncsock_p, dat->dir_path); | ||
164 | + if (rootfd == -1) | ||
165 | + goto l_control_dump_end; | ||
166 | + | ||
167 | + arg.dirfd[DUMP_DIRFD_ROOT] = rootfd; | ||
168 | + | ||
169 | + dirfd_obj = DUMP_DIRFD_ROOT+1; | ||
170 | + while (dirfd_obj < DUMP_DIRFD_MAX) { | ||
171 | + const char *const subdir = subdirs[dirfd_obj]; | ||
172 | + | ||
173 | + arg.dirfd[dirfd_obj] = control_mkdir_open(clsyncsock_p, subdir); | ||
174 | + if (arg.dirfd[dirfd_obj] == -1) | ||
175 | + goto l_control_dump_end; | ||
176 | + | ||
177 | + dirfd_obj++; | ||
178 | + } | ||
179 | + | ||
180 | + arg.clsyncsock_p = clsyncsock_p; | ||
181 | + arg.ctx_p = ctx_p; | ||
182 | + | ||
183 | + int queue_id = 0; | ||
184 | + while (queue_id < QUEUE_MAX) { | ||
185 | + char buf[BUFSIZ]; | ||
186 | + snprintf(buf, BUFSIZ, "%u", queue_id); | ||
187 | + | ||
188 | + arg.fd_out = openat(arg.dirfd[DUMP_DIRFD_QUEUE], buf, O_WRONLY); | ||
189 | + | ||
190 | + arg.data = DUMP_LTYPE_EVINFO; | ||
191 | + g_hash_table_foreach(indexes_p->fpath2ei_coll_ht[queue_id], control_dump_liststep, &arg); | ||
192 | + arg.data = DUMP_LTYPE_EXCLUDE; | ||
193 | + g_hash_table_foreach(indexes_p->exc_fpath_coll_ht[queue_id], control_dump_liststep, &arg); | ||
194 | + | ||
195 | + close(arg.fd_out); | ||
196 | + queue_id++; | ||
197 | + } | ||
198 | + | ||
199 | + threads_foreach(control_dump_thread, STATE_RUNNING, &arg); | ||
200 | + | ||
201 | +l_control_dump_end: | ||
202 | + dirfd_obj = DUMP_DIRFD_ROOT; | ||
203 | + while (dirfd_obj < DUMP_DIRFD_MAX) { | ||
204 | + if (arg.dirfd[dirfd_obj] != -1) | ||
205 | + close(arg.dirfd[dirfd_obj]); | ||
206 | + dirfd_obj++; | ||
207 | + } | ||
208 | + | ||
209 | + return errno ? errno : socket_send(clsyncsock_p, SOCKCMD_REPLY_DUMP); | ||
210 | +} | ||
211 | + | ||
212 | + | ||
31 | int control_procclsyncsock(socket_sockthreaddata_t *arg, sockcmd_t *sockcmd_p) { | 213 | int control_procclsyncsock(socket_sockthreaddata_t *arg, sockcmd_t *sockcmd_p) { |
32 | - clsyncsock_t *clsyncsock_p = arg->clsyncsock_p; | 214 | + clsyncsock_t *clsyncsock_p = arg->clsyncsock_p; |
33 | - ctx_t *ctx_p = (ctx_t *)arg->arg; | 215 | + ctx_t *ctx_p = (ctx_t *)arg->arg; |
34 | 216 | ||
35 | switch(sockcmd_p->cmd_id) { | 217 | switch(sockcmd_p->cmd_id) { |
36 | - case SOCKCMD_REQUEST_INFO: { | 218 | + case SOCKCMD_REQUEST_DUMP: |
219 | + control_dump(ctx_p, clsyncsock_p, sockcmd_p); | ||
220 | + break; | ||
221 | + case SOCKCMD_REQUEST_INFO: | ||
37 | socket_send(clsyncsock_p, SOCKCMD_REPLY_INFO, ctx_p->config_block, ctx_p->label, ctx_p->flags, ctx_p->flags_set); | 222 | socket_send(clsyncsock_p, SOCKCMD_REPLY_INFO, ctx_p->config_block, ctx_p->label, ctx_p->flags, ctx_p->flags_set); |
38 | break; | 223 | break; |
39 | - } | 224 | + case SOCKCMD_REQUEST_DIE: |
40 | - case SOCKCMD_REQUEST_DIE: { | ||
41 | sync_term(SIGTERM); | 225 | sync_term(SIGTERM); |
42 | break; | 226 | break; |
43 | - } | ||
44 | default: | 227 | default: |
45 | return EINVAL; | 228 | return EINVAL; |
46 | } | 229 | } |
@@ -232,6 +232,7 @@ struct ctx { | @@ -232,6 +232,7 @@ struct ctx { | ||
232 | sigset_t *sigset; | 232 | sigset_t *sigset; |
233 | char isignoredexitcode[(1<<8)]; | 233 | char isignoredexitcode[(1<<8)]; |
234 | #endif | 234 | #endif |
235 | + void *indexes_p; | ||
235 | }; | 236 | }; |
236 | typedef struct ctx ctx_t; | 237 | typedef struct ctx ctx_t; |
237 | 238 |
@@ -17,6 +17,9 @@ | @@ -17,6 +17,9 @@ | ||
17 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 17 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
18 | */ | 18 | */ |
19 | 19 | ||
20 | +#ifndef __CLSYNC_INDEXES_H | ||
21 | +#define __CLSYNC_INDEXES_H | ||
22 | + | ||
20 | #include <glib.h> | 23 | #include <glib.h> |
21 | 24 | ||
22 | struct indexes { | 25 | struct indexes { |
@@ -30,3 +33,5 @@ struct indexes { | @@ -30,3 +33,5 @@ struct indexes { | ||
30 | }; | 33 | }; |
31 | typedef struct indexes indexes_t; | 34 | typedef struct indexes indexes_t; |
32 | 35 | ||
36 | +#endif | ||
37 | + |
@@ -58,6 +58,7 @@ static char *recv_ptrs[SOCKET_MAX]; | @@ -58,6 +58,7 @@ static char *recv_ptrs[SOCKET_MAX]; | ||
58 | 58 | ||
59 | const char *const textmessage_args[SOCKCMD_MAXID] = { | 59 | const char *const textmessage_args[SOCKCMD_MAXID] = { |
60 | [SOCKCMD_REQUEST_NEGOTIATION] = "%u", | 60 | [SOCKCMD_REQUEST_NEGOTIATION] = "%u", |
61 | + [SOCKCMD_REQUEST_DUMP] = "%s", | ||
61 | [SOCKCMD_REPLY_NEGOTIATION] = "%u", | 62 | [SOCKCMD_REPLY_NEGOTIATION] = "%u", |
62 | [SOCKCMD_REPLY_ACK] = "%03u %lu", | 63 | [SOCKCMD_REPLY_ACK] = "%03u %lu", |
63 | [SOCKCMD_REPLY_EINVAL] = "%03u %lu", | 64 | [SOCKCMD_REPLY_EINVAL] = "%03u %lu", |
@@ -65,6 +66,9 @@ const char *const textmessage_args[SOCKCMD_MAXID] = { | @@ -65,6 +66,9 @@ const char *const textmessage_args[SOCKCMD_MAXID] = { | ||
65 | [SOCKCMD_REPLY_INFO] = "%s\003/ %s\003/ %x %x", | 66 | [SOCKCMD_REPLY_INFO] = "%s\003/ %s\003/ %x %x", |
66 | [SOCKCMD_REPLY_UNKNOWNCMD] = "%03u %lu", | 67 | [SOCKCMD_REPLY_UNKNOWNCMD] = "%03u %lu", |
67 | [SOCKCMD_REPLY_INVALIDCMDID] = "%lu", | 68 | [SOCKCMD_REPLY_INVALIDCMDID] = "%lu", |
69 | + [SOCKCMD_REPLY_EEXIST] = "%s\003/", | ||
70 | + [SOCKCMD_REPLY_EPERM] = "%s\003/", | ||
71 | + [SOCKCMD_REPLY_ECUSTOM] = "%s\003/ %s\003/ %u %s\003/", | ||
68 | }; | 72 | }; |
69 | 73 | ||
70 | const char *const textmessage_descr[SOCKCMD_MAXID] = { | 74 | const char *const textmessage_descr[SOCKCMD_MAXID] = { |
@@ -78,8 +82,12 @@ const char *const textmessage_descr[SOCKCMD_MAXID] = { | @@ -78,8 +82,12 @@ const char *const textmessage_descr[SOCKCMD_MAXID] = { | ||
78 | [SOCKCMD_REPLY_BYE] = "Bye.", | 82 | [SOCKCMD_REPLY_BYE] = "Bye.", |
79 | [SOCKCMD_REPLY_VERSION] = "clsync v%u.%u%s", | 83 | [SOCKCMD_REPLY_VERSION] = "clsync v%u.%u%s", |
80 | [SOCKCMD_REPLY_INFO] = "config_block == \"%s\"; label == \"%s\"; flags == %x; flags_set == %x.", | 84 | [SOCKCMD_REPLY_INFO] = "config_block == \"%s\"; label == \"%s\"; flags == %x; flags_set == %x.", |
85 | + [SOCKCMD_REPLY_DUMP] = "Ready", | ||
81 | [SOCKCMD_REPLY_UNKNOWNCMD] = "Unknown command.", | 86 | [SOCKCMD_REPLY_UNKNOWNCMD] = "Unknown command.", |
82 | [SOCKCMD_REPLY_INVALIDCMDID] = "Invalid command id. Required: 0 <= cmd_id < 1000.", | 87 | [SOCKCMD_REPLY_INVALIDCMDID] = "Invalid command id. Required: 0 <= cmd_id < 1000.", |
88 | + [SOCKCMD_REPLY_EEXIST] = "File exists: \"%s\".", | ||
89 | + [SOCKCMD_REPLY_EPERM] = "Permission denied: \"%s\".", | ||
90 | + [SOCKCMD_REPLY_ECUSTOM] = "%s(%s): Error #%u: \"%s\".", | ||
83 | }; | 91 | }; |
84 | 92 | ||
85 | int socket_check_bysock(int sock) { | 93 | int socket_check_bysock(int sock) { |
@@ -346,6 +354,9 @@ static inline int parse_text_data(sockcmd_t *sockcmd_p, char *args, size_t args_ | @@ -346,6 +354,9 @@ static inline int parse_text_data(sockcmd_t *sockcmd_p, char *args, size_t args_ | ||
346 | case SOCKCMD_REPLY_NEGOTIATION: | 354 | case SOCKCMD_REPLY_NEGOTIATION: |
347 | PARSE_TEXT_DATA_SSCANF(sockcmd_dat_negotiation_t, &d->prot, &d->subprot); | 355 | PARSE_TEXT_DATA_SSCANF(sockcmd_dat_negotiation_t, &d->prot, &d->subprot); |
348 | break; | 356 | break; |
357 | + case SOCKCMD_REQUEST_DUMP: | ||
358 | + PARSE_TEXT_DATA_SSCANF(sockcmd_dat_dump_t, &d->dir_path); | ||
359 | + break; | ||
349 | case SOCKCMD_REPLY_ACK: | 360 | case SOCKCMD_REPLY_ACK: |
350 | PARSE_TEXT_DATA_SSCANF(sockcmd_dat_ack_t, &d->cmd_id, &d->cmd_num); | 361 | PARSE_TEXT_DATA_SSCANF(sockcmd_dat_ack_t, &d->cmd_id, &d->cmd_num); |
351 | break; | 362 | break; |
@@ -368,10 +379,16 @@ static inline int parse_text_data(sockcmd_t *sockcmd_p, char *args, size_t args_ | @@ -368,10 +379,16 @@ static inline int parse_text_data(sockcmd_t *sockcmd_p, char *args, size_t args_ | ||
368 | case SOCKCMD_REPLY_INVALIDCMDID: | 379 | case SOCKCMD_REPLY_INVALIDCMDID: |
369 | PARSE_TEXT_DATA_SSCANF(sockcmd_dat_invalidcmd_t, &d->cmd_num); | 380 | PARSE_TEXT_DATA_SSCANF(sockcmd_dat_invalidcmd_t, &d->cmd_num); |
370 | break; | 381 | break; |
382 | + case SOCKCMD_REPLY_EEXIST: | ||
383 | + PARSE_TEXT_DATA_SSCANF(sockcmd_dat_eexist_t, &d->file_path); | ||
384 | + break; | ||
385 | + case SOCKCMD_REPLY_EPERM: | ||
386 | + PARSE_TEXT_DATA_SSCANF(sockcmd_dat_eperm_t, &d->descr); | ||
387 | + break; | ||
371 | default: | 388 | default: |
372 | sockcmd_p->data = xmalloc(args_len+1); | 389 | sockcmd_p->data = xmalloc(args_len+1); |
373 | memcpy(sockcmd_p->data, args, args_len); | 390 | memcpy(sockcmd_p->data, args, args_len); |
374 | - sockcmd_p->data[args_len] = 0; | 391 | + ((char *)sockcmd_p->data)[args_len] = 0; |
375 | break; | 392 | break; |
376 | } | 393 | } |
377 | 394 |
@@ -78,18 +78,22 @@ enum sockcmd_id { | @@ -78,18 +78,22 @@ enum sockcmd_id { | ||
78 | SOCKCMD_REPLY_UNKNOWNCMD = 160, | 78 | SOCKCMD_REPLY_UNKNOWNCMD = 160, |
79 | SOCKCMD_REPLY_INVALIDCMDID = 161, | 79 | SOCKCMD_REPLY_INVALIDCMDID = 161, |
80 | SOCKCMD_REPLY_EINVAL = 162, | 80 | SOCKCMD_REPLY_EINVAL = 162, |
81 | + SOCKCMD_REPLY_EEXIST = 163, | ||
82 | + SOCKCMD_REPLY_EPERM = 164, | ||
83 | + SOCKCMD_REPLY_ECUSTOM = 199, | ||
81 | SOCKCMD_REQUEST_LOGIN = 200, | 84 | SOCKCMD_REQUEST_LOGIN = 200, |
82 | SOCKCMD_REQUEST_VERSION = 201, | 85 | SOCKCMD_REQUEST_VERSION = 201, |
83 | SOCKCMD_REQUEST_INFO = 202, | 86 | SOCKCMD_REQUEST_INFO = 202, |
87 | + SOCKCMD_REQUEST_DUMP = 203, | ||
84 | SOCKCMD_REQUEST_DIE = 210, | 88 | SOCKCMD_REQUEST_DIE = 210, |
85 | SOCKCMD_REQUEST_QUIT = 250, | 89 | SOCKCMD_REQUEST_QUIT = 250, |
86 | SOCKCMD_REPLY_LOGIN = 300, | 90 | SOCKCMD_REPLY_LOGIN = 300, |
87 | SOCKCMD_REPLY_VERSION = 301, | 91 | SOCKCMD_REPLY_VERSION = 301, |
88 | SOCKCMD_REPLY_INFO = 302, | 92 | SOCKCMD_REPLY_INFO = 302, |
93 | + SOCKCMD_REPLY_DUMP = 303, | ||
89 | SOCKCMD_REPLY_DIE = 310, | 94 | SOCKCMD_REPLY_DIE = 310, |
90 | - SOCKCMD_REPLY_UNEXPECTEDEND = 300, | ||
91 | - SOCKCMD_REPLY_QUIT = 301, | ||
92 | SOCKCMD_REPLY_BYE = 350, | 95 | SOCKCMD_REPLY_BYE = 350, |
96 | + SOCKCMD_REPLY_UNEXPECTEDEND = 351, | ||
93 | SOCKCMD_MAXID | 97 | SOCKCMD_MAXID |
94 | }; | 98 | }; |
95 | typedef enum sockcmd_id sockcmd_id_t; | 99 | typedef enum sockcmd_id sockcmd_id_t; |
@@ -132,11 +136,26 @@ struct sockcmd_dat_info { | @@ -132,11 +136,26 @@ struct sockcmd_dat_info { | ||
132 | typedef struct sockcmd_dat_info sockcmd_dat_info_t; | 136 | typedef struct sockcmd_dat_info sockcmd_dat_info_t; |
133 | #endif | 137 | #endif |
134 | 138 | ||
139 | +struct sockcmd_dat_dump { | ||
140 | + char dir_path[PATH_MAX]; | ||
141 | +}; | ||
142 | +typedef struct sockcmd_dat_dump sockcmd_dat_dump_t; | ||
143 | + | ||
144 | +struct sockcmd_dat_eexist { | ||
145 | + char file_path[PATH_MAX]; | ||
146 | +}; | ||
147 | +typedef struct sockcmd_dat_eexist sockcmd_dat_eexist_t; | ||
148 | + | ||
149 | +struct sockcmd_dat_eperm { | ||
150 | + char descr[BUFSIZ]; | ||
151 | +}; | ||
152 | +typedef struct sockcmd_dat_eperm sockcmd_dat_eperm_t; | ||
153 | + | ||
135 | struct sockcmd { | 154 | struct sockcmd { |
136 | uint64_t cmd_num; | 155 | uint64_t cmd_num; |
137 | uint16_t cmd_id; | 156 | uint16_t cmd_id; |
138 | size_t data_len; | 157 | size_t data_len; |
139 | - char *data; | 158 | + void *data; |
140 | }; | 159 | }; |
141 | typedef struct sockcmd sockcmd_t; | 160 | typedef struct sockcmd sockcmd_t; |
142 | 161 |
@@ -803,11 +803,12 @@ static inline int so_call_sync(ctx_t *ctx_p, indexes_t *indexes_p, int n, api_ev | @@ -803,11 +803,12 @@ static inline int so_call_sync(ctx_t *ctx_p, indexes_t *indexes_p, int n, api_ev | ||
803 | threadinfo_p->try_n = 0; | 803 | threadinfo_p->try_n = 0; |
804 | threadinfo_p->callback = NULL; | 804 | threadinfo_p->callback = NULL; |
805 | threadinfo_p->argv = NULL; | 805 | threadinfo_p->argv = NULL; |
806 | - threadinfo_p->ctx_p = ctx_p; | 806 | + threadinfo_p->ctx_p = ctx_p; |
807 | threadinfo_p->starttime = time(NULL); | 807 | threadinfo_p->starttime = time(NULL); |
808 | threadinfo_p->fpath2ei_ht = g_hash_table_dup(indexes_p->fpath2ei_ht, g_str_hash, g_str_equal, free, free, (gpointer(*)(gpointer))strdup, eidup); | 808 | threadinfo_p->fpath2ei_ht = g_hash_table_dup(indexes_p->fpath2ei_ht, g_str_hash, g_str_equal, free, free, (gpointer(*)(gpointer))strdup, eidup); |
809 | threadinfo_p->n = n; | 809 | threadinfo_p->n = n; |
810 | threadinfo_p->ei = ei; | 810 | threadinfo_p->ei = ei; |
811 | + threadinfo_p->iteration = ctx_p->iteration_num; | ||
811 | 812 | ||
812 | if (ctx_p->synctimeout) | 813 | if (ctx_p->synctimeout) |
813 | threadinfo_p->expiretime = threadinfo_p->starttime + ctx_p->synctimeout; | 814 | threadinfo_p->expiretime = threadinfo_p->starttime + ctx_p->synctimeout; |
@@ -937,9 +938,10 @@ static inline int so_call_rsync(ctx_t *ctx_p, indexes_t *indexes_p, const char * | @@ -937,9 +938,10 @@ static inline int so_call_rsync(ctx_t *ctx_p, indexes_t *indexes_p, const char * | ||
937 | threadinfo_p->try_n = 0; | 938 | threadinfo_p->try_n = 0; |
938 | threadinfo_p->callback = NULL; | 939 | threadinfo_p->callback = NULL; |
939 | threadinfo_p->argv = xmalloc(sizeof(char *) * 3); | 940 | threadinfo_p->argv = xmalloc(sizeof(char *) * 3); |
940 | - threadinfo_p->ctx_p = ctx_p; | 941 | + threadinfo_p->ctx_p = ctx_p; |
941 | threadinfo_p->starttime = time(NULL); | 942 | threadinfo_p->starttime = time(NULL); |
942 | threadinfo_p->fpath2ei_ht = g_hash_table_dup(indexes_p->fpath2ei_ht, g_str_hash, g_str_equal, free, free, (gpointer(*)(gpointer))strdup, eidup); | 943 | threadinfo_p->fpath2ei_ht = g_hash_table_dup(indexes_p->fpath2ei_ht, g_str_hash, g_str_equal, free, free, (gpointer(*)(gpointer))strdup, eidup); |
944 | + threadinfo_p->iteration = ctx_p->iteration_num; | ||
943 | 945 | ||
944 | threadinfo_p->argv[0] = strdup(inclistfile); | 946 | threadinfo_p->argv[0] = strdup(inclistfile); |
945 | threadinfo_p->argv[1] = strdup(exclistfile); | 947 | threadinfo_p->argv[1] = strdup(exclistfile); |
@@ -1184,9 +1186,10 @@ static inline int sync_exec_thread(ctx_t *ctx_p, indexes_t *indexes_p, thread_ca | @@ -1184,9 +1186,10 @@ static inline int sync_exec_thread(ctx_t *ctx_p, indexes_t *indexes_p, thread_ca | ||
1184 | threadinfo_p->try_n = 0; | 1186 | threadinfo_p->try_n = 0; |
1185 | threadinfo_p->callback = callback; | 1187 | threadinfo_p->callback = callback; |
1186 | threadinfo_p->argv = argv; | 1188 | threadinfo_p->argv = argv; |
1187 | - threadinfo_p->ctx_p = ctx_p; | 1189 | + threadinfo_p->ctx_p = ctx_p; |
1188 | threadinfo_p->starttime = time(NULL); | 1190 | threadinfo_p->starttime = time(NULL); |
1189 | threadinfo_p->fpath2ei_ht = g_hash_table_dup(indexes_p->fpath2ei_ht, g_str_hash, g_str_equal, free, free, (gpointer(*)(gpointer))strdup, eidup); | 1191 | threadinfo_p->fpath2ei_ht = g_hash_table_dup(indexes_p->fpath2ei_ht, g_str_hash, g_str_equal, free, free, (gpointer(*)(gpointer))strdup, eidup); |
1192 | + threadinfo_p->iteration = ctx_p->iteration_num; | ||
1190 | 1193 | ||
1191 | if (ctx_p->synctimeout) | 1194 | if (ctx_p->synctimeout) |
1192 | threadinfo_p->expiretime = threadinfo_p->starttime + ctx_p->synctimeout; | 1195 | threadinfo_p->expiretime = threadinfo_p->starttime + ctx_p->synctimeout; |
@@ -2678,14 +2681,14 @@ int sync_idle_dosync_collectedevents(ctx_t *ctx_p, indexes_t *indexes_p) { | @@ -2678,14 +2681,14 @@ int sync_idle_dosync_collectedevents(ctx_t *ctx_p, indexes_t *indexes_p) { | ||
2678 | g_hash_table_remove_all(indexes_p->fpath2ei_ht); | 2681 | g_hash_table_remove_all(indexes_p->fpath2ei_ht); |
2679 | } | 2682 | } |
2680 | 2683 | ||
2681 | - if (!ctx_p->flags[THREADING]) { | 2684 | + if(ctx_p->iteration_num < ~0) // ~0 is the max value for unsigned variables |
2682 | - if(ctx_p->iteration_num < ~0) // ~0 is the max value for unsigned variables | 2685 | + ctx_p->iteration_num++; |
2683 | - ctx_p->iteration_num++; | 2686 | + |
2687 | + if (!ctx_p->flags[THREADING]) | ||
2684 | setenv_iteration(ctx_p->iteration_num); | 2688 | setenv_iteration(ctx_p->iteration_num); |
2685 | 2689 | ||
2686 | - debug(3, "next iteration: %u/%u", | 2690 | + debug(3, "next iteration: %u/%u", |
2687 | - ctx_p->iteration_num, ctx_p->flags[MAXITERATIONS]); | 2691 | + ctx_p->iteration_num, ctx_p->flags[MAXITERATIONS]); |
2688 | - } | ||
2689 | 2692 | ||
2690 | return 0; | 2693 | return 0; |
2691 | } | 2694 | } |
@@ -3306,9 +3309,9 @@ int sync_run(ctx_t *ctx_p) { | @@ -3306,9 +3309,9 @@ int sync_run(ctx_t *ctx_p) { | ||
3306 | ret = pthread_sigmask(SIG_BLOCK, &sigset_sighandler, NULL); | 3309 | ret = pthread_sigmask(SIG_BLOCK, &sigset_sighandler, NULL); |
3307 | if (ret) return ret; | 3310 | if (ret) return ret; |
3308 | 3311 | ||
3309 | - sighandler_arg.ctx_p = ctx_p; | 3312 | + sighandler_arg.ctx_p = ctx_p; |
3310 | -// sighandler_arg.indexes_p = &indexes; | 3313 | +// sighandler_arg.indexes_p = &indexes; |
3311 | - sighandler_arg.pthread_parent = pthread_self(); | 3314 | + sighandler_arg.pthread_parent = pthread_self(); |
3312 | sighandler_arg.exitcode_p = &ret; | 3315 | sighandler_arg.exitcode_p = &ret; |
3313 | sighandler_arg.sigset_p = &sigset_sighandler; | 3316 | sighandler_arg.sigset_p = &sigset_sighandler; |
3314 | ret = pthread_create(&pthread_sighandler, NULL, (void *(*)(void *))sync_sighandler, &sighandler_arg); | 3317 | ret = pthread_create(&pthread_sighandler, NULL, (void *(*)(void *))sync_sighandler, &sighandler_arg); |
@@ -3325,12 +3328,14 @@ int sync_run(ctx_t *ctx_p) { | @@ -3325,12 +3328,14 @@ int sync_run(ctx_t *ctx_p) { | ||
3325 | 3328 | ||
3326 | // Creating hash tables | 3329 | // Creating hash tables |
3327 | 3330 | ||
3328 | - indexes_t indexes = {NULL}; | 3331 | + indexes_t indexes = {NULL}; |
3329 | - indexes.wd2fpath_ht = g_hash_table_new_full(g_direct_hash, g_direct_equal, 0, 0); | 3332 | + ctx_p->indexes_p = &indexes; |
3330 | - indexes.fpath2wd_ht = g_hash_table_new_full(g_str_hash, g_str_equal, free, 0); | 3333 | + |
3331 | - indexes.fpath2ei_ht = g_hash_table_new_full(g_str_hash, g_str_equal, free, free); | 3334 | + indexes.wd2fpath_ht = g_hash_table_new_full(g_direct_hash, g_direct_equal, 0, 0); |
3332 | - indexes.exc_fpath_ht = g_hash_table_new_full(g_str_hash, g_str_equal, free, 0); | 3335 | + indexes.fpath2wd_ht = g_hash_table_new_full(g_str_hash, g_str_equal, free, 0); |
3333 | - indexes.out_lines_aggr_ht = g_hash_table_new_full(g_str_hash, g_str_equal, free, 0); | 3336 | + indexes.fpath2ei_ht = g_hash_table_new_full(g_str_hash, g_str_equal, free, free); |
3337 | + indexes.exc_fpath_ht = g_hash_table_new_full(g_str_hash, g_str_equal, free, 0); | ||
3338 | + indexes.out_lines_aggr_ht = g_hash_table_new_full(g_str_hash, g_str_equal, free, 0); | ||
3334 | i=0; | 3339 | i=0; |
3335 | while (i<QUEUE_MAX) { | 3340 | while (i<QUEUE_MAX) { |
3336 | switch (i) { | 3341 | switch (i) { |