<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <title>libinotifytools: inotifytools.c Source File</title> <link href="tabs.css" rel="stylesheet" type="text/css"> <link href="doxygen.css" rel="stylesheet" type="text/css"> </head><body> <!-- Generated by Doxygen 1.5.9 --> <div class="navigation" id="top"> <div class="tabs"> <ul> <li><a href="index.html"><span>Main Page</span></a></li> <li><a href="pages.html"><span>Related Pages</span></a></li> <li class="current"><a href="files.html"><span>Files</span></a></li> </ul> </div> <div class="tabs"> <ul> <li><a href="files.html"><span>File List</span></a></li> <li><a href="globals.html"><span>File Members</span></a></li> </ul> </div> <h1>inotifytools.c</h1><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">// kate: replace-tabs off; space-indent off;</span> <a name="l00002"></a>00002 <a name="l00015"></a>00015 <span class="preprocessor">#include "../../config.h"</span> <a name="l00016"></a>00016 <span class="preprocessor">#include "<a class="code" href="inotifytools_8h.html" title="inotifytools library public interface.">inotifytools/inotifytools.h</a>"</span> <a name="l00017"></a>00017 <span class="preprocessor">#include "inotifytools_p.h"</span> <a name="l00018"></a>00018 <a name="l00019"></a>00019 <span class="preprocessor">#include <string.h></span> <a name="l00020"></a>00020 <span class="preprocessor">#include <strings.h></span> <a name="l00021"></a>00021 <span class="preprocessor">#include <stdlib.h></span> <a name="l00022"></a>00022 <span class="preprocessor">#include <stdio.h></span> <a name="l00023"></a>00023 <span class="preprocessor">#include <errno.h></span> <a name="l00024"></a>00024 <span class="preprocessor">#include <sys/select.h></span> <a name="l00025"></a>00025 <span class="preprocessor">#include <sys/types.h></span> <a name="l00026"></a>00026 <span class="preprocessor">#include <sys/stat.h></span> <a name="l00027"></a>00027 <span class="preprocessor">#include <sys/ioctl.h></span> <a name="l00028"></a>00028 <span class="preprocessor">#include <unistd.h></span> <a name="l00029"></a>00029 <span class="preprocessor">#include <dirent.h></span> <a name="l00030"></a>00030 <span class="preprocessor">#include <time.h></span> <a name="l00031"></a>00031 <span class="preprocessor">#include <regex.h></span> <a name="l00032"></a>00032 <span class="preprocessor">#include <setjmp.h></span> <a name="l00033"></a>00033 <a name="l00034"></a>00034 <span class="preprocessor">#include "inotifytools/inotify.h"</span> <a name="l00035"></a>00035 <a name="l00122"></a>00122 <span class="preprocessor">#define MAX_EVENTS 4096</span> <a name="l00123"></a>00123 <span class="preprocessor"></span><span class="preprocessor">#define MAX_STRLEN 4096</span> <a name="l00124"></a>00124 <span class="preprocessor"></span><span class="preprocessor">#define INOTIFY_PROCDIR "/proc/sys/fs/inotify/"</span> <a name="l00125"></a>00125 <span class="preprocessor"></span><span class="preprocessor">#define WATCHES_SIZE_PATH INOTIFY_PROCDIR "max_user_watches"</span> <a name="l00126"></a>00126 <span class="preprocessor"></span><span class="preprocessor">#define QUEUE_SIZE_PATH INOTIFY_PROCDIR "max_queued_watches"</span> <a name="l00127"></a>00127 <span class="preprocessor"></span><span class="preprocessor">#define INSTANCES_PATH INOTIFY_PROCDIR "max_user_instances"</span> <a name="l00128"></a>00128 <span class="preprocessor"></span> <a name="l00129"></a>00129 <span class="keyword">static</span> <span class="keywordtype">int</span> inotify_fd; <a name="l00130"></a>00130 <span class="keyword">static</span> <span class="keywordtype">unsigned</span> num_access; <a name="l00131"></a>00131 <span class="keyword">static</span> <span class="keywordtype">unsigned</span> num_modify; <a name="l00132"></a>00132 <span class="keyword">static</span> <span class="keywordtype">unsigned</span> num_attrib; <a name="l00133"></a>00133 <span class="keyword">static</span> <span class="keywordtype">unsigned</span> num_close_nowrite; <a name="l00134"></a>00134 <span class="keyword">static</span> <span class="keywordtype">unsigned</span> num_close_write; <a name="l00135"></a>00135 <span class="keyword">static</span> <span class="keywordtype">unsigned</span> num_open; <a name="l00136"></a>00136 <span class="keyword">static</span> <span class="keywordtype">unsigned</span> num_move_self; <a name="l00137"></a>00137 <span class="keyword">static</span> <span class="keywordtype">unsigned</span> num_moved_to; <a name="l00138"></a>00138 <span class="keyword">static</span> <span class="keywordtype">unsigned</span> num_moved_from; <a name="l00139"></a>00139 <span class="keyword">static</span> <span class="keywordtype">unsigned</span> num_create; <a name="l00140"></a>00140 <span class="keyword">static</span> <span class="keywordtype">unsigned</span> num_delete; <a name="l00141"></a>00141 <span class="keyword">static</span> <span class="keywordtype">unsigned</span> num_delete_self; <a name="l00142"></a>00142 <span class="keyword">static</span> <span class="keywordtype">unsigned</span> num_unmount; <a name="l00143"></a>00143 <span class="keyword">static</span> <span class="keywordtype">unsigned</span> num_total; <a name="l00144"></a>00144 <span class="keyword">static</span> <span class="keywordtype">int</span> collect_stats = 0; <a name="l00145"></a>00145 <a name="l00146"></a>00146 <span class="keyword">struct </span>rbtree *tree_wd = 0; <a name="l00147"></a>00147 <span class="keyword">struct </span>rbtree *tree_filename = 0; <a name="l00148"></a>00148 <span class="keyword">static</span> <span class="keywordtype">int</span> error = 0; <a name="l00149"></a>00149 <span class="keyword">static</span> <span class="keywordtype">int</span> init = 0; <a name="l00150"></a>00150 <span class="keyword">static</span> <span class="keywordtype">char</span>* timefmt = 0; <a name="l00151"></a>00151 <span class="keyword">static</span> regex_t* regex = 0; <a name="l00152"></a>00152 <a name="l00153"></a>00153 <span class="keywordtype">int</span> isdir( <span class="keywordtype">char</span> <span class="keyword">const</span> * path ); <a name="l00154"></a>00154 <span class="keywordtype">void</span> record_stats( <span class="keyword">struct</span> inotify_event <span class="keyword">const</span> * event ); <a name="l00155"></a>00155 <span class="keywordtype">int</span> onestr_to_event(<span class="keywordtype">char</span> <span class="keyword">const</span> * event); <a name="l00156"></a>00156 <a name="l00174"></a>00174 <span class="preprocessor">#define niceassert(cond,mesg) _niceassert((long)cond, __LINE__, __FILE__, \</span> <a name="l00175"></a>00175 <span class="preprocessor"> #cond, mesg)</span> <a name="l00176"></a>00176 <span class="preprocessor"></span> <a name="l00177"></a>00177 <span class="preprocessor">#define nasprintf(...) niceassert( -1 != asprintf(__VA_ARGS__), "out of memory")</span> <a name="l00178"></a>00178 <span class="preprocessor"></span> <a name="l00196"></a>00196 <span class="keywordtype">void</span> _niceassert( <span class="keywordtype">long</span> cond, <span class="keywordtype">int</span> line, <span class="keywordtype">char</span> <span class="keyword">const</span> * file, <span class="keywordtype">char</span> <span class="keyword">const</span> * condstr, <a name="l00197"></a>00197 <span class="keywordtype">char</span> <span class="keyword">const</span> * mesg ) { <a name="l00198"></a>00198 <span class="keywordflow">if</span> ( cond ) <span class="keywordflow">return</span>; <a name="l00199"></a>00199 <a name="l00200"></a>00200 <span class="keywordflow">if</span> ( mesg ) { <a name="l00201"></a>00201 fprintf(stderr, <span class="stringliteral">"%s:%d assertion ( %s ) failed: %s\n"</span>, file, line, <a name="l00202"></a>00202 condstr, mesg ); <a name="l00203"></a>00203 } <a name="l00204"></a>00204 <span class="keywordflow">else</span> { <a name="l00205"></a>00205 fprintf(stderr, <span class="stringliteral">"%s:%d assertion ( %s ) failed.\n"</span>, file, line, condstr); <a name="l00206"></a>00206 } <a name="l00207"></a>00207 } <a name="l00208"></a>00208 <a name="l00218"></a>00218 <span class="keywordtype">char</span> * chrtostr(<span class="keywordtype">char</span> ch) { <a name="l00219"></a>00219 <span class="keyword">static</span> <span class="keywordtype">char</span> str[2] = { <span class="charliteral">'\0'</span>, <span class="charliteral">'\0'</span> }; <a name="l00220"></a>00220 str[0] = ch; <a name="l00221"></a>00221 <span class="keywordflow">return</span> str; <a name="l00222"></a>00222 } <a name="l00223"></a>00223 <a name="l00227"></a>00227 <span class="keywordtype">int</span> read_num_from_file( <span class="keywordtype">char</span> * filename, <span class="keywordtype">int</span> * num ) { <a name="l00228"></a>00228 FILE * file = fopen( filename, <span class="stringliteral">"r"</span> ); <a name="l00229"></a>00229 <span class="keywordflow">if</span> ( !file ) { <a name="l00230"></a>00230 error = errno; <a name="l00231"></a>00231 <span class="keywordflow">return</span> 0; <a name="l00232"></a>00232 } <a name="l00233"></a>00233 <a name="l00234"></a>00234 <span class="keywordflow">if</span> ( EOF == fscanf( file, <span class="stringliteral">"%d"</span>, num ) ) { <a name="l00235"></a>00235 error = errno; <a name="l00236"></a>00236 <span class="keywordflow">return</span> 0; <a name="l00237"></a>00237 } <a name="l00238"></a>00238 <a name="l00239"></a>00239 niceassert( 0 == fclose( file ), 0 ); <a name="l00240"></a>00240 <a name="l00241"></a>00241 <span class="keywordflow">return</span> 1; <a name="l00242"></a>00242 } <a name="l00243"></a>00243 <a name="l00244"></a>00244 <span class="keywordtype">int</span> wd_compare(<span class="keyword">const</span> <span class="keywordtype">void</span> *d1, <span class="keyword">const</span> <span class="keywordtype">void</span> *d2, <span class="keyword">const</span> <span class="keywordtype">void</span> *config) { <a name="l00245"></a>00245 <span class="keywordflow">if</span> (!d1 || !d2) <span class="keywordflow">return</span> d1 - d2; <a name="l00246"></a>00246 <span class="keywordflow">return</span> ((watch*)d1)->wd - ((watch*)d2)->wd; <a name="l00247"></a>00247 } <a name="l00248"></a>00248 <a name="l00249"></a>00249 <span class="keywordtype">int</span> filename_compare(<span class="keyword">const</span> <span class="keywordtype">void</span> *d1, <span class="keyword">const</span> <span class="keywordtype">void</span> *d2, <span class="keyword">const</span> <span class="keywordtype">void</span> *config) { <a name="l00250"></a>00250 <span class="keywordflow">if</span> (!d1 || !d2) <span class="keywordflow">return</span> d1 - d2; <a name="l00251"></a>00251 <span class="keywordflow">return</span> strcmp(((watch*)d1)->filename, ((watch*)d2)->filename); <a name="l00252"></a>00252 } <a name="l00253"></a>00253 <a name="l00257"></a>00257 watch *watch_from_wd( <span class="keywordtype">int</span> wd ) { <a name="l00258"></a>00258 watch w; <a name="l00259"></a>00259 w.wd = wd; <a name="l00260"></a>00260 <span class="keywordflow">return</span> (watch*)rbfind(&w, tree_wd); <a name="l00261"></a>00261 } <a name="l00262"></a>00262 <a name="l00266"></a>00266 watch *watch_from_filename( <span class="keywordtype">char</span> <span class="keyword">const</span> *filename ) { <a name="l00267"></a>00267 watch w; <a name="l00268"></a>00268 w.filename = (<span class="keywordtype">char</span>*)filename; <a name="l00269"></a>00269 <span class="keywordflow">return</span> (watch*)rbfind(&w, tree_filename); <a name="l00270"></a>00270 } <a name="l00271"></a>00271 <a name="l00281"></a><a class="code" href="inotifytools_8h.html#3765c7874caeb0732926f34ae3c3cd63">00281</a> <span class="keywordtype">int</span> <a class="code" href="inotifytools_8h.html#3765c7874caeb0732926f34ae3c3cd63">inotifytools_initialize</a>() { <a name="l00282"></a>00282 <span class="keywordflow">if</span> (init) <span class="keywordflow">return</span> 1; <a name="l00283"></a>00283 <a name="l00284"></a>00284 error = 0; <a name="l00285"></a>00285 <span class="comment">// Try to initialise inotify</span> <a name="l00286"></a>00286 inotify_fd = inotify_init(); <a name="l00287"></a>00287 <span class="keywordflow">if</span> (inotify_fd < 0) { <a name="l00288"></a>00288 error = inotify_fd; <a name="l00289"></a>00289 <span class="keywordflow">return</span> 0; <a name="l00290"></a>00290 } <a name="l00291"></a>00291 <a name="l00292"></a>00292 collect_stats = 0; <a name="l00293"></a>00293 init = 1; <a name="l00294"></a>00294 tree_wd = rbinit(wd_compare, 0); <a name="l00295"></a>00295 tree_filename = rbinit(filename_compare, 0); <a name="l00296"></a>00296 timefmt = 0; <a name="l00297"></a>00297 <a name="l00298"></a>00298 <span class="keywordflow">return</span> 1; <a name="l00299"></a>00299 } <a name="l00300"></a>00300 <a name="l00304"></a>00304 <span class="keywordtype">void</span> destroy_watch(watch *w) { <a name="l00305"></a>00305 <span class="keywordflow">if</span> (w->filename) free(w->filename); <a name="l00306"></a>00306 free(w); <a name="l00307"></a>00307 } <a name="l00308"></a>00308 <a name="l00312"></a>00312 <span class="keywordtype">void</span> cleanup_tree(<span class="keyword">const</span> <span class="keywordtype">void</span> *nodep, <a name="l00313"></a>00313 <span class="keyword">const</span> VISIT which, <a name="l00314"></a>00314 <span class="keyword">const</span> <span class="keywordtype">int</span> depth, <span class="keywordtype">void</span>* arg) { <a name="l00315"></a>00315 <span class="keywordflow">if</span> (which != endorder && which != leaf) <span class="keywordflow">return</span>; <a name="l00316"></a>00316 watch *w = (watch*)nodep; <a name="l00317"></a>00317 destroy_watch(w); <a name="l00318"></a>00318 } <a name="l00319"></a>00319 <a name="l00326"></a><a class="code" href="inotifytools_8h.html#7efdc91ac4b26c374d287aa11b3af994">00326</a> <span class="keywordtype">void</span> <a class="code" href="inotifytools_8h.html#7efdc91ac4b26c374d287aa11b3af994">inotifytools_cleanup</a>() { <a name="l00327"></a>00327 <span class="keywordflow">if</span> (!init) <span class="keywordflow">return</span>; <a name="l00328"></a>00328 <a name="l00329"></a>00329 init = 0; <a name="l00330"></a>00330 close(inotify_fd); <a name="l00331"></a>00331 collect_stats = 0; <a name="l00332"></a>00332 error = 0; <a name="l00333"></a>00333 timefmt = 0; <a name="l00334"></a>00334 <a name="l00335"></a>00335 <span class="keywordflow">if</span> (regex) { <a name="l00336"></a>00336 regfree(regex); <a name="l00337"></a>00337 free(regex); <a name="l00338"></a>00338 regex = 0; <a name="l00339"></a>00339 } <a name="l00340"></a>00340 <a name="l00341"></a>00341 rbwalk(tree_wd, cleanup_tree, 0); <a name="l00342"></a>00342 rbdestroy(tree_wd); tree_wd = 0; <a name="l00343"></a>00343 rbdestroy(tree_filename); tree_filename = 0; <a name="l00344"></a>00344 } <a name="l00345"></a>00345 <a name="l00349"></a>00349 <span class="keywordtype">void</span> empty_stats(<span class="keyword">const</span> <span class="keywordtype">void</span> *nodep, <a name="l00350"></a>00350 <span class="keyword">const</span> VISIT which, <a name="l00351"></a>00351 <span class="keyword">const</span> <span class="keywordtype">int</span> depth, <span class="keywordtype">void</span> *arg) { <a name="l00352"></a>00352 <span class="keywordflow">if</span> (which != endorder && which != leaf) <span class="keywordflow">return</span>; <a name="l00353"></a>00353 watch *w = (watch*)nodep; <a name="l00354"></a>00354 w->hit_access = 0; <a name="l00355"></a>00355 w->hit_modify = 0; <a name="l00356"></a>00356 w->hit_attrib = 0; <a name="l00357"></a>00357 w->hit_close_nowrite = 0; <a name="l00358"></a>00358 w->hit_close_write = 0; <a name="l00359"></a>00359 w->hit_open = 0; <a name="l00360"></a>00360 w->hit_move_self = 0; <a name="l00361"></a>00361 w->hit_moved_from = 0; <a name="l00362"></a>00362 w->hit_moved_to = 0; <a name="l00363"></a>00363 w->hit_create = 0; <a name="l00364"></a>00364 w->hit_delete = 0; <a name="l00365"></a>00365 w->hit_delete_self = 0; <a name="l00366"></a>00366 w->hit_unmount = 0; <a name="l00367"></a>00367 w->hit_total = 0; <a name="l00368"></a>00368 } <a name="l00369"></a>00369 <a name="l00373"></a>00373 <span class="keywordtype">void</span> replace_filename(<span class="keyword">const</span> <span class="keywordtype">void</span> *nodep, <a name="l00374"></a>00374 <span class="keyword">const</span> VISIT which, <a name="l00375"></a>00375 <span class="keyword">const</span> <span class="keywordtype">int</span> depth, <span class="keywordtype">void</span> *arg) { <a name="l00376"></a>00376 <span class="keywordflow">if</span> (which != endorder && which != leaf) <span class="keywordflow">return</span>; <a name="l00377"></a>00377 watch *w = (watch*)nodep; <a name="l00378"></a>00378 <span class="keywordtype">char</span> *old_name = ((<span class="keywordtype">char</span>**)arg)[0]; <a name="l00379"></a>00379 <span class="keywordtype">char</span> *new_name = ((<span class="keywordtype">char</span>**)arg)[1]; <a name="l00380"></a>00380 <span class="keywordtype">int</span> old_len = *((<span class="keywordtype">int</span>*)&((<span class="keywordtype">char</span>**)arg)[2]); <a name="l00381"></a>00381 <span class="keywordtype">char</span> *name; <a name="l00382"></a>00382 <span class="keywordflow">if</span> ( 0 == strncmp( old_name, w->filename, old_len ) ) { <a name="l00383"></a>00383 nasprintf( &name, <span class="stringliteral">"%s%s"</span>, new_name, &(w->filename[old_len]) ); <a name="l00384"></a>00384 <span class="keywordflow">if</span> (!strcmp( w->filename, new_name )) { <a name="l00385"></a>00385 free(name); <a name="l00386"></a>00386 } <span class="keywordflow">else</span> { <a name="l00387"></a>00387 rbdelete(w, tree_filename); <a name="l00388"></a>00388 free( w->filename ); <a name="l00389"></a>00389 w->filename = name; <a name="l00390"></a>00390 rbsearch(w, tree_filename); <a name="l00391"></a>00391 } <a name="l00392"></a>00392 } <a name="l00393"></a>00393 } <a name="l00394"></a>00394 <a name="l00398"></a>00398 <span class="keywordtype">void</span> get_num(<span class="keyword">const</span> <span class="keywordtype">void</span> *nodep, <a name="l00399"></a>00399 <span class="keyword">const</span> VISIT which, <a name="l00400"></a>00400 <span class="keyword">const</span> <span class="keywordtype">int</span> depth, <span class="keywordtype">void</span> *arg) { <a name="l00401"></a>00401 <span class="keywordflow">if</span> (which != endorder && which != leaf) <span class="keywordflow">return</span>; <a name="l00402"></a>00402 ++(*((<span class="keywordtype">int</span>*)arg)); <a name="l00403"></a>00403 } <a name="l00404"></a>00404 <a name="l00405"></a>00405 <a name="l00418"></a><a class="code" href="inotifytools_8h.html#e25cb60b12e3555795f55fb8c55db692">00418</a> <span class="keywordtype">void</span> <a class="code" href="inotifytools_8h.html#e25cb60b12e3555795f55fb8c55db692">inotifytools_initialize_stats</a>() { <a name="l00419"></a>00419 niceassert( init, <span class="stringliteral">"inotifytools_initialize not called yet"</span> ); <a name="l00420"></a>00420 <a name="l00421"></a>00421 <span class="comment">// if already collecting stats, reset stats</span> <a name="l00422"></a>00422 <span class="keywordflow">if</span> (collect_stats) { <a name="l00423"></a>00423 rbwalk(tree_wd, empty_stats, 0); <a name="l00424"></a>00424 } <a name="l00425"></a>00425 <a name="l00426"></a>00426 num_access = 0; <a name="l00427"></a>00427 num_modify = 0; <a name="l00428"></a>00428 num_attrib = 0; <a name="l00429"></a>00429 num_close_nowrite = 0; <a name="l00430"></a>00430 num_close_write = 0; <a name="l00431"></a>00431 num_open = 0; <a name="l00432"></a>00432 num_move_self = 0; <a name="l00433"></a>00433 num_moved_from = 0; <a name="l00434"></a>00434 num_moved_to = 0; <a name="l00435"></a>00435 num_create = 0; <a name="l00436"></a>00436 num_delete = 0; <a name="l00437"></a>00437 num_delete_self = 0; <a name="l00438"></a>00438 num_unmount = 0; <a name="l00439"></a>00439 num_total = 0; <a name="l00440"></a>00440 <a name="l00441"></a>00441 collect_stats = 1; <a name="l00442"></a>00442 } <a name="l00443"></a>00443 <a name="l00471"></a><a class="code" href="inotifytools_8h.html#7e26c94c983d93669813c439883b334f">00471</a> <span class="keywordtype">int</span> <a class="code" href="inotifytools_8h.html#7e26c94c983d93669813c439883b334f">inotifytools_str_to_event_sep</a>(<span class="keywordtype">char</span> <span class="keyword">const</span> * event, <span class="keywordtype">char</span> sep) { <a name="l00472"></a>00472 <span class="keywordflow">if</span> ( strchr( <span class="stringliteral">"_"</span> <span class="stringliteral">"abcdefghijklmnopqrstuvwxyz"</span> <a name="l00473"></a>00473 <span class="stringliteral">"ABCDEFGHIJKLMNOPQRSTUVWXYZ"</span>, sep ) ) { <a name="l00474"></a>00474 <span class="keywordflow">return</span> -1; <a name="l00475"></a>00475 } <a name="l00476"></a>00476 <a name="l00477"></a>00477 <span class="keywordtype">int</span> ret, ret1, len; <a name="l00478"></a>00478 <span class="keywordtype">char</span> * event1, * event2; <a name="l00479"></a>00479 <span class="keywordtype">char</span> eventstr[4096]; <a name="l00480"></a>00480 ret = 0; <a name="l00481"></a>00481 <a name="l00482"></a>00482 <span class="keywordflow">if</span> ( !event || !event[0] ) <span class="keywordflow">return</span> 0; <a name="l00483"></a>00483 <a name="l00484"></a>00484 event1 = (<span class="keywordtype">char</span> *)event; <a name="l00485"></a>00485 event2 = strchr( event1, sep ); <a name="l00486"></a>00486 <span class="keywordflow">while</span> ( event1 && event1[0] ) { <a name="l00487"></a>00487 <span class="keywordflow">if</span> ( event2 ) { <a name="l00488"></a>00488 len = event2 - event1; <a name="l00489"></a>00489 niceassert( len < 4096, <span class="stringliteral">"malformed event string (very long)"</span> ); <a name="l00490"></a>00490 } <a name="l00491"></a>00491 <span class="keywordflow">else</span> { <a name="l00492"></a>00492 len = strlen(event1); <a name="l00493"></a>00493 } <a name="l00494"></a>00494 <span class="keywordflow">if</span> ( len > 4095 ) len = 4095; <a name="l00495"></a>00495 strncpy( eventstr, event1, len ); <a name="l00496"></a>00496 eventstr[len] = 0; <a name="l00497"></a>00497 <a name="l00498"></a>00498 ret1 = onestr_to_event( eventstr ); <a name="l00499"></a>00499 <span class="keywordflow">if</span> ( 0 == ret1 || -1 == ret1 ) { <a name="l00500"></a>00500 ret = ret1; <a name="l00501"></a>00501 <span class="keywordflow">break</span>; <a name="l00502"></a>00502 } <a name="l00503"></a>00503 ret |= ret1; <a name="l00504"></a>00504 <a name="l00505"></a>00505 event1 = event2; <a name="l00506"></a>00506 <span class="keywordflow">if</span> ( event1 && event1[0] ) { <a name="l00507"></a>00507 <span class="comment">// jump over 'sep' character</span> <a name="l00508"></a>00508 ++event1; <a name="l00509"></a>00509 <span class="comment">// if last character was 'sep'...</span> <a name="l00510"></a>00510 <span class="keywordflow">if</span> ( !event1[0] ) <span class="keywordflow">return</span> 0; <a name="l00511"></a>00511 event2 = strchr( event1, sep ); <a name="l00512"></a>00512 } <a name="l00513"></a>00513 } <a name="l00514"></a>00514 <a name="l00515"></a>00515 <span class="keywordflow">return</span> ret; <a name="l00516"></a>00516 } <a name="l00517"></a>00517 <a name="l00541"></a><a class="code" href="inotifytools_8h.html#c5f03415912fa505bcb7f2caf9273b45">00541</a> <span class="keywordtype">int</span> <a class="code" href="inotifytools_8h.html#c5f03415912fa505bcb7f2caf9273b45">inotifytools_str_to_event</a>(<span class="keywordtype">char</span> <span class="keyword">const</span> * event) { <a name="l00542"></a>00542 <span class="keywordflow">return</span> <a class="code" href="inotifytools_8h.html#7e26c94c983d93669813c439883b334f">inotifytools_str_to_event_sep</a>( event, <span class="charliteral">','</span> ); <a name="l00543"></a>00543 } <a name="l00544"></a>00544 <a name="l00556"></a>00556 <span class="keywordtype">int</span> onestr_to_event(<span class="keywordtype">char</span> <span class="keyword">const</span> * event) <a name="l00557"></a>00557 { <a name="l00558"></a>00558 <span class="keyword">static</span> <span class="keywordtype">int</span> ret; <a name="l00559"></a>00559 ret = -1; <a name="l00560"></a>00560 <a name="l00561"></a>00561 <span class="keywordflow">if</span> ( !event || !event[0] ) <a name="l00562"></a>00562 ret = 0; <a name="l00563"></a>00563 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( 0 == strcasecmp(event, <span class="stringliteral">"ACCESS"</span>) ) <a name="l00564"></a>00564 ret = IN_ACCESS; <a name="l00565"></a>00565 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( 0 == strcasecmp(event, <span class="stringliteral">"MODIFY"</span>) ) <a name="l00566"></a>00566 ret = IN_MODIFY; <a name="l00567"></a>00567 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( 0 == strcasecmp(event, <span class="stringliteral">"ATTRIB"</span>) ) <a name="l00568"></a>00568 ret = IN_ATTRIB; <a name="l00569"></a>00569 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( 0 == strcasecmp(event, <span class="stringliteral">"CLOSE_WRITE"</span>) ) <a name="l00570"></a>00570 ret = IN_CLOSE_WRITE; <a name="l00571"></a>00571 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( 0 == strcasecmp(event, <span class="stringliteral">"CLOSE_NOWRITE"</span>) ) <a name="l00572"></a>00572 ret = IN_CLOSE_NOWRITE; <a name="l00573"></a>00573 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( 0 == strcasecmp(event, <span class="stringliteral">"OPEN"</span>) ) <a name="l00574"></a>00574 ret = IN_OPEN; <a name="l00575"></a>00575 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( 0 == strcasecmp(event, <span class="stringliteral">"MOVED_FROM"</span>) ) <a name="l00576"></a>00576 ret = IN_MOVED_FROM; <a name="l00577"></a>00577 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( 0 == strcasecmp(event, <span class="stringliteral">"MOVED_TO"</span>) ) <a name="l00578"></a>00578 ret = IN_MOVED_TO; <a name="l00579"></a>00579 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( 0 == strcasecmp(event, <span class="stringliteral">"CREATE"</span>) ) <a name="l00580"></a>00580 ret = IN_CREATE; <a name="l00581"></a>00581 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( 0 == strcasecmp(event, <span class="stringliteral">"DELETE"</span>) ) <a name="l00582"></a>00582 ret = IN_DELETE; <a name="l00583"></a>00583 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( 0 == strcasecmp(event, <span class="stringliteral">"DELETE_SELF"</span>) ) <a name="l00584"></a>00584 ret = IN_DELETE_SELF; <a name="l00585"></a>00585 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( 0 == strcasecmp(event, <span class="stringliteral">"UNMOUNT"</span>) ) <a name="l00586"></a>00586 ret = IN_UNMOUNT; <a name="l00587"></a>00587 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( 0 == strcasecmp(event, <span class="stringliteral">"Q_OVERFLOW"</span>) ) <a name="l00588"></a>00588 ret = IN_Q_OVERFLOW; <a name="l00589"></a>00589 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( 0 == strcasecmp(event, <span class="stringliteral">"IGNORED"</span>) ) <a name="l00590"></a>00590 ret = IN_IGNORED; <a name="l00591"></a>00591 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( 0 == strcasecmp(event, <span class="stringliteral">"CLOSE"</span>) ) <a name="l00592"></a>00592 ret = IN_CLOSE; <a name="l00593"></a>00593 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( 0 == strcasecmp(event, <span class="stringliteral">"MOVE_SELF"</span>) ) <a name="l00594"></a>00594 ret = IN_MOVE_SELF; <a name="l00595"></a>00595 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( 0 == strcasecmp(event, <span class="stringliteral">"MOVE"</span>) ) <a name="l00596"></a>00596 ret = IN_MOVE; <a name="l00597"></a>00597 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( 0 == strcasecmp(event, <span class="stringliteral">"ISDIR"</span>) ) <a name="l00598"></a>00598 ret = IN_ISDIR; <a name="l00599"></a>00599 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( 0 == strcasecmp(event, <span class="stringliteral">"ONESHOT"</span>) ) <a name="l00600"></a>00600 ret = IN_ONESHOT; <a name="l00601"></a>00601 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( 0 == strcasecmp(event, <span class="stringliteral">"ALL_EVENTS"</span>) ) <a name="l00602"></a>00602 ret = IN_ALL_EVENTS; <a name="l00603"></a>00603 <a name="l00604"></a>00604 <span class="keywordflow">return</span> ret; <a name="l00605"></a>00605 } <a name="l00606"></a>00606 <a name="l00628"></a><a class="code" href="inotifytools_8h.html#744bb8792d8ea8edbaf8f845fe1d9307">00628</a> <span class="keywordtype">char</span> * <a class="code" href="inotifytools_8h.html#744bb8792d8ea8edbaf8f845fe1d9307">inotifytools_event_to_str</a>(<span class="keywordtype">int</span> events) { <a name="l00629"></a>00629 <span class="keywordflow">return</span> <a class="code" href="inotifytools_8h.html#317a5b1ea969f570a49c4549b22e7e71">inotifytools_event_to_str_sep</a>(events, <span class="charliteral">','</span>); <a name="l00630"></a>00630 } <a name="l00631"></a>00631 <a name="l00656"></a><a class="code" href="inotifytools_8h.html#317a5b1ea969f570a49c4549b22e7e71">00656</a> <span class="keywordtype">char</span> * <a class="code" href="inotifytools_8h.html#317a5b1ea969f570a49c4549b22e7e71">inotifytools_event_to_str_sep</a>(<span class="keywordtype">int</span> events, <span class="keywordtype">char</span> sep) <a name="l00657"></a>00657 { <a name="l00658"></a>00658 <span class="keyword">static</span> <span class="keywordtype">char</span> ret[1024]; <a name="l00659"></a>00659 ret[0] = <span class="charliteral">'\0'</span>; <a name="l00660"></a>00660 ret[1] = <span class="charliteral">'\0'</span>; <a name="l00661"></a>00661 <a name="l00662"></a>00662 <span class="keywordflow">if</span> ( IN_ACCESS & events ) { <a name="l00663"></a>00663 strcat( ret, chrtostr(sep) ); <a name="l00664"></a>00664 strcat( ret, <span class="stringliteral">"ACCESS"</span> ); <a name="l00665"></a>00665 } <a name="l00666"></a>00666 <span class="keywordflow">if</span> ( IN_MODIFY & events ) { <a name="l00667"></a>00667 strcat( ret, chrtostr(sep) ); <a name="l00668"></a>00668 strcat( ret, <span class="stringliteral">"MODIFY"</span> ); <a name="l00669"></a>00669 } <a name="l00670"></a>00670 <span class="keywordflow">if</span> ( IN_ATTRIB & events ) { <a name="l00671"></a>00671 strcat( ret, chrtostr(sep) ); <a name="l00672"></a>00672 strcat( ret, <span class="stringliteral">"ATTRIB"</span> ); <a name="l00673"></a>00673 } <a name="l00674"></a>00674 <span class="keywordflow">if</span> ( IN_CLOSE_WRITE & events ) { <a name="l00675"></a>00675 strcat( ret, chrtostr(sep) ); <a name="l00676"></a>00676 strcat( ret, <span class="stringliteral">"CLOSE_WRITE"</span> ); <a name="l00677"></a>00677 } <a name="l00678"></a>00678 <span class="keywordflow">if</span> ( IN_CLOSE_NOWRITE & events ) { <a name="l00679"></a>00679 strcat( ret, chrtostr(sep) ); <a name="l00680"></a>00680 strcat( ret, <span class="stringliteral">"CLOSE_NOWRITE"</span> ); <a name="l00681"></a>00681 } <a name="l00682"></a>00682 <span class="keywordflow">if</span> ( IN_OPEN & events ) { <a name="l00683"></a>00683 strcat( ret, chrtostr(sep) ); <a name="l00684"></a>00684 strcat( ret, <span class="stringliteral">"OPEN"</span> ); <a name="l00685"></a>00685 } <a name="l00686"></a>00686 <span class="keywordflow">if</span> ( IN_MOVED_FROM & events ) { <a name="l00687"></a>00687 strcat( ret, chrtostr(sep) ); <a name="l00688"></a>00688 strcat( ret, <span class="stringliteral">"MOVED_FROM"</span> ); <a name="l00689"></a>00689 } <a name="l00690"></a>00690 <span class="keywordflow">if</span> ( IN_MOVED_TO & events ) { <a name="l00691"></a>00691 strcat( ret, chrtostr(sep) ); <a name="l00692"></a>00692 strcat( ret, <span class="stringliteral">"MOVED_TO"</span> ); <a name="l00693"></a>00693 } <a name="l00694"></a>00694 <span class="keywordflow">if</span> ( IN_CREATE & events ) { <a name="l00695"></a>00695 strcat( ret, chrtostr(sep) ); <a name="l00696"></a>00696 strcat( ret, <span class="stringliteral">"CREATE"</span> ); <a name="l00697"></a>00697 } <a name="l00698"></a>00698 <span class="keywordflow">if</span> ( IN_DELETE & events ) { <a name="l00699"></a>00699 strcat( ret, chrtostr(sep) ); <a name="l00700"></a>00700 strcat( ret, <span class="stringliteral">"DELETE"</span> ); <a name="l00701"></a>00701 } <a name="l00702"></a>00702 <span class="keywordflow">if</span> ( IN_DELETE_SELF & events ) { <a name="l00703"></a>00703 strcat( ret, chrtostr(sep) ); <a name="l00704"></a>00704 strcat( ret, <span class="stringliteral">"DELETE_SELF"</span> ); <a name="l00705"></a>00705 } <a name="l00706"></a>00706 <span class="keywordflow">if</span> ( IN_UNMOUNT & events ) { <a name="l00707"></a>00707 strcat( ret, chrtostr(sep) ); <a name="l00708"></a>00708 strcat( ret, <span class="stringliteral">"UNMOUNT"</span> ); <a name="l00709"></a>00709 } <a name="l00710"></a>00710 <span class="keywordflow">if</span> ( IN_Q_OVERFLOW & events ) { <a name="l00711"></a>00711 strcat( ret, chrtostr(sep) ); <a name="l00712"></a>00712 strcat( ret, <span class="stringliteral">"Q_OVERFLOW"</span> ); <a name="l00713"></a>00713 } <a name="l00714"></a>00714 <span class="keywordflow">if</span> ( IN_IGNORED & events ) { <a name="l00715"></a>00715 strcat( ret, chrtostr(sep) ); <a name="l00716"></a>00716 strcat( ret, <span class="stringliteral">"IGNORED"</span> ); <a name="l00717"></a>00717 } <a name="l00718"></a>00718 <span class="keywordflow">if</span> ( IN_CLOSE & events ) { <a name="l00719"></a>00719 strcat( ret, chrtostr(sep) ); <a name="l00720"></a>00720 strcat( ret, <span class="stringliteral">"CLOSE"</span> ); <a name="l00721"></a>00721 } <a name="l00722"></a>00722 <span class="keywordflow">if</span> ( IN_MOVE_SELF & events ) { <a name="l00723"></a>00723 strcat( ret, chrtostr(sep) ); <a name="l00724"></a>00724 strcat( ret, <span class="stringliteral">"MOVE_SELF"</span> ); <a name="l00725"></a>00725 } <a name="l00726"></a>00726 <span class="keywordflow">if</span> ( IN_ISDIR & events ) { <a name="l00727"></a>00727 strcat( ret, chrtostr(sep) ); <a name="l00728"></a>00728 strcat( ret, <span class="stringliteral">"ISDIR"</span> ); <a name="l00729"></a>00729 } <a name="l00730"></a>00730 <span class="keywordflow">if</span> ( IN_ONESHOT & events ) { <a name="l00731"></a>00731 strcat( ret, chrtostr(sep) ); <a name="l00732"></a>00732 strcat( ret, <span class="stringliteral">"ONESHOT"</span> ); <a name="l00733"></a>00733 } <a name="l00734"></a>00734 <a name="l00735"></a>00735 <span class="comment">// Maybe we didn't match any... ?</span> <a name="l00736"></a>00736 <span class="keywordflow">if</span> (ret[0] == <span class="charliteral">'\0'</span>) { <a name="l00737"></a>00737 niceassert( -1 != sprintf( ret, <span class="stringliteral">"%c0x%08x"</span>, sep, events ), 0 ); <a name="l00738"></a>00738 } <a name="l00739"></a>00739 <a name="l00740"></a>00740 <span class="keywordflow">return</span> &ret[1]; <a name="l00741"></a>00741 } <a name="l00742"></a>00742 <a name="l00763"></a><a class="code" href="inotifytools_8h.html#fd4dcc915248f2d0b0ae708e88611186">00763</a> <span class="keywordtype">char</span> * <a class="code" href="inotifytools_8h.html#fd4dcc915248f2d0b0ae708e88611186">inotifytools_filename_from_wd</a>( <span class="keywordtype">int</span> wd ) { <a name="l00764"></a>00764 niceassert( init, <span class="stringliteral">"inotifytools_initialize not called yet"</span> ); <a name="l00765"></a>00765 watch *w = watch_from_wd(wd); <a name="l00766"></a>00766 <span class="keywordflow">if</span> (!w) <span class="keywordflow">return</span> 0; <a name="l00767"></a>00767 <span class="keywordflow">return</span> w->filename; <a name="l00768"></a>00768 } <a name="l00769"></a>00769 <a name="l00784"></a><a class="code" href="inotifytools_8h.html#594e7f515b392c07c4f1f4eeffcda6c3">00784</a> <span class="keywordtype">int</span> <a class="code" href="inotifytools_8h.html#594e7f515b392c07c4f1f4eeffcda6c3">inotifytools_wd_from_filename</a>( <span class="keywordtype">char</span> <span class="keyword">const</span> * filename ) { <a name="l00785"></a>00785 niceassert( init, <span class="stringliteral">"inotifytools_initialize not called yet"</span> ); <a name="l00786"></a>00786 watch *w = watch_from_filename(filename); <a name="l00787"></a>00787 <span class="keywordflow">if</span> (!w) <span class="keywordflow">return</span> -1; <a name="l00788"></a>00788 <span class="keywordflow">return</span> w->wd; <a name="l00789"></a>00789 } <a name="l00790"></a>00790 <a name="l00805"></a><a class="code" href="inotifytools_8h.html#f80acc2952c748a80641926ff222571c">00805</a> <span class="keywordtype">void</span> <a class="code" href="inotifytools_8h.html#f80acc2952c748a80641926ff222571c">inotifytools_set_filename_by_wd</a>( <span class="keywordtype">int</span> wd, <span class="keywordtype">char</span> <span class="keyword">const</span> * filename ) { <a name="l00806"></a>00806 niceassert( init, <span class="stringliteral">"inotifytools_initialize not called yet"</span> ); <a name="l00807"></a>00807 watch *w = watch_from_wd(wd); <a name="l00808"></a>00808 <span class="keywordflow">if</span> (!w) <span class="keywordflow">return</span>; <a name="l00809"></a>00809 <span class="keywordflow">if</span> (w->filename) free(w->filename); <a name="l00810"></a>00810 w->filename = strdup(filename); <a name="l00811"></a>00811 } <a name="l00812"></a>00812 <a name="l00827"></a><a class="code" href="inotifytools_8h.html#764239f33bd2a092c445362e75828181">00827</a> <span class="keywordtype">void</span> <a class="code" href="inotifytools_8h.html#764239f33bd2a092c445362e75828181">inotifytools_set_filename_by_filename</a>( <span class="keywordtype">char</span> <span class="keyword">const</span> * oldname, <a name="l00828"></a>00828 <span class="keywordtype">char</span> <span class="keyword">const</span> * newname ) { <a name="l00829"></a>00829 watch *w = watch_from_filename(oldname); <a name="l00830"></a>00830 <span class="keywordflow">if</span> (!w) <span class="keywordflow">return</span>; <a name="l00831"></a>00831 <span class="keywordflow">if</span> (w->filename) free(w->filename); <a name="l00832"></a>00832 w->filename = strdup(newname); <a name="l00833"></a>00833 } <a name="l00834"></a>00834 <a name="l00857"></a><a class="code" href="inotifytools_8h.html#c6f5ecf6f3d854535132fe9790db008d">00857</a> <span class="keywordtype">void</span> <a class="code" href="inotifytools_8h.html#c6f5ecf6f3d854535132fe9790db008d">inotifytools_replace_filename</a>( <span class="keywordtype">char</span> <span class="keyword">const</span> * oldname, <a name="l00858"></a>00858 <span class="keywordtype">char</span> <span class="keyword">const</span> * newname ) { <a name="l00859"></a>00859 <span class="keywordflow">if</span> ( !oldname || !newname ) <span class="keywordflow">return</span>; <a name="l00860"></a>00860 <span class="keywordtype">char</span> *names[2+<span class="keyword">sizeof</span>(int)/<span class="keyword">sizeof</span>(<span class="keywordtype">char</span>*)]; <a name="l00861"></a>00861 names[0] = (<span class="keywordtype">char</span>*)oldname; <a name="l00862"></a>00862 names[1] = (<span class="keywordtype">char</span>*)newname; <a name="l00863"></a>00863 *((<span class="keywordtype">int</span>*)&names[2]) = strlen(oldname); <a name="l00864"></a>00864 rbwalk(tree_filename, replace_filename, (<span class="keywordtype">void</span>*)names); <a name="l00865"></a>00865 } <a name="l00866"></a>00866 <a name="l00870"></a>00870 <span class="keywordtype">int</span> remove_inotify_watch(watch *w) { <a name="l00871"></a>00871 error = 0; <a name="l00872"></a>00872 <span class="keywordtype">int</span> status = inotify_rm_watch( inotify_fd, w->wd ); <a name="l00873"></a>00873 <span class="keywordflow">if</span> ( status < 0 ) { <a name="l00874"></a>00874 fprintf(stderr, <span class="stringliteral">"Failed to remove watch on %s: %s\n"</span>, w->filename, <a name="l00875"></a>00875 strerror(status) ); <a name="l00876"></a>00876 error = status; <a name="l00877"></a>00877 <span class="keywordflow">return</span> 0; <a name="l00878"></a>00878 } <a name="l00879"></a>00879 <span class="keywordflow">return</span> 1; <a name="l00880"></a>00880 } <a name="l00881"></a>00881 <a name="l00885"></a>00885 watch *create_watch(<span class="keywordtype">int</span> wd, <span class="keywordtype">char</span> *filename) { <a name="l00886"></a>00886 <span class="keywordflow">if</span> ( wd <= 0 || !filename) <span class="keywordflow">return</span> 0; <a name="l00887"></a>00887 <a name="l00888"></a>00888 watch *w = (watch*)calloc(1, <span class="keyword">sizeof</span>(watch)); <a name="l00889"></a>00889 w->wd = wd; <a name="l00890"></a>00890 w->filename = strdup(filename); <a name="l00891"></a>00891 rbsearch(w, tree_wd); <a name="l00892"></a>00892 rbsearch(w, tree_filename); <a name="l00893"></a>00893 } <a name="l00894"></a>00894 <a name="l00907"></a><a class="code" href="inotifytools_8h.html#771f60d2232201c691fe725d5cf7e019">00907</a> <span class="keywordtype">int</span> <a class="code" href="inotifytools_8h.html#771f60d2232201c691fe725d5cf7e019">inotifytools_remove_watch_by_wd</a>( <span class="keywordtype">int</span> wd ) { <a name="l00908"></a>00908 niceassert( init, <span class="stringliteral">"inotifytools_initialize not called yet"</span> ); <a name="l00909"></a>00909 watch *w = watch_from_wd(wd); <a name="l00910"></a>00910 <span class="keywordflow">if</span> (!w) <span class="keywordflow">return</span> 1; <a name="l00911"></a>00911 <a name="l00912"></a>00912 <span class="keywordflow">if</span> (!remove_inotify_watch(w)) <span class="keywordflow">return</span> 0; <a name="l00913"></a>00913 rbdelete(w, tree_wd); <a name="l00914"></a>00914 rbdelete(w, tree_filename); <a name="l00915"></a>00915 destroy_watch(w); <a name="l00916"></a>00916 <span class="keywordflow">return</span> 1; <a name="l00917"></a>00917 } <a name="l00918"></a>00918 <a name="l00930"></a><a class="code" href="inotifytools_8h.html#2a4ca66a9d8b0825d4272cd5003a9a0f">00930</a> <span class="keywordtype">int</span> <a class="code" href="inotifytools_8h.html#2a4ca66a9d8b0825d4272cd5003a9a0f">inotifytools_remove_watch_by_filename</a>( <span class="keywordtype">char</span> <span class="keyword">const</span> * filename ) { <a name="l00931"></a>00931 niceassert( init, <span class="stringliteral">"inotifytools_initialize not called yet"</span> ); <a name="l00932"></a>00932 watch *w = watch_from_filename(filename); <a name="l00933"></a>00933 <span class="keywordflow">if</span> (!w) <span class="keywordflow">return</span> 1; <a name="l00934"></a>00934 <a name="l00935"></a>00935 <span class="keywordflow">if</span> (!remove_inotify_watch(w)) <span class="keywordflow">return</span> 0; <a name="l00936"></a>00936 rbdelete(w, tree_wd); <a name="l00937"></a>00937 rbdelete(w, tree_filename); <a name="l00938"></a>00938 destroy_watch(w); <a name="l00939"></a>00939 <span class="keywordflow">return</span> 1; <a name="l00940"></a>00940 } <a name="l00941"></a>00941 <a name="l00953"></a><a class="code" href="inotifytools_8h.html#f9ce33904730bcafbda98c35b1ba4931">00953</a> <span class="keywordtype">int</span> <a class="code" href="inotifytools_8h.html#f9ce33904730bcafbda98c35b1ba4931">inotifytools_watch_file</a>( <span class="keywordtype">char</span> <span class="keyword">const</span> * filename, <span class="keywordtype">int</span> events ) { <a name="l00954"></a>00954 <span class="keyword">static</span> <span class="keywordtype">char</span> <span class="keyword">const</span> * filenames[2]; <a name="l00955"></a>00955 filenames[0] = filename; <a name="l00956"></a>00956 filenames[1] = NULL; <a name="l00957"></a>00957 <span class="keywordflow">return</span> <a class="code" href="inotifytools_8h.html#88c6a7db52fbd9310ef72d2588c9c1df">inotifytools_watch_files</a>( filenames, events ); <a name="l00958"></a>00958 } <a name="l00959"></a>00959 <a name="l00975"></a><a class="code" href="inotifytools_8h.html#88c6a7db52fbd9310ef72d2588c9c1df">00975</a> <span class="keywordtype">int</span> <a class="code" href="inotifytools_8h.html#88c6a7db52fbd9310ef72d2588c9c1df">inotifytools_watch_files</a>( <span class="keywordtype">char</span> <span class="keyword">const</span> * filenames[], <span class="keywordtype">int</span> events ) { <a name="l00976"></a>00976 niceassert( init, <span class="stringliteral">"inotifytools_initialize not called yet"</span> ); <a name="l00977"></a>00977 error = 0; <a name="l00978"></a>00978 <a name="l00979"></a>00979 <span class="keyword">static</span> <span class="keywordtype">int</span> i; <a name="l00980"></a>00980 <span class="keywordflow">for</span> ( i = 0; filenames[i]; ++i ) { <a name="l00981"></a>00981 <span class="keyword">static</span> <span class="keywordtype">int</span> wd; <a name="l00982"></a>00982 wd = inotify_add_watch( inotify_fd, filenames[i], events ); <a name="l00983"></a>00983 <span class="keywordflow">if</span> ( wd < 0 ) { <a name="l00984"></a>00984 <span class="keywordflow">if</span> ( wd == -1 ) { <a name="l00985"></a>00985 error = errno; <a name="l00986"></a>00986 <span class="keywordflow">return</span> 0; <a name="l00987"></a>00987 } <span class="comment">// if ( wd == -1 )</span> <a name="l00988"></a>00988 <span class="keywordflow">else</span> { <a name="l00989"></a>00989 fprintf( stderr, <span class="stringliteral">"Failed to watch %s: returned wd was %d "</span> <a name="l00990"></a>00990 <span class="stringliteral">"(expected -1 or >0 )"</span>, filenames[i], wd ); <a name="l00991"></a>00991 <span class="comment">// no appropriate value for error</span> <a name="l00992"></a>00992 <span class="keywordflow">return</span> 0; <a name="l00993"></a>00993 } <span class="comment">// else</span> <a name="l00994"></a>00994 } <span class="comment">// if ( wd < 0 )</span> <a name="l00995"></a>00995 <a name="l00996"></a>00996 <span class="keywordtype">char</span> *filename; <a name="l00997"></a>00997 <span class="comment">// Always end filename with / if it is a directory</span> <a name="l00998"></a>00998 <span class="keywordflow">if</span> ( !isdir(filenames[i]) <a name="l00999"></a>00999 || filenames[i][strlen(filenames[i])-1] == <span class="charliteral">'/'</span>) { <a name="l01000"></a>01000 filename = strdup(filenames[i]); <a name="l01001"></a>01001 } <a name="l01002"></a>01002 <span class="keywordflow">else</span> { <a name="l01003"></a>01003 nasprintf( &filename, <span class="stringliteral">"%s/"</span>, filenames[i] ); <a name="l01004"></a>01004 } <a name="l01005"></a>01005 create_watch(wd, filename); <a name="l01006"></a>01006 free(filename); <a name="l01007"></a>01007 } <span class="comment">// for</span> <a name="l01008"></a>01008 <a name="l01009"></a>01009 <span class="keywordflow">return</span> 1; <a name="l01010"></a>01010 } <a name="l01011"></a>01011 <a name="l01038"></a><a class="code" href="inotifytools_8h.html#2e121fde1cac7875d25a7e6c3bc57e1a">01038</a> <span class="keyword">struct </span>inotify_event * <a class="code" href="inotifytools_8h.html#2e121fde1cac7875d25a7e6c3bc57e1a">inotifytools_next_event</a>( <span class="keywordtype">int</span> timeout ) { <a name="l01039"></a>01039 <span class="keywordflow">return</span> <a class="code" href="inotifytools_8h.html#188fd24a5d8ff504e1a3616ded73a4c1">inotifytools_next_events</a>( timeout, 1 ); <a name="l01040"></a>01040 } <a name="l01041"></a>01041 <a name="l01042"></a>01042 <a name="l01092"></a><a class="code" href="inotifytools_8h.html#188fd24a5d8ff504e1a3616ded73a4c1">01092</a> <span class="keyword">struct </span>inotify_event * <a class="code" href="inotifytools_8h.html#188fd24a5d8ff504e1a3616ded73a4c1">inotifytools_next_events</a>( <span class="keywordtype">int</span> timeout, <span class="keywordtype">int</span> num_events ) { <a name="l01093"></a>01093 niceassert( init, <span class="stringliteral">"inotifytools_initialize not called yet"</span> ); <a name="l01094"></a>01094 niceassert( num_events <= MAX_EVENTS, <span class="stringliteral">"too many events requested"</span> ); <a name="l01095"></a>01095 <a name="l01096"></a>01096 <span class="keywordflow">if</span> ( num_events < 1 ) <span class="keywordflow">return</span> NULL; <a name="l01097"></a>01097 <a name="l01098"></a>01098 <span class="keyword">static</span> <span class="keyword">struct </span>inotify_event event[MAX_EVENTS]; <a name="l01099"></a>01099 <span class="keyword">static</span> <span class="keyword">struct </span>inotify_event * ret; <a name="l01100"></a>01100 <span class="keyword">static</span> <span class="keywordtype">int</span> first_byte = 0; <a name="l01101"></a>01101 <span class="keyword">static</span> ssize_t bytes; <a name="l01102"></a>01102 <span class="keyword">static</span> jmp_buf jmp; <a name="l01103"></a>01103 <span class="keyword">static</span> <span class="keywordtype">char</span> match_name[MAX_STRLEN]; <a name="l01104"></a>01104 <a name="l01105"></a>01105 <span class="preprocessor">#define RETURN(A) {\</span> <a name="l01106"></a>01106 <span class="preprocessor"> if (regex) {\</span> <a name="l01107"></a>01107 <span class="preprocessor"> inotifytools_snprintf(match_name, MAX_STRLEN, A, "%w%f");\</span> <a name="l01108"></a>01108 <span class="preprocessor"> if (0 == regexec(regex, match_name, 0, 0, 0)) {\</span> <a name="l01109"></a>01109 <span class="preprocessor"> longjmp(jmp,0);\</span> <a name="l01110"></a>01110 <span class="preprocessor"> }\</span> <a name="l01111"></a>01111 <span class="preprocessor"> }\</span> <a name="l01112"></a>01112 <span class="preprocessor"> if ( collect_stats ) {\</span> <a name="l01113"></a>01113 <span class="preprocessor"> record_stats( A );\</span> <a name="l01114"></a>01114 <span class="preprocessor"> }\</span> <a name="l01115"></a>01115 <span class="preprocessor"> return A;\</span> <a name="l01116"></a>01116 <span class="preprocessor">}</span> <a name="l01117"></a>01117 <span class="preprocessor"></span> <a name="l01118"></a>01118 setjmp(jmp); <a name="l01119"></a>01119 <a name="l01120"></a>01120 error = 0; <a name="l01121"></a>01121 <a name="l01122"></a>01122 <span class="comment">// first_byte is index into event buffer</span> <a name="l01123"></a>01123 <span class="keywordflow">if</span> ( first_byte != 0 <a name="l01124"></a>01124 && first_byte <= (<span class="keywordtype">int</span>)(bytes - <span class="keyword">sizeof</span>(<span class="keyword">struct</span> inotify_event)) ) { <a name="l01125"></a>01125 <a name="l01126"></a>01126 ret = (<span class="keyword">struct </span>inotify_event *)((<span class="keywordtype">char</span> *)&<span class="keyword">event</span>[0] + first_byte); <a name="l01127"></a>01127 first_byte += <span class="keyword">sizeof</span>(<span class="keyword">struct </span>inotify_event) + ret->len; <a name="l01128"></a>01128 <a name="l01129"></a>01129 <span class="comment">// if the pointer to the next event exactly hits end of bytes read,</span> <a name="l01130"></a>01130 <span class="comment">// that's good. next time we're called, we'll read.</span> <a name="l01131"></a>01131 <span class="keywordflow">if</span> ( first_byte == bytes ) { <a name="l01132"></a>01132 first_byte = 0; <a name="l01133"></a>01133 } <a name="l01134"></a>01134 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( first_byte > bytes ) { <a name="l01135"></a>01135 <span class="comment">// oh... no. this can't be happening. An incomplete event.</span> <a name="l01136"></a>01136 <span class="comment">// Copy what we currently have into first element, call self to</span> <a name="l01137"></a>01137 <span class="comment">// read remainder.</span> <a name="l01138"></a>01138 <span class="comment">// oh, and they BETTER NOT overlap.</span> <a name="l01139"></a>01139 <span class="comment">// Boy I hope this code works.</span> <a name="l01140"></a>01140 <span class="comment">// But I think this can never happen due to how inotify is written.</span> <a name="l01141"></a>01141 niceassert( (<span class="keywordtype">long</span>)((<span class="keywordtype">char</span> *)&event[0] + <a name="l01142"></a>01142 <span class="keyword">sizeof</span>(<span class="keyword">struct</span> inotify_event) + <a name="l01143"></a>01143 event[0].len) <= (<span class="keywordtype">long</span>)ret, <a name="l01144"></a>01144 <span class="stringliteral">"extremely unlucky user, death imminent"</span> ); <a name="l01145"></a>01145 <span class="comment">// how much of the event do we have?</span> <a name="l01146"></a>01146 bytes = (<span class="keywordtype">char</span> *)&event[0] + bytes - (<span class="keywordtype">char</span> *)ret; <a name="l01147"></a>01147 memcpy( &event[0], ret, bytes ); <a name="l01148"></a>01148 <span class="keywordflow">return</span> <a class="code" href="inotifytools_8h.html#188fd24a5d8ff504e1a3616ded73a4c1">inotifytools_next_events</a>( timeout, num_events ); <a name="l01149"></a>01149 } <a name="l01150"></a>01150 RETURN(ret); <a name="l01151"></a>01151 <a name="l01152"></a>01152 } <a name="l01153"></a>01153 <a name="l01154"></a>01154 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( first_byte == 0 ) { <a name="l01155"></a>01155 bytes = 0; <a name="l01156"></a>01156 } <a name="l01157"></a>01157 <a name="l01158"></a>01158 <a name="l01159"></a>01159 <span class="keyword">static</span> ssize_t this_bytes; <a name="l01160"></a>01160 <span class="keyword">static</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> bytes_to_read; <a name="l01161"></a>01161 <span class="keyword">static</span> <span class="keywordtype">int</span> rc; <a name="l01162"></a>01162 <span class="keyword">static</span> fd_set read_fds; <a name="l01163"></a>01163 <a name="l01164"></a>01164 <span class="keyword">static</span> <span class="keyword">struct </span>timeval read_timeout; <a name="l01165"></a>01165 read_timeout.tv_sec = timeout; <a name="l01166"></a>01166 read_timeout.tv_usec = 0; <a name="l01167"></a>01167 <span class="keyword">static</span> <span class="keyword">struct </span>timeval * read_timeout_ptr; <a name="l01168"></a>01168 read_timeout_ptr = ( timeout <= 0 ? NULL : &read_timeout ); <a name="l01169"></a>01169 <a name="l01170"></a>01170 FD_ZERO(&read_fds); <a name="l01171"></a>01171 FD_SET(inotify_fd, &read_fds); <a name="l01172"></a>01172 rc = select(inotify_fd + 1, &read_fds, <a name="l01173"></a>01173 NULL, NULL, read_timeout_ptr); <a name="l01174"></a>01174 <span class="keywordflow">if</span> ( rc < 0 ) { <a name="l01175"></a>01175 <span class="comment">// error</span> <a name="l01176"></a>01176 error = errno; <a name="l01177"></a>01177 <span class="keywordflow">return</span> NULL; <a name="l01178"></a>01178 } <a name="l01179"></a>01179 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( rc == 0 ) { <a name="l01180"></a>01180 <span class="comment">// timeout</span> <a name="l01181"></a>01181 <span class="keywordflow">return</span> NULL; <a name="l01182"></a>01182 } <a name="l01183"></a>01183 <a name="l01184"></a>01184 <span class="comment">// wait until we have enough bytes to read</span> <a name="l01185"></a>01185 <span class="keywordflow">do</span> { <a name="l01186"></a>01186 rc = ioctl( inotify_fd, FIONREAD, &bytes_to_read ); <a name="l01187"></a>01187 } <span class="keywordflow">while</span> ( !rc && <a name="l01188"></a>01188 bytes_to_read < <span class="keyword">sizeof</span>(<span class="keyword">struct</span> inotify_event)*num_events ); <a name="l01189"></a>01189 <a name="l01190"></a>01190 <span class="keywordflow">if</span> ( rc == -1 ) { <a name="l01191"></a>01191 error = errno; <a name="l01192"></a>01192 <span class="keywordflow">return</span> NULL; <a name="l01193"></a>01193 } <a name="l01194"></a>01194 <a name="l01195"></a>01195 this_bytes = read(inotify_fd, &event[0] + bytes, <a name="l01196"></a>01196 <span class="keyword">sizeof</span>(<span class="keyword">struct</span> inotify_event)*MAX_EVENTS - bytes); <a name="l01197"></a>01197 <span class="keywordflow">if</span> ( this_bytes < 0 ) { <a name="l01198"></a>01198 error = errno; <a name="l01199"></a>01199 <span class="keywordflow">return</span> NULL; <a name="l01200"></a>01200 } <a name="l01201"></a>01201 <span class="keywordflow">if</span> ( this_bytes == 0 ) { <a name="l01202"></a>01202 fprintf(stderr, <span class="stringliteral">"Inotify reported end-of-file. Possibly too many "</span> <a name="l01203"></a>01203 <span class="stringliteral">"events occurred at once.\n"</span>); <a name="l01204"></a>01204 <span class="keywordflow">return</span> NULL; <a name="l01205"></a>01205 } <a name="l01206"></a>01206 bytes += this_bytes; <a name="l01207"></a>01207 <a name="l01208"></a>01208 ret = &<span class="keyword">event</span>[0]; <a name="l01209"></a>01209 first_byte = <span class="keyword">sizeof</span>(<span class="keyword">struct </span>inotify_event) + ret->len; <a name="l01210"></a>01210 niceassert( first_byte <= bytes, <span class="stringliteral">"ridiculously long filename, things will "</span> <a name="l01211"></a>01211 <span class="stringliteral">"almost certainly screw up."</span> ); <a name="l01212"></a>01212 <span class="keywordflow">if</span> ( first_byte == bytes ) { <a name="l01213"></a>01213 first_byte = 0; <a name="l01214"></a>01214 } <a name="l01215"></a>01215 <a name="l01216"></a>01216 RETURN(ret); <a name="l01217"></a>01217 <a name="l01218"></a>01218 <span class="preprocessor">#undef RETURN</span> <a name="l01219"></a>01219 <span class="preprocessor"></span>} <a name="l01220"></a>01220 <a name="l01246"></a><a class="code" href="inotifytools_8h.html#583ff8d0e64f527af4232814ad493dce">01246</a> <span class="keywordtype">int</span> <a class="code" href="inotifytools_8h.html#583ff8d0e64f527af4232814ad493dce">inotifytools_watch_recursively</a>( <span class="keywordtype">char</span> <span class="keyword">const</span> * path, <span class="keywordtype">int</span> events ) { <a name="l01247"></a>01247 <span class="keywordflow">return</span> <a class="code" href="inotifytools_8h.html#20981c7f1410d458b5ef0654b9adf1e4">inotifytools_watch_recursively_with_exclude</a>( path, events, 0 ); <a name="l01248"></a>01248 } <a name="l01249"></a>01249 <a name="l01282"></a><a class="code" href="inotifytools_8h.html#20981c7f1410d458b5ef0654b9adf1e4">01282</a> <span class="keywordtype">int</span> <a class="code" href="inotifytools_8h.html#20981c7f1410d458b5ef0654b9adf1e4">inotifytools_watch_recursively_with_exclude</a>( <span class="keywordtype">char</span> <span class="keyword">const</span> * path, <span class="keywordtype">int</span> events, <a name="l01283"></a>01283 <span class="keywordtype">char</span> <span class="keyword">const</span> ** exclude_list ) { <a name="l01284"></a>01284 niceassert( init, <span class="stringliteral">"inotifytools_initialize not called yet"</span> ); <a name="l01285"></a>01285 <a name="l01286"></a>01286 DIR * dir; <a name="l01287"></a>01287 <span class="keywordtype">char</span> * my_path; <a name="l01288"></a>01288 error = 0; <a name="l01289"></a>01289 dir = opendir( path ); <a name="l01290"></a>01290 <span class="keywordflow">if</span> ( !dir ) { <a name="l01291"></a>01291 <span class="comment">// If not a directory, don't need to do anything special</span> <a name="l01292"></a>01292 <span class="keywordflow">if</span> ( errno == ENOTDIR ) { <a name="l01293"></a>01293 <span class="keywordflow">return</span> <a class="code" href="inotifytools_8h.html#f9ce33904730bcafbda98c35b1ba4931">inotifytools_watch_file</a>( path, events ); <a name="l01294"></a>01294 } <a name="l01295"></a>01295 <span class="keywordflow">else</span> { <a name="l01296"></a>01296 error = errno; <a name="l01297"></a>01297 <span class="keywordflow">return</span> 0; <a name="l01298"></a>01298 } <a name="l01299"></a>01299 } <a name="l01300"></a>01300 <a name="l01301"></a>01301 <span class="keywordflow">if</span> ( path[strlen(path)-1] != <span class="charliteral">'/'</span> ) { <a name="l01302"></a>01302 nasprintf( &my_path, <span class="stringliteral">"%s/"</span>, path ); <a name="l01303"></a>01303 } <a name="l01304"></a>01304 <span class="keywordflow">else</span> { <a name="l01305"></a>01305 my_path = (<span class="keywordtype">char</span> *)path; <a name="l01306"></a>01306 } <a name="l01307"></a>01307 <a name="l01308"></a>01308 <span class="keyword">static</span> <span class="keyword">struct </span>dirent * ent; <a name="l01309"></a>01309 <span class="keywordtype">char</span> * next_file; <a name="l01310"></a>01310 <span class="keyword">static</span> <span class="keyword">struct </span>stat64 my_stat; <a name="l01311"></a>01311 ent = readdir( dir ); <a name="l01312"></a>01312 <span class="comment">// Watch each directory within this directory</span> <a name="l01313"></a>01313 <span class="keywordflow">while</span> ( ent ) { <a name="l01314"></a>01314 <span class="keywordflow">if</span> ( (0 != strcmp( ent->d_name, <span class="stringliteral">"."</span> )) && <a name="l01315"></a>01315 (0 != strcmp( ent->d_name, <span class="stringliteral">".."</span> )) ) { <a name="l01316"></a>01316 nasprintf(&next_file,<span class="stringliteral">"%s%s"</span>, my_path, ent->d_name); <a name="l01317"></a>01317 <span class="keywordflow">if</span> ( -1 == lstat64( next_file, &my_stat ) ) { <a name="l01318"></a>01318 error = errno; <a name="l01319"></a>01319 free( next_file ); <a name="l01320"></a>01320 <span class="keywordflow">if</span> ( errno != EACCES ) { <a name="l01321"></a>01321 error = errno; <a name="l01322"></a>01322 <span class="keywordflow">if</span> ( my_path != path ) free( my_path ); <a name="l01323"></a>01323 closedir( dir ); <a name="l01324"></a>01324 <span class="keywordflow">return</span> 0; <a name="l01325"></a>01325 } <a name="l01326"></a>01326 } <a name="l01327"></a>01327 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( S_ISDIR( my_stat.st_mode ) && <a name="l01328"></a>01328 !S_ISLNK( my_stat.st_mode )) { <a name="l01329"></a>01329 free( next_file ); <a name="l01330"></a>01330 nasprintf(&next_file,<span class="stringliteral">"%s%s/"</span>, my_path, ent->d_name); <a name="l01331"></a>01331 <span class="keyword">static</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> no_watch; <a name="l01332"></a>01332 <span class="keyword">static</span> <span class="keywordtype">char</span> <span class="keyword">const</span> ** exclude_entry; <a name="l01333"></a>01333 <a name="l01334"></a>01334 no_watch = 0; <a name="l01335"></a>01335 <span class="keywordflow">for</span> (exclude_entry = exclude_list; <a name="l01336"></a>01336 exclude_entry && *exclude_entry && !no_watch; <a name="l01337"></a>01337 ++exclude_entry) { <a name="l01338"></a>01338 <span class="keyword">static</span> <span class="keywordtype">int</span> exclude_length; <a name="l01339"></a>01339 <a name="l01340"></a>01340 exclude_length = strlen(*exclude_entry); <a name="l01341"></a>01341 <span class="keywordflow">if</span> ((*exclude_entry)[exclude_length-1] == <span class="charliteral">'/'</span>) { <a name="l01342"></a>01342 --exclude_length; <a name="l01343"></a>01343 } <a name="l01344"></a>01344 <span class="keywordflow">if</span> ( strlen(next_file) == (<span class="keywordtype">unsigned</span>)(exclude_length + 1) && <a name="l01345"></a>01345 !strncmp(*exclude_entry, next_file, exclude_length)) { <a name="l01346"></a>01346 <span class="comment">// directory found in exclude list</span> <a name="l01347"></a>01347 no_watch = 1; <a name="l01348"></a>01348 } <a name="l01349"></a>01349 } <a name="l01350"></a>01350 <span class="keywordflow">if</span> (!no_watch) { <a name="l01351"></a>01351 <span class="keyword">static</span> <span class="keywordtype">int</span> status; <a name="l01352"></a>01352 status = <a class="code" href="inotifytools_8h.html#20981c7f1410d458b5ef0654b9adf1e4">inotifytools_watch_recursively_with_exclude</a>( <a name="l01353"></a>01353 next_file, <a name="l01354"></a>01354 events, <a name="l01355"></a>01355 exclude_list ); <a name="l01356"></a>01356 <span class="comment">// For some errors, we will continue.</span> <a name="l01357"></a>01357 <span class="keywordflow">if</span> ( !status && (EACCES != error) && (ENOENT != error) && <a name="l01358"></a>01358 (ELOOP != error) ) { <a name="l01359"></a>01359 free( next_file ); <a name="l01360"></a>01360 <span class="keywordflow">if</span> ( my_path != path ) free( my_path ); <a name="l01361"></a>01361 closedir( dir ); <a name="l01362"></a>01362 <span class="keywordflow">return</span> 0; <a name="l01363"></a>01363 } <a name="l01364"></a>01364 } <span class="comment">// if !no_watch</span> <a name="l01365"></a>01365 free( next_file ); <a name="l01366"></a>01366 } <span class="comment">// if isdir and not islnk</span> <a name="l01367"></a>01367 <span class="keywordflow">else</span> { <a name="l01368"></a>01368 free( next_file ); <a name="l01369"></a>01369 } <a name="l01370"></a>01370 } <a name="l01371"></a>01371 ent = readdir( dir ); <a name="l01372"></a>01372 error = 0; <a name="l01373"></a>01373 } <a name="l01374"></a>01374 <a name="l01375"></a>01375 closedir( dir ); <a name="l01376"></a>01376 <a name="l01377"></a>01377 <span class="keywordtype">int</span> ret = <a class="code" href="inotifytools_8h.html#f9ce33904730bcafbda98c35b1ba4931">inotifytools_watch_file</a>( my_path, events ); <a name="l01378"></a>01378 <span class="keywordflow">if</span> ( my_path != path ) free( my_path ); <a name="l01379"></a>01379 <span class="keywordflow">return</span> ret; <a name="l01380"></a>01380 } <a name="l01381"></a>01381 <a name="l01385"></a>01385 <span class="keywordtype">void</span> record_stats( <span class="keyword">struct</span> inotify_event <span class="keyword">const</span> * event ) { <a name="l01386"></a>01386 <span class="keywordflow">if</span> (!event) <span class="keywordflow">return</span>; <a name="l01387"></a>01387 watch *w = watch_from_wd(event->wd); <a name="l01388"></a>01388 <span class="keywordflow">if</span> (!w) <span class="keywordflow">return</span>; <a name="l01389"></a>01389 <span class="keywordflow">if</span> ( IN_ACCESS & event->mask ) { <a name="l01390"></a>01390 ++w->hit_access; <a name="l01391"></a>01391 ++num_access; <a name="l01392"></a>01392 } <a name="l01393"></a>01393 <span class="keywordflow">if</span> ( IN_MODIFY & event->mask ) { <a name="l01394"></a>01394 ++w->hit_modify; <a name="l01395"></a>01395 ++num_modify; <a name="l01396"></a>01396 } <a name="l01397"></a>01397 <span class="keywordflow">if</span> ( IN_ATTRIB & event->mask ) { <a name="l01398"></a>01398 ++w->hit_attrib; <a name="l01399"></a>01399 ++num_attrib; <a name="l01400"></a>01400 } <a name="l01401"></a>01401 <span class="keywordflow">if</span> ( IN_CLOSE_WRITE & event->mask ) { <a name="l01402"></a>01402 ++w->hit_close_write; <a name="l01403"></a>01403 ++num_close_write; <a name="l01404"></a>01404 } <a name="l01405"></a>01405 <span class="keywordflow">if</span> ( IN_CLOSE_NOWRITE & event->mask ) { <a name="l01406"></a>01406 ++w->hit_close_nowrite; <a name="l01407"></a>01407 ++num_close_nowrite; <a name="l01408"></a>01408 } <a name="l01409"></a>01409 <span class="keywordflow">if</span> ( IN_OPEN & event->mask ) { <a name="l01410"></a>01410 ++w->hit_open; <a name="l01411"></a>01411 ++num_open; <a name="l01412"></a>01412 } <a name="l01413"></a>01413 <span class="keywordflow">if</span> ( IN_MOVED_FROM & event->mask ) { <a name="l01414"></a>01414 ++w->hit_moved_from; <a name="l01415"></a>01415 ++num_moved_from; <a name="l01416"></a>01416 } <a name="l01417"></a>01417 <span class="keywordflow">if</span> ( IN_MOVED_TO & event->mask ) { <a name="l01418"></a>01418 ++w->hit_moved_to; <a name="l01419"></a>01419 ++num_moved_to; <a name="l01420"></a>01420 } <a name="l01421"></a>01421 <span class="keywordflow">if</span> ( IN_CREATE & event->mask ) { <a name="l01422"></a>01422 ++w->hit_create; <a name="l01423"></a>01423 ++num_create; <a name="l01424"></a>01424 } <a name="l01425"></a>01425 <span class="keywordflow">if</span> ( IN_DELETE & event->mask ) { <a name="l01426"></a>01426 ++w->hit_delete; <a name="l01427"></a>01427 ++num_delete; <a name="l01428"></a>01428 } <a name="l01429"></a>01429 <span class="keywordflow">if</span> ( IN_DELETE_SELF & event->mask ) { <a name="l01430"></a>01430 ++w->hit_delete_self; <a name="l01431"></a>01431 ++num_delete_self; <a name="l01432"></a>01432 } <a name="l01433"></a>01433 <span class="keywordflow">if</span> ( IN_UNMOUNT & event->mask ) { <a name="l01434"></a>01434 ++w->hit_unmount; <a name="l01435"></a>01435 ++num_unmount; <a name="l01436"></a>01436 } <a name="l01437"></a>01437 <span class="keywordflow">if</span> ( IN_MOVE_SELF & event->mask ) { <a name="l01438"></a>01438 ++w->hit_move_self; <a name="l01439"></a>01439 ++num_move_self; <a name="l01440"></a>01440 } <a name="l01441"></a>01441 <a name="l01442"></a>01442 ++w->hit_total; <a name="l01443"></a>01443 ++num_total; <a name="l01444"></a>01444 <a name="l01445"></a>01445 } <a name="l01446"></a>01446 <a name="l01447"></a>01447 <span class="keywordtype">int</span> *stat_ptr(watch *w, <span class="keywordtype">int</span> event) <a name="l01448"></a>01448 { <a name="l01449"></a>01449 <span class="keywordflow">if</span> ( IN_ACCESS == event ) <a name="l01450"></a>01450 <span class="keywordflow">return</span> &w->hit_access; <a name="l01451"></a>01451 <span class="keywordflow">if</span> ( IN_MODIFY == event ) <a name="l01452"></a>01452 <span class="keywordflow">return</span> &w->hit_modify; <a name="l01453"></a>01453 <span class="keywordflow">if</span> ( IN_ATTRIB == event ) <a name="l01454"></a>01454 <span class="keywordflow">return</span> &w->hit_attrib; <a name="l01455"></a>01455 <span class="keywordflow">if</span> ( IN_CLOSE_WRITE == event ) <a name="l01456"></a>01456 <span class="keywordflow">return</span> &w->hit_close_write; <a name="l01457"></a>01457 <span class="keywordflow">if</span> ( IN_CLOSE_NOWRITE == event ) <a name="l01458"></a>01458 <span class="keywordflow">return</span> &w->hit_close_nowrite; <a name="l01459"></a>01459 <span class="keywordflow">if</span> ( IN_OPEN == event ) <a name="l01460"></a>01460 <span class="keywordflow">return</span> &w->hit_open; <a name="l01461"></a>01461 <span class="keywordflow">if</span> ( IN_MOVED_FROM == event ) <a name="l01462"></a>01462 <span class="keywordflow">return</span> &w->hit_moved_from; <a name="l01463"></a>01463 <span class="keywordflow">if</span> ( IN_MOVED_TO == event ) <a name="l01464"></a>01464 <span class="keywordflow">return</span> &w->hit_moved_to; <a name="l01465"></a>01465 <span class="keywordflow">if</span> ( IN_CREATE == event ) <a name="l01466"></a>01466 <span class="keywordflow">return</span> &w->hit_create; <a name="l01467"></a>01467 <span class="keywordflow">if</span> ( IN_DELETE == event ) <a name="l01468"></a>01468 <span class="keywordflow">return</span> &w->hit_delete; <a name="l01469"></a>01469 <span class="keywordflow">if</span> ( IN_DELETE_SELF == event ) <a name="l01470"></a>01470 <span class="keywordflow">return</span> &w->hit_delete_self; <a name="l01471"></a>01471 <span class="keywordflow">if</span> ( IN_UNMOUNT == event ) <a name="l01472"></a>01472 <span class="keywordflow">return</span> &w->hit_unmount; <a name="l01473"></a>01473 <span class="keywordflow">if</span> ( IN_MOVE_SELF == event ) <a name="l01474"></a>01474 <span class="keywordflow">return</span> &w->hit_move_self; <a name="l01475"></a>01475 <span class="keywordflow">if</span> ( 0 == event ) <a name="l01476"></a>01476 <span class="keywordflow">return</span> &w->hit_total; <a name="l01477"></a>01477 <span class="keywordflow">return</span> 0; <a name="l01478"></a>01478 } <a name="l01479"></a>01479 <a name="l01495"></a><a class="code" href="inotifytools_8h.html#4d5002bd8504b70faed608886e0fa307">01495</a> <span class="keywordtype">int</span> <a class="code" href="inotifytools_8h.html#4d5002bd8504b70faed608886e0fa307">inotifytools_get_stat_by_wd</a>( <span class="keywordtype">int</span> wd, <span class="keywordtype">int</span> event ) { <a name="l01496"></a>01496 <span class="keywordflow">if</span> (!collect_stats) <span class="keywordflow">return</span> -1; <a name="l01497"></a>01497 <a name="l01498"></a>01498 watch *w = watch_from_wd(wd); <a name="l01499"></a>01499 <span class="keywordflow">if</span> (!w) <span class="keywordflow">return</span> -1; <a name="l01500"></a>01500 <span class="keywordtype">int</span> *i = stat_ptr(w, event); <a name="l01501"></a>01501 <span class="keywordflow">if</span> (!i) <span class="keywordflow">return</span> -1; <a name="l01502"></a>01502 <span class="keywordflow">return</span> *i; <a name="l01503"></a>01503 } <a name="l01504"></a>01504 <a name="l01518"></a><a class="code" href="inotifytools_8h.html#f3de070bdf428d548e0b54f5e9043dcc">01518</a> <span class="keywordtype">int</span> <a class="code" href="inotifytools_8h.html#f3de070bdf428d548e0b54f5e9043dcc">inotifytools_get_stat_total</a>( <span class="keywordtype">int</span> event ) { <a name="l01519"></a>01519 <span class="keywordflow">if</span> (!collect_stats) <span class="keywordflow">return</span> -1; <a name="l01520"></a>01520 <span class="keywordflow">if</span> ( IN_ACCESS == event ) <a name="l01521"></a>01521 <span class="keywordflow">return</span> num_access; <a name="l01522"></a>01522 <span class="keywordflow">if</span> ( IN_MODIFY == event ) <a name="l01523"></a>01523 <span class="keywordflow">return</span> num_modify; <a name="l01524"></a>01524 <span class="keywordflow">if</span> ( IN_ATTRIB == event ) <a name="l01525"></a>01525 <span class="keywordflow">return</span> num_attrib; <a name="l01526"></a>01526 <span class="keywordflow">if</span> ( IN_CLOSE_WRITE == event ) <a name="l01527"></a>01527 <span class="keywordflow">return</span> num_close_write; <a name="l01528"></a>01528 <span class="keywordflow">if</span> ( IN_CLOSE_NOWRITE == event ) <a name="l01529"></a>01529 <span class="keywordflow">return</span> num_close_nowrite; <a name="l01530"></a>01530 <span class="keywordflow">if</span> ( IN_OPEN == event ) <a name="l01531"></a>01531 <span class="keywordflow">return</span> num_open; <a name="l01532"></a>01532 <span class="keywordflow">if</span> ( IN_MOVED_FROM == event ) <a name="l01533"></a>01533 <span class="keywordflow">return</span> num_moved_from; <a name="l01534"></a>01534 <span class="keywordflow">if</span> ( IN_MOVED_TO == event ) <a name="l01535"></a>01535 <span class="keywordflow">return</span> num_moved_to; <a name="l01536"></a>01536 <span class="keywordflow">if</span> ( IN_CREATE == event ) <a name="l01537"></a>01537 <span class="keywordflow">return</span> num_create; <a name="l01538"></a>01538 <span class="keywordflow">if</span> ( IN_DELETE == event ) <a name="l01539"></a>01539 <span class="keywordflow">return</span> num_delete; <a name="l01540"></a>01540 <span class="keywordflow">if</span> ( IN_DELETE_SELF == event ) <a name="l01541"></a>01541 <span class="keywordflow">return</span> num_delete_self; <a name="l01542"></a>01542 <span class="keywordflow">if</span> ( IN_UNMOUNT == event ) <a name="l01543"></a>01543 <span class="keywordflow">return</span> num_unmount; <a name="l01544"></a>01544 <span class="keywordflow">if</span> ( IN_MOVE_SELF == event ) <a name="l01545"></a>01545 <span class="keywordflow">return</span> num_move_self; <a name="l01546"></a>01546 <a name="l01547"></a>01547 <span class="keywordflow">if</span> ( 0 == event ) <a name="l01548"></a>01548 <span class="keywordflow">return</span> num_total; <a name="l01549"></a>01549 <a name="l01550"></a>01550 <span class="keywordflow">return</span> -1; <a name="l01551"></a>01551 } <a name="l01552"></a>01552 <a name="l01572"></a><a class="code" href="inotifytools_8h.html#70bf8afcf5dce7d324d3a1a4cf48871a">01572</a> <span class="keywordtype">int</span> <a class="code" href="inotifytools_8h.html#70bf8afcf5dce7d324d3a1a4cf48871a">inotifytools_get_stat_by_filename</a>( <span class="keywordtype">char</span> <span class="keyword">const</span> * filename, <a name="l01573"></a>01573 <span class="keywordtype">int</span> event ) { <a name="l01574"></a>01574 <span class="keywordflow">return</span> <a class="code" href="inotifytools_8h.html#4d5002bd8504b70faed608886e0fa307">inotifytools_get_stat_by_wd</a>( <a class="code" href="inotifytools_8h.html#594e7f515b392c07c4f1f4eeffcda6c3">inotifytools_wd_from_filename</a>( <a name="l01575"></a>01575 filename ), event ); <a name="l01576"></a>01576 } <a name="l01577"></a>01577 <a name="l01588"></a><a class="code" href="inotifytools_8h.html#313399ccce221c8a5862892396d1a8ec">01588</a> <span class="keywordtype">int</span> <a class="code" href="inotifytools_8h.html#313399ccce221c8a5862892396d1a8ec">inotifytools_error</a>() { <a name="l01589"></a>01589 <span class="keywordflow">return</span> error; <a name="l01590"></a>01590 } <a name="l01591"></a>01591 <a name="l01595"></a>01595 <span class="keywordtype">int</span> isdir( <span class="keywordtype">char</span> <span class="keyword">const</span> * path ) { <a name="l01596"></a>01596 <span class="keyword">static</span> <span class="keyword">struct </span>stat64 my_stat; <a name="l01597"></a>01597 <a name="l01598"></a>01598 <span class="keywordflow">if</span> ( -1 == lstat64( path, &my_stat ) ) { <a name="l01599"></a>01599 <span class="keywordflow">if</span> (errno == ENOENT) <span class="keywordflow">return</span> 0; <a name="l01600"></a>01600 fprintf(stderr, <span class="stringliteral">"Stat failed on %s: %s\n"</span>, path, strerror(errno)); <a name="l01601"></a>01601 <span class="keywordflow">return</span> 0; <a name="l01602"></a>01602 } <a name="l01603"></a>01603 <a name="l01604"></a>01604 <span class="keywordflow">return</span> S_ISDIR( my_stat.st_mode ) && !S_ISLNK( my_stat.st_mode ); <a name="l01605"></a>01605 } <a name="l01606"></a>01606 <a name="l01607"></a>01607 <a name="l01614"></a><a class="code" href="inotifytools_8h.html#af934e6f66eb02f3c6e72d65c9bd610c">01614</a> <span class="keywordtype">int</span> <a class="code" href="inotifytools_8h.html#af934e6f66eb02f3c6e72d65c9bd610c">inotifytools_get_num_watches</a>() { <a name="l01615"></a>01615 <span class="keywordtype">int</span> ret = 0; <a name="l01616"></a>01616 rbwalk(tree_filename, get_num, (<span class="keywordtype">void</span>*)&ret); <a name="l01617"></a>01617 <span class="keywordflow">return</span> ret; <a name="l01618"></a>01618 } <a name="l01619"></a>01619 <a name="l01660"></a><a class="code" href="inotifytools_8h.html#c2c06dd72f39a6145ea3b6661378df31">01660</a> <span class="keywordtype">int</span> <a class="code" href="inotifytools_8h.html#c2c06dd72f39a6145ea3b6661378df31">inotifytools_printf</a>( <span class="keyword">struct</span> inotify_event* event, <span class="keywordtype">char</span>* fmt ) { <a name="l01661"></a>01661 <span class="keywordflow">return</span> <a class="code" href="inotifytools_8h.html#6ed4450ad545bde13a1328e53ed8cf6d">inotifytools_fprintf</a>( stdout, event, fmt ); <a name="l01662"></a>01662 } <a name="l01663"></a>01663 <a name="l01705"></a><a class="code" href="inotifytools_8h.html#6ed4450ad545bde13a1328e53ed8cf6d">01705</a> <span class="keywordtype">int</span> <a class="code" href="inotifytools_8h.html#6ed4450ad545bde13a1328e53ed8cf6d">inotifytools_fprintf</a>( FILE* file, <span class="keyword">struct</span> inotify_event* event, <span class="keywordtype">char</span>* fmt ) { <a name="l01706"></a>01706 <span class="keyword">static</span> <span class="keywordtype">char</span> out[MAX_STRLEN+1]; <a name="l01707"></a>01707 <span class="keyword">static</span> <span class="keywordtype">int</span> ret; <a name="l01708"></a>01708 ret = <a class="code" href="inotifytools_8h.html#abf4cbafd50012f6e35b32a052677c74">inotifytools_sprintf</a>( out, event, fmt ); <a name="l01709"></a>01709 <span class="keywordflow">if</span> ( -1 != ret ) fprintf( file, <span class="stringliteral">"%s"</span>, out ); <a name="l01710"></a>01710 <span class="keywordflow">return</span> ret; <a name="l01711"></a>01711 } <a name="l01712"></a>01712 <a name="l01763"></a><a class="code" href="inotifytools_8h.html#abf4cbafd50012f6e35b32a052677c74">01763</a> <span class="keywordtype">int</span> <a class="code" href="inotifytools_8h.html#abf4cbafd50012f6e35b32a052677c74">inotifytools_sprintf</a>( <span class="keywordtype">char</span> * out, <span class="keyword">struct</span> inotify_event* event, <span class="keywordtype">char</span>* fmt ) { <a name="l01764"></a>01764 <span class="keywordflow">return</span> <a class="code" href="inotifytools_8h.html#92f2dc66af4fd01b09b64b6813686282">inotifytools_snprintf</a>( out, MAX_STRLEN, event, fmt ); <a name="l01765"></a>01765 } <a name="l01766"></a>01766 <a name="l01767"></a>01767 <a name="l01814"></a><a class="code" href="inotifytools_8h.html#92f2dc66af4fd01b09b64b6813686282">01814</a> <span class="keywordtype">int</span> <a class="code" href="inotifytools_8h.html#92f2dc66af4fd01b09b64b6813686282">inotifytools_snprintf</a>( <span class="keywordtype">char</span> * out, <span class="keywordtype">int</span> size, <a name="l01815"></a>01815 <span class="keyword">struct</span> inotify_event* event, <span class="keywordtype">char</span>* fmt ) { <a name="l01816"></a>01816 <span class="keyword">static</span> <span class="keywordtype">char</span> * filename, * eventname, * eventstr; <a name="l01817"></a>01817 <span class="keyword">static</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, ind; <a name="l01818"></a>01818 <span class="keyword">static</span> <span class="keywordtype">char</span> ch1; <a name="l01819"></a>01819 <span class="keyword">static</span> <span class="keywordtype">char</span> timestr[MAX_STRLEN]; <a name="l01820"></a>01820 <span class="keyword">static</span> time_t now; <a name="l01821"></a>01821 <a name="l01822"></a>01822 <a name="l01823"></a>01823 <span class="keywordflow">if</span> ( event->len > 0 ) { <a name="l01824"></a>01824 eventname = <span class="keyword">event</span>->name; <a name="l01825"></a>01825 } <a name="l01826"></a>01826 <span class="keywordflow">else</span> { <a name="l01827"></a>01827 eventname = NULL; <a name="l01828"></a>01828 } <a name="l01829"></a>01829 <a name="l01830"></a>01830 <a name="l01831"></a>01831 filename = <a class="code" href="inotifytools_8h.html#fd4dcc915248f2d0b0ae708e88611186">inotifytools_filename_from_wd</a>( event->wd ); <a name="l01832"></a>01832 <a name="l01833"></a>01833 <span class="keywordflow">if</span> ( !fmt || 0 == strlen(fmt) ) { <a name="l01834"></a>01834 error = EINVAL; <a name="l01835"></a>01835 <span class="keywordflow">return</span> -1; <a name="l01836"></a>01836 } <a name="l01837"></a>01837 <span class="keywordflow">if</span> ( strlen(fmt) > MAX_STRLEN || size > MAX_STRLEN) { <a name="l01838"></a>01838 error = EMSGSIZE; <a name="l01839"></a>01839 <span class="keywordflow">return</span> -1; <a name="l01840"></a>01840 } <a name="l01841"></a>01841 <a name="l01842"></a>01842 ind = 0; <a name="l01843"></a>01843 <span class="keywordflow">for</span> ( i = 0; i < strlen(fmt) && <a name="l01844"></a>01844 (int)ind < size - 1; ++i ) { <a name="l01845"></a>01845 <span class="keywordflow">if</span> ( fmt[i] != <span class="charliteral">'%'</span> ) { <a name="l01846"></a>01846 out[ind++] = fmt[i]; <a name="l01847"></a>01847 <span class="keywordflow">continue</span>; <a name="l01848"></a>01848 } <a name="l01849"></a>01849 <a name="l01850"></a>01850 <span class="keywordflow">if</span> ( i == strlen(fmt) - 1 ) { <a name="l01851"></a>01851 <span class="comment">// last character is %, invalid</span> <a name="l01852"></a>01852 error = EINVAL; <a name="l01853"></a>01853 <span class="keywordflow">return</span> ind; <a name="l01854"></a>01854 } <a name="l01855"></a>01855 <a name="l01856"></a>01856 ch1 = fmt[i+1]; <a name="l01857"></a>01857 <a name="l01858"></a>01858 <span class="keywordflow">if</span> ( ch1 == <span class="charliteral">'%'</span> ) { <a name="l01859"></a>01859 out[ind++] = <span class="charliteral">'%'</span>; <a name="l01860"></a>01860 ++i; <a name="l01861"></a>01861 <span class="keywordflow">continue</span>; <a name="l01862"></a>01862 } <a name="l01863"></a>01863 <a name="l01864"></a>01864 <span class="keywordflow">if</span> ( ch1 == <span class="charliteral">'w'</span> ) { <a name="l01865"></a>01865 <span class="keywordflow">if</span> ( filename ) { <a name="l01866"></a>01866 strncpy( &out[ind], filename, size - ind ); <a name="l01867"></a>01867 ind += strlen(filename); <a name="l01868"></a>01868 } <a name="l01869"></a>01869 ++i; <a name="l01870"></a>01870 <span class="keywordflow">continue</span>; <a name="l01871"></a>01871 } <a name="l01872"></a>01872 <a name="l01873"></a>01873 <span class="keywordflow">if</span> ( ch1 == <span class="charliteral">'f'</span> ) { <a name="l01874"></a>01874 <span class="keywordflow">if</span> ( eventname ) { <a name="l01875"></a>01875 strncpy( &out[ind], eventname, size - ind ); <a name="l01876"></a>01876 ind += strlen(eventname); <a name="l01877"></a>01877 } <a name="l01878"></a>01878 ++i; <a name="l01879"></a>01879 <span class="keywordflow">continue</span>; <a name="l01880"></a>01880 } <a name="l01881"></a>01881 <a name="l01882"></a>01882 <span class="keywordflow">if</span> ( ch1 == <span class="charliteral">'e'</span> ) { <a name="l01883"></a>01883 eventstr = <a class="code" href="inotifytools_8h.html#744bb8792d8ea8edbaf8f845fe1d9307">inotifytools_event_to_str</a>( event->mask ); <a name="l01884"></a>01884 strncpy( &out[ind], eventstr, size - ind ); <a name="l01885"></a>01885 ind += strlen(eventstr); <a name="l01886"></a>01886 ++i; <a name="l01887"></a>01887 <span class="keywordflow">continue</span>; <a name="l01888"></a>01888 } <a name="l01889"></a>01889 <a name="l01890"></a>01890 <span class="keywordflow">if</span> ( ch1 == <span class="charliteral">'T'</span> ) { <a name="l01891"></a>01891 <a name="l01892"></a>01892 <span class="keywordflow">if</span> ( timefmt ) { <a name="l01893"></a>01893 <a name="l01894"></a>01894 now = time(0); <a name="l01895"></a>01895 <span class="keywordflow">if</span> ( 0 >= strftime( timestr, MAX_STRLEN-1, timefmt, <a name="l01896"></a>01896 localtime( &now ) ) ) { <a name="l01897"></a>01897 <a name="l01898"></a>01898 <span class="comment">// time format probably invalid</span> <a name="l01899"></a>01899 error = EINVAL; <a name="l01900"></a>01900 <span class="keywordflow">return</span> ind; <a name="l01901"></a>01901 } <a name="l01902"></a>01902 } <a name="l01903"></a>01903 <span class="keywordflow">else</span> { <a name="l01904"></a>01904 timestr[0] = 0; <a name="l01905"></a>01905 } <a name="l01906"></a>01906 <a name="l01907"></a>01907 strncpy( &out[ind], timestr, size - ind ); <a name="l01908"></a>01908 ind += strlen(timestr); <a name="l01909"></a>01909 ++i; <a name="l01910"></a>01910 <span class="keywordflow">continue</span>; <a name="l01911"></a>01911 } <a name="l01912"></a>01912 <a name="l01913"></a>01913 <span class="comment">// Check if next char in fmt is e</span> <a name="l01914"></a>01914 <span class="keywordflow">if</span> ( i < strlen(fmt) - 2 && fmt[i+2] == <span class="charliteral">'e'</span> ) { <a name="l01915"></a>01915 eventstr = <a class="code" href="inotifytools_8h.html#317a5b1ea969f570a49c4549b22e7e71">inotifytools_event_to_str_sep</a>( event->mask, ch1 ); <a name="l01916"></a>01916 strncpy( &out[ind], eventstr, size - ind ); <a name="l01917"></a>01917 ind += strlen(eventstr); <a name="l01918"></a>01918 i += 2; <a name="l01919"></a>01919 <span class="keywordflow">continue</span>; <a name="l01920"></a>01920 } <a name="l01921"></a>01921 <a name="l01922"></a>01922 <span class="comment">// OK, this wasn't a special format character, just output it as normal</span> <a name="l01923"></a>01923 <span class="keywordflow">if</span> ( ind < MAX_STRLEN ) out[ind++] = <span class="charliteral">'%'</span>; <a name="l01924"></a>01924 <span class="keywordflow">if</span> ( ind < MAX_STRLEN ) out[ind++] = ch1; <a name="l01925"></a>01925 ++i; <a name="l01926"></a>01926 } <a name="l01927"></a>01927 out[ind] = 0; <a name="l01928"></a>01928 <a name="l01929"></a>01929 <span class="keywordflow">return</span> ind - 1; <a name="l01930"></a>01930 } <a name="l01931"></a>01931 <a name="l01941"></a><a class="code" href="inotifytools_8h.html#f4528ccdf013b4c86e8f7fe4db88244a">01941</a> <span class="keywordtype">void</span> <a class="code" href="inotifytools_8h.html#f4528ccdf013b4c86e8f7fe4db88244a">inotifytools_set_printf_timefmt</a>( <span class="keywordtype">char</span> * fmt ) { <a name="l01942"></a>01942 timefmt = fmt; <a name="l01943"></a>01943 } <a name="l01944"></a>01944 <a name="l01953"></a><a class="code" href="inotifytools_8h.html#1d96f4600d1187670304b83439b0cd05">01953</a> <span class="keywordtype">int</span> <a class="code" href="inotifytools_8h.html#1d96f4600d1187670304b83439b0cd05">inotifytools_get_max_queued_events</a>() { <a name="l01954"></a>01954 <span class="keywordtype">int</span> ret; <a name="l01955"></a>01955 <span class="keywordflow">if</span> ( !read_num_from_file( QUEUE_SIZE_PATH, &ret ) ) <span class="keywordflow">return</span> -1; <a name="l01956"></a>01956 <span class="keywordflow">return</span> ret; <a name="l01957"></a>01957 } <a name="l01958"></a>01958 <a name="l01968"></a><a class="code" href="inotifytools_8h.html#9e8052a5fb77768cec9fff4aed9b9eb0">01968</a> <span class="keywordtype">int</span> <a class="code" href="inotifytools_8h.html#9e8052a5fb77768cec9fff4aed9b9eb0">inotifytools_get_max_user_instances</a>() { <a name="l01969"></a>01969 <span class="keywordtype">int</span> ret; <a name="l01970"></a>01970 <span class="keywordflow">if</span> ( !read_num_from_file( INSTANCES_PATH, &ret ) ) <span class="keywordflow">return</span> -1; <a name="l01971"></a>01971 <span class="keywordflow">return</span> ret; <a name="l01972"></a>01972 } <a name="l01973"></a>01973 <a name="l01983"></a><a class="code" href="inotifytools_8h.html#e3b79f096737ef3c7e176324514b4556">01983</a> <span class="keywordtype">int</span> <a class="code" href="inotifytools_8h.html#e3b79f096737ef3c7e176324514b4556">inotifytools_get_max_user_watches</a>() { <a name="l01984"></a>01984 <span class="keywordtype">int</span> ret; <a name="l01985"></a>01985 <span class="keywordflow">if</span> ( !read_num_from_file( WATCHES_SIZE_PATH, &ret ) ) <span class="keywordflow">return</span> -1; <a name="l01986"></a>01986 <span class="keywordflow">return</span> ret; <a name="l01987"></a>01987 } <a name="l01988"></a>01988 <a name="l02000"></a><a class="code" href="inotifytools_8h.html#07f4f258123feb8864f89663a2785ef0">02000</a> <span class="keywordtype">int</span> <a class="code" href="inotifytools_8h.html#07f4f258123feb8864f89663a2785ef0">inotifytools_ignore_events_by_regex</a>( <span class="keywordtype">char</span> <span class="keyword">const</span> *pattern, <span class="keywordtype">int</span> flags ) { <a name="l02001"></a>02001 <span class="keywordflow">if</span> (!pattern) { <a name="l02002"></a>02002 <span class="keywordflow">if</span> (regex) { <a name="l02003"></a>02003 regfree(regex); <a name="l02004"></a>02004 free(regex); <a name="l02005"></a>02005 regex = 0; <a name="l02006"></a>02006 } <a name="l02007"></a>02007 <span class="keywordflow">return</span> 1; <a name="l02008"></a>02008 } <a name="l02009"></a>02009 <a name="l02010"></a>02010 <span class="keywordflow">if</span> (regex) { regfree(regex); } <a name="l02011"></a>02011 <span class="keywordflow">else</span> { regex = (regex_t *)malloc(<span class="keyword">sizeof</span>(regex_t)); } <a name="l02012"></a>02012 <a name="l02013"></a>02013 <span class="keywordtype">int</span> ret = regcomp(regex, pattern, flags | REG_NOSUB); <a name="l02014"></a>02014 <span class="keywordflow">if</span> (0 == ret) <span class="keywordflow">return</span> 1; <a name="l02015"></a>02015 <a name="l02016"></a>02016 regfree(regex); <a name="l02017"></a>02017 free(regex); <a name="l02018"></a>02018 regex = 0; <a name="l02019"></a>02019 error = EINVAL; <a name="l02020"></a>02020 <span class="keywordflow">return</span> 0; <a name="l02021"></a>02021 } <a name="l02022"></a>02022 <a name="l02023"></a>02023 <span class="keywordtype">int</span> event_compare(<span class="keyword">const</span> <span class="keywordtype">void</span> *p1, <span class="keyword">const</span> <span class="keywordtype">void</span> *p2, <span class="keyword">const</span> <span class="keywordtype">void</span> *config) <a name="l02024"></a>02024 { <a name="l02025"></a>02025 <span class="keywordflow">if</span> (!p1 || !p2) <span class="keywordflow">return</span> p1 - p2; <a name="l02026"></a>02026 <span class="keywordtype">char</span> asc = 1; <a name="l02027"></a>02027 <span class="keywordtype">int</span> sort_event = (int)config; <a name="l02028"></a>02028 <span class="keywordflow">if</span> (sort_event == -1) { <a name="l02029"></a>02029 sort_event = 0; <a name="l02030"></a>02030 asc = 0; <a name="l02031"></a>02031 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (sort_event < 0) { <a name="l02032"></a>02032 sort_event = -sort_event; <a name="l02033"></a>02033 asc = 0; <a name="l02034"></a>02034 } <a name="l02035"></a>02035 <span class="keywordtype">int</span> *i1 = stat_ptr((watch*)p1, sort_event); <a name="l02036"></a>02036 <span class="keywordtype">int</span> *i2 = stat_ptr((watch*)p2, sort_event); <a name="l02037"></a>02037 <span class="keywordflow">if</span> (0 == *i1 - *i2) { <a name="l02038"></a>02038 <span class="keywordflow">return</span> ((watch*)p1)->wd - ((watch*)p2)->wd; <a name="l02039"></a>02039 } <a name="l02040"></a>02040 <span class="keywordflow">if</span> (asc) <a name="l02041"></a>02041 <span class="keywordflow">return</span> *i1 - *i2; <a name="l02042"></a>02042 <span class="keywordflow">else</span> <a name="l02043"></a>02043 <span class="keywordflow">return</span> *i2 - *i1; <a name="l02044"></a>02044 } <a name="l02045"></a>02045 <a name="l02046"></a>02046 <span class="keyword">struct </span>rbtree *inotifytools_wd_sorted_by_event(<span class="keywordtype">int</span> sort_event) <a name="l02047"></a>02047 { <a name="l02048"></a>02048 <span class="keyword">struct </span>rbtree *ret = rbinit(event_compare, (<span class="keywordtype">void</span>*)sort_event); <a name="l02049"></a>02049 RBLIST *all = rbopenlist(tree_wd); <a name="l02050"></a>02050 <span class="keywordtype">void</span> <span class="keyword">const</span> *p = rbreadlist(all); <a name="l02051"></a>02051 <span class="keywordflow">while</span> (p) { <a name="l02052"></a>02052 <span class="keywordtype">void</span> <span class="keyword">const</span> *r = rbsearch(p, ret); <a name="l02053"></a>02053 niceassert((<span class="keywordtype">int</span>)(r == p), <span class="stringliteral">"Couldn't insert watch into new tree"</span>); <a name="l02054"></a>02054 p = rbreadlist(all); <a name="l02055"></a>02055 } <a name="l02056"></a>02056 rbcloselist(all); <a name="l02057"></a>02057 <span class="keywordflow">return</span> ret; <a name="l02058"></a>02058 } </pre></div></div> <hr size="1"><address style="text-align: right;"><small>Generated on Fri Sep 4 02:03:43 2009 for libinotifytools by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.9 </small></address> </body> </html>