elfmz / far2l

Linux port of FAR v2
GNU General Public License v2.0
1.78k stars 173 forks source link

Feature: Consider porting FISH(FIle transfer over SHell filesystem) from Midnight Commander #1819

Closed vasya-r7 closed 1 year ago

vasya-r7 commented 1 year ago

Midnight Commander has FISH. And FISH is brilliant IMHO and superfast! It would be so nice to get FISH with far2l.

FISH supports jump hosts which NetRocks is lacking nowadays. FISH can be used instead SFTP most of the times. FISH is faster comparing to SFTP. Dirs listing is faster and download/upload speeds are much better. For example with my 30 MBit Internet transferring files with FISH via Midnight Commander saturates Internet link. SFTP via far2l download speeds are several times less than FISH(2-6x). I have Little Snitch firewall app which displays link speed in menubar. I`ve never saw SFTP via far2l saturating internet link.

Take a look at screenshots for the same file(0017.MOV) transferred via SFTP(far2l) and FISH(mc). It took MC 1 minute 23 seconds compared to Far2l (SFTP) with 2 minutes 48 seconds to transfer the same file. I repeated the test several times. Result is consistent during repetitions.

As for my system I`m using MacOs on MacBook Air M1 with Ventura 13.4. Far2l(2.5.2-beta) and MC(4.8.30 from macports) are latest as of the time of writing.

Thank you for far2l, it`s great!

image image image image
unxed commented 1 year ago

https://en.wikipedia.org/wiki/Files_transferred_over_shell_protocol ?

SCP in NetRocks is very close afaik. If you could point us to the differences, it would be indeed helpful.

vasya-r7 commented 1 year ago

SCP is fast you are right. Thanks for pointing that out.

FISH & SCP are rather similar to each other. However FISH has 2 significant implementation differences.

1) FISH stores commands used in separate scripts files instead hardcoding them in c/cpp code. You can see that commands here if you like. https://github.com/MidnightCommander/mc/tree/master/src/vfs/fish/helpers

2) FISH uses OpenSSH client stdin/stdout without trying to implement SSH proto in any way or connect to SSH on it`s own.

P.S.: I badly miss JumpHosts support with NetRocks.

unxed commented 1 year ago

As for 2, I am now trying to write NetRocks alternative as wrapper around command line sftp tool just as multiarc wraps around zip or tar. Is it something similar to what FISH in mc does?

https://github.com/unxed/netpanel

PS: Just PoC as for now, but still I was able to make ununtu-ubuntu connection and download a file.

elfmz commented 1 year ago

2unxed consider adding protocol to NetRocks instead of full plugin implementation. See https://github.com/elfmz/far2l/blob/master/NetRocks/HACKING.txt

vasya-r7 commented 1 year ago

https://github.com/unxed/netpanel

It seems to me that porting readily available and working code from Midnight would be simpler task than writing wrapper around sftp from scratch. FISH is rather primitive. And FISH commands stored in separated files can be just reused. Also FISH can be extended in almost any way you can imagine cause it just executes commands on remote server. With SFTP wrapper you are limited to standard SFTP client functionality and it`s limitations.

P.S.: Execute Midnight and try FISH. It works so good.

unxed commented 1 year ago

@elfmz извините, что на русском, но я немного устал и плохо соображаю. Думал в эту сторону, но есть проблемка: насколько я успел понять апи брокеров протоколов, там надо уметь возможность читать-писать по произвольному смещению. Консольная sftp не даёт такое. Теоретически такое можно было бы эмулировать, используя возможность докачки, и создавая пустой файл нужного размера, но это как-то совсем уж причудливо: писать такое, не обсудив сперва с коллегами, я не рискнул :) и ещё я сразу предупреждаю, что задолбаю вопросами про ipc и многопоточность, потому что в нетроксе уровень сей явно выше моего, и мне конечно, дико интересно разобраться во всем этом, но тупить на старте буду конкретно :)

Below is google translation @elfmz sorry for the Russian, but I'm a little tired and I'm bad at thinking. I thought in this direction, but there is a problem: as far as I managed to understand the api of protocol brokers, there you need to be able to read and write at an arbitrary offset. Console sftp does not give this. Theoretically, this could be emulated using the resume option and creating an empty file of the required size, but it’s somehow quite bizarre: I didn’t risk writing this without discussing it with my colleagues first :) and I also immediately warn that I’ll fill up with questions about ipc and multithreading, because in netrocks C/C++ level is clearly higher than mine, and of course, it’s wildly interesting for me to understand all this, but I’ll be stupid at the start :)

unxed commented 1 year ago

Used fish already. Good thing. Definitely porting from mc to netrocks API could be best solution if possible.

elfmz commented 1 year ago

насколько я успел понять апи брокеров протоколов, там надо уметь возможность читать-писать по произвольному смещению.

Небязательно. scp тоже не умеет по произвольному и делает так:

    if (resume_pos) {
        throw ProtocolUnsupportedError("SCP doesn't support download resume");
    }
unxed commented 1 year ago

И вот тут интересное. Докачка то как раз у консольного sftp есть. Вот нельзя ли как-то развинуть границы апи чтоб ее можно было использовать в том виде в котором она есть там?

unxed commented 1 year ago

Does FISH support download/upload resume in mc? @vasya-r7

vasya-r7 commented 1 year ago

Does FISH support download/upload resume in mc? @vasya-r7

FISH supports download/upload resume in mc. P.S.: At least I`ve tested download resume.

elfmz commented 1 year ago

Докачка то как раз у консольного sftp есть. Вот нельзя ли как-то развинуть границы апи чтоб ее можно было использовать в том виде в котором она есть там?

Непонятно что раздвигать. Докачка у консолького sftp есть - так она и у нетроксовского sftp тоже есть. А у консолького scp докачки нету. А что есть у fish - это отдельный вопрос. В любом случае апи позволяет как протоколы с докачкой так и без.

unxed commented 1 year ago

Раздвигать в том смысле чтоб докачка поддерживалась не только при доступности чтения/записи по любому смещению, но и по доступности опции "вот лежит недокачанный файл, докачивай с места, соответствующего его объему, и пиши в него же", как это в sftp сделано. Иначе придется эмулировать первый вариант поверх второго и это какаято дичь

elfmz commented 1 year ago

Но.. ведь так и сделано же: https://github.com/elfmz/far2l/blob/master/NetRocks/src/Protocol/Protocol.h#L91 или я чегото не понимаю..

unxed commented 1 year ago

API VFS mc выглядит так. @elfmz как думаете, этого достаточно для NetRocks? Т.е. можно сделать просто прокладку из одного API в другой?

void
vfs_init_fish (void)
{
    tcp_init ();

    vfs_init_subclass (&fish_subclass, "fish", VFSF_REMOTE | VFSF_USETMP, "sh");
    vfs_fish_ops->fill_names = fish_fill_names;
    vfs_fish_ops->stat = fish_stat;
    vfs_fish_ops->lstat = fish_lstat;
    vfs_fish_ops->fstat = fish_fstat;
    vfs_fish_ops->chmod = fish_chmod;
    vfs_fish_ops->chown = fish_chown;
    vfs_fish_ops->utime = fish_utime;
    vfs_fish_ops->open = fish_open;
    vfs_fish_ops->symlink = fish_symlink;
    vfs_fish_ops->link = fish_link;
    vfs_fish_ops->unlink = fish_unlink;
    vfs_fish_ops->rename = fish_rename;
    vfs_fish_ops->mkdir = fish_mkdir;
    vfs_fish_ops->rmdir = fish_rmdir;
    vfs_fish_ops->ctl = fish_ctl;
    fish_subclass.archive_same = fish_archive_same;
    fish_subclass.new_archive = fish_new_archive;
    fish_subclass.open_archive = fish_open_archive;
    fish_subclass.free_archive = fish_free_archive;
    fish_subclass.fh_new = fish_fh_new;
    fish_subclass.fh_open = fish_fh_open;
    fish_subclass.dir_load = fish_dir_load;
    fish_subclass.file_store = fish_file_store;
    fish_subclass.linear_start = fish_linear_start;
    fish_subclass.linear_read = fish_linear_read;
    fish_subclass.linear_close = fish_linear_close;
    vfs_register_class (vfs_fish_ops);
}

Там, похоже, даже чтение по произвольному смещению есть:

static int
fish_linear_start (struct vfs_class *me, vfs_file_handler_t * fh, off_t offset)
unxed commented 1 year ago

И ещё. mc вроде бы под gpl 3. Плагин к нетроксу с использованием его кода точно легально делать?

unxed commented 1 year ago

Так, я тут поизучал, как FISH в mc сделан. Офигел от гениальности. Это такая же обёртка, как я вокруг sftp хотел сделать, только вокруг ssh или rsh. То есть ей даже sftp-клиент консольный не нужен, а уж ssh клиент точно есть везде.

Там в комплекте с реализацией FISH — пачка скриптов, их содержимое передаётся через стандартный ввод (stdin) процессу удалённой оболочки. И они на той стороне уже делают то что нужно — переименовывают скажем файл или отдают его байты с такого-то по такой-то. Ну и зависимостей никаких, кроме консольного ssh клиента, опять же.

Теперь мне кажется, что надо просто всю реализацию из mc в far2l в форме плагина к Нетроксу портировать, а не изобретать велосипед. Не могу правда пока решить, как лучше — только саму fish или в принципе прокладку для любой VFS mc делать. Там ещё реализация VFS у них за собой может пол mc всяких либ потянуть.

unxed commented 1 year ago

mc's VFS API needs GLib, and since the whole concept is to implement sftp-without-dependencies, this doesn't really suit me. So, apparently, it's easier to make own implementation of FISH based on my NetPanel in the form of a protocol plugin for NetRocks, using helper scripts from mc. Moreover, among its VFS, there is nothing else of particular interest to us, except undelete that can be also ported later.

unxed commented 1 year ago

For those who are interested in my attempts to implement FISH like in mc. Here are early experiments. Currently working is a class with partial FISH implementation, and it can only connect, log in (by password or crypto key) and get a list of files, and a demo tool for this class. See readme.txt (in Russian only currently, sorry).

Further, in principle, is already a matter of technology.

FISH.TAR.GZ

PS: It even can remember password, that mc can not.

Update from September 26, 2023: I, the author of the sources posted in this message, allow dual licensing of source code used in commit 9a5b42752d3b024c6e345a1df47183e83438109c, both under mc-compatible licence and under the terms of GPL version 2.

unxed commented 1 year ago

The FISH NetRocks plugin has been brought to the state "can show a list of files from a remote server on far2l's panel" (however, nothing else can be done yet :)

Details are in readme.txt as as usual.

FISH.TAR.GZ

Update from September 26, 2023: I, the author of the sources posted in this message, allow dual licensing of source code used in commit 9a5b42752d3b024c6e345a1df47183e83438109c, both under mc-compatible licence and under the terms of GPL version 2.

unxed commented 1 year ago

oh, it's so early :)

unxed commented 1 year ago

о, я вижу, вы там что-то делали с кодом. а почему там лучше std::string, а не std::filesystem::path?

unxed commented 1 year ago

не очень понял, @elfmz вы дальше сами? или это просто исправление ошибок за мной и я могу понемногу дальше пробовать имплементировать?

elfmz commented 1 year ago

думаю пока я это переделаю чутка и потом можно вместе имплементировать

unxed commented 1 year ago

Аххаха надеюсь я не перестану понимать, как всё устроено, к тому моменту :) btw, там ещё как-то скриптам из helpers параметры передавать нужно, типа пути к папке для ls Пока не успел разобраться, как это правильно делать, и как это делалось в mc.

unxed commented 1 year ago

Ещё там хорошо бы ошибки обрабатывать, вот эти цифры после ###

А ещё уже после придумывания, как передать пароль так, чтоб ssh его съел (обычная отправка на stdin через pipe не срабатывает), узнал, что не один я этот фокус изобрел: https://sysadmin.pm/sshpass/ В её код полезно может быть глянуть тоже: https://github.com/kevinburke/sshpass

unxed commented 1 year ago

Хм, у меня после последних двух коммитов соединяться перестало, так и должно быть?

elfmz commented 1 year ago

не должно, у меня наоборот ща заработали переходы по директориям

unxed commented 1 year ago

На хост, где авторизация по паролю, заходит норм! И по папкам там ходит и типы и размер файлов показывает правильно, кайф!

А вот на хост, где авторизация по файлу-ключу, до сих пор не заходит. Виснет на «Connecting to site».

PS: Оставлю тут ссылку на веточку, чтоб людям за изменениями проще следить было: https://github.com/elfmz/far2l/tree/nr-fish

unxed commented 1 year ago

Вот на этой строчке виснет, если авторизация по ключу, ключ подходит и знакомый:

    wr = _fish->SendHelperAndWaitReply("FISH/info", {"\n### 200", "\n### "});

Замена на

    wr = _fish->SendHelperAndWaitReply("FISH/info", {"\n### 200", "\n### ", "$ "});

проблему решает, но перестаёт работать чтение списка файлов, когда заходишь по паролю.

elfmz commented 1 year ago

то есть каким то фигом между 127 и ### 200 вылезла куча шелловских пришглашений..

elfmz commented 1 year ago

а, понятно

elfmz commented 1 year ago

А сейчас? Кстати, еще и get должен заработать

unxed commented 1 year ago

Спасибо! Не у компа, ближе к ночеру смогу глянуть

unxed commented 1 year ago

Попросил потестить в чате пока :)

unxed commented 1 year ago

В чате пишут: При попытке соединиться на *wrt, висит до бесконечности на "Connecting to site"

atolismesh commented 1 year ago

Коннект на fish:user@localhost тоже висит до бесконечности на "Connecting to site". В системных логах пишет: Failed password for user from 127.0.0.1 port 41582 ssh2 Просто ssh user@localhost после набора пароля руками соединяется без проблем.

Даже если закрыть far2l, остаются висеть запущенные плагином процессы ssh с установленным коннектом

atolismesh commented 1 year ago

ProtocolFISH.cpp:

    // везде ли "$ " признак успешного залогина? проверить на dd wrt

    // Мы таки залогинены, спрашивают пароль, ключ незнакомый?
    std::vector<std::string> results = {"$ ", "password: ", "This key is not known by any other names"};

Вот пример выводы ssh root@openwrt


BusyBox v1.36.1 (2023-08-30 22:49:29 UTC) built-in shell (ash)

  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------
 OpenWrt SNAPSHOT, r23860-c5b7be8316
 -----------------------------------------------------
root@OpenWrt:~#

Имеет смысл добавить "# ", "Enter passphrase for key " ? И "% " для zsh А у некоторых стоит fish ("> ") shell или powerline, где PS1 меняется до неузнаваемости...

elfmz commented 1 year ago

добавил # прочие > и т.п. будем добавлять по мере багов, универсального решения тут явно не предвидится

unxed commented 1 year ago

А как они в mc эту проблему решают? Через час у компа буду

atolismesh commented 1 year ago

Стало соединяться с компом (Ubuntu) и Openwrt. ! Но показывает пустые начальные каталоги. А они, естественно, не пустые. Дальше на любое действие выдает ошибку.

unxed commented 1 year ago

Download работает с хоста, куда входишь по паролю, но не работает с хоста, куда входишь по ключу. Может, причина в какой-то другой разнице между ними, но и там и там убунтовый сервер (может версий разных, не помню точно).

unxed commented 1 year ago

Да, и по поводу всяких разных промптов. Может, просто сразу слать echo 'MY_RANDOM_TOKEN' и потом этого токена и ждать? Типа если пришёл то у нас есть какой-никакой живой шелл с другой стороны.

elfmz commented 1 year ago

Но показывает пустые начальные каталоги. А они, естественно, не пустые.

Замечу что после make install fish еще не работает толком, так как не копируются хелперы, так что тестить пока мона тока из билда. После make install поведение как раз такое - показывает пустые хосты

elfmz commented 1 year ago

вот теперь make install нормально ставит все

elfmz commented 1 year ago

..и сразу интересный спецэффект обнаружил - если стартовать far2l из терминала то все ок, а если из гуя, то далеко не ок. Чета терминал с ssh-ем глючит видимо.

unxed commented 1 year ago

я из гуя тестирую как раз.

только я запутался, где у вас глючит, в терминале или гуе.

у меня в гуе всё из заявленного ок, кроме возможности скачать файл с сервера, куда по ключу вхожу.

elfmz commented 1 year ago

У меня из гуя глючит а из терминала все ок. Я имею ввиду запуск самого far2l, а не его бэкенд. В обоих случаях это гуишный far2l. Просто запускаемый из xfce меню - глючит, а из терминала - работает.

unxed commented 1 year ago

Воу! Даже не знаю что сказать :) Потому что у меня просто хоткей когда-то давно настроен на запуск far2l по Alt+F3 (единственное кажется свободное из удобного было), и я даже уже не помню, какая аппа это делает.

elfmz commented 1 year ago

Оказалось надо setenv("TERM",...) сделать было