diff --git a/Makefile b/Makefile index f069f20..1d73d16 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,10 @@ CMD = blink bsearch duplicate-packets em encdir field forever G \ gitnext gitundo goodpasswd histogram mtrr neno off pdfman puniq \ -ramusage rand rclean rn rrm shython sound-reload stdout swapout T \ -timestamp tracefile upsidedown w4it-for-port-open wifi-reload wssh \ +ramusage rand rclean rina rn rrm shython sound-reload stdout swapout \ +T timestamp tracefile upsidedown w4it-for-port-open wifi-reload wssh \ ytv yyyymmdd -all: blink/blink.1 bsearch/bsearch.1 encdir/encdir.1 G/G.1 gitnext/gitnext.1 gitundo/gitundo.1 goodpasswd/goodpasswd.1 histogram/histogram.1 neno/neno.1 off/off.1 pdfman/pdfman.1 puniq/puniq.1 rand/rand.1 rn/rn.1 rrm/rrm.1 shython/shython.1 sound-reload/sound-reload.1 stdout/stdout.1 timestamp/timestamp.1 tracefile/tracefile.1 T/T.1 upsidedown/upsidedown.1 wifi-reload/wifi-reload.1 wssh/wssh.1 ytv/ytv.1 yyyymmdd/yyyymmdd.1 +all: blink/blink.1 bsearch/bsearch.1 encdir/encdir.1 G/G.1 gitnext/gitnext.1 gitundo/gitundo.1 goodpasswd/goodpasswd.1 histogram/histogram.1 neno/neno.1 off/off.1 pdfman/pdfman.1 puniq/puniq.1 rand/rand.1 rina/rina.1 rn/rn.1 rrm/rrm.1 shython/shython.1 sound-reload/sound-reload.1 stdout/stdout.1 timestamp/timestamp.1 tracefile/tracefile.1 T/T.1 upsidedown/upsidedown.1 wifi-reload/wifi-reload.1 wssh/wssh.1 ytv/ytv.1 yyyymmdd/yyyymmdd.1 %.1: % pod2man $< > $@ diff --git a/README b/README index 5dfbe14..2c33f49 100644 --- a/README +++ b/README @@ -38,6 +38,8 @@ rclean - Remove files with MD5 sums recorded by rrm (see below). reniced - Renice all commands running more than 1 CPU minute unless they are niced or whitelisted. +rina - Run if no activity. + rn - Move file(s)/dir(s) to .rm/ (wastebasket). rrm - Record file's MD5 sum before removing it. diff --git a/duplicate-packets/duplicate-packets b/duplicate-packets/duplicate-packets index 1c15dbe..eeced38 100755 --- a/duplicate-packets/duplicate-packets +++ b/duplicate-packets/duplicate-packets @@ -1,5 +1,7 @@ #!/bin/bash IF=wls1 -sudo tc qdisc del dev $IF root netem delay 300 duplicate 40 -sudo tc qdisc add dev $IF root netem delay 300 duplicate 40 +sudo tc qdisc del dev $IF root netem duplicate 50 +sudo tc qdisc add dev $IF root netem duplicate 50 +#sudo tc qdisc del dev $IF root netem duplicate 100% delay 300ms +#sudo tc qdisc add dev $IF root netem duplicate 100% delay 300ms diff --git a/rina/rina b/rina/rina new file mode 100755 index 0000000..7c49d63 --- /dev/null +++ b/rina/rina @@ -0,0 +1,173 @@ +#!/usr/bin/perl + +=pod + +=head1 NAME + +rina - run if no activity + + +=head1 SYNOPSIS + +... | B [-v] [-t timeout] I + + +=head1 OPTIONS + +=over 9 + +=item B<-v> + +Verbose. Print when I is run. + +=back + + +=head1 DESCRIPTION + +B monitors a pipe. If there is no activity on the pipe for +I seconds, it runs I. + + +=head1 EXAMPLE + +Restart networking if Google's DNS does not repond to ping: + + ping 8.8.8.8 | rina -t 20 /etc/init.d/networking restart + +=head1 AUTHOR + +Copyright (C) 2017 Ole Tange, +http://ole.tange.dk and Free Software Foundation, Inc. + + +=head1 LICENSE + +Copyright (C) 2012 Free Software Foundation, Inc. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +at your option any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + + +=head1 DEPENDENCIES + +B uses B. + + +=head1 SEE ALSO + +B + + +=cut + +use Getopt::Long; +use Time::HiRes; +use POSIX qw(strftime); + +get_options_from_array(\@ARGV); + +my $in_fh = *STDIN; + +set_fh_non_blocking($in_fh); +while(1){ + sleep($opt::timeout || 10); + if(not read($in_fh,$dummy,32768)) { + # run_command + @opt::verbose and print iso8601(Time::HiRes::time())," Running @ARGV\n"; + system(@ARGV); + wait(); + @opt::verbose and print iso8601(Time::HiRes::time())," Done @ARGV\n"; + } + # empty_buffer + while(read($in_fh,$dummy,32768)) { } +} + +sub iso8601 { + my $time = shift; + my $tz = strftime("%z", localtime($time)); + $tz =~ s/(\d{2})(\d{2})/$1:$2/; + my $ms = sprintf "%03d", int(($time - int($time))*1000); + + return strftime("%Y-%m-%dT%H:%M:%S.".$ms, localtime($time)). $tz; +} + +sub set_fh_non_blocking { + # Set filehandle as non-blocking + # Inputs: + # $fh = filehandle to be blocking + # Returns: + # N/A + my $fh = shift; + $Global::use{"Fcntl"} ||= eval "use Fcntl qw(:DEFAULT :flock); 1;"; + my $flags; + # Get the current flags on the filehandle + fcntl($fh, &F_GETFL, $flags) || die $!; + # Add non-blocking to the flags + $flags |= &O_NONBLOCK; + # Set the flags on the filehandle + fcntl($fh, &F_SETFL, $flags) || die $!; +} + +sub options_hash { + # Returns: + # %hash = the GetOptions config + return + ("debug|D=s" => \$opt::D, + "verbose|v" => \@opt::verbose, + "timeout|t=s" => \$opt::timeout, + ); +} + +sub get_options_from_array { + # Run GetOptions on @array + # Input: + # $array_ref = ref to @ARGV to parse + # @keep_only = Keep only these options + # Uses: + # @ARGV + # Returns: + # true if parsing worked + # false if parsing failed + # @$array_ref is changed + my ($array_ref, @keep_only) = @_; + if(not @$array_ref) { + # Empty array: No need to look more at that + return 1; + } + # A bit of shuffling of @ARGV needed as GetOptionsFromArray is not + # supported everywhere + my @save_argv; + my $this_is_ARGV = (\@::ARGV == $array_ref); + if(not $this_is_ARGV) { + @save_argv = @::ARGV; + @::ARGV = @{$array_ref}; + } + # If @keep_only set: Ignore all values except @keep_only + my %options = options_hash(); + if(@keep_only) { + my (%keep,@dummy); + @keep{@keep_only} = @keep_only; + for my $k (grep { not $keep{$_} } keys %options) { + # Store the value of the option in @dummy + $options{$k} = \@dummy; + } + } + my $retval = GetOptions(%options); + if(not $this_is_ARGV) { + @{$array_ref} = @::ARGV; + @::ARGV = @save_argv; + } + return $retval; +} +