Сегодня разочаровался в моём любимом Very Secure FTP Daemon.
Произошло это, когда мне нужно было реализовать что-то вроде RandomAccessFile, работающего по FTP. И когда я дошёл до seek-операций, обнаружил, что vsftpd некорректно отрабатывает пару команд REST + STOR. А именно, открывает файл всегда в режиме O_APPEND, о чём с горестью сообщает manpage:
O_APPEND
The file is opened in append mode. Before each write(), the file offset is positioned at the end of the file, as if with
lseek(). O_APPEND may lead to corrupted files on NFS file systems if more than one process appends data to a file at
once. This is because NFS does not support appending to a file, so the client kernel has to simulate it, which can’t be
done without a race condition.
Таким образом, получаем следующую ситуацию:
- Я создаю на удалённом сервере некий файл при помощи STOR.
- Записываю в файл строку «01234567890123456789″.
- Закрываю файл (прекращаю передачу данных).
- Делаю REST 3.
- Снова открываю файл через STOR.
- Записываю в файл строку «xxx».
- Закрываю файл.
В результате таких нехитрых манипуляций, по идее, я должен получить файл с содержимым «012xxx67890123456789″, вместо чего получаю файл с содержимым «01234567890123456789xxx», то есть, «xxx» ушли в конец.
При этом, ProFTPD замечательно разруливает эту ситуацию так, как надо.
Что ж, думаю, может в новой версии VSFTPD это пофиксено. Качаю исходники, собираю, ставлю, но ситуация повторяется. Пришлось поковыряться в коде и выяснить, что там действительно делается O_APPEND, что вызвало массу негодования с моей стороны и было допилено.
За сим выкладываю патч для VSFTPD и пропатченный архив для версии 2.2.2:
UPD: Забыл добавить, что внёс ещё одну фичу: файл не будет транкейтиться, если предварительно сделать REST 0.
Trackbacks /
Pingbacks