patch: reget working again [Re: Reget: bug or feature?]
- From: Alexander Savelyev <i fano com ua>
- To: Arpad Biro <biro_arpad yahoo com>
- Cc: mc-devel gnome org
- Subject: patch: reget working again [Re: Reget: bug or feature?]
- Date: Tue, 20 Jan 2004 22:04:46 +0200
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]