blob: ffdd2d434d0a44a03d45efffa1c7b14b71116b64 [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (C) 2019 Daniel Borkmann <daniel@iogearbox.net> */
#ifndef L2MD_H
#define L2MD_H
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <limits.h>
#include <git2.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
/* libgit2 backwards compat crap. */
#ifndef GIT_OBJECT_BLOB
# define GIT_OLD_VERSION 1
#endif
#ifdef GIT_OLD_VERSION
# define GIT_OBJECT_BLOB GIT_OBJ_BLOB
# define GIT_OBJECT_COMMIT GIT_OBJ_COMMIT
# define git_error_last giterr_last
#endif
#ifndef __check_format_printf
# define __check_format_printf(pos_fmtstr, pos_fmtargs) \
__attribute__ ((format (printf, (pos_fmtstr), (pos_fmtargs))))
#endif
#ifndef __noreturn
# define __noreturn __attribute__ ((noreturn))
#endif
#define REPOS "repos"
#define OIDS "oids"
#define MAIL "m"
struct config;
struct config_repo;
struct mail_ops {
const char *name;
void (*bootstrap)(struct config *cfg);
void (*new_mail)(struct config_repo *repo, uint32_t url,
const char *oid, const void *raw, size_t len);
void (*set_defaults)(struct config *cfg);
};
struct config_general {
char out[PATH_MAX];
char base[PATH_MAX];
uint32_t period;
};
struct config_url {
char path[PATH_MAX];
char oid[GIT_OID_HEXSZ + 1];
bool oid_known;
};
struct config_repo {
char name[128];
char out[PATH_MAX];
git_repository *git;
struct config_url *urls;
uint32_t urls_num;
uint32_t initial_import;
bool limit;
bool sync_enabled;
};
struct config {
struct config_general general;
struct config_repo *repos;
uint32_t repos_num;
const struct mail_ops *ops;
bool oneshot;
};
#define repo_for_each(cfg, repo, i) \
for (repo = &cfg->repos[(i = 0)]; i < cfg->repos_num; \
repo = &cfg->repos[++i]) \
if (!repo->sync_enabled) { \
verbose("skipping disabled repo %s\n", repo->name); \
continue; \
} \
else
#define url_for_each(repo, url, i) \
for (url = &repo->urls[(i = 0)]; i < repo->urls_num; \
url = &repo->urls[++i])
#define repo_last(cfg) \
&cfg->repos[cfg->repos_num - 1]
#define url_last(repo) \
&repo->urls[repo->urls_num - 1]
extern pid_t own_pid;
extern bool verbose_enabled;
extern const struct mail_ops ops_maildir;
extern const struct mail_ops ops_pipe;
struct config *config_init(int argc, char **argv);
void config_uninit(struct config *cfg);
void bootstrap_env(struct config *cfg);
void sync_env(struct config *cfg);
void sync_mail(struct config *cfg);
void sync_done(struct config *cfg);
void repo_clone(struct config_repo *repo, struct config_url *url, const char *target);
void repo_pull(struct config_repo *repo, struct config_url *url, const char *target);
void repo_walk_files(struct config *cfg, struct config_repo *repo, uint32_t url,
const char *path, const char *oid_last, char *oid_done,
void (*repo_walker)(struct config *cfg, struct config_repo *repo,
uint32_t url, const char *oid,
const void *raw, size_t len));
void repo_local_path(struct config *cfg, struct config_repo *repo,
struct config_url *url, char *out, size_t len);
void repo_local_oid(struct config *cfg, struct config_repo *repo,
struct config_url *url, char *out, size_t len);
void *xmalloc(size_t size);
void *xzmalloc(size_t size);
void *xrealloc(void *old, size_t size);
void xfree(void *ptr);
void xmkdir1(const char *path);
void xmkdir2(const char *base, const char *name);
void xmkdir1_with_subdirs(const char *path);
void xpipe(int pipefd[2]);
void xwrite(int fd, const char *to, size_t len);
int xread_file(const char *file, char *to, size_t len, bool fatal);
int xwrite_file(const char *file, const char *to, size_t len, bool fatal);
int timeval_sub(struct timeval *res, struct timeval *x,
struct timeval *y);
size_t __strlcpy(char *dest, const char *src, size_t size);
int slprintf(char *dst, size_t size, const char *fmt, ...);
void verbose(const char *format, ...) __check_format_printf(1, 2);
void panic(const char *format, ...) __check_format_printf(1, 2) __noreturn;
void warn(const char *format, ...) __check_format_printf(1, 2);
void die(void) __noreturn;
#endif /* L2MD_H */