#17 vfs::ftp > copy directories broken?

closed-fixed
5
2003-07-07
2003-07-04
No

The enclosed script (
WARNING!! it does open a completely unprotected
server socket, and creates/overwrites directories
/tmp/testDir and /tmp/testDir.copy)
produces the output reproduced below (llinux): it
refuses to copy a subdirectory, even though it can glob it.

Now: am I doing something stupid, or is this a bug? I
suspect it may have something to do with the "." and
".." directories (look at the [glob */*] output).

Also: is this an extension or core bug?

[mig@mini tmp]$ tclsh test.tcl
##############
/tmp/testDir.vfs/. /tmp/testDir.vfs/..
/tmp/testDir.vfs/a /tmp/testDir.vfs/subDir
/tmp/testDir.vfs/./. /tmp/testDir.vfs/./..
/tmp/testDir.vfs/./a /tmp/testDir.vfs/./subDir
/tmp/testDir.vfs/subDir/. /tmp/testDir.vfs/subDir/..
/tmp/testDir.vfs/subDir/b
##############
error copying "/tmp/testDir.vfs/subDir": no such file
or directory
while executing
"file copy $s [file join $dest [file tail $s]]"
(procedure "::tcl::CopyDirectory" line 50)
invoked from within
"::tcl::CopyDirectory copying /tmp/testDir.vfs
/tmp/testDir.copy"
invoked from within
"file copy -force /tmp/testDir.vfs /tmp/testDir.copy"
(file "test.tcl" line 43)
[mig@mini tmp]$

Discussion

  • miguel sofer

    miguel sofer - 2003-07-04
     
  • miguel sofer

    miguel sofer - 2003-07-04

    Logged In: YES
    user_id=148712

    Arghh ... old version, missing a subtest: vfs::tcl does see
    the subdirectory, and is able to read from it! This is
    verified by adding
    the lines

    set f [open /tmp/testDir.vfs/subDir/b]
    puts [gets $f]
    close $f

    before the attempted [file copy].

     
  • miguel sofer

    miguel sofer - 2003-07-04

    Logged In: YES
    user_id=148712

    verified that the problem is on the vfs side (against a
    non-tcl ftpd)

     
  • Vince Darley

    Vince Darley - 2003-07-06

    Logged In: YES
    user_id=32170

    Well, I've noticed one bug in Tcl's core here, but it is only on
    windows:

    % file normalize /tmp
    /tmp

    when it should give 'C:/tmp'

    The '.' and '..' issues are simply peculiarities, but not a
    fundamental problem. The entire vfs code (and Tcl's core)
    should be robust to whether any filesystem treats '.' and '..'
    as hidden or not (or even simultaneously hidden and not). At
    least that's how I understand it (try 'glob -type hidden */*' in
    the native fs, for example).

    Unfortunately, on Windows, your script simply seems to hang
    in the 'file copy', so I can't actually debug further.

     
  • Vince Darley

    Vince Darley - 2003-07-06

    Logged In: YES
    user_id=32170

    It would be helpful to have more of a log (you have 'return' in
    your log command...)

     
  • Vince Darley

    Vince Darley - 2003-07-06

    Logged In: YES
    user_id=32170

    Ok, I think I've tracked this down, although still lots of
    problems with things hanging completely (does 'ftpd' really
    work on Windows?).

    The problem is the vfs::ftp's 'stat' is trying to find the size of
    a directory, which isn't a good idea... I'll check a fix for that
    in, anyway, so please test.

     
  • Vince Darley

    Vince Darley - 2003-07-07
    • assigned_to: nobody --> vincentdarley
     
  • Vince Darley

    Vince Darley - 2003-07-07
    • status: open --> closed-fixed
     
  • Vince Darley

    Vince Darley - 2003-07-07

    Logged In: YES
    user_id=32170

    I was able to test this on a different ftp server and my fix
    works. Here is the primary fix:

    proc vfs::ftp::stat {fd name} {
    ::vfs::log "stat $name"
    if {$name == ""} {
    return [list type directory mtime 0 size 0 mode 0777
    ino -1 \ depth 0 name "" dev -1 uid -1 gid -1 nlink 1]
    }
    # get information on the type of this file
    set ftpInfo [_findFtpInfo $fd $name]
    if {$ftpInfo == ""} {
    vfs::filesystem posixerror $::vfs::posix(ENOENT)
    }
    ::vfs::log $ftpInfo
    set perms [lindex $ftpInfo 0]
    if {[string index $perms 0] == "d"} {
    lappend res type directory size 0
    set mtime 0
    } else {
    lappend res type file size [ftp::FileSize $fd $name]
    set mtime [ftp::ModTime $fd $name]
    }
    lappend res dev -1 uid -1 gid -1 nlink 1 depth 0 \ atime $mtime ctime $mtime mtime $mtime mode 0777
    return $res
    }

     

Log in to post a comment.