patch: reget working again [Re: Reget: bug or feature?]



Arpad Biro wrote:
Hi,

MC 4.6.1-pre1:

It seems that when copying files, "reget" means to append the last
s-t bytes of the source file to the target file, where s is the source
size and t is the target size.

However, when performing "move", "reget" works differently:
the whole source file is appended to the target.

Is this difference a bug or a feature?

It's a bug, below is a patch for this feature. Using global variable the same patch only 6 rows length :)

--
~.

   Alexander

 >>> mailto:i fano com ua

--- mc/src/file.c	Mon Oct 27 19:36:19 2003
+++ mc/src/file.c	Tue Jan 20 21:48:50 2004
@@ -583,8 +583,16 @@
     }
 
     gettimeofday (&tv_transfer_start, (struct timezone *) NULL);
+    {
+	int notftp = strncmp(src_path, "/#ftp:", 6);
 
-    while ((src_desc = mc_open (src_path, O_RDONLY | O_LINEAR)) < 0) {
+	while (1) {
+	    if (notftp || !ctx->do_reget)
+	        src_desc = mc_open (src_path, O_RDONLY | O_LINEAR);
+	    else
+	        src_desc = mc_open (src_path, O_RDONLY | O_LINEAR | O_FTPREGET, ctx->do_reget);
+	    if (src_desc >= 0)
+		break;
 	return_status =
 	    file_error (_(" Cannot open source file \"%s\" \n %s "),
 			src_path);
@@ -593,14 +601,14 @@
 	ctx->do_append = 0;
 	return return_status;
     }
-
-    if (ctx->do_reget) {
+	if (ctx->do_reget && notftp) {
 	if (mc_lseek (src_desc, ctx->do_reget, SEEK_SET) != ctx->do_reget) {
 	    message (1, _("Warning"),
 			_(" Reget failed, about to overwrite file "));
 	    ctx->do_reget = ctx->do_append = 0;
 	}
     }
+    }
 
     while (mc_fstat (src_desc, &sb)) {
 	return_status =
@@ -618,6 +626,9 @@
     utb.modtime = sb.st_mtime;
     file_size = sb.st_size;
 
+    if(ctx->do_reget)
+	n_read_total = ctx->do_reget;
+
     /* Create the new regular file with small permissions initially,
        do not create a security hole.  FIXME: You have security hole
        here, btw. Imagine copying to /tmp and symlink attack :-( */
@@ -739,8 +750,8 @@
 
 		if (n_read_total) {
 		    ctx->eta_secs =
-			((dt / (double) n_read_total) * file_size) - dt;
-		    ctx->bps = n_read_total / ((dt < 1) ? 1 : dt);
+			((dt / (double) (n_read_total - ctx->do_reget)) * (file_size - ctx->do_reget)) - dt;
+		    ctx->bps = (n_read_total - ctx->do_reget) / ((dt < 1) ? 1 : dt);
 		} else
 		    ctx->eta_secs = 0.0;
 	    }
@@ -751,7 +762,7 @@
 		    (tv_current.tv_sec - tv_transfer_start.tv_sec);
 		if (ctx->bps_time < 1)
 		    ctx->bps_time = 1;
-		ctx->bps = n_read_total / ctx->bps_time;
+		ctx->bps = (n_read_total - ctx->do_reget) / ctx->bps_time;
 	    }
 
 	    file_progress_set_stalled_label (ctx, stalled_msg);
--- mc/src/fileopctx.c	Sat Oct 11 11:54:32 2003
+++ mc/src/fileopctx.c	Mon Jan 19 03:44:53 2004
@@ -44,7 +44,6 @@
     ctx->eta_secs = 0.0;
     ctx->progress_bytes = 0.0;
     ctx->op_preserve = TRUE;
-    ctx->do_reget = TRUE;
     ctx->stat_func = (mc_stat_fn) mc_lstat;
     ctx->preserve = TRUE;
     ctx->preserve_uidgid = (geteuid () == 0) ? TRUE : FALSE;
--- mc/src/fileopctx.h	Fri Oct 24 21:28:32 2003
+++ mc/src/fileopctx.h	Mon Jan 19 03:46:15 2004
@@ -47,7 +47,7 @@
 	int recursive_result;
 
 	/* Whether to do a reget */
-	int do_reget;
+	off_t do_reget;
 
 	/* Controls appending to files */
 	int do_append;
--- mc/vfs/direntry.c	Wed Nov 26 23:10:43 2003
+++ mc/vfs/direntry.c	Tue Jan 20 19:32:37 2004
@@ -690,14 +690,22 @@
 }
 
 static void *
-vfs_s_open (struct vfs_class *me, const char *file, int flags, int mode)
+vfs_s_open (struct vfs_class *me, const char *file, int flags, int mode, ...)
 {
     int was_changed = 0;
     struct vfs_s_fh *fh;
     struct vfs_s_super *super;
     char *q;
     struct vfs_s_inode *ino;
+    va_list ap;
+    off_t reget = 0;
 
+    if(flags & O_FTPREGET) {
+	va_start (ap, mode);
+	reget = va_arg (ap, off_t);
+	va_end (ap);
+	flags &= ~O_FTPREGET;
+    }
     if ((q = vfs_s_get_path (me, file, &super, 0)) == NULL)
 	return NULL;
     ino = vfs_s_find_inode (me, super, q, LINK_FOLLOW, FL_NONE);
@@ -747,7 +755,7 @@
     if (IS_LINEAR (flags)) {
 	if (MEDATA->linear_start) {
 	    print_vfs_message (_("Starting linear transfer..."));
-	    if (!MEDATA->linear_start (me, fh, 0)) {
+	    if (!MEDATA->linear_start (me, fh, reget)) {
 		g_free (fh);
 		return NULL;
 	    }
--- mc/vfs/fish.c	Sat Dec  6 06:24:56 2003
+++ mc/vfs/fish.c	Mon Jan 19 04:40:24 2004
@@ -571,10 +571,12 @@
     return -1;
 }
 
-static int fish_linear_start(struct vfs_class *me, struct vfs_s_fh *fh, int offset)
+static int fish_linear_start(struct vfs_class *me, struct vfs_s_fh *fh, off_t offset)
 {
     char *name;
     char *quoted_name;
+    int i;
+
     if (offset)
         ERRNOR (E_NOTSUPP, 0);
     name = vfs_s_fullpath (me, fh->ino);
@@ -584,7 +586,7 @@
     g_free (name);
     name = quoted_name;
     fh->u.fish.append = 0;
-    offset = fish_command (me, FH_SUPER, WANT_STRING,
+    i = fish_command (me, FH_SUPER, WANT_STRING,
 		"#RETR /%s\n"
 		"ls -l /%s 2>/dev/null | (\n"
 		  "read var1 var2 var3 var4 var5 var6\n"
@@ -595,7 +597,7 @@
 		"echo '### 200'\n", 
 		name, name, name );
     g_free (name);
-    if (offset != PRELIM) ERRNOR (E_REMOTE, 0);
+    if (i != PRELIM) ERRNOR (E_REMOTE, 0);
     fh->linear = LS_LINEAR_OPEN;
     fh->u.fish.got = 0;
     if (sscanf( reply_str, "%d", &fh->u.fish.total )!=1)
--- mc/vfs/ftpfs.c	Wed Nov 26 23:10:44 2003
+++ mc/vfs/ftpfs.c	Tue Jan 20 19:32:28 2004
@@ -930,17 +930,16 @@
 
 static int
 ftpfs_open_data_connection (struct vfs_class *me, struct vfs_s_super *super, const char *cmd,
-		      const char *remote, int isbinary, int reget)
+		      const char *remote, int isbinary, off_t reget)
 {
     struct sockaddr_in from;
     int s, j, data, fromlen = sizeof(from);
-    
     if ((s = ftpfs_initconn (me, super)) == -1)
         return -1;
     if (ftpfs_changetype (me, super, isbinary) == -1)
         return -1;
-    if (reget > 0){
-	j = ftpfs_command (me, super, WAIT_REPLY, "REST %d", reget);
+    if (reget){
+	j = ftpfs_command (me, super, WAIT_REPLY, "REST %qu", (unsigned long long)reget);
 	if (j != CONTINUE)
 	    return -1;
     }
@@ -1370,7 +1369,7 @@
 }
 
 static int 
-ftpfs_linear_start(struct vfs_class *me, struct vfs_s_fh *fh, int offset)
+ftpfs_linear_start(struct vfs_class *me, struct vfs_s_fh *fh, off_t offset)
 {
     char *name = vfs_s_fullpath (me, fh->ino);
 
--- mc/vfs/vfs.c	Wed Nov 26 23:25:30 2003
+++ mc/vfs/vfs.c	Tue Jan 20 19:32:15 2004
@@ -310,22 +310,28 @@
     int  mode;
     void *info;
     va_list ap;
+    off_t reget = 0;
 
     char *file = vfs_canon (filename);
     struct vfs_class *vfs = vfs_get_class (file);
 
     /* Get the mode flag */	/* FIXME: should look if O_CREAT is present */
     va_start (ap, flags);
-    mode = va_arg (ap, int);
+    if (flags & O_FTPREGET)
+	reget = va_arg (ap, off_t);
+    else
+	mode = va_arg (ap, int);
     va_end (ap);
-    
     if (!vfs->open) {
 	g_free (file);
 	errno = -EOPNOTSUPP;
 	return -1;
     }
 
-    info = (*vfs->open) (vfs, file, flags, mode);	/* open must be supported */
+    if(flags & O_FTPREGET)
+	info = (*vfs->open) (vfs, file, flags, 0, reget);	/* open must be supported */
+    else
+	info = (*vfs->open) (vfs, file, flags, mode);	/* open must be supported */
     g_free (file);
     if (!info){
 	errno = ferrno (vfs);
--- mc/vfs/vfs.h	Wed Nov 26 23:10:44 2003
+++ mc/vfs/vfs.h	Tue Jan 20 19:26:49 2004
@@ -28,7 +28,7 @@
     int (*which) (struct vfs_class *me, char *path);
 
     void *(*open) (struct vfs_class *me, const char *fname, int flags,
-		   int mode);
+		   int mode, ...);
     int (*close) (void *vfs_info);
     int (*read) (void *vfs_info, char *buffer, int count);
     int (*write) (void *vfs_info, char *buf, int count);
@@ -215,6 +215,8 @@
 #define IS_LINEAR(a) ((a) == (O_RDONLY | O_LINEAR))	/* Return only 0 and 1 ! */
 #define NO_LINEAR(a) (((a) == (O_RDONLY | O_LINEAR)) ? O_RDONLY : (a))
 #endif
+
+#define O_FTPREGET 0x80000000
 
 /* O_LINEAR is strange beast, be careful. If you open file asserting
  * O_RDONLY | O_LINEAR, you promise:
--- mc/vfs/xdirentry.h	Fri Nov 14 10:25:51 2003
+++ mc/vfs/xdirentry.h	Mon Jan 19 04:39:11 2004
@@ -148,7 +148,7 @@
 		       char *path, char *localname);
 
     int (*linear_start) (struct vfs_class *me, struct vfs_s_fh *fh,
-			 int from);
+			 off_t from);
     int (*linear_read) (struct vfs_class *me, struct vfs_s_fh *fh,
 			void *buf, int len);
     void (*linear_close) (struct vfs_class *me, struct vfs_s_fh *fh);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]