Index: src/networks/donkey/donkeyClient.ml
===================================================================
RCS file: /sources/mldonkey/mldonkey/src/networks/donkey/donkeyClient.ml,v
retrieving revision 1.118
diff -u -w -r1.118 donkeyClient.ml
--- src/networks/donkey/donkeyClient.ml	8 Jan 2007 12:26:38 -0000	1.118
+++ src/networks/donkey/donkeyClient.ml	8 Jan 2007 14:00:44 -0000
@@ -415,7 +415,13 @@
         
   
 let new_chunk up begin_pos end_pos =
-  if begin_pos <> end_pos then
+  let req_size = end_pos -- begin_pos in
+  let req_location = (begin_pos ++ end_pos) // (2L ** block_size) in
+  if !verbose_upload then
+    lprintf_nl "new block: (%Ld,%Ld) size %Ld chunk #%Ld" begin_pos end_pos req_size req_location;
+  if (req_size < Int64.zero) || (req_size > zone_size) || ((up.up_current <> req_location) && (req_size <> Int64.zero)) then
+    up.up_finish <- true;
+  if ((not up.up_finish) || (not !!upload_complete_chunks)) && (req_size > Int64.zero) && (req_size <= zone_size) then
     let chunk = (begin_pos, end_pos) in
     (* the zone requested is already "in the pipe" *)
     if not (List.mem chunk up.up_flying_chunks) then
@@ -2004,15 +2010,8 @@
 
       let prio = (file_priority file) in
       let client_upload_lifetime = ref ((max 0 !!upload_lifetime) * 60) in
-      let client_received_enough c =
-        if !!upload_full_chunks then
-          c.client_session_uploaded > (block_size ++ 20L ** 1024L)
-        else
-          last_time() > c.client_connect_time + !client_upload_lifetime + 5 * prio
-      in
-      begin
         
-        if !!dynamic_upload_lifetime
+      if !!dynamic_upload_lifetime && not !!upload_complete_chunks
             && c.client_session_uploaded > c.client_session_downloaded
             && c.client_session_uploaded > Int64.of_int !!dynamic_upload_threshold ** zone_size
         then
@@ -2020,6 +2019,15 @@
           Int64.to_int 
             (Int64.of_int !client_upload_lifetime 
               ** c.client_session_downloaded // c.client_session_uploaded);
+
+      let client_received_enough c =
+        if !!upload_full_chunks && not !!upload_complete_chunks then
+          c.client_session_uploaded > (block_size ++ 20L ** 1024L)
+        else
+          last_time() > c.client_connect_time + !client_upload_lifetime + 5 * prio
+      in
+
+      begin
         if client_received_enough c then
           if Intmap.length !CommonUploads.pending_slots_map = 0 then
             begin
@@ -2051,6 +2059,8 @@
                 up_end_chunk = Int64.zero;
                 up_chunks = [];
 		up_flying_chunks = [];
+                up_current = Int64.zero;
+                up_finish = true;
                 up_waiting = old_up.up_waiting;
               }, old_up.up_waiting
           | _ ->
@@ -2060,18 +2070,30 @@
                 up_end_chunk = Int64.zero;
                 up_chunks = [];
 		up_flying_chunks = [];
+                up_current = ((t.Q.start_pos1 ++ t.Q.end_pos1) // (2L ** block_size));
+                up_finish = false;
                 up_waiting = false;
               }, false
         in
         new_chunk up t.Q.start_pos1 t.Q.end_pos1;
         new_chunk up t.Q.start_pos2 t.Q.end_pos2;
         new_chunk up t.Q.start_pos3 t.Q.end_pos3;
+        (match up.up_chunks with
+          [] ->
+(* it should never happen here, that a client with up.up_finish = false
+   has an empty block queue *)
+            if up.up_finish && !!upload_complete_chunks then
+              begin
+                DonkeyOneFile.remove_client_slot c;
+                raise Not_found
+              end;
+          | chunks ->
         c.client_upload <- Some up;
         set_client_upload (as_client c) (as_file file);
         if not waiting && !CommonUploads.has_upload = 0 then begin
             CommonUploads.ready_for_upload (as_client c);
             up.up_waiting <- true
-          end
+          end)
       end;
       if !verbose_upload then lprintf_nl "QueryBloc treated"
       
Index: src/networks/donkey/donkeyFiles.ml
===================================================================
RCS file: /sources/mldonkey/mldonkey/src/networks/donkey/donkeyFiles.ml,v
retrieving revision 1.24
diff -u -w -r1.24 donkeyFiles.ml
--- src/networks/donkey/donkeyFiles.ml	8 Jan 2007 12:26:38 -0000	1.24
+++ src/networks/donkey/donkeyFiles.ml	8 Jan 2007 14:00:45 -0000
@@ -149,6 +149,8 @@
                     if !verbose_upload then
                         lprintf_nl "NO MORE CHUNKS";
 		    up.up_waiting <- false;
+                    if up.up_finish && !!upload_complete_chunks then
+                      DonkeyOneFile.remove_client_slot c;
                 | (begin_pos, end_pos) :: _ ->
                     up.up_pos <- begin_pos;
                     up.up_end_chunk <- end_pos;
Index: src/networks/donkey/donkeyOptions.ml
===================================================================
RCS file: /sources/mldonkey/mldonkey/src/networks/donkey/donkeyOptions.ml,v
retrieving revision 1.58
diff -u -w -r1.58 donkeyOptions.ml
--- src/networks/donkey/donkeyOptions.ml	8 Jan 2007 12:20:40 -0000	1.58
+++ src/networks/donkey/donkeyOptions.ml	8 Jan 2007 14:00:45 -0000
@@ -178,6 +178,12 @@
   "If true, each client is allowed to receive one chunk, this setting overrides upload_lifetime"
     bool_option false
 
+let upload_complete_chunks = define_expert_option donkey_section ["upload_complete_chunks"]
+  "If true, each client is allowed to complete only one chunk, independent, if it is empty or
+   partial. this setting overrides upload_full_chunks and dynamic_upload_lifetime,
+   but is, as a failsafe, limited by upload_lifetime (should be set reasonable high)"
+    bool_option false
+
 let dynamic_upload_lifetime = define_expert_option donkey_section ["dynamic_upload_lifetime"]
   "Each client upload lifetime depends on download-upload ratio"
     bool_option false
Index: src/networks/donkey/donkeyTypes.ml
===================================================================
RCS file: /sources/mldonkey/mldonkey/src/networks/donkey/donkeyTypes.ml,v
retrieving revision 1.57
diff -u -w -r1.57 donkeyTypes.ml
--- src/networks/donkey/donkeyTypes.ml	8 Jan 2007 12:26:38 -0000	1.57
+++ src/networks/donkey/donkeyTypes.ml	8 Jan 2007 14:00:45 -0000
@@ -610,6 +610,8 @@
     mutable up_chunks : (int64 * int64) list;
     (* zones sent but not yet received by other peer, oldest first *)
     mutable up_flying_chunks : (int64 * int64) list; 
+    mutable up_current : int64;
+    mutable up_finish : bool;
     mutable up_waiting : bool;
   }
 
