Welcome to little lamb

Code » limb » master » tree

[master] / src / liblimb / shldata-rw.h / shldata_read.c

/* This file is part of limb                           https://lila.oss/limb
 * Copyright (C) 2023 Olivier Brunel                          jjk@jjacky.com */
/* SPDX-License-Identifier: GPL-2.0-only */
#include <errno.h>
#include <limb/buffer.h>
#include <limb/buffer-shldata.h>
#include <limb/djbunix.h>
#include <limb/shldata-rw.h>

static int
chkmagic(u32 magic, u32 wmagic)
{
    if (!wmagic) return shldata_chkmagic(magic);
    if (magic == wmagic) return 1;

    return (errno = EINVAL, 0);
}

int
shldata_read(u32 *magic, u64 *ver, unsigned *algo, unsigned *iter, stralloc *sa,
             int bfd, const char *file, const char *pwd, size_t plen)
{
    int ret = 0;
    char buf[4096];
    buffer b = BUFFER_INIT(&buffer_read, -1, buf, sizeof(buf));

    b.fd = openb_readat(bfd, file);
    if (b.fd < 0) return 0;

    buffer_shldata_ctx bsd = BUFFER_SHLDATA_ZERO;

    u32 wmagic;
    wmagic = (shldata_chkmagic(*magic)) ? *magic : 0;

    size_t salen = sa->len;
    if (!buffer_gethdr(&b, magic, ver)
            || !chkmagic(*magic, wmagic)
            || !buffer_shldata_getinit_sa(&b, pwd, plen, algo, iter, sa, &bsd)
            || !stralloc_readyplus(sa, buffer_shldata_datasize(&bsd))
            || !buffer_shldata_get(&b, sa->s + sa->len, buffer_shldata_datasize(&bsd), &bsd)
            || (sa->len += buffer_shldata_datasize(&bsd), 0)
            || !buffer_shldata_getfinal_sa(&b, sa, &bsd))
        goto err;

    salen = sa->len;
    ret = 1;
err:
    sa->len = salen;
    fd_close(b.fd);
    buffer_shldata_free(&bsd);
    return ret;
}