nbos

nbos

https://git.tonybtw.com/nbos.git git://git.tonybtw.com/nbos.git
1,868 bytes raw
1
#define _GNU_SOURCE
2
#include "fetch.h"
3
4
#include <errno.h>
5
#include <stdio.h>
6
#include <string.h>
7
8
#include "hash.h"
9
#include "run.h"
10
11
/**
12
 * fetch() - Download a package's source tarball and verify its hash.
13
 * @p: Package whose @src URL and @sha256 are used.
14
 * @dest_path: Destination path on disk.
15
 *
16
 * Shells out to curl(1) so nb does not link libcurl. The downloaded
17
 * file's sha256 is compared against @p->sha256.
18
 *
19
 * Return: FETCH_OK_VAL on success, a tagged error otherwise.
20
 */
21
fetch_error fetch(const pkg *p, const char *dest_path) {
22
    // TODO: replace this with execvpe or libcurl
23
    char *const argv[] = {
24
        "/usr/bin/curl",
25
        "-fsSL",
26
        "--retry", "3",
27
        "--retry-delay", "2",
28
        "-o", (char *)dest_path,
29
        (char *)p->src,
30
        nullptr,
31
    };
32
33
    char *const envp[] = { nullptr };
34
35
    char log_path[4096];
36
    int n = snprintf(log_path, sizeof(log_path), "%s.fetch.log", dest_path);
37
    if (n < 0 || (size_t)n >= sizeof(log_path)) {
38
        return (fetch_error){
39
            .kind = FETCH_E_IO,
40
            .url = p->src,
41
            .errno_val = ENAMETOOLONG,
42
        };
43
    }
44
45
    run_error rerr = run("/usr/bin/curl", argv, envp, nullptr, log_path);
46
    if (rerr.kind != RUN_OK) {
47
        fetch_error fe = {
48
            .kind = FETCH_E_NETWORK,
49
            .url = p->src,
50
            .errno_val = 0,
51
        };
52
        if (rerr.kind == RUN_E_SPAWN || rerr.kind == RUN_E_IO) {
53
            fe.kind = FETCH_E_IO;
54
            fe.errno_val = rerr.errno_val;
55
        }
56
        return fe;
57
    }
58
59
    char actual[65] = {0};
60
    if (!sha256_verify_file(dest_path, p->sha256, actual)) {
61
        return (fetch_error){
62
            .kind = FETCH_E_HASH_MISMATCH,
63
            .url = p->src,
64
            .expected_sha = p->sha256,
65
            .actual_sha = strdup(actual),
66
        };
67
    }
68
69
    return FETCH_OK_VAL;
70
}