lftp does not perform file contents integrity check (eg a hash) when comparing files. This is important to know when ensuring the integrity of downloaded files.
I first suspected this when dealing with a corrupted download and noting that the mirror command completed too fast for a hash to be done. I then confirmed by inspecting the lftp source code. Specifically: the FileInfo::SameAs method handles this (latest src on github (pasted below)).
bool FileInfo::SameAs(const FileInfo *fi,int ignore) const { if(defined&NAME && fi->defined&NAME) if(strcmp(name,fi->name)) return false; if(defined&TYPE && fi->defined&TYPE) if(filetype!=fi->filetype) return false; if((defined&TYPE && filetype==DIRECTORY) || (fi->defined&TYPE && fi->filetype==DIRECTORY)) return false; // can't guarantee directory is the same (recursively) if(defined&SYMLINK_DEF && fi->defined&SYMLINK_DEF) return (strcmp(symlink,fi->symlink)==0); if(defined&DATE && fi->defined&DATE && !(ignore&DATE)) { time_t p=date.ts_prec; if(p<fi->date.ts_prec) p=fi->date.ts_prec; if(!(ignore&IGNORE_DATE_IF_OLDER && date<fi->date) && labs(date-fi->date)>p) return false; } if(defined&SIZE && fi->defined&SIZE && !(ignore&SIZE)) { if(!(ignore&IGNORE_SIZE_IF_OLDER && defined&DATE && fi->defined&DATE && date<fi->date) && (size!=fi->size)) return false; } return true; }
Looking this over you can see that lftp tries to check the following:
- filename
- filetype
- symlink or not
- date
- filesize
Even these checks can't be fully trusted though because they are simply skipped if something returns as undefined.
If you are lucky the FTP host will provide a text file with checksum hashes so you can verify the downloaded content. I was not so lucky and had to redownload completely.