Ticket #2267 (fish: resume download)

implemented resuming file downloads (reget) in FISH VFS

Signed-off-by: Ilia Maslakov <il.smind@gmail.com>
This commit is contained in:
Ilia Maslakov 2010-07-18 18:56:06 +00:00
parent 34f09fa7c3
commit 0795cc2bc9
4 changed files with 128 additions and 26 deletions

View File

@ -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)

View File

@ -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

View File

@ -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"

View File

@ -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