aboutsummaryrefslogtreecommitdiffstats
path: root/l2md.h
blob: ffdd2d434d0a44a03d45efffa1c7b14b71116b64 (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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/* 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 */