-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.h
157 lines (126 loc) · 4.57 KB
/
utils.h
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
157
/**
* \file
* Utility functions.
*/
#include <stdbool.h>
#include <stdio.h>
#include <sys/types.h>
/** Maximum path length, arbitrarily chosen. */
#define MTRIX_MAX_PATH ((size_t)1024U)
/** Maximum unix socket path length, based on Linux's maximum. */
#define MTRIX_MAX_UNIX_PATH ((size_t)108U)
/** Maximum length for URLs built by \ref build_url. */
#define MTRIX_MAX_URL_LEN ((size_t)1024U)
/** Maximum number of command arguments (excluding the command name). */
#define MTRIX_MAX_ARGS ((size_t)2U)
/** Helper macro for \ref build_url that creates a `const char *` array. */
#define BUILD_URL(url, ...) build_url(url, (const char *[]){__VA_ARGS__, NULL})
/** Program name, used as a prefix for log messages if non-`NULL`. */
extern const char *PROG_NAME;
/** Command name, used as a second prefix for log messages if non-`NULL`. */
extern const char *CMD_NAME;
/** Sets the output stream used by log functions and returns previous value. */
FILE *log_set(FILE *f);
/** Resizable buffer used by several functions. */
struct mtrix_buffer {
/** Owning pointer to the dynamically-allocated data. */
char *p;
/** Size of the buffer pointed to by \ref p. */
size_t n;
};
/**
* Writes the printf-style message to the error output.
* If non-null, \ref PROG_NAME and \ref CMD_NAME are prepended.
*/
void log_err(const char *fmt, ...);
/** \see log_err */
void log_errv(const char *fmt, va_list argp);
/**
* Similar to \ref log_err, but also logs `strerror(errno)`.
* `: %s\n` is appended, where `%s` is the result of `strerror(errno)`. `errno`
* is cleared.
*/
void log_errno(const char *fmt, ...);
/** See glibc's function. */
static const char *strchrnul(const char *s, int c);
/** See libbsd's function. */
static size_t strlcpy(char *restrict dst, const char *restrict src, size_t n);
/**
* Checks if a string has a certain prefix.
* \return The first character after the prefix or `NULL` if not a prefix.
*/
char *is_prefix(const char *prefix, const char *s);
/**
* Copies a value from an `argv`-style array.
* Checks for non-emptiness and length are performed and errors are logged.
*/
bool copy_arg(const char *name, struct mtrix_buffer dst, const char *src);
/** Concatenate \c n segments, with length checking. */
char *join_path(char v[static MTRIX_MAX_PATH], int n, ...);
/** Performs an \c open(2)s with \c O_CREAT followed by \c fopen. */
FILE *open_or_create(const char *path, const char *flags);
/**
* Repeatedly calls \c read(2) until all data are read.
* \returns \c true iff \c n bytes were read without error.
*/
bool read_all(int fd, void *p, size_t n);
/**
* Repeatedly calls \c write(2) until all data are written.
* \returns \c true iff \c n bytes were written without error.
*/
bool write_all(int fd, const void *p, size_t n);
/**
* Executes a command with optional input/output/error redirection.
* If any of the `f*` parameters are not `-1`, the corresponding file descriptor
* is replaced by it before the `exec` call.
* \param argv `execv`-style argument list.
* \param fin Substitute for `stdin`.
* \param fout Substitute for `stdout`.
* \param ferr Substitute for `stderr`.
*/
bool exec(const char *const *argv, int fin, int fout, int ferr);
/** Waits for `n` child processes to exit. */
bool wait_n(size_t n, const pid_t *p);
/** Replaces new-line characters with spaces. */
void join_lines(unsigned char *b, unsigned char *e);
/** Copies data to the buffer, reallocating if necessary. */
size_t mtrix_buffer_append(
const char *p, size_t size, size_t n, struct mtrix_buffer *b);
/** Joins several URL parts into one, limited to \ref MTRIX_MAX_URL_LEN. */
bool build_url(char *url, const char *const *v);
/**
* Performs a `GET` request.
* \param url Target RUL.
* \param b Output buffer, resized as required.
* \param verbose Emit debug output.
*/
bool request(const char *url, struct mtrix_buffer *b, bool verbose);
/** Data used for `POST` requests. */
typedef struct {
/** Target URL. */
const char *url;
/** Length of \ref data. */
size_t data_len;
/** `POST` payload. */
const char *data;
} post_request;
/**
* Performs a `POST` request.
* \param r `POST` url/payload.
* \param b Output buffer, resized as required.
* \param verbose Emit debug output.
*/
bool post(post_request r, bool verbose, struct mtrix_buffer *b);
static inline const char *strchrnul(const char *s, int c) {
while(*s && *s != c)
++s;
return s;
}
static inline size_t strlcpy(
char *restrict dst, const char *restrict src, size_t n)
{
const char *const p = dst;
while(n && (*dst++ = *src++))
--n;
return (size_t)(dst - p);
}