/*
* Load and unload nsscash files
*
* Copyright (C) 2019 Simon Ruderich
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
#include "file.h"
#include
#include
#include
#include
#include
#include
#include
#include
bool map_file(const char *path, struct file *f) {
// Fully initialize the struct for unmap_file() and other users
memset(f, 0, sizeof(*f));
f->fd = open(path, O_RDONLY | O_CLOEXEC);
if (f->fd < 0) {
goto fail;
}
struct stat s;
if (fstat(f->fd, &s)) {
goto fail;
}
f->size = (size_t)s.st_size; // for munmap()
// mmap is used for speed and simple random access
void *x = mmap(NULL, f->size, PROT_READ, MAP_PRIVATE, f->fd, 0);
if (x == MAP_FAILED) {
goto fail;
}
const struct header *h = x;
f->header = h;
// Check MAGIC
if (memcmp(h->magic, MAGIC, sizeof(h->magic))) {
errno = EINVAL;
goto fail;
}
// Only version 1 is supported at the moment; this will also prevent
// running on big-endian systems which is currently not possible
if (h->version != 1) {
errno = EINVAL;
goto fail;
}
return true;
fail: {
int save_errno = errno;
unmap_file(f);
errno = save_errno;
return false;
}
}
void unmap_file(struct file *f) {
if (f->header != NULL) {
munmap((void *)f->header, f->size);
f->header = NULL;
}
if (f->fd >= 0) {
close(f->fd);
f->fd = -1;
}
}