clsync
Loading...
Searching...
No Matches
mon_dtracepipe.c
Go to the documentation of this file.
1/*
2 clsync - file tree sync utility based on inotify/kqueue
3
4 Copyright (C) 2013-2014 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#include "common.h"
20#include "malloc.h"
21#include "error.h"
22#include "indexes.h"
23#include "sync.h"
24#include "mon_dtracepipe.h"
25
26#define DTRACE_SCRIPT "BEGIN\
27{\
28 dir = $1;\
29 dirlen = strlen(dir);\
30}\
31\
32syscall::open*:entry\
33/\
34arg1 & (O_WRONLY|O_RDWR) &&\
35 substr(copyinstr(arg0),0,dirlen)==dir\
36/\
37{\
38 printf("%s\n",copyinstr(arg0));\
39}\
40\
41syscall::mkdir*:entry\
42/\
43 substr(copyinstr(arg0),0,dirlen)==dir\
44/\
45{\
46 printf("%s\n",copyinstr(arg0));\
47}"
48
49struct mondata {
50 FILE *pipe;
51};
52typedef struct mondata mondata_t;
53
54#define DTRACEPIPE_INIT_ERROR {\
55 free(ctx_p->fsmondata);\
56 ctx_p->fsmondata = NULL;\
57 return -1;\
58 }
59
61{
62 char cmd[BUFSIZ];
63 ctx_p->fsmondata = xcalloc ( sizeof ( mondata_t ), 1 );
65
66 if ( snprintf ( cmd, "%s -n '%s' '%s'", DTRACE_PATH, DTRACE_SCRIPT, ) >= BUFSIZ ) {
67 errno = EMSGSIZE;
68 error ( "Too long cmd." );
70 }
71
72 FILE *pipe = popen ( cmd, "r" );
73
74 if ( pipe == NULL ) {
75 error ( "Cannot popen(\""DTRACE_PATH"\", \"r\")" );
77 }
78
79 if ( setvbuf ( pipe, NULL, _IONBF, 0 ) ) {
80 error ( "Cannot set unbuffered mode for pipe of \""DTRACE_PATH"\" process" );
82 }
83
84 mondata->pipe = pipe;
85 return 0;
86}
87
90int dtracepipe_wait ( struct ctx *ctx_p, struct indexes *indexes_p, struct timeval *timeout_p )
91{
93 struct timeval timeout_abs, tv_abs;
94 int dontwait = 0;
95 struct dtracepipe_event *event_p = &mondata->event;
96
97 if ( timeout_p->tv_sec == 0 && timeout_p->tv_usec == 0 )
98 dontwait = 1;
99
100 if ( !dontwait ) {
101 gettimeofday ( &tv_abs, NULL );
102 timeradd ( &tv_abs, timeout_p, &timeout_abs );
103 }
104
105 int pipe_fd = fileno ( mondata->pipe );
106
107 while ( 42 ) {
108 int path_count;
109
110 // Checking if there already a recond in mondata
111 if ( *event_p->path ) {
112 debug ( 2, "we have an event. return 1." );
113 return 1;
114 }
115
116 // Getting a record
117 {
118 debug ( 3, "select() with timeout %li.%06li secs (dontwait == %u).", timeout_p->tv_sec, timeout_p->tv_usec, dontwait );
119 fd_set rfds;
120 FD_ZERO ( &rfds );
121 FD_SET ( pipe_fd, &rfds );
122 int rc = select ( pipe_fd + 1, &rfds, NULL, NULL, timeout_p );
123
124 if ( rc == 0 || rc == -1 )
125 return rc;
126
127 line_len = getline ( &dtracepipe_wait_line, &dtracepipe_wait_line_siz, mondata->pipe );
128
129 if ( line_len == -1 ) {
130 error ( "Cannot read line from \""DTRACE_PATH"\" pipe [using getline()]" );
131 return -1;
132 }
133
134 if ( !dontwait ) {
135 debug ( 5, "old timeout_p->: tv_sec == %lu; tv_usec == %lu", timeout_p->tv_sec, timeout_p->tv_usec );
136 gettimeofday ( &tv_abs, NULL );
137
138 if ( timercmp ( &timeout_abs, &tv_abs, < ) )
139 timersub ( &timeout_abs, &tv_abs, timeout_p );
140 else
141 memset ( timeout_p, 0, sizeof ( *timeout_p ) );
142
143 debug ( 5, "new timeout_p->: tv_sec == %lu; tv_usec == %lu", timeout_p->tv_sec, timeout_p->tv_usec );
144 }
145 }
146 // Parsing the record
147 path_count = 0;
148 debug ( 3, "parsing the event" );
149
150 while ( au_parsed < au_len ) {
151 if ( au_fetch_tok ( &tok, &au_buf[au_parsed], au_len - au_parsed ) == -1 )
152 return -1;
153
154 au_parsed += tok.len;
155
156 switch ( tok.id ) {
157 case AUT_HEADER32:
158 case AUT_HEADER32_EX:
159 case AUT_HEADER64:
160 case AUT_HEADER64_EX: {
161 event_p->type = tok.tt.hdr32.e_type;
162 path_count = 0;
163 break;
164 }
165
166 case AUT_PATH: {
167 char *ptr;
168 int dir_wd, dir_iswatched;
169 ptr = memrchr ( tok.tt.path.path, '/', tok.tt.path.len );
170#ifdef PARANOID
171
172 if ( ptr == NULL )
173 critical ( "relative path received from au_fetch_tok(): \"%s\" (len: %u)", tok.tt.path.path, tok.tt.path.len );
174
175#endif
176 debug ( 6, "Event on \"%s\".", tok.tt.path.path );
177 *ptr = 0;
178 dir_wd = indexes_fpath2wd ( indexes_p, tok.tt.path.path );
179 dir_iswatched = ( dir_wd != -1 );
180 debug ( 7, "Directory is \"%s\". dir_wd == %i; dir_iswatched == %u", tok.tt.path.path, dir_wd, dir_iswatched );
181 *ptr = '/';
182
183 if ( dir_iswatched ) {
184 debug ( 5, "Event on \"%s\" is watched. Pushing. path_count == %u", tok.tt.path.path, path_count );
185
186 switch ( path_count ) {
187 case 0:
188 memcpy ( event_p->path, tok.tt.path.path, tok.tt.path.len + 1 );
189 break;
190
191 case 1:
192 memcpy ( event_p->path_to, tok.tt.path.path, tok.tt.path.len + 1 );
193 break;
194#ifdef PARANOID
195
196 default:
197 warning ( "To many paths on BSM event: \"%s\" (already count: %u)", tok.tt.path.path, path_count );
198 break;
199#endif
200 }
201 }
202
203 path_count++;
204 break;
205 }
206
207 default:
208 continue;
209 }
210 }
211
212 // Cleanup
213 debug ( 4, "clean up" );
214 free ( au_buf );
215 au_buf = NULL;
216 au_len = 0;
217 au_parsed = 0;
218 }
219
220 return -1;
221}
222int dtracepipe_handle ( struct ctx *ctx_p, struct indexes *indexes_p )
223{
224 return -1;
225}
226int dtracepipe_add_watch_dir ( struct ctx *ctx_p, struct indexes *indexes_p, const char *const accpath )
227{
228 return -1;
229}
231{
233 free ( dtracepipe_wait_line );
234 free ( mondata );
235 return -1;
236}
#define BUFSIZ
#define DTRACE_PATH
#define critical(...)
Definition error.h:32
#define error(...)
Definition error.h:36
#define debug(debug_level,...)
Definition error.h:50
#define warning(...)
Definition error.h:40
size_t dtracepipe_wait_line_siz
int dtracepipe_deinit(ctx_t *ctx_p)
#define DTRACEPIPE_INIT_ERROR
#define DTRACE_SCRIPT
int dtracepipe_wait(struct ctx *ctx_p, struct indexes *indexes_p, struct timeval *timeout_p)
int dtracepipe_init(ctx_t *ctx_p)
int dtracepipe_handle(struct ctx *ctx_p, struct indexes *indexes_p)
char * dtracepipe_wait_line
int dtracepipe_add_watch_dir(struct ctx *ctx_p, struct indexes *indexes_p, const char *const accpath)
ctx_t * ctx_p
Definition mon_kqueue.c:85
Definition ctx.h:315
void * fsmondata
Definition ctx.h:419
struct bsm_event * event
Definition mon_bsm.c:46
FILE * pipe
Definition mon_bsm.c:41