Копирование файла с помощью libssh - PullRequest
0 голосов
/ 14 января 2019

Я пытаюсь написать простую программу (игрушечный пример), которая копирует файл с удаленного хоста на локальный компьютер.

Работает, когда я пытаюсь скопировать текстовый файл, но не для таких файлов, как mp4.

Вот мой код, который состоит из частей, сшитых вместе из урока: https://pastebin.com/0FPrmeDx

Здесь происходит ошибка:

int scp_receive(ssh_session session, ssh_scp scp)
{
  int rc;
  int size, mode;
  char *filename, *buffer;

  rc = ssh_scp_pull_request(scp);
  if (rc != SSH_SCP_REQUEST_NEWFILE)
  {
    fprintf(stderr, "Error receiving information about file: %s\n",
            ssh_get_error(session));
    return SSH_ERROR;
  }

  size = ssh_scp_request_get_size(scp);
  filename = strdup(ssh_scp_request_get_filename(scp));
  mode = ssh_scp_request_get_permissions(scp);
  printf("Receiving file %s, size %d, permisssions 0%o\n",
          filename, size, mode);
  free(filename);

  buffer = malloc(size);
  if (buffer == NULL)
  {
    fprintf(stderr, "Memory allocation error\n");
    return SSH_ERROR;
  }

  ssh_scp_accept_request(scp);
  rc = ssh_scp_read(scp, buffer, size);
  if (rc == SSH_ERROR)
  {
    fprintf(stderr, "Error receiving file data: %s\n",
            ssh_get_error(session));
    free(buffer);
    return rc;
  }
  printf("Done!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");

  int filedesc = open("/home/user/video.mp4", O_WRONLY | O_CREAT);

  if (filedesc < 0) {
    return -1;
  }

  write(filedesc, buffer, size);
  free(buffer);

  close(filedesc);

  rc = ssh_scp_pull_request(scp);
  if (rc != SSH_SCP_REQUEST_EOF)
  {
    fprintf(stderr, "Unexpected request: %s\n",
            ssh_get_error(session));
    return SSH_ERROR;
  }

  return SSH_OK;
}

Ошибка с кодом:

rc = ssh_scp_pull_request(scp);
if (rc != SSH_SCP_REQUEST_EOF)
{
   fprintf(stderr, "Unexpected request: %s\n",
           ssh_get_error(session));
   return SSH_ERROR;
}

Это ошибка, которую я получаю:

Unexpected request: ssh_scp_pull_request called under invalid state

Я пытался понять это, но я не мог добиться прогресса в этом.

Обновление 1:

Размер скопированного файла точно такой же, как и у исходного файла, для файлов txt и mp4. Тем не менее, скопированный файл, кажется, в основном пустой При копировании разрешения изменяются с -rwxr-xr-x на --wxr-----.

Обновление 2:

Кажется, что размер файла играет здесь важную роль. Очень маленькие файлы (10-15kb) копируются без проблем. Большие файлы не копируются и выдают вышеупомянутую ошибку ...

1 Ответ

0 голосов
/ 14 января 2019

Вы не можете ожидать, что ssh_scp_read() читает все данные за один вызов. Вы должны выполнять итерацию, пока не останется больше данных для чтения:

int r = 0;
while (r < size) {
    int st = ssh_scp_read(scp, buffer+r, size-r);
    r += st;
}

Теперь последующий вызов ssh_scp_pull_request(scp) должен быть успешным.

...