1 /*
2  * mbsync - mailbox synchronizer
3  * Copyright (C) 2000-2002 Michael R. Elkins <me@mutt.org>
4  * Copyright (C) 2002-2006,2010-2012 Oswald Buddenhagen <ossi@users.sf.net>
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  * As a special exception, mbsync may be linked with the OpenSSL library,
20  * despite that library's more restrictive license.
21  */
22 
23 #ifndef COMMON_H
24 #define COMMON_H
25 
26 #include <autodefs.h>
27 
28 #include <sys/types.h>
29 #include <stdarg.h>
30 #include <stdio.h>
31 #include <time.h>
32 
33 typedef unsigned char uchar;
34 typedef unsigned short ushort;
35 typedef unsigned int uint;
36 typedef unsigned long ulong;
37 
38 #define as(ar) (sizeof(ar)/sizeof(ar[0]))
39 
40 #define stringify__(x) #x
41 #define stringify(x) stringify__(x)
42 
43 // From https://stackoverflow.com/a/62984543/3685191
44 #define deparen(x) esc_(ish_ x)
45 #define esc_(...) esc__(__VA_ARGS__)
46 #define esc__(...) van_ ## __VA_ARGS__
47 #define ish_(...) ish_ __VA_ARGS__
48 #define van_ish_
49 
50 #define shifted_bit(in, from, to) \
51 	((int)(((uint)(in) / (from > to ? from / to : 1) * (to > from ? to / from : 1)) & to))
52 
53 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
54 # define ATTR_UNUSED __attribute__((unused))
55 # define ATTR_NORETURN __attribute__((noreturn))
56 # define ATTR_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var)))
57 #else
58 # define ATTR_UNUSED
59 # define ATTR_NORETURN
60 # define ATTR_PRINTFLIKE(fmt,var)
61 #endif
62 
63 #if defined(__clang__)
64 # define DO_PRAGMA__(text) _Pragma(#text)
65 # define DIAG_PUSH DO_PRAGMA__(clang diagnostic push)
66 # define DIAG_POP DO_PRAGMA__(clang diagnostic pop)
67 # define DIAG_DISABLE(text) DO_PRAGMA__(clang diagnostic ignored text)
68 #elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5)
69 # define DO_PRAGMA__(text) _Pragma(#text)
70 # define DIAG_PUSH DO_PRAGMA__(GCC diagnostic push)
71 # define DIAG_POP DO_PRAGMA__(GCC diagnostic pop)
72 # define DIAG_DISABLE(text) DO_PRAGMA__(GCC diagnostic ignored text)
73 #else
74 # define DIAG_PUSH
75 # define DIAG_POP
76 # define DIAG_DISABLE(text)
77 #endif
78 
79 #if __GNUC__ >= 7 || defined(__clang__)
80 # define FALLTHROUGH __attribute__((fallthrough));
81 #else
82 # define FALLTHROUGH
83 #endif
84 
85 #ifdef __GNUC__
86 # define INLINE __inline__
87 #else
88 # define INLINE
89 #endif
90 
91 #define EXE "mbsync"
92 
93 /* main.c */
94 
95 #define DEBUG_CRASH     0x01
96 #define DEBUG_MAILDIR   0x02
97 #define DEBUG_NET       0x04
98 #define DEBUG_NET_ALL   0x08
99 #define DEBUG_SYNC      0x10
100 #define DEBUG_MAIN      0x20
101 #define DEBUG_DRV       0x40
102 #define DEBUG_DRV_ALL   0x80
103 #define DEBUG_ALL       (0xFF & ~(DEBUG_NET_ALL | DEBUG_DRV_ALL))
104 #define QUIET           0x100
105 #define VERYQUIET       0x200
106 #define PROGRESS        0x400
107 #define VERBOSE         0x800
108 #define KEEPJOURNAL     0x1000
109 #define ZERODELAY       0x2000
110 #define FORCEASYNC      0x4000
111 
112 extern int DFlags;
113 extern int JLimit;
114 extern int UseFSync;
115 extern char FieldDelimiter;
116 
117 extern int Pid;
118 extern char Hostname[256];
119 extern const char *Home;
120 
121 extern uint BufferLimit;
122 
123 extern int new_total[2], new_done[2];
124 extern int flags_total[2], flags_done[2];
125 extern int trash_total[2], trash_done[2];
126 
127 void stats( void );
128 
129 /* util.c */
130 
131 void ATTR_PRINTFLIKE(2, 0) vdebug( int, const char *, va_list va );
132 void ATTR_PRINTFLIKE(2, 0) vdebugn( int, const char *, va_list va );
133 void ATTR_PRINTFLIKE(1, 2) info( const char *, ... );
134 void ATTR_PRINTFLIKE(1, 2) infon( const char *, ... );
135 void ATTR_PRINTFLIKE(1, 2) progress( const char *, ... );
136 void ATTR_PRINTFLIKE(1, 2) notice( const char *, ... );
137 void ATTR_PRINTFLIKE(1, 2) warn( const char *, ... );
138 void ATTR_PRINTFLIKE(1, 2) error( const char *, ... );
139 void ATTR_PRINTFLIKE(1, 0) vsys_error( const char *, va_list va );
140 void ATTR_PRINTFLIKE(1, 2) sys_error( const char *, ... );
141 void flushn( void );
142 
143 typedef struct string_list {
144 	struct string_list *next;
145 	char string[1];
146 } string_list_t;
147 
148 void add_string_list_n( string_list_t **list, const char *str, uint len );
149 void add_string_list( string_list_t **list, const char *str );
150 void free_string_list( string_list_t *list );
151 
152 #ifndef HAVE_MEMRCHR
153 void *memrchr( const void *s, int c, size_t n );
154 #endif
155 #ifndef HAVE_STRNLEN
156 size_t strnlen( const char *str, size_t maxlen );
157 #endif
158 
159 int starts_with( const char *str, int strl, const char *cmp, uint cmpl );
160 int starts_with_upper( const char *str, int strl, const char *cmp, uint cmpl );
161 int equals( const char *str, int strl, const char *cmp, uint cmpl );
162 
163 #ifndef HAVE_TIMEGM
164 time_t timegm( struct tm *tm );
165 #endif
166 
167 void *nfmalloc( size_t sz );
168 void *nfcalloc( size_t sz );
169 void *nfrealloc( void *mem, size_t sz );
170 char *nfstrndup( const char *str, size_t nchars );
171 char *nfstrdup( const char *str );
172 int ATTR_PRINTFLIKE(2, 0) nfvasprintf( char **str, const char *fmt, va_list va );
173 int ATTR_PRINTFLIKE(2, 3) nfasprintf( char **str, const char *fmt, ... );
174 int ATTR_PRINTFLIKE(3, 4) nfsnprintf( char *buf, int blen, const char *fmt, ... );
175 void ATTR_NORETURN oob( void );
176 void ATTR_NORETURN oom( void );
177 
178 char *expand_strdup( const char *s );
179 
180 int map_name( const char *arg, char **result, uint reserve, const char *in, const char *out );
181 
182 #define DEFINE_ARRAY_TYPE(T) \
183 	typedef struct { \
184 		T *data; \
185 		uint size; \
186 	} T##_array_t; \
187 	typedef union { \
188 		T##_array_t array; \
189 		struct { \
190 			T *data; \
191 			uint size; \
192 			uint alloc; \
193 		}; \
194 	} T##_array_alloc_t; \
195 	static INLINE T *T##_array_append( T##_array_alloc_t *arr ) \
196 	{ \
197 		if (arr->size == arr->alloc) { \
198 			arr->alloc = arr->alloc * 2 + 100; \
199 			arr->data = nfrealloc( arr->data, arr->alloc * sizeof(T) ); \
200 		} \
201 		return &arr->data[arr->size++]; \
202 	}
203 
204 #define ARRAY_INIT(arr) \
205 	do { (arr)->data = NULL; (arr)->size = (arr)->alloc = 0; } while (0)
206 
207 #define ARRAY_SQUEEZE(arr) \
208 	do { \
209 		(arr)->data = nfrealloc( (arr)->data, (arr)->size * sizeof((arr)->data[0]) ); \
210 	} while (0)
211 
212 DEFINE_ARRAY_TYPE(uint)
213 void sort_uint_array( uint_array_t array );
214 int find_uint_array( const uint_array_t array, uint value );
215 
216 void arc4_init( void );
217 uchar arc4_getbyte( void );
218 
219 uint bucketsForSize( uint size );
220 
221 typedef struct list_head {
222 	struct list_head *next, *prev;
223 } list_head_t;
224 
225 typedef struct notifier {
226 	struct notifier *next;
227 	void (*cb)( int what, void *aux );
228 	void *aux;
229 #ifdef HAVE_POLL_H
230 	uint index;
231 #else
232 	int fd;
233 	short events;
234 #endif
235 } notifier_t;
236 
237 #ifdef HAVE_POLL_H
238 # include <poll.h>
239 #else
240 # define POLLIN 1
241 # define POLLOUT 4
242 # define POLLERR 8
243 #endif
244 
245 void init_notifier( notifier_t *sn, int fd, void (*cb)( int, void * ), void *aux );
246 void conf_notifier( notifier_t *sn, short and_events, short or_events );
247 short notifier_config( notifier_t *sn );
248 void wipe_notifier( notifier_t *sn );
249 
250 typedef struct {
251 	list_head_t links;
252 	void (*cb)( void *aux );
253 	void *aux;
254 	time_t timeout;
255 } wakeup_t;
256 
257 void init_wakeup( wakeup_t *tmr, void (*cb)( void * ), void *aux );
258 void conf_wakeup( wakeup_t *tmr, int timeout );
259 void wipe_wakeup( wakeup_t *tmr );
pending_wakeup(wakeup_t * tmr)260 static INLINE int ATTR_UNUSED pending_wakeup( wakeup_t *tmr ) { return tmr->links.next != NULL; }
261 
262 void main_loop( void );
263 
264 #endif
265