I've been studying the source code of lftp for several days, and
although the original idea was fixing a single bug, then I found more
things that were not working. I decided to separate them in several
mails, to keep it clean. I realize because lftp is such an old and
advanced program, I may have missed some side effects the proposed
patches have. They are just ideas of how I'd fix it, as I didn't want
to report something without at least putting some thought into solving
it. Also, I don't know if they are known bugs, or maybe intentional
features, or if the behavior of some of them can be changed ('fixed')
with an option.

**Problem:
Certain options like cmd:parallel won't work when used with lftp -c
because Reconfig is never called. This happens to all the options
queried in Reconfig (cmd:long-running, cmd:remote-completion,
cmd:csh-history, cmd:verify-path, cmd:verify-path-cached,
cmd:verify-host, cmd:verbose (this one is not in the man page, not
sure why), cmd:parallel)
Reconfig() is called when a feeder is removed, a cmdexec is
initialized, in getqueue and changesession. Maybe somewhere else, but
that's not relevant.

Those options can be set in a file you can then read with a source
command, or just put in .lftp/rc. A source command is automatically
run to read rc, and it uses a filefeeder to read the file. After the
feeder dies, Reconfig is executed.

Notice cmd:queue-parallel is different, CmdExec::GetQueue(bool create)
calls Reconfig in the new CmdExec that is spawned
(queue->Reconfig(0);)

**Tests:
(With an empty rc)

-This won't work (both files will be downloaded sequentially because
max_waiting=1):
lftp -f testfile

testfile:
get cmd:parallel 2;
get http://file1;
get http://file2;

-But this will work:

set cmd:parallel 2;
open http://something.com;
get http://file1;
get http://file2;

That works because open is calling Reconfig. It's just an example, you
can put any command that calls it.

**Fix:
-CMD(set) in commands.cc could call Reconfig regardless of the option
you are changing. It's not efficient, but I don't think it will matter
at all, and it's simple. That's what I implemented in the patch.

-CMD(set) in commands.cc could be modified so it checks if the option
being set needs to call Reconfig. This means a huge if, and if
Reconfig is changed, that will have to be changed as well. I suppose
the if would be faster than calling Reconfig when not needed, but I
don't see how it would help.

-exec_parsed_command() could be modified to call Reconfig if the
current command is not a set but the previous one was. I don't like
that because then the new options won't be used until you run out of
sets.

-Yet another option would be to store a bool variable in ResType that
can tell CMD(set) if it must call Reconfig. This way you don't have a
giant if, but it seems overkill.

Maybe it was designed to use an open before you get something, I don't
know. If that is indeed the case, I thought it was confusing that it
worked sequentially without an open, but you couldn't use cmd:parallel
unless you had an open (that doesn't even need to open the proper
domain). And anyway, it works with any command that calls Reconfig,
open is not special in that regard.

Attachment: reconfig.patch
Description: Binary data

Reply via email to