Search code examples
cunixftpbinaryfilesfread

How do you convert binary file to bytes?


I'm building a simple ftp which allows the user to ask basic commands of a unix server (eg: cd home/file/) and upload files to the server and download files from the server. I have gotten the basic commands to work and print between client and server, but copying files that aren't text is a challenge.

My current code for the get function is as follows:

Cli6.c

    else if (strcmp(tokens[0], "get") == 0) {
        char *filecpy = convertfile("mtg.jpg");
        printf("%s .... %d\n", filecpy, strlen(filecpy));
    }

FTP.c

char *convertfile(const char *filename) {
    FILE *fileptr; 
    char *buffer;
    long filen;
    size_t result;
     
    fileptr = fopen(filename, "rb");
     
    fseek(fileptr, 0, SEEK_END);
    filen = ftell(fileptr);
    rewind(fileptr);
     
    printf("File size: %d\n", filen);
     
    buffer = (char *)malloc(filen + 1); // this is only allocating 8bytes
     
    fread(buffer,filen, 1,fileptr);
    printf("Buffer: %s\n", buffer);
    close(fileptr);
     
     
    /*
    char *c; 
    char *buffer;
    fileptr = fopen(filename, "rb");
    while (c != EOF) {
        fread(&c, (size_t)1, (size_t)1, fileptr);
        buffer[c]++;
        c = fgetc(fileptr);
        sprintf(buffer[strlen(buffer)], "%c", c);
    }
    close(fileptr);
    */         
     
    return buffer;
}
 
//convert bytes to file
void convertbytes(const char *buffer, const char *filename) {
    FILE *fileptr; 
    printf("%s .... %d\n", buffer, strlen(buffer));
    fileptr = fopen(filename, "wb");
    //for (int i = 0; i < sizeof(buffer); i++) {
    fwrite(buffer, 1, strlen(buffer), fileptr);
        //printf("%c :: %d\n", buffer[i], i);
    //}
     
    close(fileptr);
}

Right now, I'm only trying to copy the files correctly, so no sending over to server yet. With this code, I can copy text files fine, but another file, such as a .o file containing 6.0kb, will be copied with 8 bytes. I'm attempting to convert the file to bytes (ready to send somewhere) and then building a file from bytes. Am I approaching this wrong? Should I be using other means to do this? What is the correct way of build a simple FTP?


Solution

  • This is because your buffer is filled with binary data. Binary data can contain a null character (\0, or 0x00), and it is not compatible with strlen, since strlen will stop at the first null character.

    You can try something like that to return the actual lenght of the file:

    struct buffer {
        char  *buffer;
        size_t filelen;
    }
    
    struct buffer *convertfile(const char *filename)
    {
         ...
    }
    

    And:

    struct buffer * filecpy = convertfile("mtg.jpg");
    printf("%.*s .... %d\n",filecpy.filelen, filecpy.buffer, filecpy.filelen);