Package: flamethrower
Version: 0.1.8-4
Severity: normal
Tags: patch

--- Please enter the report below this line. ---

After a /etc/init.d/flamethrower stop (or systemctl stop flamethrower), there 
still remains some "udp-sender" processes running. 
These processes have been spawned  by flamethrowerd at startup. 

More precisely, the Perl script flamethrowerd starts a:
sh -c udp-sender [various parameters] for each directory to be replicated which 
in turn starts the "udp-sender" program.
flamethrowerd takes care of killing each "sh -c" processes, but does not record 
the pid of the child process 
(the udp-sender process started by the shell). Hence these processes are still 
alive after flamethrowerd shutdown.

This is mainly due to the way flamethrower spawns the udp-sender process in 
Perl. 
It uses the open("$cmd|") construct which spawns a shell if $cmd contains 
special characters that must be interpreted by a shell (e.g. "*").
Here $cmd contains double quote.

I have written a patch attached to this email to use another syntax (open("-|", 
@cmd) where @cmd is a list of strings consisting of the binary to start along 
with its arguments.
This patch works on my system. Could you propagate it upstream ?    

Best regards,

Frédéric

--- System information. ---
Architecture: amd64
Kernel:       Linux 4.2.0-1-amd64

Debian Release: stretch/sid
  500 unstable        www.deb-multimedia.org 
  500 unstable        ftp.fr.debian.org 
  500 stable          dl.google.com 

--- Package information. ---
Package's Depends field is empty.

Package's Recommends field is empty.

Package's Suggests field is empty.
diff --git a/flamethrowerd b/flamethrowerd
index 7d8432b..c86cc73 100755
--- a/flamethrowerd
+++ b/flamethrowerd
@@ -15,6 +15,7 @@ $0 = "flamethrowerd";
 
 use strict;
 use File::stat;
+use File::Which;
 use Getopt::Long;
 use POSIX qw(setsid);
 
@@ -151,107 +152,107 @@ sub build_udp_sender_cmd {
     #
     # Global settings
     #
-    my $min_clients;
+    my @min_clients;
     if ( $ft_config->get("min_clients") ) {
-        $min_clients = " --min-clients " . $ft_config->get("min_clients");
+        @min_clients = ("--min-clients", $ft_config->get("min_clients"));
     }
     
-    my $max_wait;
+    my @max_wait;
     if ( $ft_config->get("max_wait") ) {
-        $max_wait = " --max-wait " . $ft_config->get("max_wait");
+        @max_wait = ("--max-wait" , $ft_config->get("max_wait"));
     }
     
-    my $min_wait;
+    my @min_wait;
     if ( $ft_config->get("min_wait") ) {
-        $min_wait = " --min-wait " . $ft_config->get("min_wait");
+        @min_wait = ("--min-wait", $ft_config->get("min_wait"));
     }
     
-    my $async;
+    my @async;
     if ( $ft_config->get("async") ) {
         if ( lc ($ft_config->get("async")) eq "on" ) {
-            $async = " --async";
+            @async = ("--async");
         }
     }
     
-    my $autostart;
+    my @autostart;
     if ( $ft_config->get("autostart") ) {
-        $autostart = " --autostart " . $ft_config->get("autostart");
+        @autostart = ("--autostart", $ft_config->get("autostart"));
     }
     
-    my $blocksize;
+    my @blocksize;
     if ( $ft_config->get("blocksize") ) {
-        $blocksize = " --blocksize " . $ft_config->get("blocksize");
+        @blocksize = ("--blocksize", $ft_config->get("blocksize"));
     }
     
-    my $broadcast;
+    my @broadcast;
     if ( $ft_config->get("broadcast") ) {
         if ( lc ($ft_config->get("broadcast")) eq "on" ) {
-            $broadcast = " --broadcast";
+            @broadcast = ("--broadcast");
         }
     }
     
-    my $fec;
+    my @fec;
     if ( $ft_config->get("fec") ) {
-        $fec = " --fec " . $ft_config->get("fec");
+        @fec = ("--fec", $ft_config->get("fec"));
     }
     
-    my $interface;
+    my @interface;
     if ( $ft_config->get("interface") ) {
-        $interface = " --interface " . $ft_config->get("interface");
+        @interface = ("--interface", $ft_config->get("interface"));
     }
     
-    my $log;
+    my @log;
     if ( $ft_config->get("log") ) {
-        $log = " --log " . $ft_config->get("log") . ".$module";
+        @log = ("--log", $ft_config->get("log") . ".$module");
     }
     
-    my $max_bitrate;
+    my @max_bitrate;
     if ( $ft_config->get("max_bitrate") ) {
-        $max_bitrate = " --max-bitrate " . $ft_config->get("max_bitrate");
+        @max_bitrate = ("--max-bitrate", $ft_config->get("max_bitrate"));
     }
     
-    my $full_duplex;
+    my @full_duplex = ();
     if ( $ft_config->get("full_duplex") ) {
         if ( lc ($ft_config->get("full_duplex")) eq "on" ) {
-            $full_duplex = " --full-duplex";
+            @full_duplex = ("--full-duplex");
         }
     }
     
-    my $mcast_addr;
+    my @mcast_addr;
     if ( $ft_config->get("mcast_addr") ) {
-        $mcast_addr = " --mcast-addr " . $ft_config->get("mcast_addr");
+        @mcast_addr = ("--mcast-addr", $ft_config->get("mcast_addr"));
     }
     
-    my $mcast_all_addr;
+    my @mcast_all_addr;
     if ( $ft_config->get("mcast_all_addr") ) {
-        $mcast_all_addr = " --mcast-all-addr " . $ft_config->get("mcast_all_addr");
+        @mcast_all_addr = ("--mcast-all-addr", $ft_config->get("mcast_all_addr"));
     }
     
-    my $min_slice_size;
+    my @min_slice_size;
     if ( $ft_config->get("min_slice_size") ) {
-        $min_slice_size = " --min-slice-size " . $ft_config->get("min_slice_size");
+        @min_slice_size = ("--min-slice-size", $ft_config->get("min_slice_size"));
     }
     
-    my $slice_size;
+    my @slice_size;
     if ( $ft_config->get("slice_size") ) {
-        $slice_size = " --slice-size " . $ft_config->get("slice_size");
+        @slice_size = ("--slice-size", $ft_config->get("slice_size"));
     }
     
-    my $pointopoint;
+    my @pointopoint;
     if ( $ft_config->get("pointopoint") ) {
         if ( lc ($ft_config->get("pointopoint")) eq "on" ) {
-            $pointopoint = " --pointopoint";
+            @pointopoint = ("--pointopoint");
         }
     }
     
-    my $rexmit_hello_interval;
+    my @rexmit_hello_interval;
     if ( $ft_config->get("rexmit_hello_interval") ) {
-        $rexmit_hello_interval = " --rexmit-hello-interval " . $ft_config->get("rexmit_hello_interval");
+        @rexmit_hello_interval = ("--rexmit-hello-interval", $ft_config->get("rexmit_hello_interval"));
     }
     
-    my $ttl;
+    my @ttl;
     if ( $ft_config->get("ttl") ) {
-        $ttl = " --ttl " . $ft_config->get("ttl");
+        @ttl = (" --ttl", $ft_config->get("ttl"));
     }
     #
     ############################################################################
@@ -266,40 +267,40 @@ sub build_udp_sender_cmd {
         $dir = $ft_config->get("${module}_dir");
     }
     
-    my $portbase;
+    my @portbase;
     if ( $ft_config->get("${module}_portbase") ) {
-        $portbase = " --portbase " . $ft_config->get("${module}_portbase");
+        @portbase = ("--portbase", $ft_config->get("${module}_portbase"));
     }
     
     if ($ft_config->varlist("${module}_async")) {
         if ( $ft_config->get("${module}_async") ) {
             if ( lc ($ft_config->get("${module}_async")) eq "on" ) {
-                $async = " --async";
+                @async = ("--async");
             }
         }
     }
 
     if ($ft_config->varlist("${module}_ttl")) {
         if ( $ft_config->get("${module}_ttl") ) {
-            $ttl = " --ttl " . $ft_config->get("${module}_ttl");
+            @ttl = ("--ttl", $ft_config->get("${module}_ttl"));
         }
     }
 
     if ($ft_config->varlist("${module}_mcast_all_addr")) {
         if ( $ft_config->get("${module}_mcast_all_addr") ) {
-            $mcast_all_addr = " --mcast-all-addr " . $ft_config->get("${module}_mcast_all_addr");
+            @mcast_all_addr = ("--mcast-all-addr", $ft_config->get("${module}_mcast_all_addr"));
         }
     }
     
     if ($ft_config->varlist("${module}_log")) {
         if ( $ft_config->get("${module}_log") ) {
-            $log = " --log " . $ft_config->get("${module}_log");
+            @log = ("--log", $ft_config->get("${module}_log"));
         }
     }
     
     if ($ft_config->varlist("${module}_interface")) {
         if ( $ft_config->get("${module}_interface") ) {
-            $interface = " --interface " . $ft_config->get("${module}_interface");
+            @interface = ("--interface", $ft_config->get("${module}_interface"));
         }
     }
     #
@@ -312,30 +313,31 @@ sub build_udp_sender_cmd {
     #
     # -S, --sparse / handle sparse files efficiently
     #
-    my $cmd = qq(udp-sender --pipe "tar -B -S -cpf - -C $dir .");
+    my @cmd = (which("udp-sender"), qq(--pipe), qq(tar -B -S -cpf - -C $dir .));
+    
     #my $cmd = qq(udp-sender --pipe 'tar -czpf - -C $dir .');
-    $cmd .= $portbase               if(defined $portbase);
-    $cmd .= $min_clients            if(defined $min_clients);
-    $cmd .= $max_wait               if(defined $max_wait);
-    $cmd .= $min_wait               if(defined $min_wait);
-    $cmd .= $async                  if(defined $async);
-    $cmd .= $autostart              if(defined $autostart);
-    $cmd .= $blocksize              if(defined $blocksize);
-    $cmd .= $broadcast              if(defined $broadcast);
-    $cmd .= $fec                    if(defined $fec);
-    $cmd .= $interface              if(defined $interface);
-    $cmd .= $log                    if(defined $log);
-    $cmd .= $max_bitrate            if(defined $max_bitrate);
-    $cmd .= $full_duplex            if(defined $full_duplex);
-    $cmd .= $mcast_addr             if(defined $mcast_addr);
-    $cmd .= $mcast_all_addr         if(defined $mcast_all_addr);
-    $cmd .= $min_slice_size         if(defined $min_slice_size);
-    $cmd .= $slice_size             if(defined $slice_size);
-    $cmd .= $pointopoint            if(defined $pointopoint);
-    $cmd .= $rexmit_hello_interval  if(defined $rexmit_hello_interval);
-    $cmd .= $ttl                    if(defined $ttl);
-
-    return $cmd;
+    @cmd = (@cmd, @portbase)               if(@portbase);
+    @cmd = (@cmd, @min_clients)            if(@min_clients);
+    @cmd = (@cmd, @max_wait)               if(@max_wait);
+    @cmd = (@cmd, @min_wait)               if(@min_wait);
+    @cmd = (@cmd, @async)                  if(@async);
+    @cmd = (@cmd, @autostart)              if(@autostart);
+    @cmd = (@cmd, @blocksize)              if(@blocksize);
+    @cmd = (@cmd, @broadcast)              if(@broadcast);
+    @cmd = (@cmd, @fec)                    if(@fec);
+    @cmd = (@cmd, @interface)              if(@interface);
+    @cmd = (@cmd, @log)                    if(@log);
+    @cmd = (@cmd, @max_bitrate)            if(@max_bitrate);
+    @cmd = (@cmd, @full_duplex)            if(@full_duplex);
+    @cmd = (@cmd, @mcast_addr)             if(@mcast_addr);
+    @cmd = (@cmd, @mcast_all_addr)         if(@mcast_all_addr); 
+    @cmd = (@cmd, @min_slice_size)         if(@min_slice_size);
+    @cmd = (@cmd, @slice_size)             if(@slice_size);
+    @cmd = (@cmd, @pointopoint)            if(@pointopoint);
+    @cmd = (@cmd, @rexmit_hello_interval)  if(@rexmit_hello_interval);
+    @cmd = (@cmd, @ttl)                    if(@ttl);
+    
+    return @cmd;
 }
 
 # Usage: update_directory();
@@ -573,10 +575,10 @@ sub cast {
 
         print "casting $module\n" if($debug);
 
-        my $cmd = build_udp_sender_cmd($module);
-        print "cmd $cmd\n" if($debug);
+        my @cmd = build_udp_sender_cmd($module);
+        print "cmd @cmd\n" if($debug);
 
-        my $child_pid = open(SENDER, "$cmd|") or die "Couldn't fork: $cmd";
+        my $child_pid = open(SENDER, "-|", @cmd) or die "Couldn't fork: @cmd";
             record_pid($child_file, $child_pid);
             while(<SENDER>){
                 print $_ if($debug);

Reply via email to