diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/daemon/common/commonFile.ml ./src/daemon/common/commonFile.ml
--- ./src/daemon/common/commonFile.ml	2006-11-12 13:44:24.000000000 +0100
+++ ./src/daemon/common/commonFile.ml	2006-11-15 01:51:29.000000000 +0100
@@ -552,9 +552,10 @@
   impl.impl_file_last_seen <- age
     
 let file_preview (file : file) =
-  let cmd = Printf.sprintf "%s \"%s\" \"%s\"" !!previewer
-	      (file_disk_name file) (file_best_name file) in
-  ignore (Sys.command cmd)
+  ignore(
+    Unix.create_process !!previewer 
+      [| Filename2.basename !!previewer; file_disk_name file; file_best_name file |]
+      Unix.stdin Unix.stdout Unix.stderr)
 
 (*************************************************************************)
 (*                                                                       *)
diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/daemon/common/commonOptions.ml ./src/daemon/common/commonOptions.ml
--- ./src/daemon/common/commonOptions.ml	2006-11-14 12:23:11.000000000 +0100
+++ ./src/daemon/common/commonOptions.ml	2006-11-15 01:51:29.000000000 +0100
@@ -1023,6 +1023,10 @@
   "URLs of RSS feeds"
     (list_option Url.option) []
 
+let rss_preprocessor = define_expert_option current_section ["rss_preprocessor"]
+  "If MLDonkey can not read broken RSS feeds, use this program to preprocess them"
+    string_option "xmllint"
+
 let ip_blocking_descriptions = define_expert_option current_section ["ip_blocking_descriptions"]
   "Keep IP blocking ranges descriptions in memory"
     bool_option false
diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/daemon/common/commonWeb.ml ./src/daemon/common/commonWeb.ml
--- ./src/daemon/common/commonWeb.ml	2006-11-14 21:04:11.000000000 +0100
+++ ./src/daemon/common/commonWeb.ml	2006-11-15 02:53:05.000000000 +0100
@@ -192,13 +179,47 @@
 
 let rss_feeds = Hashtbl.create 10
 
-
 let _ =
   add_web_kind "rss" "Syndication feeds to get periodically updated data" 
     (fun url filename ->
       lprintf_nl (_b "parsing feed %s (rss)") url;
-      let c = Rss.channel_of_file filename in
-      (try Sys.remove filename with _ -> ());
+      let c =
+	(try
+	  let rss_c = Rss.channel_of_file filename in
+	  (try Sys.remove filename with _ -> ());
+	  rss_c
+	with Xml.Error _ ->
+	  lprintf_nl (_b "found buggy feed, preprocessing with %s and trying again") !!rss_preprocessor;
+	  (try
+	    let pipe_out, pipe_in = Unix.pipe () in
+	    let pid = Unix.create_process !!rss_preprocessor [| !!rss_preprocessor; filename |] 
+		Unix.stdin pipe_in pipe_in in
+	    Unix.close pipe_in;
+	    let output = Buffer.create 1024 in
+	    let buffersize = 1024 in
+	    let buffer = String.create buffersize in
+	    (try
+	      while true do
+		let nread = Unix.read pipe_out buffer 0 buffersize in
+		if nread = 0 then raise End_of_file;
+		Buffer.add_substring output buffer 0 nread
+	      done
+	     with 
+	     | End_of_file -> ()
+	     | Unix.Unix_error (code, f, arg) ->
+		 lprintf_nl "%s failed: %s" !!rss_preprocessor (Unix.error_message code));
+	    (try Unix.close pipe_out with _ -> ());
+	    (try Sys.remove filename with _ -> ());
+	    let _pid, _ = Unix.waitpid [] pid in
+	    let result = Buffer.contents output in
+	    if result = "" then begin
+	      lprintf_nl (_b "%s produced empty content for feed %s, program missing?") !!rss_preprocessor url;
+	      raise Not_found
+	    end;
+	    Rss.channel_of_string result
+	  with Unix.Unix_error (code, f, arg) ->
+	    lprintf_nl (_b "%s failed: %s") !!rss_preprocessor (Unix.error_message code); raise Not_found))
+      in
       let feed =
         try Hashtbl.find rss_feeds url with
           Not_found ->
diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/daemon/driver/driverCommands.ml ./src/daemon/driver/driverCommands.ml
--- ./src/daemon/driver/driverCommands.ml	2006-11-14 12:25:05.000000000 +0100
+++ ./src/daemon/driver/driverCommands.ml	2006-11-15 01:51:29.000000000 +0100
@@ -1104,16 +1104,43 @@
     "!", Arg_multiple (fun arg o ->
         if !!allow_any_command then
           match arg with
-            c :: tail ->
-              let args = String2.unsplit tail ' ' in
+            c :: args ->
               let cmd = try List.assoc c !!allowed_commands with Not_found -> c in
-              let tmp = Filename.temp_file "com" ".out" in
-              let ret = Sys.command (Printf.sprintf "%s %s > %s"
-                    cmd args tmp) in
-              let output = File.to_string tmp in
-              Sys.remove tmp;
-              Printf.sprintf (_b "%s\n---------------- Exited with code %d") output ret
-          | _ -> _s "no command given"
+	      (try
+		 let pipe_out, pipe_in = Unix.pipe () in
+		 let pid = Unix.create_process cmd 
+		   (Array.of_list (Filename2.basename c :: args))
+		   Unix.stdin pipe_in pipe_in in
+		 Unix.close pipe_in;
+		 (* can't close pipe_out in the already forked+executed process... *)
+		 let output = Buffer.create 1024 in
+		 let buffersize = 1024 in
+		 let buffer = String.create buffersize in
+		 (try
+		    while true do
+		      let nread = Unix.read pipe_out buffer 0 buffersize in
+		      if nread = 0 then raise End_of_file;
+		      Buffer.add_substring output buffer 0 nread
+		    done
+		  with 
+		  | End_of_file -> ()
+		  | Unix.Unix_error (code, f, arg) ->
+		      lprintf_nl "%s failed%s: %s" f (if arg = "" then "" else " on " ^ arg) (Unix.error_message code));
+		 (try Unix.close pipe_out with _ -> ());
+		 let _pid, status = Unix.waitpid [] pid in
+		 Printf.sprintf (_b "%s\n---------------- %s") 
+		   (Buffer.contents output) 
+		   (match status with
+		    | Unix.WEXITED exitcode ->
+			Printf.sprintf "Exited with code %d" exitcode
+		    | Unix.WSIGNALED signal ->
+			Printf.sprintf "Was killed by signal %d" signal
+		    | Unix.WSTOPPED signal -> (* does it matter for us ? *)
+			Printf.sprintf "Was stopped by signal %d" signal)
+		   
+	       with Unix.Unix_error (code, f, arg) ->
+		 Printf.sprintf "%s failed%s: %s" f (if arg = "" then "" else " on " ^ arg) (Unix.error_message code))
+          | [] -> _s "no command given"
         else
         match arg with
           [arg] ->
