2017-07-21 3 views
0

Ich versuche, eine Datei von meinem Server herunterzuladen; Sowohl der Client als auch der Server sind Linux, und ssh_scp_read() gibt eine falsche Ganzzahl zurück. Laut der Dokumentation schreibt die Funktion bis zu 65536 Bytes, liest aber nur 16384, wenn die Datei 37980 ist, aber das ist nicht meine Hauptsorge; nahe dem Ende dieser 16384 Bytes fängt es an, den Puffer mit Null-Müll zu füllen, der dann in die Datei geschrieben wird.ssh_scp_read gibt Müll zurück

Die Erstellung rekursiver Verzeichnisse funktioniert einwandfrei; Das Problem besteht darin, Dateien herunterzuladen, die größer als 16384 Byte sind. An dieser Stelle werde ich sftp anstelle von scp verwenden, aber ich würde gerne wissen, was ich falsch mache.

Dies ist der Funktionscode:

int get(ssh_session gno_ses,ssh_scp scp) 
{ 
    int rc; 
    int size, permissions; 
    char *buff, *filename, path[PATH_MAX]; 

    while(1) 
    { 
     rc = ssh_scp_pull_request(scp); 
     switch (rc) 
     { 
      // cases [...] 
      case SSH_SCP_REQUEST_NEWFILE: 
       size = ssh_scp_request_get_size(scp); 
       printf("Size is %d\n",size); 
       filename = strdup(ssh_scp_request_get_filename(scp)); 
       permissions = ssh_scp_request_get_permissions(scp); 

       FILE *file; 
       file = fopen(filename, "w+"); 
       if (!file) 
       { 
        ssh_scp_deny_request(scp,"Unable to open"); 
        fprintf(stderr, " %s: %s\n", filename, strerror(errno)); 
        fclose(file); 
        break; 
       } 

       buff = malloc(size); 
       printf("Size of buffer is %d\n", size); 
       if (!buff) 
       { 
        fprintf(stderr, "\nBuff memory allocation error.\n"); 
        return SSH_ERROR; 
       } 

       if(ssh_scp_accept_request(scp) != SSH_OK) 
       { 
        fprintf(stderr, "Error accepting request: %s\n", ssh_get_error(gno_ses)); 
        break; 
       } 

       do 
       { 
        rc = ssh_scp_read(scp, buff, size); 
        if (rc == SSH_ERROR) 
        { 
         fprintf(stderr, "Error receiving file data: %s\n", ssh_get_error(gno_ses)); 
         break; 
        } 
        if (fwrite(buff, 1, size, file) != size) 
        { 
         perror("Error at writting to file: "); 
         break; 
        } 
        printf("ssh_scp_read got %d\n",rc); 
       } while (rc != 0); 

       fclose(file); 
       free(filename); 
       free(buff); 
       break; 
     } 
    } 
    return SSH_OK; 
} 

Und dies ist die Ausgabe:

Size is 37980 
Size of buffer is 37980 
ssh_scp_read got 16384 
ssh_scp_read got 16384 
ssh_scp_read got 5212 
Error receiving file data: ssh_scp_read called under invalid state 

Jede Eingabe geschätzt würde.

Antwort

0

Ihre innere Schleife ändern

int len = size; 
do 
    { 
        rc = ssh_scp_read(scp, buff, size); 
        if (rc == SSH_ERROR) 
        { 
         fprintf(stderr, "Error receiving file data: %s\n", 
         ssh_get_error(gno_ses)); 
         break; 
        } 
        if (fwrite(buff, 1, rc, file) != size) 
        { 
         perror("Error at writting to file: "); 
         break; 
        } 
        printf("ssh_scp_read got %d\n",rc); 
        len-=rc; 
    } while (len); 
+0

Danke für den Code, es zu beheben Es ist der "ssh_scp_read", der unter ungültigem Zustand aufgerufen wurde, aber das war nicht das Problem, NULL-Garbabe wird immer noch in die Datei geschrieben. Es muss etwas mit dem Puffer oder dem Schreiben sein. – Vanreyn

1

Das Problem war, dass ich size Bytes schrieb, wenn in der Tat scp_scp_read() berichtet hatte, dass es weniger gelesen hatte, dass als:

rc = ssh_scp_read(scp, buff, size); 
fwrite(buff, 1, size, file) 

Das Update ist zu schreiben nur rc bytes:

  int len_loop = size; 
      int len; 
      do 
      { 
       rc = ssh_scp_read(scp, buff, size); 
       if (rc == SSH_ERROR || rc < 0) 
       { 
        fprintf(stderr, "Error receiving file data: %s\n", ssh_get_error(gno_ses)); 
        break; 
       } 
       else if (!rc) 
       { 
        break; 
       } 
       len = fwrite(buff, 1, rc, file); 
       if (len != rc) 
       { 
        perror("Error at writting to file: "); 
        break; 
       } 
       printf("ssh_scp_read got %d\n",rc); 
       len_loop -= rc; 
      } while(len_loop);