summaryrefslogtreecommitdiffstats
path: root/src/include/source_date_epoch.h
blob: 9080526f796dbc961e21e8ae3cd0a40286000946 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// SPDX-License-Identifier: GPL-2.0-or-later
/** @file
 * Functions to parse the "SOURCE_DATE_EPOCH" environment variable for reproducible build hacks, see
 *     https://reproducible-builds.org/docs/source-date-epoch/
 *//*
 * Authors:
 *   Patrick Storz <eduard.braun2@gmx.de>
 *
 * Copyright (C) 2019 Authors
 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
 */

#ifndef SEEN_SOURCE_DATE_EPOCH
#define SEEN_SOURCE_DATE_EPOCH

#include <sstream>
#include <iostream>
#include <cstdlib>
#include <ctime>

namespace ReproducibleBuilds {

/** parse current time from SOURCE_DATE_EPOCH environment variable
 *
 *  \return current time (or zero if SOURCE_DATE_EPOCH unset)
 */
time_t now()
{
    time_t now = 0;

    char *source_date_epoch = std::getenv("SOURCE_DATE_EPOCH");
    if (source_date_epoch) {
        std::istringstream iss(source_date_epoch);
        iss >> now;
        if (iss.fail() || !iss.eof()) {
            std::cerr << "Error: Cannot parse SOURCE_DATE_EPOCH as integer\n";
            exit(27);
        }
    }

    return now;
}

/** like ReproducibleBuilds::now() but returns a ISO 8601 formatted string
 *
 *  \return current time as ISO 8601 formatted string (or empty string if SOURCE_DATE_EPOCH unset)
 */
Glib::ustring now_iso_8601()
{
    Glib::ustring now_formatted;

    time_t now = ReproducibleBuilds::now();
    if (now) {
        const tm *now_struct;
        char buffer[25];

        now_struct = gmtime(&now);
        if (strftime(buffer, 25, "%Y-%m-%dT%H:%M:%S", now_struct)) {
            now_formatted = buffer;
        }
    }

    return now_formatted;
}

} // namespace ReproducibleBuilds

#endif // SEEN_SOURCE_DATE_EPOCH