From 0795cc2bc92b148f26a7ef822a9199ccb60437d2 Mon Sep 17 00:00:00 2001 From: Ilia Maslakov Date: Sun, 18 Jul 2010 18:56:06 +0000 Subject: [PATCH] Ticket #2267 (fish: resume download) implemented resuming file downloads (reget) in FISH VFS Signed-off-by: Ilia Maslakov --- lib/vfs/mc-vfs/fish.c | 41 +++++++++-------- lib/vfs/mc-vfs/fish/get | 98 ++++++++++++++++++++++++++++++++++++++-- lib/vfs/mc-vfs/fish/info | 6 ++- lib/vfs/mc-vfs/fishdef.h | 9 +++- 4 files changed, 128 insertions(+), 26 deletions(-) diff --git a/lib/vfs/mc-vfs/fish.c b/lib/vfs/mc-vfs/fish.c index 20ae4ca6d..c9b67c602 100644 --- a/lib/vfs/mc-vfs/fish.c +++ b/lib/vfs/mc-vfs/fish.c @@ -105,6 +105,7 @@ int fish_directory_timeout = 900; #define FISH_HAVE_PERL 8 #define FISH_HAVE_LSQ 16 #define FISH_HAVE_DATE_MDYT 32 +#define FISH_HAVE_TAIL 64 static char reply_str[80]; @@ -293,7 +294,7 @@ fish_set_env (int flags) { GString *tmp; - tmp = g_string_sized_new (128); + tmp = g_string_sized_new (150); g_string_assign (tmp, "export "); if ((flags & FISH_HAVE_HEAD) != 0) @@ -314,6 +315,9 @@ fish_set_env (int flags) if ((flags & FISH_HAVE_DATE_MDYT) != 0) g_string_append (tmp, "FISH_HAVE_DATE_MDYT=1 "); + if ((flags & FISH_HAVE_TAIL) != 0) + g_string_append (tmp, "FISH_HAVE_TAIL=1 "); + return g_string_free (tmp, FALSE); } @@ -491,19 +495,19 @@ fish_open_archive (struct vfs_class *me, struct vfs_s_super *super, if (password) SUP.password = password; SUP.scr_ls = fish_load_script_from_file (host, FISH_LS_FILE, FISH_LS_DEF_CONTENT); - SUP.scr_exists = fish_load_script_from_file (host, FISH_EXISTS_FILE, FISH_EXISTS_FILE); - SUP.scr_mkdir = fish_load_script_from_file (host, FISH_MKDIR_FILE, FISH_MKDIR_FILE); - SUP.scr_unlink = fish_load_script_from_file (host, FISH_UNLINK_FILE, FISH_UNLINK_FILE); - SUP.scr_chown = fish_load_script_from_file (host, FISH_CHOWN_FILE, FISH_CHOWN_FILE); - SUP.scr_chmod = fish_load_script_from_file (host, FISH_CHMOD_FILE, FISH_CHMOD_FILE); - SUP.scr_rmdir = fish_load_script_from_file (host, FISH_RMDIR_FILE, FISH_RMDIR_FILE); - SUP.scr_ln = fish_load_script_from_file (host, FISH_LN_FILE, FISH_LN_FILE); - SUP.scr_mv = fish_load_script_from_file (host, FISH_MV_FILE, FISH_MV_FILE); - SUP.scr_hardlink = fish_load_script_from_file (host, FISH_HARDLINK_FILE, FISH_HARDLINK_FILE); - SUP.scr_get = fish_load_script_from_file (host, FISH_GET_FILE, FISH_GET_FILE); - SUP.scr_send = fish_load_script_from_file (host, FISH_SEND_FILE,FISH_SEND_FILE); - SUP.scr_append = fish_load_script_from_file (host, FISH_APPEND_FILE, FISH_APPEND_FILE); - SUP.scr_info = fish_load_script_from_file (host, FISH_INFO_FILE, FISH_INFO_FILE); + SUP.scr_exists = fish_load_script_from_file (host, FISH_EXISTS_FILE, FISH_EXISTS_DEF_CONTENT); + SUP.scr_mkdir = fish_load_script_from_file (host, FISH_MKDIR_FILE, FISH_MKDIR_DEF_CONTENT); + SUP.scr_unlink = fish_load_script_from_file (host, FISH_UNLINK_FILE, FISH_UNLINK_DEF_CONTENT); + SUP.scr_chown = fish_load_script_from_file (host, FISH_CHOWN_FILE, FISH_CHOWN_DEF_CONTENT); + SUP.scr_chmod = fish_load_script_from_file (host, FISH_CHMOD_FILE, FISH_CHMOD_DEF_CONTENT); + SUP.scr_rmdir = fish_load_script_from_file (host, FISH_RMDIR_FILE, FISH_RMDIR_DEF_CONTENT); + SUP.scr_ln = fish_load_script_from_file (host, FISH_LN_FILE, FISH_LN_DEF_CONTENT); + SUP.scr_mv = fish_load_script_from_file (host, FISH_MV_FILE, FISH_MV_DEF_CONTENT); + SUP.scr_hardlink = fish_load_script_from_file (host, FISH_HARDLINK_FILE, FISH_HARDLINK_DEF_CONTENT); + SUP.scr_get = fish_load_script_from_file (host, FISH_GET_FILE, FISH_GET_DEF_CONTENT); + SUP.scr_send = fish_load_script_from_file (host, FISH_SEND_FILE,FISH_SEND_DEF_CONTENT); + SUP.scr_append = fish_load_script_from_file (host, FISH_APPEND_FILE, FISH_APPEND_DEF_CONTENT); + SUP.scr_info = fish_load_script_from_file (host, FISH_INFO_FILE, FISH_INFO_DEF_CONTENT); return fish_open_archive_int (me, super); } @@ -866,8 +870,7 @@ fish_linear_start (struct vfs_class *me, struct vfs_s_fh *fh, off_t offset) struct vfs_s_super *super = FH_SUPER; char *name; char *quoted_name; - if (offset) - ERRNOR (E_NOTSUPP, 0); + name = vfs_s_fullpath (me, fh->ino); if (name == NULL) return 0; @@ -882,8 +885,10 @@ fish_linear_start (struct vfs_class *me, struct vfs_s_fh *fh, off_t offset) * standard output (i.e. over the network). */ - shell_commands = g_strconcat (SUP.scr_env, "FISH_FILENAME=%s;\n", SUP.scr_get, (char *) NULL); - offset = fish_command (me, super, WANT_STRING, shell_commands, quoted_name); + shell_commands = g_strconcat (SUP.scr_env, "FISH_FILENAME=%s FISH_START_OFFSET=%lu;\n", + SUP.scr_get, (char *) NULL); + offset = fish_command (me, super, WANT_STRING, shell_commands, quoted_name, + (unsigned long) offset); g_free (shell_commands); g_free (quoted_name); if (offset != PRELIM) diff --git a/lib/vfs/mc-vfs/fish/get b/lib/vfs/mc-vfs/fish/get index 76b5b36e0..fd83ea522 100755 --- a/lib/vfs/mc-vfs/fish/get +++ b/lib/vfs/mc-vfs/fish/get @@ -1,14 +1,102 @@ -#RETR $FISH_FILENAME -FILENAME="/${FISH_FILENAME}" +#RETR $FISH_FILENAME $FISH_START_OFFSET +export LC_TIME=C +fish_get_perl () +{ +FILENAME=$1 +OFFSET=$2 +perl -e ' +use strict; +use POSIX; +use Fcntl; +my $filename = $ARGV[0]; +my $pos = $ARGV[1]; +my $content; +my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = lstat("$filename"); +my $n; +if (open IFILE,$filename) { + if ($size<$pos) { + printf("0\n"); + } else { + $size-=$pos; + printf("$size\n"); + } + printf("### 100\n"); + seek (IFILE, $pos, 0); + while ($n = read(IFILE,$content,$blocks)!= 0) { + print $content; + } + close IFILE; + printf("### 200\n"); +} else { + printf("### 500\n"); +} +exit 0 +' "${FILENAME}" $OFFSET +} + +fish_get_tail () +{ +FILENAME=$1 +OFFSET=$2 export LC_TIME=C if dd if="${FILENAME}" of=/dev/null bs=1 count=1 2>/dev/null ; then - ls -ln "${FILENAME}" 2>/dev/null | ( + file_size=`ls -ln "${FILENAME}" 2>/dev/null | ( read p l u g s r echo $s - ) + )` + if [ $OFFSET -gt 0 ]; then + file_size=`expr $file_size - $OFFSET` + OFFSET=`expr $OFFSET + 1` + fi + if [ $file_size -gt 0 ]; then + echo $file_size + else + echo 0 + fi echo "### 100" - cat "${FILENAME}" + if [ $OFFSET -gt 0 ]; then + tail -c +${OFFSET} "${FILENAME}" + else + cat "${FILENAME}" + fi echo "### 200" else echo "### 500" fi +} + +fish_get_dd () +{ +FILENAME=$1 +OFFSET=$2 +export LC_TIME=C +if dd if="${FILENAME}" of=/dev/null bs=1 count=1 2>/dev/null ; then + file_size=`ls -ln "${FILENAME}" 2>/dev/null | ( + read p l u g s r + echo $s + )` + file_size=`expr $file_size - $OFFSET` + if [ $file_size -gt 0 ]; then + echo $file_size + else + echo 0 + fi + echo "### 100" + if [ $OFFSET -gt 0 ]; then + dd skip=$OFFSET ibs=1 if="${FILENAME}" 2>/dev/null + else + cat "${FILENAME}" + fi + echo "### 200" +else + echo "### 500" +fi +} + +if [ -n "${FISH_HAVE_PERL}" ]; then + fish_get_perl "/${FISH_FILENAME}" ${FISH_START_OFFSET} +elif [ -n "${FISH_HAVE_TAIL}" ]; then + fish_get_tail "/${FISH_FILENAME}" ${FISH_START_OFFSET} +else + fish_get_dd "/${FISH_FILENAME}" ${FISH_START_OFFSET} +fi diff --git a/lib/vfs/mc-vfs/fish/info b/lib/vfs/mc-vfs/fish/info index fc801727b..db208dbd9 100755 --- a/lib/vfs/mc-vfs/fish/info +++ b/lib/vfs/mc-vfs/fish/info @@ -5,6 +5,7 @@ export LC_TIME=C #FISH_HAVE_PERL 8 #FISH_HAVE_LSQ 16 #FISH_HAVE_DATE_MDYT 32 +#FISH_HAVE_TAIL 64 res=0 if `echo yes| head -c 1 > /dev/null 2>&1` ; then res=`expr $res + 1` @@ -21,7 +22,7 @@ fi if `ls -Q / >/dev/null 2>&1` ; then res=`expr $res + 16` fi -dat=`ls -lan / 2>/dev/null | head -n 3|tail -n 1 | ( +dat=`ls -lan / 2>/dev/null | head -n 3 | tail -n 1 | ( while read p l u g s rec; do if [ -n "$g" ]; then if [ -n "$l" ]; then @@ -34,5 +35,8 @@ r=`echo "0123456789"| grep "$dat"` if [ -z "$r" ]; then res=`expr $res + 32` fi +if `echo yes| tail -c +1 - > /dev/null 2>&1` ; then + res=`expr $res + 64` +fi echo $res echo "### 200" diff --git a/lib/vfs/mc-vfs/fishdef.h b/lib/vfs/mc-vfs/fishdef.h index 92299e734..64bf16bd5 100644 --- a/lib/vfs/mc-vfs/fishdef.h +++ b/lib/vfs/mc-vfs/fishdef.h @@ -201,6 +201,7 @@ "#FISH_HAVE_PERL 8\n" \ "#FISH_HAVE_LSQ 16\n" \ "#FISH_HAVE_DATE_MDYT 32\n" \ +"#FISH_HAVE_TAIL 64\n" \ "res=0\n" \ "if `echo yes| head -c 1 > /dev/null 2>&1` ; then\n" \ " res=`expr $res + 1`\n" \ @@ -217,7 +218,7 @@ "if `ls -Q / >/dev/null 2>&1` ; then\n" \ " res=`expr $res + 16`\n" \ "fi\n" \ -"dat=`ls -lan / 2>/dev/null | head -n 3|tail -n 1 | (\n" \ +"dat=`ls -lan / 2>/dev/null | head -n 3 | tail -n 1 | (\n" \ " while read p l u g s rec; do\n" \ " if [ -n \"$g\" ]; then\n" \ " if [ -n \"$l\" ]; then\n" \ @@ -225,12 +226,16 @@ " fi\n" \ " fi\n" \ " done\n" \ -") |head -c 1`\n" \ +") | cut -c1 2>/dev/null`\n" \ "r=`echo \"0123456789\"| grep \"$dat\"`\n" \ "if [ -z \"$r\" ]; then\n" \ " res=`expr $res + 32`\n" \ "fi\n" \ +"if `echo yes| tail -c +1 - > /dev/null 2>&1` ; then\n" \ +" res=`expr $res + 64`\n" \ +"fi\n" \ "echo $res\n" \ "echo \"### 200\"\n" + #endif