-/* $OpenBSD: main.c,v 1.91 2021/01/29 10:13:16 claudio Exp $ */
+/* $OpenBSD: main.c,v 1.92 2021/02/02 18:35:38 claudio Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
* An rsync repository.
*/
struct repo {
- char *host; /* hostname */
- char *module; /* module name */
- int loaded; /* whether loaded or not */
- size_t id; /* identifier (array index) */
+ char *repo; /* repository rsync URI */
+ char *local; /* local path name */
+ char *notify; /* RRDB notify URI if available */
+ size_t id; /* identifier (array index) */
+ int loaded; /* whether loaded or not */
};
size_t entity_queue;
{
const char *host, *mod;
size_t hostsz, modsz, i;
+ char *local;
struct repo *rp;
struct ibuf *b;
&mod, &modsz, NULL, NULL, NULL, uri))
errx(1, "%s: malformed", uri);
+ if (asprintf(&local, "%.*s/%.*s", (int)hostsz, host,
+ (int)modsz, mod) == -1)
+ err(1, "asprintf");
+
/* Look up in repository table. */
for (i = 0; i < rt.reposz; i++) {
- if (strlen(rt.repos[i].host) != hostsz)
- continue;
- if (strlen(rt.repos[i].module) != modsz)
- continue;
- if (strncasecmp(rt.repos[i].host, host, hostsz))
- continue;
- if (strncasecmp(rt.repos[i].module, mod, modsz))
+ if (strcmp(rt.repos[i].local, local))
continue;
+ free(local);
return &rt.repos[i];
}
rp = &rt.repos[rt.reposz++];
memset(rp, 0, sizeof(struct repo));
rp->id = rt.reposz - 1;
+ rp->local = local;
- if ((rp->host = strndup(host, hostsz)) == NULL ||
- (rp->module = strndup(mod, modsz)) == NULL)
- err(1, "strndup");
-
- i = rt.reposz - 1;
+ if ((rp->repo = strndup(uri, mod + modsz - uri)) == NULL)
+ err(1, "strdup");
if (!noop) {
- logx("%s/%s: pulling from network", rp->host, rp->module);
- if ((b = ibuf_dynamic(128, UINT_MAX)) == NULL)
+ if (asprintf(&local, "%s", rp->local) == -1)
+ err(1, "asprintf");
+ logx("%s: pulling from network", local);
+ if ((b = ibuf_dynamic(256, UINT_MAX)) == NULL)
err(1, NULL);
- io_simple_buffer(b, &i, sizeof(i));
- io_str_buffer(b, rp->host);
- io_str_buffer(b, rp->module);
-
+ io_simple_buffer(b, &rp->id, sizeof(rp->id));
+ io_str_buffer(b, local);
+ io_str_buffer(b, rp->repo);
ibuf_close(msgq, b);
+ free(local);
} else {
rp->loaded = 1;
- logx("%s/%s: using cache", rp->host, rp->module);
+ logx("%s: using cache", rp->local);
stats.repos++;
/* there is nothing in the queue so no need to flush */
}
{
char *nfile;
- uri += 8 + strlen(repo->host) + 1 + strlen(repo->module) + 1;
-
- if (asprintf(&nfile, "%s/%s/%s", repo->host, repo->module, uri) == -1)
+ uri += strlen(repo->repo) + 1;
+ if (asprintf(&nfile, "%s/%s", repo->local, uri) == -1)
err(1, "asprintf");
return nfile;
}
char *cp, *nfile;
/* Construct local path from filename. */
- /* We know this is host/module/... */
-
cp = strrchr(mft, '/');
assert(cp != NULL);
assert(cp - mft < INT_MAX);
*/
static void
queue_add_from_cert(struct msgbuf *procq, struct msgbuf *rsyncq,
- struct entityq *q, const char *rsyncuri, const char *rrdpuri)
+ struct entityq *q, const struct cert *cert)
{
- char *nfile;
const struct repo *repo;
+ char *nfile;
- if (rsyncuri == NULL)
- return;
-
- /* Look up the repository. */
- repo = repo_lookup(rsyncq, rsyncuri);
- nfile = repo_filename(repo, rsyncuri);
+ repo = repo_lookup(rsyncq, cert->mft);
+ nfile = repo_filename(repo, cert->mft);
entityq_add(procq, q, nfile, RTYPE_MFT, repo, NULL, 0, NULL);
}
* process the MFT.
*/
queue_add_from_cert(procq, rsyncq,
- q, cert->mft, cert->notify);
+ q, cert);
} else
st->certs_invalid++;
cert_free(cert);
err(1, "%s: chdir", cachedir);
for (i = 0; i < rt.reposz; i++) {
- if (asprintf(&argv[0], "%s/%s", rt.repos[i].host,
- rt.repos[i].module) == -1)
+ if (asprintf(&argv[0], "%s", rt.repos[i].local) == -1)
err(1, NULL);
argv[1] = NULL;
if ((fts = fts_open(argv, FTS_PHYSICAL | FTS_NOSTAT,
if (c == 0) {
for (i = j = 0; i < rt.reposz; i++)
- if (!rt.repos[i].loaded)
+ if (!rt.repos[i].loaded) {
+ logx("pending repo %s",
+ rt.repos[i].local);
j++;
+ }
logx("period stats: %zu pending repos", j);
logx("period stats: %zu pending entries", entity_queue);
continue;
io_simple_read(rsync, &i, sizeof(size_t));
io_simple_read(rsync, &ok, sizeof(ok));
assert(i < rt.reposz);
+
assert(!rt.repos[i].loaded);
rt.repos[i].loaded = 1;
if (ok)
- logx("%s/%s: loaded from network",
- rt.repos[i].host, rt.repos[i].module);
+ logx("%s: loaded from network",
+ rt.repos[i].local);
else
- logx("%s/%s: load from network failed, "
- "fallback to cache",
- rt.repos[i].host, rt.repos[i].module);
+ logx("%s: load from network failed, "
+ "fallback to cache", rt.repos[i].local);
stats.repos++;
entityq_flush(&procq, &q, &rt.repos[i]);
}
/* Memory cleanup. */
for (i = 0; i < rt.reposz; i++) {
- free(rt.repos[i].host);
- free(rt.repos[i].module);
+ free(rt.repos[i].local);
+ free(rt.repos[i].repo);
}
free(rt.repos);
-/* $OpenBSD: rsync.c,v 1.14 2021/01/12 09:22:11 claudio Exp $ */
+/* $OpenBSD: rsync.c,v 1.15 2021/02/02 18:35:38 claudio Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
{
size_t id, i, idsz = 0;
ssize_t ssz;
- char *host = NULL, *mod = NULL, *uri = NULL,
- *dst = NULL, *path, *save, *cmd;
+ char *uri = NULL, *dst = NULL, *path, *save, *cmd;
const char *pp;
pid_t pid;
char *args[32];
if (unveil(NULL, NULL) == -1)
err(1, "unveil");
+ if (pledge("stdio cpath proc exec", NULL) == -1)
+ err(1, "pledge");
+
/* Initialise retriever for children exiting. */
if (sigemptyset(&mask) == -1)
/* Read host and module. */
- io_str_read(fd, &host);
- io_str_read(fd, &mod);
- assert(host);
- assert(mod);
+ io_str_read(fd, &dst);
+ io_str_read(fd, &uri);
+ assert(dst);
+ assert(uri);
/*
* Create source and destination locations.
* will not build the destination for us.
*/
- if (mkdir(host, 0700) == -1 && EEXIST != errno)
- err(1, "%s", host);
-
- if (asprintf(&dst, "%s/%s", host, mod) == -1)
- err(1, NULL);
- if (mkdir(dst, 0700) == -1 && EEXIST != errno)
+ if (mkpath(dst))
err(1, "%s", dst);
- if (asprintf(&uri, "rsync://%s/%s", host, mod) == -1)
- err(1, NULL);
-
/* Run process itself, wait for exit, check error. */
if ((pid = fork()) == -1)
/* Clean up temporary values. */
- free(mod);
free(dst);
- free(host);
}
/* No need for these to be hanging around. */