Unix: various enhancements to the ping command:

Fixed bug in 100% packet loss response.
Errors from ping are now sent to irc.error().
Added packet count, interval, ttl, and wait options.
Added additional test cases.

Also, Enabled threading for Unix plugin, and
for wtf, spell, and ping commands.

Signed-off-by: Daniel Folkinshteyn <nanotube@users.sourceforge.net>
This commit is contained in:
brian c 2010-07-12 16:42:03 -04:00 committed by Valentin Lorentz
parent 61167ce909
commit cc5f3c1049
2 changed files with 58 additions and 19 deletions

View File

@ -68,6 +68,7 @@ def pipeReadline(fd, timeout=2):
raise TimeoutError
class Unix(callbacks.Plugin):
threaded = True
@internationalizeDocstring
def errno(self, irc, msg, args, s):
"""<error number or code>
@ -186,7 +187,7 @@ class Unix(callbacks.Plugin):
else:
resp = 'Something unexpected was seen in the [ai]spell output.'
irc.reply(resp)
spell = wrap(spell, ['somethingWithoutSpaces'])
spell = thread(wrap(spell, ['something']))
@internationalizeDocstring
def fortune(self, irc, msg, args):
@ -253,12 +254,20 @@ class Unix(callbacks.Plugin):
irc.error(_('The wtf command is not configured. If it is installed '
'on this system, reconfigure the '
'supybot.plugins.Unix.wtf.command configuration '
<<<<<<< HEAD
'variable appropriately.'))
wtf = wrap(wtf, [optional(('literal', ['is'])), 'something'])
=======
'variable appropriately.')
wtf = thread(wrap(wtf, [optional(('literal', ['is'])), 'something']))
>>>>>>> edc4d86... Unix: various enhancements to the ping command:
def ping(self, irc, msg, args, host):
"""<host or ip>
Sends an ICMP echo request to the specified host
def ping(self, irc, msg, args, optlist, host):
"""[--c <count>] [--i <interval>] [--t <ttl>] [--W <timeout>] <host or ip>
Sends an ICMP echo request to the specified host.
The arguments correspond with those listed in ping(8). --c is
limited to 10 packets or less (default is 5). --i is limited to 5
or less. --W is limited to 10 or less.
"""
pingCmd = self.registryValue('ping.command')
if not pingCmd:
@ -270,26 +279,40 @@ class Unix(callbacks.Plugin):
try: host = host.group(0)
except AttributeError: pass
args = [pingCmd]
for opt, val in optlist:
if opt == 'c' and val > 10: val = 10
if opt == 'i' and val > 5: val = 5
if opt == 'W' and val > 10: val = 10
args.append('-%s' % opt)
args.append(str(val))
if '-c' not in args:
args.append('-c')
args.append('5')
args.append(host)
try:
inst = subprocess.Popen([pingCmd,'-c','1', host],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=file(os.devnull))
inst = subprocess.Popen(args, stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=file(os.devnull))
except OSError, e:
irc.error('It seems the configured ping command was '
'not available (%s).' % e, Raise=True)
result = inst.communicate()
if result[1]: # stderr
irc.reply(' '.join(result[1].split()))
irc.error(' '.join(result[1].split()))
else:
response = result[0].split("\n");
irc.reply(' '.join(response[1].split()[3:5]).split(':')[0]
+ ': ' + ' '.join(response[-3:]))
_hostExpr = re.compile(r'^[a-z0-9][a-z0-9\.-]*$', re.I)
ping = wrap(ping, [first('ip', ('matches', _hostExpr, 'Invalid hostname'))])
if response[1]:
irc.reply(' '.join(response[1].split()[3:5]).split(':')[0]
+ ': ' + ' '.join(response[-3:]))
else:
irc.reply(' '.join(response[0].split()[1:3])
+ ': ' + ' '.join(response[-3:]))
_hostExpr = re.compile(r'^[a-z0-9][a-z0-9\.-]*[a-z0-9]$', re.I)
ping = thread(wrap(ping, [getopts({'c':'positiveInt','i':'float',
't':'positiveInt','W':'positiveInt'}),
first('ip', ('matches', _hostExpr, 'Invalid hostname'))]))
Class = Unix
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

View File

@ -67,9 +67,25 @@ if os.name == 'posix':
if utils.findBinaryInPath('ping') is not None:
def testPing(self):
self.assertNotError('unix ping localhost')
self.assertNotError('unix ping 127.0.0.1')
self.assertError('unix ping')
self.assertError('unix ping -localhost')
self.assertError('unix ping local%host')
def testPingCount(self):
self.assertNotError('unix ping --c 1 127.0.0.1')
self.assertError('unix ping --c a 127.0.0.1')
self.assertRegexp('unix ping --c 11 127.0.0.1','10 packets')
self.assertRegexp('unix ping 127.0.0.1','5 packets')
def testPingInterval(self):
self.assertNotError('unix ping --i 1 --c 1 127.0.0.1')
self.assertError('unix ping --i a --c 1 127.0.0.1')
# Super-user privileged interval setting
self.assertError('unix ping --i 0.1 --c 1 127.0.0.1')
def testPingTtl(self):
self.assertNotError('unix ping --t 64 --c 1 127.0.0.1')
self.assertError('unix ping --t a --c 1 127.0.0.1')
def testPingWait(self):
self.assertNotError('unix ping --W 1 --c 1 127.0.0.1')
self.assertError('unix ping --W a --c 1 127.0.0.1')
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: