I have to create a request datagram (RRQ) for a Tftp client like this:
But i can't use a struct because the fields have variable length.
i tried the struct and something iterating on a char.
I have to create a request datagram (RRQ) for a Tftp client like this:
But i can't use a struct because the fields have variable length.
i tried the struct and something iterating on a char.
 
    
     
    
    Create an array of bytes and append to it. You can make this easier by using pointer arithmetic to keep track of where you've written, kind of like a cursor.
We can make life easier for ourselves by tracking where in the request memory the archive and mode strings start so we can easily find them later.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
typedef struct {
    char *archive;
    char *mode;
    char *request;
} Read_Request;
Read_Request *read_request_create(const char *archive, const char *mode) {
    Read_Request *rrq = malloc(sizeof(Read_Request));
    // Allocate sufficient memory for the opcode and both strings,
    // including the terminating nulls.
    rrq->request = malloc(2 + strlen(archive) + 1 + strlen(mode) + 1);
    // Start the request with the opcode.
    // 2 byte network byte order integer.
    uint16_t opcode = htons(1);
    memcpy(rrq->request, &opcode, sizeof(opcode));
    // Put the start of the archive 2 bytes in, just after the opcode.
    rrq->archive = rrq->request + 2;
    // Copy the archive string into position.
    strcpy(rrq->archive, archive);
    // Put the start of the mode just after the archive and its null byte.
    rrq->mode = rrq->archive + strlen(archive) + 1;
    // Append the mode.
    strcpy(rrq->mode, mode);
    return rrq;
}
Then printing is easy. Print the 2 byte opcode. Then since a C string stops at a null byte, we can simply print the archive and mode strings.
void read_request_print(Read_Request *rrq) {
    // Turn the first two bytes (the opcode) into two hex characters.
    unsigned char *opcode = (unsigned char *)rrq->request;
    printf("opcode: %0x%0x\n", opcode[0], opcode[1]);
    printf("archive: '%s'\n", rrq->archive);
    printf("mode: '%s'\n", rrq->mode);
}
int main() {
    Read_Request *rrq = read_request_create("archive", "mode");
    read_request_print(rrq);
}
