There are many other threads talking about binary file corruption, yet they all seem unrelated to my problem somehow.
I have a C program that downloads/reads files.
Because I do not write all the files I get into a file, the function that I use with curl rather stores data into a string. I may be free to write this string into a file, or not, later.
I have a binary file. I put it on a FTP.
If I download it via a ftp client like filezilla, it contains the right things (that is, the same characters I get when I cat my compiled binary) If I use a curl command line to download the file, it contains the right things as well.
If I use my program to download such a file, it will only contain a string like "ELF" followed by 3 unwritable/unreadable characters.
It's important to note that this only happens with binary files. Text files were transferred/read just file. It's also important to know that it seems to be the data that is passed to my function from curl that's already false: if I put a printf of the data in my write function, I see the same ELF + 3 unreadable chars string, therefore the method I use later on to write it into a file isn't in question.
When I use verbose, curl says it's in binary mode yet the binary isn't properly transferred.
Here is what I have so far, works fine with any file that's not binary, will always be garbage otherwise. Thanks in advance:
struct string
{
char *ptr;
size_t len;
};
char *usr_psswd(char *user, char *psswd)
{
char *usrpsswd;
usrpsswd = (char *)malloc(strlen(user) + strlen(psswd) + 2);
int i = 0;
int j = 0;
while (user[i])
{
usrpsswd[i] = user[i];
++i;
}
usrpsswd[i++] = ':';
while (psswd[j])
{
usrpsswd[i] = psswd[j];
++i;
++j;
}
usrpsswd[i] = 0;
return usrpsswd;
}
void init_string(struct string *s)
{
s->len = 0;
s->ptr = malloc(s->len+1);
if (s->ptr == NULL)
{
fprintf(stderr, "malloc() failed\n");
exit(EXIT_FAILURE);
}
s->ptr[0] = '\0';
}
size_t writefunc(void *ptr, size_t size, size_t nmemb, struct string *s)
{
size_t new_len = s->len + size*nmemb;
s->ptr = realloc(s->ptr, new_len+1);
if (s->ptr == NULL)
{
fprintf(stderr, "realloc() failed\n");
exit(EXIT_FAILURE);
}
memcpy(s->ptr+s->len, ptr, size*nmemb);
s->ptr[new_len] = '\0';
s->len = new_len;
return size*nmemb;
}
char *curl_get(char *addr, t_data *data)
{
CURL *curl;
CURLcode res;
char *rtrn;
curl = curl_easy_init();
if(curl)
{
struct string s;
init_string(&s);
curl_easy_setopt(curl, CURLOPT_URL, addr);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
curl_easy_setopt(curl, CURLOPT_PORT, 21);
curl_easy_setopt(curl, CURLOPT_USERPWD, usr_psswd(data->login, data->password));
res = curl_easy_perform(curl);
if(res != CURLE_OK)
{
printf("curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
free(s.ptr);
curl_easy_cleanup(curl);
return NULL;
}
rtrn = strdup(s.ptr);
free(s.ptr);
curl_easy_cleanup(curl);
}
return rtrn;
}