#ssh #sftp #openssh #dirent.h
#ssh #sftp #openssh #dirent.h
Вопрос:
У меня есть фрагмент кода, который считывает каталог для файлов для обработки. В настоящее время я использую для этого методы dirent.h,opendir(), readdir(). Мне сказали, что мне нужно сделать то же самое, только теперь это каталог на удаленной машине с доступом SSH / SFTP.
Единственный способ (который я могу придумать) сделать то же самое, ничего не меняя в системе, кроме моего исходного кода, — это запустить команду «ssh user@host ls», проанализировать и обработать на основе результатов анализаторов.
Реальный вопрос здесь в том, существуют ли способы выполнения opendir(), readdir() (или чего-то подобного) через SSH / SFTP?
Ответ №1:
Самый простой способ, если вы используете Linux или Mac OS X (или некоторые BSD), — использовать sshfs для подключения к файловой системе. Тогда большинство вызовов файловой системы будут просто работать напрямую, без изменений.
В противном случае вы можете обратиться к источнику sshfs для получения подсказок о том, как это работает.
Ответ №2:
Да, у SFTP есть протокол для этого. Прочитайте самый последний документ здесь: http://tools.ietf.org/wg/secsh/draft-ietf-secsh-filexfer /
Комментарии:
1. Реализовано ли это где-нибудь?
2. Меня беспокоит, что OpenSSH, похоже, не имеет стабильного API или какой-либо документации по API, за исключением замечаний в коде.
3. sshfs просто запускает ssh как отдельный процесс и использует необработанный SFTP по каналу, устраняя необходимость в стабильном API
4. OpenSSH реализует сетевой протокол, а не API — стандартного SSH API не существует. sshfs — это одна из альтернатив, в противном случае вам нужно использовать клиентскую библиотеку SFTP.
Ответ №3:
Начиная с OpenSSH 5.1, существует ограниченная реализация для этого. Он не полностью реализует стандарт File XFER. Поэтому я не могу проверить наличие таких вещей, как типы файлов, но я могу отсканировать сами имена файлов… Используя код «sftp.c» в исходном коде OpenSSH, я просто собрал adhoc main(), который можно было изменять по мере необходимости… Я надеюсь, что на этот вопрос можно будет более вдумчиво ответить позже.
/* Username is a NULL terminated string
Host is a NULL terminated string indicating remote IP */
void setup_args(arglist *args, char *username, char *host)
{
// Arg init allocation
memset(args, '', sizeof(*args));
args->list = NULL;
// Arg setup
addargs(args, "%s", "/usr/bin/ssh");
addargs(args, "%s", "-oForwardX11 no");
addargs(args, "%s", "-oForwardAgent no");
addargs(args, "%s", "-oPermitLocalCommand no");
addargs(args, "%s", "-oClearAllForwardings yes");
addargs(args, "%s%s", "-l", username);
addargs(args, "%s", "-oProtocol 2");
addargs(args, "%s", "-s");
addargs(args, "%s", host);
addargs(args, "%s", "sftp");
}
void run_program()
{
// Setup connection parameters.
int in, out; // The IO file descriptors.
arglist args;
setup_args(amp;args, "chenz", "172.16.22.128");
connect_to_server("/usr/bin/ssh", args.list, amp;in, amp;out);
freeargs(amp;args);
// Create connection
struct sftp_conn *conn;
conn = do_init(in, out, copy_buffer_len, num_requests);
if (conn == NULL)
fatal("Couldn't initialise connection to server");
//Get the current directory
char *pwd;
pwd = do_realpath(conn, ".");
printf("PWD: %sn", pwd);
if (pwd == NULL)
fatal("Need cwd");
SFTP_DIRENT** dirent;
do_readdir(conn, "/home/chenz", amp;dirent);
int i = 0;
while (dirent[i] != 0) {
printf("filename: %sn", dirent[i]->filename);
printf("longname: %sn", dirent[i]->longname);
printf("attrib:n", dirent[i]->a);
i ;
}
// Clean up file descriptors
close(in);
close(out);
// Wait for kill signal and exit
while (waitpid(sshpid, NULL, 0) == -1)
if (errno != EINTR)
fatal("Couldn't wait for ssh process: %s",
strerror(errno));
//exit(err == 0 ? 0 : 1);
exit(0);
}