You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
fail2ban/pyinotify.patch

1379 lines
49 KiB

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>
Attachment #381327 for bug #551895</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="verify-v1" content="1hLjVPyIYh2cX7CL+s5A0k6pKt2FRq7/FSQ/cqGi9J8=">
<meta name="y_key" content="1cdf458efae704ba">
<link rel="Top" href="https://bugzilla.redhat.com/">
<link href="skins/standard/global.css"
rel="stylesheet"
type="text/css">
<link href="skins/standard/create_attachment.css"
rel="stylesheet"
type="text/css">
<!--[if lte IE 7]>
<link href="skins/standard/IE-fixes.css"
rel="stylesheet"
type="text/css">
<![endif]-->
<link href="skins/standard/global.css"
rel="alternate stylesheet"
title="Classic"
type="text/css">
<link href="skins/standard/create_attachment.css"
rel="alternate stylesheet"
title="Classic"
type="text/css">
<!--[if lte IE 7]>
<link href="skins/standard/IE-fixes.css"
rel="alternate stylesheet"
title="Classic"
type="text/css">
<![endif]-->
<link href="skins/contrib/Dusk/global.css"
rel="alternate stylesheet"
title="Dusk"
type="text/css">
<link href="skins/contrib/Dusk/create_attachment.css"
rel="alternate stylesheet"
title="Dusk"
type="text/css">
<!--[if lte IE 7]>
<link href="skins/contrib/Dusk/IE-fixes.css"
rel="alternate stylesheet"
title="Dusk"
type="text/css">
<![endif]-->
<link href="skins/contrib/RedHat/global.css"
rel="stylesheet"
title="RedHat"
type="text/css">
<link href="skins/contrib/RedHat/create_attachment.css"
rel="stylesheet"
title="RedHat"
type="text/css">
<!--[if lte IE 7]>
<link href="skins/contrib/RedHat/IE-fixes.css"
rel="stylesheet"
title="RedHat"
type="text/css">
<![endif]-->
<link href="skins/custom/global.css" rel="stylesheet" type="text/css">
<link href="skins/custom/create_attachment.css" rel="stylesheet" type="text/css">
<!--[if lte IE 7]>
<link href="skins/custom/IE-fixes.css"
rel="stylesheet"
type="text/css">
<![endif]-->
<script src="js/cookies.js" type="text/javascript" language="JavaScript"></script>
<script src="js/yui/yahoo-dom-event.js" type="text/javascript"></script>
<script src="js/yui/cookie.js" type="text/javascript"></script>
<script src="js/global.js" type="text/javascript"></script>
<script type="text/javascript">
<!--
YAHOO.namespace('bugzilla');
if (YAHOO.env.ua.gecko) {
YAHOO.util.Event._simpleRemove(window, "unload",
YAHOO.util.Event._unload);
}
function unhide_language_selector() {
YAHOO.util.Dom.removeClass(
'lang_links_container', 'bz_default_hidden'
);
}
YAHOO.util.Event.onDOMReady(unhide_language_selector);
var BUGZILLA = {
param: {
cookiepath: '\/'
},
string: {
attach_desc_required:
'You must enter a Description for this attachment.'
}
};
// -->
</script>
<script src="js/attachment.js" type="text/javascript"></script>
<script type="text/javascript">
// REDHAT EXTENSION 441550
// Set use_ajax for use in the js files
var use_ajax = '1';
// REDHAT EXTENSION 426374
// Server URL is set here since we cannot access Param('sslbase')
// in the js/ files.
var server_url = 'https://bugzilla.redhat.com/xmlrpc.cgi';
</script>
<link rel="search" type="application/opensearchdescription+xml"
title="Red Hat Bugzilla" href="./search_plugin.cgi">
<link rel="shortcut icon" href="images/favicon.ico">
</head>
<body onload="restore_all(); document.checkboxform.restore_indicator.checked = true
setcookie('Bugzilla_javascript',1,1,'/','bugzilla.redhat.com',0);"
class="bugzilla-redhat-com yui-skin-sam">
<div id="header">
<div id="banner">
</div>
<table border="0" cellspacing="0" cellpadding="0" id="titles">
<tr>
<td id="title">
<p>Red Hat Bugzilla &ndash;
Attachment #381327: Patch to add in pyinotify support
for <a href="show_bug.cgi?id=551895">bug #551895</a></p>
</td>
</tr>
</table>
<table id="lang_links_container" cellpadding="0" cellspacing="0"
class="bz_default_hidden"><tr><td>
</td></tr></table>
<ul class="links">
<li><a href="./">Home</a></li>
<li><span class="separator">| </span><a href="enter_bug.cgi">New</a></li>
<li><span class="separator">| </span><a href="query.cgi">Search</a></li>
<li><span class="separator"> | </span><a href="page.cgi?id=browse.html">Browse</a></li>
<li class="form">
<span class="separator">| </span>
<form action="buglist.cgi" method="get"
onsubmit="if (this.quicksearch.value == '')
{ alert('Please enter one or more search terms first.');
return false; } return true;">
<input class="txt" type="text" id="quicksearch_top" name="quicksearch"
value="">
<input class="btn" type="submit" value="Search"
id="find_top"></form>
<a href="page.cgi?id=quicksearch.html" title="Quicksearch Help">[?]</a></li>
<li><span class="separator">| </span><a href="report.cgi">Reports</a></li>
<li>
<span class="separator">| </span>
<a href="request.cgi">Requests</a></li>
<li>
<span class="separator">| </span>
<a href="/docs/en/html/attachments.html#patchviewer" target="_blank">Help</a>
</li>
<li id="new_account_container_top">
<span class="separator">| </span>
<a href="createaccount.cgi">New&nbsp;Account</a>
</li>
<li id="mini_login_container_top">
<span class="separator">| </span>
<a id="login_link_top" href="https://bugzilla.redhat.com/attachment.cgi?id=381327&amp;action=diff&amp;GoAheadAndLogIn=1"
onclick="return show_mini_login_form('_top')">Log In</a>
<form action="https://bugzilla.redhat.com/attachment.cgi?id=381327&amp;action=diff" method="POST"
class="mini_login bz_default_hidden"
id="mini_login_top"
onsubmit="return check_mini_login_fields( '_top' );"
>
<input id="Bugzilla_login_top"
class="bz_login"
name="Bugzilla_login"
onfocus="mini_login_on_focus('_top')"
>
<input class="bz_password"
id="Bugzilla_password_top"
name="Bugzilla_password"
type="password"
>
<input class="bz_password bz_default_hidden bz_mini_login_help" type="text"
id="Bugzilla_password_dummy_top" value="password"
onfocus="mini_login_on_focus('_top')"
>
<input type="submit" name="GoAheadAndLogIn" value="Log in"
id="log_in_top">
<script type="text/javascript">
mini_login_constants = {
"login" : "login",
"warning" : "You must set the login and password before logging in."
};
if (YAHOO.env.ua.gecko || YAHOO.env.ua.ie || YAHOO.env.ua.opera) {
YAHOO.util.Event.onDOMReady(function() {
init_mini_login_form('_top');
});
}
else {
YAHOO.util.Event.on(window, 'load', function () {
window.setTimeout(function() {
init_mini_login_form('_top');
}, 200);
});
}
</script>
<a href="#" onclick="return hide_mini_login_form('_top')">[x]</a>
</form>
</li>
<li id="forgot_container_top">
<span class="separator">| </span>
<a id="forgot_link_top" href="https://bugzilla.redhat.com/attachment.cgi?id=381327&amp;action=diff&amp;GoAheadAndLogIn=1#forgot"
onclick="return show_forgot_form('_top')">Forgot Password</a>
<form action="token.cgi" method="post" id="forgot_form_top"
class="mini_forgot bz_default_hidden">
<label>Login: <input type="text" name="loginname" size="20"></label>
<input id="forgot_button_top" value="Reset Password"
type="submit">
<input type="hidden" name="a" value="reqpw">
<a href="#" onclick="return hide_forgot_form('_top')">[x]</a>
</form>
</li>
</ul>
</div>
<div id="bugzilla-body">
<a href="attachment.cgi?id=381327">View</a>
| <a href="attachment.cgi?id=381327&amp;action=edit">Details</a>
| <a href="attachment.cgi?id=381327&amp;action=diff&amp;context=patch&amp;collapsed=&amp;headers=1&amp;format=raw">Raw&nbsp;Unified</a>
| Return to <a href="show_bug.cgi?id=551895" title="NEW - RFE: Add patch to enable inotify support">bug 551895</a>
<br>
<a href="#"
onmouseover="lastStatus = window.status; window.status='Collapse All'; return true"
onmouseout="window.status = lastStatus; return true"
onclick="return collapse_all()">Collapse All</a> |
<a href="#"
onmouseover="lastStatus = window.status; window.status='Expand All'; return true"
onmouseout="window.status = lastStatus; return true"
onclick="return expand_all()">Expand All</a>
<br><br>
<form name="checkboxform" action="attachment.cgi">
<input type="checkbox" name="restore_indicator" style="display: none"><table class="file_table"><thead><tr><td class="num"></td><td></td><td class="num"></td><td></td></tr><tr><td class="file_head" colspan="4"><a href="#" onclick="return twisty_click(this)">(-)</a><input type="checkbox" name="a/config/jail.conf" checked style="display: none">a/config/jail.conf
(-3&nbsp;/&nbsp;+6&nbsp;lines)
</td></tr></thead><tbody class="file">
<script type="text/javascript">
incremental_restore()
</script>
<tr><th colspan="4" class="section_head">
<table cellpadding="0" cellspacing="0">
<tr><th width="95%" align="left">
&nbsp;Lines&nbsp;26-38
&nbsp;&nbsp;findtime = 600
</th><th>
<a name="a/config/jail.conf_sec1" href="#a/config/jail.conf_sec1">Link&nbsp;Here</a>&nbsp;
</th></tr></table>
</th></tr>
<tr>
<td class="num">26</td>
<td><pre>maxretry = 3</pre></td>
<td class="num">26</td>
<td><pre>maxretry = 3</pre></td>
</tr>
<tr>
<td class="num">27</td>
<td><pre></pre></td>
<td class="num">27</td>
<td><pre></pre></td>
</tr>
<tr>
<td class="num">28</td>
<td><pre># &quot;backend&quot; specifies the backend used to get files modification. Available</pre></td>
<td class="num">28</td>
<td><pre># &quot;backend&quot; specifies the backend used to get files modification. Available</pre></td>
</tr>
<tr>
<td class="num">29</td>
<td class="changed"><pre># options are &quot;gamin&quot;, &quot;polling&quot; and &quot;auto&quot;. This option can be overridden in</pre></td>
<td class="num">29</td>
<td class="changed"><pre># options are &quot;inotify&quot;, &quot;gamin&quot;, &quot;polling&quot; and &quot;auto&quot;. This option can be</pre></td>
</tr>
<tr>
<td class="num">30</td>
<td class="changed"><pre># each jail too (use &quot;gamin&quot; for a jail and &quot;polling&quot; for another).</pre></td>
<td class="num">30</td>
<td class="changed"><pre># overridden in each jail too (use &quot;gamin&quot; for a jail and &quot;polling&quot; for</pre></td>
</tr>
<tr>
<td class="num"></td>
<td class="changed"></td>
<td class="num">31</td>
<td class="changed"><pre># another).</pre></td>
</tr>
<tr>
<td class="num">31</td>
<td><pre>#</pre></td>
<td class="num">32</td>
<td><pre>#</pre></td>
</tr>
<tr>
<td class="num"></td>
<td></td>
<td class="num">33</td>
<td class="added"><pre># inotify: requires pyinotify and the a kernel supporting Inotify</pre></td>
</tr>
<tr>
<td class="num">32</td>
<td><pre># gamin: requires Gamin (a file alteration monitor) to be installed. If Gamin</pre></td>
<td class="num">34</td>
<td><pre># gamin: requires Gamin (a file alteration monitor) to be installed. If Gamin</pre></td>
</tr>
<tr>
<td class="num">33</td>
<td><pre># is not installed, Fail2ban will use polling.</pre></td>
<td class="num">35</td>
<td><pre># is not installed, Fail2ban will use polling.</pre></td>
</tr>
<tr>
<td class="num">34</td>
<td><pre># polling: uses a polling algorithm which does not require external libraries.</pre></td>
<td class="num">36</td>
<td><pre># polling: uses a polling algorithm which does not require external libraries.</pre></td>
</tr>
<tr>
<td class="num">35</td>
<td class="changed"><pre># auto: will choose Gamin if available and polling otherwise.</pre></td>
<td class="num">37</td>
<td class="changed"><pre># auto: will choose Inotify if pyinotify is present, if not then it will</pre></td>
</tr>
<tr>
<td class="num"></td>
<td class="changed"></td>
<td class="num">38</td>
<td class="changed"><pre># try Gamin and use that if available, and polling otherwise.</pre></td>
</tr>
<tr>
<td class="num">36</td>
<td><pre>backend = auto</pre></td>
<td class="num">39</td>
<td><pre>backend = auto</pre></td>
</tr>
<tr>
<td class="num">37</td>
<td><pre></pre></td>
<td class="num">40</td>
<td><pre></pre></td>
</tr>
<tr>
<td class="num">38</td>
<td><pre></pre></td>
<td class="num">41</td>
<td><pre></pre></td>
</tr>
</table><table class="file_table"><thead><tr><td class="num"></td><td></td><td class="num"></td><td></td></tr><tr><td class="file_head" colspan="4"><a href="#" onclick="return twisty_click(this)">(-)</a><input type="checkbox" name="a/server/filterinotify.py" checked style="display: none">a/server/filterinotify.py
(+157&nbsp;lines)
</td></tr></thead><tbody class="file">
<script type="text/javascript">
incremental_restore()
</script>
<tr><th colspan="4" class="section_head">
<table cellpadding="0" cellspacing="0">
<tr><th width="95%" align="left">
Line&nbsp;0
&nbsp;&nbsp;
</th><th>
<a name="a/server/filterinotify.py_sec1" href="#a/server/filterinotify.py_sec1">Link&nbsp;Here</a>&nbsp;
</th></tr></table>
</th></tr>
<tr>
<td class="num" rowspan="157"></td>
<td rowspan="157"></td>
<td class="num">1</td>
<td class="added"><pre># This file is part of Fail2Ban.</pre></td>
</tr>
<tr>
<td class="num">2</td>
<td class="added"><pre>#</pre></td>
</tr>
<tr>
<td class="num">3</td>
<td class="added"><pre># Fail2Ban is free software; you can redistribute it and/or modify</pre></td>
</tr>
<tr>
<td class="num">4</td>
<td class="added"><pre># it under the terms of the GNU General Public License as published by</pre></td>
</tr>
<tr>
<td class="num">5</td>
<td class="added"><pre># the Free Software Foundation; either version 2 of the License, or</pre></td>
</tr>
<tr>
<td class="num">6</td>
<td class="added"><pre># (at your option) any later version.</pre></td>
</tr>
<tr>
<td class="num">7</td>
<td class="added"><pre>#</pre></td>
</tr>
<tr>
<td class="num">8</td>
<td class="added"><pre># Fail2Ban is distributed in the hope that it will be useful,</pre></td>
</tr>
<tr>
<td class="num">9</td>
<td class="added"><pre># but WITHOUT ANY WARRANTY; without even the implied warranty of</pre></td>
</tr>
<tr>
<td class="num">10</td>
<td class="added"><pre># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</pre></td>
</tr>
<tr>
<td class="num">11</td>
<td class="added"><pre># GNU General Public License for more details.</pre></td>
</tr>
<tr>
<td class="num">12</td>
<td class="added"><pre>#</pre></td>
</tr>
<tr>
<td class="num">13</td>
<td class="added"><pre># You should have received a copy of the GNU General Public License</pre></td>
</tr>
<tr>
<td class="num">14</td>
<td class="added"><pre># along with Fail2Ban; if not, write to the Free Software</pre></td>
</tr>
<tr>
<td class="num">15</td>
<td class="added"><pre># Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA</pre></td>
</tr>
<tr>
<td class="num">16</td>
<td class="added"><pre></pre></td>
</tr>
<tr>
<td class="num">17</td>
<td class="added"><pre># Author: Jonathan G. Underwood</pre></td>
</tr>
<tr>
<td class="num">18</td>
<td class="added"><pre># </pre></td>
</tr>
<tr>
<td class="num">19</td>
<td class="added"><pre># $Revision$</pre></td>
</tr>
<tr>
<td class="num">20</td>
<td class="added"><pre></pre></td>
</tr>
<tr>
<td class="num">21</td>
<td class="added"><pre>__author__ = &quot;Jonathan G. Underwood&quot;</pre></td>
</tr>
<tr>
<td class="num">22</td>
<td class="added"><pre>__version__ = &quot;$Revision$&quot;</pre></td>
</tr>
<tr>
<td class="num">23</td>
<td class="added"><pre>__date__ = &quot;$Date$&quot;</pre></td>
</tr>
<tr>
<td class="num">24</td>
<td class="added"><pre>__copyright__ = &quot;Copyright (c) 2010 Jonathan G. Underwood&quot;</pre></td>
</tr>
<tr>
<td class="num">25</td>
<td class="added"><pre>__license__ = &quot;GPL&quot;</pre></td>
</tr>
<tr>
<td class="num">26</td>
<td class="added"><pre></pre></td>
</tr>
<tr>
<td class="num">27</td>
<td class="added"><pre>from failmanager import FailManagerEmpty</pre></td>
</tr>
<tr>
<td class="num">28</td>
<td class="added"><pre>from filter import FileFilter</pre></td>
</tr>
<tr>
<td class="num">29</td>
<td class="added"><pre>from mytime import MyTime</pre></td>
</tr>
<tr>
<td class="num">30</td>
<td class="added"><pre></pre></td>
</tr>
<tr>
<td class="num">31</td>
<td class="added"><pre>import time, logging</pre></td>
</tr>
<tr>
<td class="num">32</td>
<td class="added"><pre></pre></td>
</tr>
<tr>
<td class="num">33</td>
<td class="added"><pre>import pyinotify</pre></td>
</tr>
<tr>
<td class="num">34</td>
<td class="added"><pre>from pyinotify import ProcessEvent, WatchManager, Notifier</pre></td>
</tr>
<tr>
<td class="num">35</td>
<td class="added"><pre></pre></td>
</tr>
<tr>
<td class="num">36</td>
<td class="added"><pre># Gets the instance of the logger.</pre></td>
</tr>
<tr>
<td class="num">37</td>
<td class="added"><pre>logSys = logging.getLogger(&quot;fail2ban.filter&quot;)</pre></td>
</tr>
<tr>
<td class="num">38</td>
<td class="added"><pre></pre></td>
</tr>
<tr>
<td class="num">39</td>
<td class="added"><pre>##</pre></td>
</tr>
<tr>
<td class="num">40</td>
<td class="added"><pre># Log reader class.</pre></td>
</tr>
<tr>
<td class="num">41</td>
<td class="added"><pre>#</pre></td>
</tr>
<tr>
<td class="num">42</td>
<td class="added"><pre># This class reads a log file and detects login failures or anything else</pre></td>
</tr>
<tr>
<td class="num">43</td>
<td class="added"><pre># that matches a given regular expression. This class is instanciated by</pre></td>
</tr>
<tr>
<td class="num">44</td>
<td class="added"><pre># a Jail object.</pre></td>
</tr>
<tr>
<td class="num">45</td>
<td class="added"><pre></pre></td>
</tr>
<tr>
<td class="num">46</td>
<td class="added"><pre>class FilterInotify(ProcessEvent, FileFilter):</pre></td>
</tr>
<tr>
<td class="num">47</td>
<td class="added"><pre></pre></td>
</tr>
<tr>
<td class="num">48</td>
<td class="added"><pre> ##</pre></td>
</tr>
<tr>
<td class="num">49</td>
<td class="added"><pre> # Constructor.</pre></td>
</tr>
<tr>
<td class="num">50</td>
<td class="added"><pre> #</pre></td>
</tr>
<tr>
<td class="num">51</td>
<td class="added"><pre> # Initialize the filter object with default values.</pre></td>
</tr>
<tr>
<td class="num">52</td>
<td class="added"><pre> # &#64;param jail the jail object</pre></td>
</tr>
<tr>
<td class="num">53</td>
<td class="added"><pre> </pre></td>
</tr>
<tr>
<td class="num">54</td>
<td class="added"><pre> # Note that according to the pyinotify documentation we shouldn't</pre></td>
</tr>
<tr>
<td class="num">55</td>
<td class="added"><pre> # define an __init__ function, but define a my_init function which is</pre></td>
</tr>
<tr>
<td class="num">56</td>
<td class="added"><pre> # called by ProcessEvent.__init__. However, that approach appears not</pre></td>
</tr>
<tr>
<td class="num">57</td>
<td class="added"><pre> # to work here and so we define __init__ and call</pre></td>
</tr>
<tr>
<td class="num">58</td>
<td class="added"><pre> # ProcessEvent.__init__ from here.</pre></td>
</tr>
<tr>
<td class="num">59</td>
<td class="added"><pre> def __init__(self, jail):</pre></td>
</tr>
<tr>
<td class="num">60</td>
<td class="added"><pre> FileFilter.__init__(self, jail)</pre></td>
</tr>
<tr>
<td class="num">61</td>
<td class="added"><pre> ProcessEvent.__init__(self)</pre></td>
</tr>
<tr>
<td class="num">62</td>
<td class="added"><pre> self.__monitor = WatchManager()</pre></td>
</tr>
<tr>
<td class="num">63</td>
<td class="added"><pre> self.__notifier = Notifier(self.__monitor, self)</pre></td>
</tr>
<tr>
<td class="num">64</td>
<td class="added"><pre> self.__mask = pyinotify.IN_MODIFY | pyinotify.IN_CREATE</pre></td>
</tr>
<tr>
<td class="num">65</td>
<td class="added"><pre> </pre></td>
</tr>
<tr>
<td class="num">66</td>
<td class="added"><pre> ##</pre></td>
</tr>
<tr>
<td class="num">67</td>
<td class="added"><pre> # Event handling functions used by pyinotify.ProcessEvent</pre></td>
</tr>
<tr>
<td class="num">68</td>
<td class="added"><pre> # instance. These simply call the __handleMod method.</pre></td>
</tr>
<tr>
<td class="num">69</td>
<td class="added"><pre> # &#64;event an event object</pre></td>
</tr>
<tr>
<td class="num">70</td>
<td class="added"><pre></pre></td>
</tr>
<tr>
<td class="num">71</td>
<td class="added"><pre> def process_IN_MODIFY(self, event):</pre></td>
</tr>
<tr>
<td class="num">72</td>
<td class="added"><pre> logSys.debug(&quot;process_IN_MODIFY called&quot;)</pre></td>
</tr>
<tr>
<td class="num">73</td>
<td class="added"><pre> self.__handleMod(event)</pre></td>
</tr>
<tr>
<td class="num">74</td>
<td class="added"><pre></pre></td>
</tr>
<tr>
<td class="num">75</td>
<td class="added"><pre> def process_IN_CREATE(self, event):</pre></td>
</tr>
<tr>
<td class="num">76</td>
<td class="added"><pre> logSys.debug(&quot;process_IN_CREATE called&quot;)</pre></td>
</tr>
<tr>
<td class="num">77</td>
<td class="added"><pre> self.__handleMod(event)</pre></td>
</tr>
<tr>
<td class="num">78</td>
<td class="added"><pre></pre></td>
</tr>
<tr>
<td class="num">79</td>
<td class="added"><pre> ##</pre></td>
</tr>
<tr>
<td class="num">80</td>
<td class="added"><pre> # This method handles all modified file events</pre></td>
</tr>
<tr>
<td class="num">81</td>
<td class="added"><pre> # &#64;event an event object</pre></td>
</tr>
<tr>
<td class="num">82</td>
<td class="added"><pre></pre></td>
</tr>
<tr>
<td class="num">83</td>
<td class="added"><pre> def __handleMod(self, event):</pre></td>
</tr>
<tr>
<td class="num">84</td>
<td class="added"><pre> self.getFailures(event.path)</pre></td>
</tr>
<tr>
<td class="num">85</td>
<td class="added"><pre> try:</pre></td>
</tr>
<tr>
<td class="num">86</td>
<td class="added"><pre> while True:</pre></td>
</tr>
<tr>
<td class="num">87</td>
<td class="added"><pre> ticket = self.failManager.toBan()</pre></td>
</tr>
<tr>
<td class="num">88</td>
<td class="added"><pre> self.jail.putFailTicket(ticket)</pre></td>
</tr>
<tr>
<td class="num">89</td>
<td class="added"><pre> except FailManagerEmpty:</pre></td>
</tr>
<tr>
<td class="num">90</td>
<td class="added"><pre> self.failManager.cleanup(MyTime.time())</pre></td>
</tr>
<tr>
<td class="num">91</td>
<td class="added"><pre> self.dateDetector.sortTemplate()</pre></td>
</tr>
<tr>
<td class="num">92</td>
<td class="added"><pre> </pre></td>
</tr>
<tr>
<td class="num">93</td>
<td class="added"><pre> ##</pre></td>
</tr>
<tr>
<td class="num">94</td>
<td class="added"><pre> # Add a log file path</pre></td>
</tr>
<tr>
<td class="num">95</td>
<td class="added"><pre> #</pre></td>
</tr>
<tr>
<td class="num">96</td>
<td class="added"><pre> # &#64;param path log file path</pre></td>
</tr>
<tr>
<td class="num">97</td>
<td class="added"><pre></pre></td>
</tr>
<tr>
<td class="num">98</td>
<td class="added"><pre> def addLogPath(self, path, tail = False):</pre></td>
</tr>
<tr>
<td class="num">99</td>
<td class="added"><pre> if self.containsLogPath(path):</pre></td>
</tr>
<tr>
<td class="num">100</td>
<td class="added"><pre> logSys.error(path + &quot; already exists&quot;)</pre></td>
</tr>
<tr>
<td class="num">101</td>
<td class="added"><pre> else:</pre></td>
</tr>
<tr>
<td class="num">102</td>
<td class="added"><pre> wd = self.__monitor.add_watch(path, self.__mask)</pre></td>
</tr>
<tr>
<td class="num">103</td>
<td class="added"><pre> if wd[path] &gt; 0:</pre></td>
</tr>
<tr>
<td class="num">104</td>
<td class="added"><pre> FileFilter.addLogPath(self, path, tail)</pre></td>
</tr>
<tr>
<td class="num">105</td>
<td class="added"><pre> logSys.info(&quot;Added logfile = %s&quot; % path)</pre></td>
</tr>
<tr>
<td class="num">106</td>
<td class="added"><pre> else:</pre></td>
</tr>
<tr>
<td class="num">107</td>
<td class="added"><pre> logSys.error(&quot;Failed to add an inotify watch for logfile = %s&quot; % path)</pre></td>
</tr>
<tr>
<td class="num">108</td>
<td class="added"><pre> </pre></td>
</tr>
<tr>
<td class="num">109</td>
<td class="added"><pre> ##</pre></td>
</tr>
<tr>
<td class="num">110</td>
<td class="added"><pre> # Delete a log path</pre></td>
</tr>
<tr>
<td class="num">111</td>
<td class="added"><pre> #</pre></td>
</tr>
<tr>
<td class="num">112</td>
<td class="added"><pre> # &#64;param path the log file to delete</pre></td>
</tr>
<tr>
<td class="num">113</td>
<td class="added"><pre> </pre></td>
</tr>
<tr>
<td class="num">114</td>
<td class="added"><pre> def delLogPath(self, path):</pre></td>
</tr>
<tr>
<td class="num">115</td>
<td class="added"><pre> if not self.containsLogPath(path):</pre></td>
</tr>
<tr>
<td class="num">116</td>
<td class="added"><pre> logSys.error(path + &quot; is not monitored&quot;)</pre></td>
</tr>
<tr>
<td class="num">117</td>
<td class="added"><pre> else:</pre></td>
</tr>
<tr>
<td class="num">118</td>
<td class="added"><pre> rd = self.__monitor.rm_watch(self.__monitor.get_wd(path))</pre></td>
</tr>
<tr>
<td class="num">119</td>
<td class="added"><pre> if rd[path]:</pre></td>
</tr>
<tr>
<td class="num">120</td>
<td class="added"><pre> FileFilter.delLogPath(self, path)</pre></td>
</tr>
<tr>
<td class="num">121</td>
<td class="added"><pre> logSys.info(&quot;Removed logfile = %s&quot; % path)</pre></td>
</tr>
<tr>
<td class="num">122</td>
<td class="added"><pre> else:</pre></td>
</tr>
<tr>
<td class="num">123</td>
<td class="added"><pre> logSys.error(&quot;Failed to remove inotify watch for logfile = %s&quot; % path)</pre></td>
</tr>
<tr>
<td class="num">124</td>
<td class="added"><pre> </pre></td>
</tr>
<tr>
<td class="num">125</td>
<td class="added"><pre> ##</pre></td>
</tr>
<tr>
<td class="num">126</td>
<td class="added"><pre> # Main loop.</pre></td>
</tr>
<tr>
<td class="num">127</td>
<td class="added"><pre> #</pre></td>
</tr>
<tr>
<td class="num">128</td>
<td class="added"><pre> # This function is the main loop of the thread. It checks if the</pre></td>
</tr>
<tr>
<td class="num">129</td>
<td class="added"><pre> # file has been modified and looks for failures.</pre></td>
</tr>
<tr>
<td class="num">130</td>
<td class="added"><pre> # &#64;return True when the thread exits nicely</pre></td>
</tr>
<tr>
<td class="num">131</td>
<td class="added"><pre></pre></td>
</tr>
<tr>
<td class="num">132</td>
<td class="added"><pre> def run(self):</pre></td>
</tr>
<tr>
<td class="num">133</td>
<td class="added"><pre> self.setActive(True)</pre></td>
</tr>
<tr>
<td class="num">134</td>
<td class="added"><pre> while self._isActive():</pre></td>
</tr>
<tr>
<td class="num">135</td>
<td class="added"><pre> if not self.getIdle():</pre></td>
</tr>
<tr>
<td class="num">136</td>
<td class="added"><pre> # We cannot block here because we want to be able to</pre></td>
</tr>
<tr>
<td class="num">137</td>
<td class="added"><pre> # exit. __notifier.check_events will block for</pre></td>
</tr>
<tr>
<td class="num">138</td>
<td class="added"><pre> # timeout milliseconds.</pre></td>
</tr>
<tr>
<td class="num">139</td>
<td class="added"><pre> if self.__notifier.check_events(timeout=10):</pre></td>
</tr>
<tr>
<td class="num">140</td>
<td class="added"><pre> self.__notifier.read_events()</pre></td>
</tr>
<tr>
<td class="num">141</td>
<td class="added"><pre> self.__notifier.process_events()</pre></td>
</tr>
<tr>
<td class="num">142</td>
<td class="added"><pre> time.sleep(self.getSleepTime())</pre></td>
</tr>
<tr>
<td class="num">143</td>
<td class="added"><pre> else:</pre></td>
</tr>
<tr>
<td class="num">144</td>
<td class="added"><pre> time.sleep(self.getSleepTime())</pre></td>
</tr>
<tr>
<td class="num">145</td>
<td class="added"><pre></pre></td>
</tr>
<tr>
<td class="num">146</td>
<td class="added"><pre> # Cleanup when shutting down</pre></td>
</tr>
<tr>
<td class="num">147</td>
<td class="added"><pre> for wd in self.watchd.keys():</pre></td>
</tr>
<tr>
<td class="num">148</td>
<td class="added"><pre> self.__monitor.rm_watch(wd)</pre></td>
</tr>
<tr>
<td class="num">149</td>
<td class="added"><pre> del self.__monitor</pre></td>
</tr>
<tr>
<td class="num">150</td>
<td class="added"><pre> self.__notifier.stop()</pre></td>
</tr>
<tr>
<td class="num">151</td>
<td class="added"><pre> del self.__notifier</pre></td>
</tr>
<tr>
<td class="num">152</td>
<td class="added"><pre></pre></td>
</tr>
<tr>
<td class="num">153</td>
<td class="added"><pre> logSys.debug(self.jail.getName() + &quot;: filter terminated&quot;)</pre></td>
</tr>
<tr>
<td class="num">154</td>
<td class="added"><pre> return True</pre></td>
</tr>
<tr>
<td class="num">155</td>
<td class="added"><pre></pre></td>
</tr>
<tr>
<td class="num">156</td>
<td class="added"><pre></pre></td>
</tr>
<tr>
<td class="num">157</td>
<td class="added"><pre> </pre></td>
</tr>
</table><table class="file_table"><thead><tr><td class="num"></td><td></td><td class="num"></td><td></td></tr><tr><td class="file_head" colspan="4"><a href="#" onclick="return twisty_click(this)">(-)</a><input type="checkbox" name="a/server/jail.py" checked style="display: none">a/server/jail.py
(-2&nbsp;/&nbsp;+16&nbsp;lines)
</td></tr></thead><tbody class="file">
<script type="text/javascript">
incremental_restore()
</script>
<tr><th colspan="4" class="section_head">
<table cellpadding="0" cellspacing="0">
<tr><th width="95%" align="left">
&nbsp;Lines&nbsp;40-56
&nbsp;&nbsp;class Jail:
</th><th>
<a name="a/server/jail.py_sec1" href="#a/server/jail.py_sec1">Link&nbsp;Here</a>&nbsp;
</th></tr></table>
</th></tr>
<tr>
<td class="num">40</td>
<td><pre> logSys.info(&quot;Creating new jail '%s'&quot; % self.__name)</pre></td>
<td class="num">40</td>
<td><pre> logSys.info(&quot;Creating new jail '%s'&quot; % self.__name)</pre></td>
</tr>
<tr>
<td class="num">41</td>
<td><pre> if backend == &quot;polling&quot;:</pre></td>
<td class="num">41</td>
<td><pre> if backend == &quot;polling&quot;:</pre></td>
</tr>
<tr>
<td class="num">42</td>
<td><pre> self.__initPoller()</pre></td>
<td class="num">42</td>
<td><pre> self.__initPoller()</pre></td>
</tr>
<tr>
<td class="num" rowspan="4"></td>
<td rowspan="4"></td>
<td class="num">43</td>
<td class="added"><pre> elif backend == &quot;inotify&quot;:</pre></td>
</tr>
<tr>
<td class="num">44</td>
<td class="added"><pre> self.__initInotify()</pre></td>
</tr>
<tr>
<td class="num">45</td>
<td class="added"><pre> elif backend == &quot;gamin&quot;:</pre></td>
</tr>
<tr>
<td class="num">46</td>
<td class="added"><pre> self.__initGamin()</pre></td>
</tr>
<tr>
<td class="num">43</td>
<td><pre> else:</pre></td>
<td class="num">47</td>
<td><pre> else:</pre></td>
</tr>
<tr>
<td class="num">44</td>
<td><pre> try:</pre></td>
<td class="num">48</td>
<td><pre> try:</pre></td>
</tr>
<tr>
<td class="num">45</td>
<td class="changed"><pre> self.__initGamin()</pre></td>
<td class="num">49</td>
<td class="changed"><pre> self.__initInotify()</pre></td>
</tr>
<tr>
<td class="num">46</td>
<td><pre> except ImportError:</pre></td>
<td class="num">50</td>
<td><pre> except ImportError:</pre></td>
</tr>
<tr>
<td class="num">47</td>
<td class="changed"><pre> self.__initPoller()</pre></td>
<td class="num">51</td>
<td class="changed"><pre> try:</pre></td>
</tr>
<tr>
<td class="num" rowspan="3"></td>
<td class="changed" rowspan="3"></td>
<td class="num">52</td>
<td class="changed"><pre> self.__initGamin()</pre></td>
</tr>
<tr>
<td class="num">53</td>
<td class="changed"><pre> except ImportError:</pre></td>
</tr>
<tr>
<td class="num">54</td>
<td class="changed"><pre> self.__initPoller()</pre></td>
</tr>
<tr>
<td class="num">48</td>
<td><pre> self.__action = Actions(self)</pre></td>
<td class="num">55</td>
<td><pre> self.__action = Actions(self)</pre></td>
</tr>
<tr>
<td class="num">49</td>
<td><pre> </pre></td>
<td class="num">56</td>
<td><pre> </pre></td>
</tr>
<tr>
<td class="num">50</td>
<td><pre> def __initPoller(self):</pre></td>
<td class="num">57</td>
<td><pre> def __initPoller(self):</pre></td>
</tr>
<tr>
<td class="num">51</td>
<td><pre> logSys.info(&quot;Jail '%s' uses poller&quot; % self.__name)</pre></td>
<td class="num">58</td>
<td><pre> logSys.info(&quot;Jail '%s' uses poller&quot; % self.__name)</pre></td>
</tr>
<tr>
<td class="num">52</td>
<td><pre> from filterpoll import FilterPoll</pre></td>
<td class="num">59</td>
<td><pre> from filterpoll import FilterPoll</pre></td>
</tr>
<tr>
<td class="num">53</td>
<td><pre> self.__filter = FilterPoll(self)</pre></td>
<td class="num">60</td>
<td><pre> self.__filter = FilterPoll(self)</pre></td>
</tr>
<tr>
<td class="num" rowspan="7"></td>
<td rowspan="7"></td>
<td class="num">61</td>
<td class="added"><pre></pre></td>
</tr>
<tr>
<td class="num">62</td>
<td class="added"><pre> def __initInotify(self):</pre></td>
</tr>
<tr>
<td class="num">63</td>
<td class="added"><pre> # Try to import pyinotify</pre></td>
</tr>
<tr>
<td class="num">64</td>
<td class="added"><pre> import pyinotify</pre></td>
</tr>
<tr>
<td class="num">65</td>
<td class="added"><pre> logSys.info(&quot;Jail '%s' uses Inotify&quot; % self.__name)</pre></td>
</tr>
<tr>
<td class="num">66</td>
<td class="added"><pre> from filterinotify import FilterInotify</pre></td>
</tr>
<tr>
<td class="num">67</td>
<td class="added"><pre> self.__filter = FilterInotify(self)</pre></td>
</tr>
<tr>
<td class="num">54</td>
<td><pre> </pre></td>
<td class="num">68</td>
<td><pre> </pre></td>
</tr>
<tr>
<td class="num">55</td>
<td><pre> def __initGamin(self):</pre></td>
<td class="num">69</td>
<td><pre> def __initGamin(self):</pre></td>
</tr>
<tr>
<td class="num">56</td>
<td><pre> # Try to import gamin</pre></td>
<td class="num">70</td>
<td><pre> # Try to import gamin</pre></td>
</tr>
</table></form>
<br>
<span>Return to <a href="show_bug.cgi?id=551895" title="NEW - RFE: Add patch to enable inotify support">bug 551895</a></span>
</div>
<div id="footer">
<div class="intro"></div>
<ul id="useful-links">
<li id="links-actions"><ul class="links">
<li><a href="./">Home</a></li>
<li><span class="separator">| </span><a href="enter_bug.cgi">New</a></li>
<li><span class="separator">| </span><a href="query.cgi">Search</a></li>
<li><span class="separator"> | </span><a href="page.cgi?id=browse.html">Browse</a></li>
<li class="form">
<span class="separator">| </span>
<form action="buglist.cgi" method="get"
onsubmit="if (this.quicksearch.value == '')
{ alert('Please enter one or more search terms first.');
return false; } return true;">
<input class="txt" type="text" id="quicksearch_bottom" name="quicksearch"
value="">
<input class="btn" type="submit" value="Search"
id="find_bottom"></form>
<a href="page.cgi?id=quicksearch.html" title="Quicksearch Help">[?]</a></li>
<li><span class="separator">| </span><a href="report.cgi">Reports</a></li>
<li>
<span class="separator">| </span>
<a href="request.cgi">Requests</a></li>
<li id="new_account_container_bottom">
<span class="separator">| </span>
<a href="createaccount.cgi">New&nbsp;Account</a>
</li>
<li id="mini_login_container_bottom">
<span class="separator">| </span>
<a id="login_link_bottom" href="https://bugzilla.redhat.com/index.cgi?GoAheadAndLogIn=1"
onclick="return show_mini_login_form('_bottom')">Log In</a>
<form action="https://bugzilla.redhat.com/index.cgi" method="POST"
class="mini_login bz_default_hidden"
id="mini_login_bottom"
onsubmit="return check_mini_login_fields( '_bottom' );"
>
<input id="Bugzilla_login_bottom"
class="bz_login"
name="Bugzilla_login"
onfocus="mini_login_on_focus('_bottom')"
>
<input class="bz_password"
id="Bugzilla_password_bottom"
name="Bugzilla_password"
type="password"
>
<input class="bz_password bz_default_hidden bz_mini_login_help" type="text"
id="Bugzilla_password_dummy_bottom" value="password"
onfocus="mini_login_on_focus('_bottom')"
>
<input type="submit" name="GoAheadAndLogIn" value="Log in"
id="log_in_bottom">
<script type="text/javascript">
mini_login_constants = {
"login" : "login",
"warning" : "You must set the login and password before logging in."
};
if (YAHOO.env.ua.gecko || YAHOO.env.ua.ie || YAHOO.env.ua.opera) {
YAHOO.util.Event.onDOMReady(function() {
init_mini_login_form('_bottom');
});
}
else {
YAHOO.util.Event.on(window, 'load', function () {
window.setTimeout(function() {
init_mini_login_form('_bottom');
}, 200);
});
}
</script>
<a href="#" onclick="return hide_mini_login_form('_bottom')">[x]</a>
</form>
</li>
<li id="forgot_container_bottom">
<span class="separator">| </span>
<a id="forgot_link_bottom" href="https://bugzilla.redhat.com/index.cgi?GoAheadAndLogIn=1#forgot"
onclick="return show_forgot_form('_bottom')">Forgot Password</a>
<form action="token.cgi" method="post" id="forgot_form_bottom"
class="mini_forgot bz_default_hidden">
<label>Login: <input type="text" name="loginname" size="20"></label>
<input id="forgot_button_bottom" value="Reset Password"
type="submit">
<input type="hidden" name="a" value="reqpw">
<a href="#" onclick="return hide_forgot_form('_bottom')">[x]</a>
</form>
</li>
</ul>
</li>
</ul>
<div class="outro"></div>
</div>
</body>
</html>