Reputation: 3
I want sign a tar.gz file and verify the signature for do this i put a signature (in char) in my file. Then i have an another executable who check the sign and if she is good delete this, and to do that i get the content of the file whitout my signature and copy on an other file that a create.
But here is the problem, When a do this my tar.gz original file make a size of 141 and my newly created file make a size of 140. Then when a decompress them i have this error message:
gzip: stdin: unexpected end of file tar:
Child returned status 1 tar:
Error is not recoverable: exiting now
I think when i get the content i forgot a charactere. I tried to use clearerr or feof whitout success.
This is my code for get the content of the signed file:
#define SIZE_SIGNATURE (423)
int get_size(char *file)
{
struct stat sb;
int size = 0;
if (stat(file, &sb) == -1) {
fprintf(stderr, "Cant access the %s file\n", file);
return (-1);
}
size = sb.st_size - SIZE_SIGNATURE;
size = size / 4;
if (size <= 0) {
fprintf(stderr, "The content of the file is invalid\n");
return (-1);
}
return (size);
}
int *get_content(char *file, int size)
{
FILE *fp = NULL;
int *content = NULL;
int i = 0;
content = malloc(sizeof(int) * size);
if (!content) {
fprintf(stderr, "Error, malloc fail\n");
return (NULL);
}
fp = fopen(file,"rb");
if (!fp) {
fprintf(stderr, "Cant open %s file\n", file);
return (NULL);
}
fread(content, sizeof(int), size, fp);
fclose(fp);
return (content);
}
And when i have created my new file i put the content on them like this:
fp = fopen(new_name, "a");
if (!fp) {
fprintf(stderr, "A problem has occured during file creation.\n Cant delete signature\n");
free(new_name);
return;
}
fwrite(content, sizeof(int), size, fp);
Why i do: size = size / 4 (i dont know if is the thing to do)
He is a little code for understanding the thing i simply put three int in non lisible charactere
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
void ecriture1()
{
FILE* F;
int a = 5;
int b = 6;
int d = 42;
F = fopen("test.bin","wb");
fwrite(&a,sizeof(int),1,F);
fwrite(&d,sizeof(int),1,F);
fwrite(&b,sizeof(int),1,F);
fclose(F);
}
void lecture1()
{
int *tab;
int i = 0;
int size;
struct stat sb;
FILE* F;
stat("test.bin", &sb);
F = fopen("test.bin","rb");
size = sb.st_size;
tab = malloc(sizeof(int) * size);
while (i < size) {
fread(&tab[i], sizeof(int), 1, F);
i++;
}
for (i = 0; i < size; i++)
printf("[i] = %d,", tab[i]);
printf("\n");
fclose(F);
}
int main()
{
ecriture1();
lecture1();
return 0;
}
He is the resultat when i dont put the / 4:
[i] = 5,[i] = 42,[i] = 6,[i] = 0,[i] = 0,[i] = 0,[i] = 0,[i] = 0,[i] = 0,[i] = 0,[i] = 0,[i] = 0,
And when i put / 4:
[i] = 5,[i] = 42,[i] = 6,
EDIT:
In my programe when i delete the / 4 and i decompresse the new .tar.gz i have this error message:
gzip: stdin: invalid compressed data--length error
tar: Child returned status 1
tar: Error is not recoverable: exiting now
So i think without error on my part that i should put the / 4 but i cant explain this.
Upvotes: 0
Views: 4081
Reputation: 815
You have a rounding error because you divide the size by 4.
I think the reason why you do size / 4
is because you later do sizeof(int) * size
and if you have 4 byte integers then that will cause your size to be 4 times larger than you want. So I think you wrote two bugs there that cancel each other out.
I would suggest you remove the / 4
as well as also removing the sizeof(int) *
and thus always just let size be the byte count.
As a bonus, this will remove the rounding error that you might have which is probably the whole reason for your problem. Because 141/4 = 35,25
which will be rounded to 35
. Then 35 * sizeof(int) = 35 * 4 = 140
.
Also I would not recommend storing arbitrary binary data of arbitrary size in an array of int
because an int
array should have a size evenly divisible by 4. I would probably go for a char *
or just a void *
rather than int *
.
Upvotes: 1