Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > c6601b2b228e5b275ef3625eb28da668 > files > 19

libinotifytools-devel-3.13-3mdv2010.0.i586.rpm

<!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&nbsp;Page</span></a></li>
      <li><a href="pages.html"><span>Related&nbsp;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&nbsp;List</span></a></li>
      <li><a href="globals.html"><span>File&nbsp;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 &lt;string.h&gt;</span>
<a name="l00020"></a>00020 <span class="preprocessor">#include &lt;strings.h&gt;</span>
<a name="l00021"></a>00021 <span class="preprocessor">#include &lt;stdlib.h&gt;</span>
<a name="l00022"></a>00022 <span class="preprocessor">#include &lt;stdio.h&gt;</span>
<a name="l00023"></a>00023 <span class="preprocessor">#include &lt;errno.h&gt;</span>
<a name="l00024"></a>00024 <span class="preprocessor">#include &lt;sys/select.h&gt;</span>
<a name="l00025"></a>00025 <span class="preprocessor">#include &lt;sys/types.h&gt;</span>
<a name="l00026"></a>00026 <span class="preprocessor">#include &lt;sys/stat.h&gt;</span>
<a name="l00027"></a>00027 <span class="preprocessor">#include &lt;sys/ioctl.h&gt;</span>
<a name="l00028"></a>00028 <span class="preprocessor">#include &lt;unistd.h&gt;</span>
<a name="l00029"></a>00029 <span class="preprocessor">#include &lt;dirent.h&gt;</span>
<a name="l00030"></a>00030 <span class="preprocessor">#include &lt;time.h&gt;</span>
<a name="l00031"></a>00031 <span class="preprocessor">#include &lt;regex.h&gt;</span>
<a name="l00032"></a>00032 <span class="preprocessor">#include &lt;setjmp.h&gt;</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)-&gt;wd - ((watch*)d2)-&gt;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)-&gt;filename, ((watch*)d2)-&gt;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(&amp;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(&amp;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 &lt; 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-&gt;filename) free(w-&gt;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 &amp;&amp; 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 &amp;&amp; which != leaf) <span class="keywordflow">return</span>;
<a name="l00353"></a>00353         watch *w = (watch*)nodep;
<a name="l00354"></a>00354         w-&gt;hit_access = 0;
<a name="l00355"></a>00355         w-&gt;hit_modify = 0;
<a name="l00356"></a>00356         w-&gt;hit_attrib = 0;
<a name="l00357"></a>00357         w-&gt;hit_close_nowrite = 0;
<a name="l00358"></a>00358         w-&gt;hit_close_write = 0;
<a name="l00359"></a>00359         w-&gt;hit_open = 0;
<a name="l00360"></a>00360         w-&gt;hit_move_self = 0;
<a name="l00361"></a>00361         w-&gt;hit_moved_from = 0;
<a name="l00362"></a>00362         w-&gt;hit_moved_to = 0;
<a name="l00363"></a>00363         w-&gt;hit_create = 0;
<a name="l00364"></a>00364         w-&gt;hit_delete = 0;
<a name="l00365"></a>00365         w-&gt;hit_delete_self = 0;
<a name="l00366"></a>00366         w-&gt;hit_unmount = 0;
<a name="l00367"></a>00367         w-&gt;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 &amp;&amp; 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>*)&amp;((<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-&gt;filename, old_len ) ) {
<a name="l00383"></a>00383                 nasprintf( &amp;name, <span class="stringliteral">"%s%s"</span>, new_name, &amp;(w-&gt;filename[old_len]) );
<a name="l00384"></a>00384                 <span class="keywordflow">if</span> (!strcmp( w-&gt;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-&gt;filename );
<a name="l00389"></a>00389                         w-&gt;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 &amp;&amp; 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 &amp;&amp; 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 &lt; 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 &gt; 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 &amp;&amp; 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 &amp; 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 &amp; 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 &amp; 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 &amp; 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 &amp; 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 &amp; 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 &amp; 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 &amp; 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 &amp; 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 &amp; 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 &amp; 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 &amp; 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 &amp; 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 &amp; 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 &amp; 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 &amp; 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 &amp; 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 &amp; 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> &amp;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-&gt;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-&gt;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-&gt;filename) free(w-&gt;filename);
<a name="l00810"></a>00810         w-&gt;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-&gt;filename) free(w-&gt;filename);
<a name="l00832"></a>00832         w-&gt;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>*)&amp;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-&gt;wd );
<a name="l00873"></a>00873         <span class="keywordflow">if</span> ( status &lt; 0 ) {
<a name="l00874"></a>00874                 fprintf(stderr, <span class="stringliteral">"Failed to remove watch on %s: %s\n"</span>, w-&gt;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 &lt;= 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-&gt;wd = wd;
<a name="l00890"></a>00890         w-&gt;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 &lt; 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 &gt;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 &lt; 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( &amp;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 &lt;= 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 &lt; 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           &amp;&amp; first_byte &lt;= (<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> *)&amp;<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-&gt;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 &gt; 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> *)&amp;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) &lt;= (<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> *)&amp;event[0] + bytes - (<span class="keywordtype">char</span> *)ret;
<a name="l01147"></a>01147                         memcpy( &amp;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 &lt;= 0 ? NULL : &amp;read_timeout );
<a name="l01169"></a>01169 
<a name="l01170"></a>01170         FD_ZERO(&amp;read_fds);
<a name="l01171"></a>01171         FD_SET(inotify_fd, &amp;read_fds);
<a name="l01172"></a>01172         rc = select(inotify_fd + 1, &amp;read_fds,
<a name="l01173"></a>01173                     NULL, NULL, read_timeout_ptr);
<a name="l01174"></a>01174         <span class="keywordflow">if</span> ( rc &lt; 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, &amp;bytes_to_read );
<a name="l01187"></a>01187         } <span class="keywordflow">while</span> ( !rc &amp;&amp;
<a name="l01188"></a>01188                   bytes_to_read &lt; <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, &amp;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 &lt; 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 = &amp;<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-&gt;len;
<a name="l01210"></a>01210         niceassert( first_byte &lt;= 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( &amp;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-&gt;d_name, <span class="stringliteral">"."</span> )) &amp;&amp;
<a name="l01315"></a>01315                      (0 != strcmp( ent-&gt;d_name, <span class="stringliteral">".."</span> )) ) {
<a name="l01316"></a>01316                         nasprintf(&amp;next_file,<span class="stringliteral">"%s%s"</span>, my_path, ent-&gt;d_name);
<a name="l01317"></a>01317                         <span class="keywordflow">if</span> ( -1 == lstat64( next_file, &amp;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 ) &amp;&amp;
<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(&amp;next_file,<span class="stringliteral">"%s%s/"</span>, my_path, ent-&gt;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 &amp;&amp; *exclude_entry &amp;&amp; !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) &amp;&amp;
<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 &amp;&amp; (EACCES != error) &amp;&amp; (ENOENT != error) &amp;&amp;
<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-&gt;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 &amp; event-&gt;mask ) {
<a name="l01390"></a>01390                 ++w-&gt;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 &amp; event-&gt;mask ) {
<a name="l01394"></a>01394                 ++w-&gt;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 &amp; event-&gt;mask ) {
<a name="l01398"></a>01398                 ++w-&gt;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 &amp; event-&gt;mask ) {
<a name="l01402"></a>01402                 ++w-&gt;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 &amp; event-&gt;mask ) {
<a name="l01406"></a>01406                 ++w-&gt;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 &amp; event-&gt;mask ) {
<a name="l01410"></a>01410                 ++w-&gt;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 &amp; event-&gt;mask ) {
<a name="l01414"></a>01414                 ++w-&gt;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 &amp; event-&gt;mask ) {
<a name="l01418"></a>01418                 ++w-&gt;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 &amp; event-&gt;mask ) {
<a name="l01422"></a>01422                 ++w-&gt;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 &amp; event-&gt;mask ) {
<a name="l01426"></a>01426                 ++w-&gt;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 &amp; event-&gt;mask ) {
<a name="l01430"></a>01430                 ++w-&gt;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 &amp; event-&gt;mask ) {
<a name="l01434"></a>01434                 ++w-&gt;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 &amp; event-&gt;mask ) {
<a name="l01438"></a>01438                 ++w-&gt;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-&gt;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> &amp;w-&gt;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> &amp;w-&gt;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> &amp;w-&gt;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> &amp;w-&gt;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> &amp;w-&gt;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> &amp;w-&gt;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> &amp;w-&gt;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> &amp;w-&gt;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> &amp;w-&gt;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> &amp;w-&gt;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> &amp;w-&gt;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> &amp;w-&gt;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> &amp;w-&gt;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> &amp;w-&gt;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, &amp;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 ) &amp;&amp; !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>*)&amp;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-&gt;len &gt; 0 ) {
<a name="l01824"></a>01824                 eventname = <span class="keyword">event</span>-&gt;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-&gt;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) &gt; MAX_STRLEN || size &gt; 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 &lt; strlen(fmt) &amp;&amp;
<a name="l01844"></a>01844                      (int)ind &lt; 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( &amp;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( &amp;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-&gt;mask );
<a name="l01884"></a>01884                         strncpy( &amp;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 &gt;= strftime( timestr, MAX_STRLEN-1, timefmt,
<a name="l01896"></a>01896                                                     localtime( &amp;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( &amp;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 &lt; strlen(fmt) - 2 &amp;&amp; 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-&gt;mask, ch1 );
<a name="l01916"></a>01916                         strncpy( &amp;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 &lt; MAX_STRLEN ) out[ind++] = <span class="charliteral">'%'</span>;
<a name="l01924"></a>01924                 <span class="keywordflow">if</span> ( ind &lt; 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, &amp;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, &amp;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, &amp;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 &lt; 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)-&gt;wd - ((watch*)p2)-&gt;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&nbsp;
<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>