/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (C) 2019 Daniel Borkmann */ #ifndef L2MD_H #define L2MD_H #include #include #include #include #include #include #include #include /* 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 */