diff -bwur wget-ORIGINAL-1.11.4/src/ftp.c wget-1.11.4/src/ftp.c
--- wget-ORIGINAL-1.11.4/src/ftp.c	2008-06-30 10:22:54.000000000 +0900
+++ wget-1.11.4/src/ftp.c	2009-09-10 03:18:13.507264603 +0900
@@ -992,6 +992,15 @@
       fd_close (dtsock);
       return FWRITEERR;
     }
+  else if (res == -3)
+    {
+      logprintf (LOG_NOTQUIET, _("Hard quota exceeded: %s, closing control connection.\n"),
+                 con->target);
+      fd_close (csock);
+      con->csock = -1;
+      fd_close (dtsock);
+      return RETRFINISHED;
+    }
   else if (res == -1)
     {
       logprintf (LOG_NOTQUIET, _("%s (%s) - Data connection: %s; "),
@@ -1396,7 +1405,7 @@
     {
       char *old_target, *ofile;
 
-      if (opt.quota && total_downloaded_bytes > opt.quota)
+      if (opt.quota && total_downloaded_bytes > opt.quota || opt.hard_quota && total_downloaded_bytes > opt.hard_quota)
         {
           --depth;
           return QUOTEXC;
@@ -1791,6 +1800,9 @@
   if (opt.quota && total_downloaded_bytes > opt.quota)
     return QUOTEXC;
   else
+	  if (opt.hard_quota && total_downloaded_bytes > opt.hard_quota)
+	    return QUOTEXC;
+	  else
     /* #### Should we return `res' here?  */
     return RETROK;
 }
diff -bwur wget-ORIGINAL-1.11.4/src/http.c wget-1.11.4/src/http.c
--- wget-ORIGINAL-1.11.4/src/http.c	2008-06-30 10:22:54.000000000 +0900
+++ wget-1.11.4/src/http.c	2009-09-10 02:26:14.199230493 +0900
@@ -2310,6 +2310,9 @@
   else
     {
       if (hs->res < 0)
+    	  if (hs->res == -3)
+    		  hs->rderrmsg = xstrdup (_("Hard quota exceeded"));
+    	  else
         hs->rderrmsg = xstrdup (fd_errstr (sock));
       CLOSE_INVALIDATE (sock);
     }
@@ -2811,8 +2814,31 @@
               goto exit;
             }
         }
-      else /* from now on hstat.res can only be -1 */
+      else /* from now on hstat.res can only be -1 or -3 */
+        {
+    	  if(hstat.res == -3)
+			{
+              if (hstat.contlen == -1)
         {
+                  logprintf (LOG_VERBOSE,
+                             _("%s (%s) - Interrupting at byte %s (%s).\n"),
+                             tms, tmrate, number_to_static_string (hstat.len),
+                             hstat.rderrmsg);
+                  ret = RETROK;
+                  break;
+                }
+              else /* hstat.res == -1 and contlen is given */
+                {
+                  logprintf (LOG_VERBOSE,
+                             _("%s (%s) - Interrupting at byte %s/%s (%s).\n"),
+                             tms, tmrate,
+                             number_to_static_string (hstat.len),
+                             number_to_static_string (hstat.contlen),
+                             hstat.rderrmsg);
+                  ret = RETROK;
+                  break;
+                }
+		    }
           if (hstat.contlen == -1)
             {
               logprintf (LOG_VERBOSE,
diff -bwur wget-ORIGINAL-1.11.4/src/init.c wget-1.11.4/src/init.c
--- wget-ORIGINAL-1.11.4/src/init.c	2008-04-27 13:48:23.000000000 +0900
+++ wget-1.11.4/src/init.c	2009-09-10 01:22:00.086262987 +0900
@@ -163,6 +163,7 @@
   { "ftpproxy",         &opt.ftp_proxy,         cmd_string },
   { "ftpuser",          &opt.ftp_user,          cmd_string },
   { "glob",             &opt.ftp_glob,          cmd_boolean },
+  { "hardquota",        &opt.hard_quota,        cmd_bytes_sum },
   { "header",           NULL,                   cmd_spec_header },
   { "htmlextension",    &opt.html_extension,    cmd_boolean },
   { "htmlify",          NULL,                   cmd_spec_htmlify },
diff -bwur wget-ORIGINAL-1.11.4/src/main.c wget-1.11.4/src/main.c
--- wget-ORIGINAL-1.11.4/src/main.c	2008-06-30 10:22:53.000000000 +0900
+++ wget-1.11.4/src/main.c	2009-09-10 01:46:52.350233758 +0900
@@ -219,6 +219,7 @@
     { "proxy-user", 0, OPT_VALUE, "proxyuser", -1 },
     { "quiet", 'q', OPT_BOOLEAN, "quiet", -1 },
     { "quota", 'Q', OPT_VALUE, "quota", -1 },
+    { "hard-quota", 0, OPT_VALUE, "hardquota", -1 },
     { "random-file", 0, OPT_VALUE, "randomfile", -1 },
     { "random-wait", 0, OPT_BOOLEAN, "randomwait", -1 },
     { "read-timeout", 0, OPT_VALUE, "readtimeout", -1 },
@@ -450,7 +451,9 @@
     N_("\
        --no-proxy                explicitly turn off proxy.\n"),
     N_("\
-  -Q,  --quota=NUMBER            set retrieval quota to NUMBER.\n"),
+  -Q,  --quota=NUMBER            set retrieval soft quota to NUMBER.\n"),
+    N_("\
+       --hard-quota=NUMBER       set retrieval hard quota to NUMBER.\n"),
     N_("\
        --bind-address=ADDRESS    bind to ADDRESS (hostname or IP) on local host.\n"),
     N_("\
@@ -1066,6 +1069,10 @@
         logprintf (LOG_NOTQUIET,
                    _("Download quota of %s EXCEEDED!\n"),
                    human_readable (opt.quota));
+      if (opt.hard_quota && total_downloaded_bytes > opt.hard_quota)
+        logprintf (LOG_NOTQUIET,
+                   _("Download hard quota of %s EXCEEDED!\n"),
+                   human_readable (opt.hard_quota));
     }
 
   if (opt.cookies_output)
diff -bwur wget-ORIGINAL-1.11.4/src/options.h wget-1.11.4/src/options.h
--- wget-ORIGINAL-1.11.4/src/options.h	2008-04-27 13:48:23.000000000 +0900
+++ wget-1.11.4/src/options.h	2009-09-10 01:21:30.115232597 +0900
@@ -120,6 +120,7 @@
 				   many bps. */
   SUM_SIZE_INT quota;		/* Maximum file size to download and
 				   store. */
+  SUM_SIZE_INT hard_quota;		/* Maximum traffic to download. */
 
   int numurls;			/* Number of successfully downloaded
 				   URLs #### should be removed because
diff -bwur wget-ORIGINAL-1.11.4/src/retr.c wget-1.11.4/src/retr.c
--- wget-ORIGINAL-1.11.4/src/retr.c	2008-04-27 13:48:23.000000000 +0900
+++ wget-1.11.4/src/retr.c	2009-09-10 15:20:24.785775821 +0900
@@ -188,7 +188,7 @@
 
    The function exits and returns the amount of data read.  In case of
    error while reading data, -1 is returned.  In case of error while
-   writing data, -2 is returned.  */
+   writing data, -2 is returned.  In case of hard quota exceeded, -3 is returned. */
 
 int
 fd_read_body (int fd, FILE *out, wgint toread, wgint startpos,
@@ -223,6 +223,13 @@
 
   if (opt.verbose)
     {
+	  if(opt.hard_quota)
+	    {
+		  logprintf(LOG_VERBOSE, _("Hard quota: %s (%s).\n"),
+				  number_to_static_string(opt.hard_quota),
+				  human_readable (opt.hard_quota));
+
+	    }
       /* If we're skipping STARTPOS bytes, pass 0 as the INITIAL
          argument to progress_create because the indicator doesn't
          (yet) know about "skipping" data.  */
@@ -249,6 +256,8 @@
   if (opt.limit_rate && opt.limit_rate < dlbufsize)
     dlbufsize = opt.limit_rate;
 
+  SUM_SIZE_INT total_downloaded_current=total_downloaded_bytes;
+
   /* Read from FD while there is data to read.  Normally toread==0
      means that it is unknown how much data is to arrive.  However, if
      EXACT is set, then toread==0 means what it says: that no data
@@ -256,6 +265,12 @@
   while (!exact || (sum_read < toread))
     {
       int rdsize = exact ? MIN (toread - sum_read, dlbufsize) : dlbufsize;
+      if (opt.hard_quota)
+        {
+    	  rdsize = MIN (rdsize, opt.hard_quota-total_downloaded_current);
+    	  if (rdsize < 0) rdsize = 0;
+    	  if (rdsize == 0) { ret=-3; goto out; }
+        }
       double tmout = opt.read_timeout;
       if (progress_interactive)
         {
@@ -297,6 +312,7 @@
       if (ret > 0)
         {
           sum_read += ret;
+          total_downloaded_current += ret;
           if (!write_data (out, dlbuf, ret, &skip, &sum_written))
             {
               ret = -2;

