Line data Source code
1 : /*
2 : * Copyright (C) 2011 Andrea Mazzoleni
3 : *
4 : * This program is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 3 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * This program is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #ifndef __SUPPORT_H
19 : #define __SUPPORT_H
20 :
21 : /****************************************************************************/
22 : /* lock */
23 :
24 : /**
25 : * Initialize and destroy the locks.
26 : */
27 : void lock_init(void);
28 : void lock_done(void);
29 :
30 : /**
31 : * Lock used for printf.
32 : *
33 : * In Windows printf() is not atomic, and multiple threads
34 : * will have output interleaved.
35 : *
36 : * Note that even defining __USE_MINGW_ANSI_STDIO the problem persists.
37 : *
38 : * See for example:
39 : *
40 : * Weird output when I use pthread and printf.
41 : * http://stackoverflow.com/questions/13190254/weird-output-when-i-use-pthread-and-printf
42 : *
43 : * This is also required in other OS because we split output in stdlog in
44 : * two fprintf calls.
45 : */
46 : void lock_msg(void);
47 : void unlock_msg(void);
48 :
49 : /**
50 : * Lock used for memory counter.
51 : */
52 : void lock_memory(void);
53 : void unlock_memory(void);
54 :
55 : /****************************************************************************/
56 : /* random */
57 :
58 : /**
59 : * Seed the random pseudo random number generator
60 : */
61 : void random_seed(uint64_t seed);
62 :
63 : /**
64 : * Reseed the random pseudo random number generator with the tick count
65 : */
66 : void random_reseed(void);
67 :
68 : /**
69 : * Return a pseudo random number of 8 bits
70 : */
71 : unsigned char random_u8(void);
72 :
73 : /**
74 : * Return a pseudo random number of 64 bits
75 : */
76 : uint64_t random_u64(void);
77 :
78 : /****************************************************************************/
79 : /* error */
80 :
81 : /**
82 : * Return if the error is at hardware level
83 : */
84 : int is_hw(int err);
85 :
86 : /**
87 : * Log errors with standard messages
88 : */
89 : void log_fatal_errno(int err, const char* name);
90 : void log_error_errno(int err, const char* name);
91 :
92 : /****************************************************************************/
93 : /* log */
94 :
95 : /**
96 : * Pointer to log function.
97 : */
98 : typedef void log_ptr(int err, const char* format, ...) __attribute__((format(attribute_printf, 2, 3)));
99 :
100 : /**
101 : * Fatal error messages.
102 : *
103 : * Messages printed before an early termination.
104 : *
105 : * These messages go in the log file and in stderr unconditionally.
106 : */
107 : void log_fatal(int err, const char* format, ...) __attribute__((format(attribute_printf, 2, 3)));
108 :
109 : /**
110 : * Unexpected error messages.
111 : *
112 : * Messages reporting error conditions that don't prevent the program to run.
113 : *
114 : * Some of them could be also serious errors, like "silent errors".
115 : * In such case, the summary result is always printed as error,
116 : * and we are sure to notify the user in some way.
117 : *
118 : * These messages go in the log file if specified, otherwise they go in stderr.
119 : */
120 : void log_error(int err, const char* format, ...) __attribute__((format(attribute_printf, 2, 3)));
121 :
122 : /**
123 : * Expected error messages, without fallback to stderr.
124 : *
125 : * These errors are "someway" expected, and then they never go to screen.
126 : * For example, when undeleting missing files, the messages for missing files
127 : * are not shown.
128 : *
129 : * These messages go in the log file if specified, otherwise they are lost.
130 : */
131 : void log_expected(int err, const char* format, ...) __attribute__((format(attribute_printf, 2, 3)));
132 :
133 : /**
134 : * Tag messages.
135 : *
136 : * Messages are in tag format, like "tag:entry:...".
137 : *
138 : * These messages never go on the screen, but only in the log file if specified.
139 : *
140 : * Note that this function, allows not \n terminated strings.
141 : *
142 : * These messages are buffered. Use msg_flush() to flush them.
143 : */
144 : void log_tag(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
145 :
146 : /**
147 : * Flush the log.
148 : */
149 : void log_flush(void);
150 :
151 : /****************************************************************************/
152 : /* message */
153 :
154 : /**
155 : * Pointer to msg function.
156 : */
157 : typedef void msg_ptr(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
158 :
159 : /**
160 : * Message levels.
161 : *
162 : * The levels control the amount of information printed on the screen.
163 : * Note that log_fatal(), log_error(), log_expected() and log_tag() are not affected by this option.
164 : *
165 : * From the most quiet to the most verbose.
166 : */
167 : #define MSG_STATUS -3
168 : #define MSG_INFO -2
169 : #define MSG_PROGRESS -1
170 : #define MSG_BAR 0
171 : #define MSG_VERBOSE 1
172 :
173 : /**
174 : * Selected message level.
175 : */
176 : extern int msg_level;
177 :
178 : /**
179 : * State messages.
180 : *
181 : * Messages that tell what the program is doing or did, but limited to few lines.
182 : * They are status information, and summary results.
183 : */
184 : void msg_status(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
185 :
186 : /**
187 : * Info messages.
188 : *
189 : * Messages that tell what was done.
190 : * Potentially a lot of messages are possible. They can still be on the screen,
191 : * as losing them we don't lose information.
192 : *
193 : * These messages never go in the log file, because there is always a corresponding log_tag().
194 : */
195 : void msg_info(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
196 :
197 : /**
198 : * Progress messages.
199 : *
200 : * Message that tell the progress of program.
201 : *
202 : * These messages also go in the log file.
203 : */
204 : void msg_progress(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
205 :
206 : /**
207 : * Progress bar messages.
208 : *
209 : * Message that show the percentage of the progress.
210 : *
211 : * These messages never go in the log file.
212 : *
213 : * These messages are buffered. Use msg_flush() to flush them.
214 : */
215 : void msg_bar(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
216 :
217 : /**
218 : * Verbose messages.
219 : *
220 : * Message that tell what is already expected.
221 : *
222 : * These messages also go in the log file.
223 : */
224 : void msg_verbose(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
225 :
226 : /**
227 : * Flush the output.
228 : */
229 : void msg_flush(void);
230 :
231 : /****************************************************************************/
232 : /* print */
233 :
234 : /**
235 : * Print a repeated char.
236 : */
237 : void printc(char c, size_t pad);
238 :
239 : /**
240 : * Print a string with right space padding.
241 : */
242 : void printr(const char* str, size_t pad);
243 :
244 : /**
245 : * Print a string with left space padding.
246 : */
247 : void printl(const char* str, size_t pad);
248 :
249 : /**
250 : * Print a probability with space padding.
251 : */
252 : void printp(double v, size_t pad);
253 :
254 : /****************************************************************************/
255 : /* string */
256 :
257 : #define ESC_MAX (PATH_MAX * 2 + 1)
258 :
259 : /**
260 : * Escape a string for the log.
261 : *
262 : * \param buffer Preallocated buffer of ESC_MAX size.
263 : *
264 : * Chars ':', '\n', '\r' and '\' are escaped to '\d', '\\n', '\\r' and '\\'.
265 : */
266 : const char* esc_tag(const char* str, char* buffer);
267 :
268 : /**
269 : * Escape a string for the shell.
270 : *
271 : * \param buffer Preallocated buffer of ESC_MAX size.
272 : */
273 : const char* esc_shell_multi(const char** str_map, unsigned str_max, char* buffer);
274 357904 : static inline const char* esc_shell(const char* str, char* buffer)
275 : {
276 357904 : return esc_shell_multi(&str, 1, buffer);
277 : }
278 :
279 : /**
280 : * Polish a string.
281 : *
282 : * Not printable chars are replaced by spaces.
283 : *
284 : * Note that the passed string is modified.
285 : */
286 : char* strpolish(char* s);
287 :
288 : /**
289 : * Split a string in multiple tokens separated by delimiters.
290 : *
291 : * Multiple delimiters are grouped together.
292 : */
293 : unsigned strsplit(char** split_map, unsigned split_max, char* line, const char* delimiters);
294 :
295 : /**
296 : * Trim spaces from the start and the end
297 : */
298 : char* strtrim(char* s);
299 :
300 : /**
301 : * Lower case
302 : */
303 : char* strlwr(char* s);
304 :
305 : /*
306 : * Find the first occurrence of 'needle' in 'haystack' only if it
307 : * appears as a separate word (space, number or string boundaries).
308 : *
309 : * Returns a pointer to the beginning of the match, or NULL if not found.
310 : */
311 : char* worddigitstr(const char* haystack, const char* needle);
312 :
313 : /****************************************************************************/
314 : /* path */
315 :
316 : /**
317 : * Copy a path limiting the size.
318 : * Abort if too long.
319 : */
320 : void pathcpy(char* dst, size_t size, const char* src);
321 :
322 : /**
323 : * Concatenate a path limiting the size.
324 : * Abort if too long.
325 : */
326 : void pathcat(char* dst, size_t size, const char* src);
327 :
328 : /**
329 : * Concatenate a path limiting the size knowing the length.
330 : * Abort if too long.
331 : */
332 : void pathcatl(char* dst, size_t dst_len, size_t size, const char* src);
333 :
334 : /**
335 : * Concatenate a path limiting the size.
336 : * Abort if too long.
337 : */
338 : void pathcatc(char* dst, size_t size, char c);
339 :
340 : /**
341 : * Import a path limiting the size.
342 : * In Windows all the backslash are converted to the C standard of forward slash.
343 : * Abort if too long.
344 : */
345 : void pathimport(char* dst, size_t size, const char* src);
346 :
347 : /**
348 : * Export a path limiting the size.
349 : * In Windows all the C slashes are converted to the Windows backslash.
350 : * Abort if too long.
351 : */
352 : void pathexport(char* dst, size_t size, const char* src);
353 :
354 : /**
355 : * Print a path.
356 : * Abort if too long.
357 : */
358 : void pathprint(char* dst, size_t size, const char* format, ...) __attribute__((format(attribute_printf, 3, 4)));
359 :
360 : /**
361 : * Ensure the presence of a terminating slash, if it isn't empty.
362 : * Abort if too long.
363 : */
364 : void pathslash(char* dst, size_t size);
365 :
366 : /**
367 : * Cut everything after the latest slash.
368 : *
369 : * If the string doesn't contain any slash, it returns the empty string.
370 : */
371 : void pathcut(char* dst);
372 :
373 : /**
374 : * Compare two paths.
375 : * In Windows it's case insensitive and assumes \ equal at /.
376 : */
377 : int pathcmp(const char* a, const char* b);
378 :
379 : /**
380 : * Check if the root is matching the start of the specified path.
381 : *
382 : * The root MUST end with a /.
383 : *
384 : * In Windows it's case insensitive and assumes \ equal at /.
385 : */
386 : int path_is_root_of(const char* root, const char* path);
387 :
388 : /****************************************************************************/
389 : /* file-system */
390 :
391 : /**
392 : * Create all the ancestor directories if missing.
393 : * The file name, after the last /, is ignored.
394 : */
395 : int mkancestor(const char* file);
396 :
397 : /**
398 : * Change the modification time of an open file.
399 : */
400 : int fmtime(int f, int64_t mtime_sec, int mtime_nsec);
401 :
402 : /**
403 : * Change the modification time of a file or link.
404 : * Note that links are NOT deferenced.
405 : */
406 : int lmtime(const char* path, int64_t mtime_sec, int mtime_nsec);
407 :
408 : /****************************************************************************/
409 : /* advise */
410 :
411 : /**
412 : * Advise modes.
413 : */
414 : #define ADVISE_DEFAULT 0 /**< Default mode. */
415 : #define ADVISE_NONE 1 /**< Bare read/write mode. */
416 : #define ADVISE_SEQUENTIAL 2 /**< Sequential mode. */
417 : #define ADVISE_FLUSH 3 /**< Flush mode. */
418 : #define ADVISE_FLUSH_WINDOW 4 /**< Flush mode with a window of 8MB. */
419 : #define ADVISE_DISCARD 5 /**< Discard the cache after every operation. */
420 : #define ADVISE_DISCARD_WINDOW 6 /**< Discard the cache with a window of 8MB. */
421 : #define ADVISE_DIRECT 7 /**< Direct mode. */
422 :
423 : #define ADVISE_WINDOW_SIZE (8 * 1024 * 1024) /**< Window size. */
424 :
425 : struct advise_struct {
426 : int mode;
427 : data_off_t dirty_begin;
428 : data_off_t dirty_end;
429 : };
430 :
431 : void advise_init(struct advise_struct* advise, int mode);
432 : int advise_flags(struct advise_struct* advise);
433 : int advise_open(struct advise_struct* advise, int f);
434 : int advise_write(struct advise_struct* advise, int f, data_off_t offset, data_off_t size);
435 : int advise_read(struct advise_struct* advise, int f, data_off_t offset, data_off_t size);
436 :
437 : /****************************************************************************/
438 : /* memory */
439 :
440 : /**
441 : * Return the size of the allocated memory.
442 : */
443 : size_t malloc_counter_get(void);
444 :
445 : /**
446 : * Safe malloc.
447 : * If no memory is available, it aborts.
448 : */
449 : void* malloc_nofail(size_t size);
450 :
451 : /**
452 : * Safe cmalloc.
453 : * If no memory is available, it aborts.
454 : */
455 : void* calloc_nofail(size_t count, size_t size);
456 :
457 : /**
458 : * Safe strdup.
459 : * If no memory is available, it aborts.
460 : */
461 : char* strdup_nofail(const char* str);
462 :
463 : /**
464 : * Helper for printing an error about a failed allocation.
465 : */
466 : void malloc_fail(size_t size);
467 :
468 : /****************************************************************************/
469 : /* smartctl */
470 :
471 : /**
472 : * Read smartctl attributes from a stream.
473 : * Return 0 on success.
474 : */
475 : int smartctl_attribute(FILE* f, const char* file, const char* name, struct smart_attr* smart, uint64_t* info, char* serial, char* family, char* model, char* interf);
476 :
477 : /**
478 : * Flush smartctl output from a stream.
479 : */
480 : int smartctl_flush(FILE* f, const char* file, const char* name);
481 :
482 : /**
483 : * Extract the temperature from the SMART info.
484 : * Return -1 if missing
485 : */
486 : int smart_temp(devinfo_t* devinfo);
487 :
488 : /****************************************************************************/
489 : /* thread */
490 :
491 : #if HAVE_THREAD
492 : /**
493 : * Control when to signal the condition variables.
494 : *
495 : * Default is inside the mutex.
496 : *
497 : * Ensure to change that before starting any thread.
498 : */
499 : extern int thread_cond_signal_outside;
500 :
501 : /**
502 : * Thread wrappers to handle error conditions.
503 : */
504 : void thread_mutex_init(thread_mutex_t* mutex);
505 : void thread_mutex_destroy(thread_mutex_t* mutex);
506 : void thread_mutex_lock(thread_mutex_t* mutex);
507 : void thread_mutex_unlock(thread_mutex_t* mutex);
508 : void thread_cond_init(thread_cond_t* cond);
509 : void thread_cond_destroy(thread_cond_t* cond);
510 : void thread_cond_signal(thread_cond_t* cond);
511 : void thread_cond_broadcast(thread_cond_t* cond);
512 : void thread_cond_wait(thread_cond_t* cond, thread_mutex_t* mutex);
513 : void thread_cond_signal_and_unlock(thread_cond_t* cond, thread_mutex_t* mutex);
514 : void thread_cond_broadcast_and_unlock(thread_cond_t* cond, thread_mutex_t* mutex);
515 : void thread_create(thread_id_t* thread, void* (*func)(void*), void* arg);
516 : void thread_join(thread_id_t thread, void** retval);
517 : void thread_yield(void);
518 : #endif
519 :
520 : /****************************************************************************/
521 : /* match */
522 :
523 : /*
524 : * Wild match function.
525 : *
526 : * - ? matches any single character except /
527 : * - * matches any sequence of characters except /
528 : * - ** (nearby a /) matches everything including /
529 : * - ** (not near a /) like *
530 : * - ##/ reduces to nothing in addition to the normal matching of ** (using # instead of * to mess the C comment)
531 : * - [...] matches character classes with support for ranges and negation lile [!...] or [^...], except /
532 : */
533 : int wnmatch(const char* p, const char* t);
534 :
535 : #endif
536 :
|