diff -urN putty-20040805\CMDLINE.C putty-20040805-resume\CMDLINE.C
--- putty-20040805\CMDLINE.C	Sun Jul 25 15:00:26 2004
+++ putty-20040805-resume\CMDLINE.C	Thu Aug 05 15:09:38 2004
@@ -321,6 +321,12 @@
 	cfg->compression = 1;
     }
 
+    if (!strcmp(p, "-XR")) {
+	RETURN(1);
+	SAVEABLE(1);
+	cfg->file_resume = 1;
+    }
+
     if (!strcmp(p, "-1")) {
 	RETURN(1);
 	UNAVAILABLE_IN(TOOLTYPE_NONNETWORK);
diff -urN putty-20040805\PSFTP.H putty-20040805-resume\PSFTP.H
--- putty-20040805\PSFTP.H	Tue Sep 02 10:00:34 2003
+++ putty-20040805-resume\PSFTP.H	Thu Aug 05 15:09:38 2004
@@ -80,6 +80,9 @@
 /* Closes and frees the RFile */
 void close_rfile(RFile *f);
 WFile *open_new_file(char *name);
+/* I really think the interface as defined, stinks -- eloj */
+WFile *open_existing_file_append(char *name, unsigned long *size_low, unsigned long *size_high,
+			         unsigned long *mtime, unsigned long *atime);
 /* Returns <0 on error, 0 on eof, or number of bytes written, as usual */
 int write_to_file(WFile *f, void *buffer, int length);
 void set_file_times(WFile *f, unsigned long mtime, unsigned long atime);
diff -urN putty-20040805\PUTTY.H putty-20040805-resume\PUTTY.H
--- putty-20040805\PUTTY.H	Sun Jul 25 15:00:26 2004
+++ putty-20040805-resume\PUTTY.H	Thu Aug 05 15:09:38 2004
@@ -351,6 +351,7 @@
 				        * but never for loading/saving */
     int nopty;
     int compression;
+    int file_resume;
     int agentfwd;
     int change_username;	       /* allow username switching in SSH2 */
     int ssh_cipherlist[CIPHER_MAX];
diff -urN putty-20040805\SCP.C putty-20040805-resume\scp.c
--- putty-20040805\SCP.C	Sun Jul 25 15:00:26 2004
+++ putty-20040805-resume\scp.c	Thu Aug 05 15:12:20 2004
@@ -483,7 +483,7 @@
  *  Update statistic information about current file.
  */
 static void print_stats(char *name, unsigned long size, unsigned long done,
-			time_t start, time_t now)
+            unsigned long resume, time_t start, time_t now)
 {
     float ratebs;
     unsigned long eta;
@@ -495,9 +495,9 @@
     elap = (unsigned long) difftime(now, start);
 
     if (now > start)
-	ratebs = (float) done / elap;
+	ratebs = (float) (done-resume) / elap;
     else
-	ratebs = (float) done;
+	ratebs = (float) (done-resume);
 
     if (ratebs < 1.0)
 	eta = size - done;
@@ -1436,7 +1436,7 @@
     }
 }
 
-int scp_accept_filexfer(void)
+int scp_accept_filexfer(PLARGE_INTEGER resume_from)
 {
     if (using_sftp) {
 	struct sftp_packet *pktin;
@@ -1453,7 +1453,7 @@
 	    errs++;
 	    return 1;
 	}
-	scp_sftp_fileoffset = uint64_make(0, 0);
+	scp_sftp_fileoffset = uint64_make(resume_from->HighPart, resume_from->LowPart);
 	scp_sftp_xfer = xfer_download_init(scp_sftp_filehandle,
 					   scp_sftp_fileoffset);
 	sfree(scp_sftp_currentname);
@@ -1646,7 +1646,7 @@
 	    stat_bytes += k;
 	    if (time(NULL) != stat_lasttime || i + k == size) {
 		stat_lasttime = time(NULL);
-		print_stats(last, size, stat_bytes,
+		print_stats(last, size, stat_bytes, 0,
 			    stat_starttime, stat_lasttime);
 	    }
 	}
@@ -1714,6 +1714,8 @@
     unsigned long received;
     int wrerror = 0;
     unsigned long stat_bytes;
+    LARGE_INTEGER resume_from;
+
     time_t stat_starttime, stat_lasttime;
     char *stat_name;
 
@@ -1835,21 +1837,28 @@
 	    continue;
 	}
 
-	f = open_new_file(destfname);
+        resume_from.QuadPart = 0;
+        if( cfg.file_resume && (exists && (attr & FILE_ATTRIBUTE_DIRECTORY) == 0) )
+        {
+          f = open_existing_file_append(destfname, &resume_from.LowPart, &resume_from.HighPart, NULL, NULL);
+        } else {
+          f = open_new_file(destfname);
+        }
+
 	if (f == NULL) {
 	    run_err("%s: Cannot create file", destfname);
 	    continue;
 	}
 
-	if (scp_accept_filexfer())
+	if (scp_accept_filexfer(&resume_from))
 	    return;
 
-	stat_bytes = 0;
+        stat_bytes = resume_from.LowPart;
 	stat_starttime = time(NULL);
 	stat_lasttime = 0;
 	stat_name = stripslashes(destfname, 1);
 
-	received = 0;
+        received = stat_bytes;
 	while (received < act.size) {
 	    char transbuf[4096];
 	    unsigned long blksize;
@@ -1876,7 +1885,7 @@
 		if (time(NULL) > stat_lasttime ||
 		    received + read == act.size) {
 		    stat_lasttime = time(NULL);
-		    print_stats(stat_name, act.size, stat_bytes,
+		    print_stats(stat_name, act.size, stat_bytes, resume_from.LowPart,
 				stat_starttime, stat_lasttime);
 		}
 	    }
@@ -2112,6 +2121,7 @@
     printf("  -q        quiet, don't show statistics\n");
     printf("  -r        copy directories recursively\n");
     printf("  -v        show verbose messages\n");
+    printf("  -XR       enable resume of broken downloads\n");
     printf("  -load sessname  Load settings from saved session\n");
     printf("  -P port   connect to specified port\n");
     printf("  -l user   connect with specified username\n");
diff -urN putty-20040805\WINSFTP.C putty-20040805-resume\WINSFTP.C
--- putty-20040805\WINSFTP.C	Sun Oct 12 14:46:12 2003
+++ putty-20040805-resume\WINSFTP.C	Thu Aug 05 15:09:38 2004
@@ -240,6 +240,39 @@
     return ret;
 }
 
+WFile *open_existing_file_append(char *name, unsigned long *size_low, unsigned long *size_high,
+			         unsigned long *mtime, unsigned long *atime)
+{
+    HANDLE h;
+    WFile *ret;
+
+    h = CreateFile(name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL,
+		   OPEN_EXISTING, 0, 0);
+    if (h == INVALID_HANDLE_VALUE)
+	return NULL;
+
+    SetFilePointer(h,0,NULL,FILE_END);
+
+    ret = snew(WFile);
+    ret->h = h;
+
+    if (size_low)
+    {
+      *size_low = GetFileSize(h, size_high ? size_high : NULL );
+    }
+
+    if (mtime || atime) {
+	FILETIME actime, wrtime;
+	GetFileTime(h, NULL, &actime, &wrtime);
+	if (atime)
+	    TIME_WIN_TO_POSIX(actime, *atime);
+	if (mtime)
+	    TIME_WIN_TO_POSIX(wrtime, *mtime);
+    }
+
+    return ret;
+}
+
 int write_to_file(WFile *f, void *buffer, int length)
 {
     int ret, written;
