#include "cache.h"
#include "trace2/tr2_tbuf.h"
#include "trace2/tr2_sid.h"
#define TR2_ENVVAR_PARENT_SID "GIT_TRACE2_PARENT_SID"
static struct strbuf tr2sid_buf = STRBUF_INIT;
static int tr2sid_nr_git_parents;
static void tr2_sid_append_my_sid_component(void)
{
const struct git_hash_algo *algo = &hash_algos[GIT_HASH_SHA1];
struct tr2_tbuf tb_now;
git_hash_ctx ctx;
pid_t pid = getpid();
unsigned char hash[GIT_MAX_RAWSZ + 1];
char hex[GIT_MAX_HEXSZ + 1];
char hostname[HOST_NAME_MAX + 1];
tr2_tbuf_utc_datetime(&tb_now);
strbuf_addstr(&tr2sid_buf, tb_now.buf);
strbuf_addch(&tr2sid_buf, '-');
if (xgethostname(hostname, sizeof(hostname)))
strbuf_add(&tr2sid_buf, "Localhost", 9);
else {
algo->init_fn(&ctx);
algo->update_fn(&ctx, hostname, strlen(hostname));
algo->final_fn(hash, &ctx);
hash_to_hex_algop_r(hex, hash, algo);
strbuf_addch(&tr2sid_buf, 'H');
strbuf_add(&tr2sid_buf, hex, 8);
}
strbuf_addf(&tr2sid_buf, "-P%08"PRIx32, (uint32_t)pid);
}
static void tr2_sid_compute(void)
{
const char *parent_sid;
if (tr2sid_buf.len)
return;
parent_sid = getenv(TR2_ENVVAR_PARENT_SID);
if (parent_sid && *parent_sid) {
const char *p;
for (p = parent_sid; *p; p++)
if (*p == '/')
tr2sid_nr_git_parents++;
strbuf_addstr(&tr2sid_buf, parent_sid);
strbuf_addch(&tr2sid_buf, '/');
tr2sid_nr_git_parents++;
}
tr2_sid_append_my_sid_component();
setenv(TR2_ENVVAR_PARENT_SID, tr2sid_buf.buf, 1);
}
const char *tr2_sid_get(void)
{
if (!tr2sid_buf.len)
tr2_sid_compute();
return tr2sid_buf.buf;
}
int tr2_sid_depth(void)
{
if (!tr2sid_buf.len)
tr2_sid_compute();
return tr2sid_nr_git_parents;
}
void tr2_sid_release(void)
{
strbuf_release(&tr2sid_buf);
}