119 lines
2.4 KiB
C
119 lines
2.4 KiB
C
#include <zyb/extract.h>
|
|
|
|
// libc
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <limits.h>
|
|
|
|
// libzepkg
|
|
#include <crypt/sha256.h>
|
|
|
|
int zyb_extract_leader(FILE *fptr, struct lead *leader) {
|
|
if (fptr == NULL)
|
|
return 1;
|
|
|
|
char magic[4];
|
|
size_t bytes = fread(magic, 1, 4, fptr);
|
|
if (bytes != 4)
|
|
return 1;
|
|
|
|
if (strcmp(magic, ZYB_MAGIC))
|
|
return 1;
|
|
|
|
bytes = fread(&leader + 4, 1, sizeof(struct lead) - 4, fptr);
|
|
if (bytes != sizeof(struct lead) - 4)
|
|
return 1;
|
|
|
|
if (leader->version != ZYB_FORMAT_VER)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int zyb_extract_dependency(FILE *fptr, struct dependency *dep) {
|
|
if (fptr == NULL)
|
|
return 1;
|
|
|
|
char magic[4];
|
|
size_t bytes = fread(magic, 1, 4, fptr);
|
|
if (bytes != 4)
|
|
return 1;
|
|
|
|
if (strcmp(magic, ZYB_DEP_MAGIC))
|
|
return 1;
|
|
|
|
bytes = fread(&dep + 4, 1, sizeof(struct dependency) - 4, fptr);
|
|
if (bytes != sizeof(struct dependency) - 4)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int zyb_extract_header(FILE *fptr, struct zyb_header *header) {
|
|
if (fptr == NULL)
|
|
return 1;
|
|
|
|
struct lead leader;
|
|
int ret;
|
|
if ((ret = zyb_extract_leader(fptr, &leader)))
|
|
return ret;
|
|
header->leader = leader;
|
|
|
|
if (header->leader.dependencies > 0) {
|
|
for (int i = 0; i < header->leader.dependencies; i++) {
|
|
header = realloc(header, sizeof(header) + sizeof(struct dependency));
|
|
|
|
struct dependency dep;
|
|
if ((ret = zyb_extract_dependency(fptr, &dep)))
|
|
return ret;
|
|
header->dependencies[i] = dep;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int zyb_extract_file(FILE *fptr, char *dir) {
|
|
if (fptr == NULL)
|
|
return 1;
|
|
|
|
char magic[4];
|
|
size_t bytes = fread(magic, 1, 4, fptr);
|
|
if (bytes != 4)
|
|
return 1;
|
|
|
|
if (strcmp(magic, ZYB_FILE_MAGIC))
|
|
return 1;
|
|
|
|
// Read path in chunks of 2 bytes (to account for alignment)
|
|
char *path = malloc(PATH_MAX);
|
|
for (int i = 0; i < PATH_MAX; i += 2) {
|
|
fread(path + i, 1, 2, fptr);
|
|
if (path[i] == '\0' || path[i + 1] == '\0')
|
|
goto eos;
|
|
}
|
|
// If it reaches this point, means the string is longer than PATH_MAX
|
|
return 1;
|
|
|
|
eos: // End of string;
|
|
// Read rest of header
|
|
mode_t permissions;
|
|
bytes = fread(&permissions, sizeof(mode_t), 1, fptr);
|
|
if (bytes != sizeof(mode_t))
|
|
return 1;
|
|
|
|
off_t size;
|
|
bytes = fread(&size, sizeof(off_t), 1, fptr);
|
|
if (bytes != sizeof(off_t))
|
|
return 1;
|
|
|
|
unsigned char checksum[32];
|
|
bytes = fread(&checksum, 1, 32, fptr);
|
|
if (bytes != 32)
|
|
return 1;
|
|
|
|
// Move pointer 2 bytes to account for padding
|
|
fseek(fptr, 2, SEEK_CUR);
|
|
|
|
return 0;
|
|
}
|