17 |
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
18 |
*/ |
*/ |
19 |
|
|
20 |
|
#define _GNU_SOURCE |
21 |
|
|
22 |
|
#include <config.h> |
23 |
|
|
24 |
#include "util.h" |
#include "util.h" |
25 |
|
|
26 |
#include <assert.h> |
#include <assert.h> |
28 |
#include <limits.h> |
#include <limits.h> |
29 |
#include <stdarg.h> |
#include <stdarg.h> |
30 |
#include <stdio.h> |
#include <stdio.h> |
31 |
|
#include <stdint.h> |
32 |
#include <string.h> |
#include <string.h> |
33 |
#include <strings.h> |
#include <strings.h> |
34 |
|
|
51 |
exit(EXIT_FAILURE); |
exit(EXIT_FAILURE); |
52 |
} |
} |
53 |
|
|
54 |
|
size_t addst(size_t x, size_t y) { |
55 |
|
if (SIZE_MAX - x < y) { |
56 |
|
fatal("integer overflow"); |
57 |
|
} |
58 |
|
return x + y; |
59 |
|
} |
60 |
|
|
61 |
|
size_t mulst(size_t x, size_t y) { |
62 |
|
if (x == 0 || y == 0) { |
63 |
|
return 0; |
64 |
|
} |
65 |
|
if (SIZE_MAX / x < y) { |
66 |
|
fatal("integer overflow"); |
67 |
|
} |
68 |
|
return x * y; |
69 |
|
} |
70 |
|
|
71 |
void * xmalloc(size_t size) { |
void * xmalloc(size_t size) { |
72 |
void * result = malloc(size); |
void * result = malloc(size); |
73 |
if (result == NULL) { |
if (result == NULL) { |
92 |
return result; |
return result; |
93 |
} |
} |
94 |
|
|
95 |
|
char * xstrndup(const char * s, size_t size) { |
96 |
|
char * result = strndup(s, size); |
97 |
|
if (result == NULL) { |
98 |
|
fatal("out of memory"); |
99 |
|
} |
100 |
|
return result; |
101 |
|
} |
102 |
|
|
103 |
|
int xasprintf(char ** s, const char * template, ...) { |
104 |
|
va_list a; |
105 |
|
va_start(a, template); |
106 |
|
int result = vasprintf(s, template, a); |
107 |
|
va_end(a); |
108 |
|
if (result < 0) { |
109 |
|
fatal("out of memory"); |
110 |
|
} |
111 |
|
return result; |
112 |
|
} |
113 |
|
|
114 |
char * xgetcwd(void) { |
char * xgetcwd(void) { |
115 |
char * result = getcwd(NULL, 0); |
char * result = getcwd(NULL, 0); |
116 |
if (result == NULL) { |
if (result == NULL) { |
199 |
} |
} |
200 |
} |
} |
201 |
|
|
202 |
|
bool str_starts_with(const char * string, const char * prefix) { |
203 |
|
const char * string_ptr = string; |
204 |
|
const char * prefix_ptr = prefix; |
205 |
|
while (*string_ptr != '\0' && *prefix_ptr != '\0') { |
206 |
|
if (*string_ptr != *prefix_ptr) { |
207 |
|
return false; |
208 |
|
} |
209 |
|
string_ptr++; |
210 |
|
prefix_ptr++; |
211 |
|
} |
212 |
|
if (*string_ptr == '\0' && *prefix_ptr != '\0') { |
213 |
|
return false; |
214 |
|
} |
215 |
|
return true; |
216 |
|
} |
217 |
|
|
218 |
|
bool str_ends_with(const char * string, const char * suffix) { |
219 |
|
size_t string_length = strlen(string); |
220 |
|
size_t suffix_length = strlen(suffix); |
221 |
|
if (string_length < suffix_length) { |
222 |
|
return false; |
223 |
|
} |
224 |
|
return strcmp(string + string_length - suffix_length, suffix) == 0; |
225 |
|
} |
226 |
|
|
227 |
char * make_path(const char * parent, const char * relative_path) { |
char * make_path(const char * parent, const char * relative_path) { |
228 |
size_t parent_length = strlen(parent); |
size_t parent_length = strlen(parent); |
229 |
size_t relative_path_length = strlen(relative_path); |
size_t relative_path_length = strlen(relative_path); |
230 |
char * result = xmalloc(parent_length + relative_path_length + 2); |
size_t result_length = addst(parent_length, relative_path_length); |
231 |
|
result_length = addst(result_length, 2); |
232 |
|
char * result = xmalloc(result_length); |
233 |
strcpy(result, parent); |
strcpy(result, parent); |
234 |
result[parent_length] = '/'; |
result[parent_length] = '/'; |
235 |
strcpy(result + parent_length + 1, relative_path); |
strcpy(result + parent_length + 1, relative_path); |
356 |
fclose(destination); |
fclose(destination); |
357 |
} |
} |
358 |
|
|
359 |
int directory_is_empty(const char * directory) { |
bool directory_is_empty(const char * directory) { |
360 |
|
bool result = true; |
361 |
DIR * dir = xopendir(directory); |
DIR * dir = xopendir(directory); |
|
int num_entries = 0; |
|
362 |
struct dirent * e; |
struct dirent * e; |
363 |
while ((e = readdir(dir)) != NULL) { |
while ((e = readdir(dir)) != NULL) { |
364 |
if (strcmp(e->d_name, ".") != 0 && |
if (strcmp(e->d_name, ".") != 0 && |
365 |
strcmp(e->d_name, "..") != 0) { |
strcmp(e->d_name, "..") != 0) { |
366 |
num_entries++; |
result = false; |
367 |
|
break; |
368 |
} |
} |
369 |
} |
} |
370 |
closedir(dir); |
closedir(dir); |
371 |
return num_entries == 0; |
return result; |
372 |
} |
} |
373 |
|
|
374 |
static struct DirListEntry * recursive_dir_list(const char * root, const char * directory_wrt_root, struct DirListEntry * head) { |
static struct DirListEntry * recursive_dir_list(const char * root, const char * directory_wrt_root, struct DirListEntry * head) { |
417 |
} |
} |
418 |
} |
} |
419 |
|
|
420 |
|
#ifndef HAVE_CLOSESOCKET |
421 |
|
int closesocket(int s) { |
422 |
|
return close(s); |
423 |
|
} |
424 |
|
#endif |
425 |
|
|
426 |
#ifndef HAVE_VASPRINTF |
#ifndef HAVE_VASPRINTF |
427 |
int vasprintf(char ** s, const char * template, va_list a) { |
int vasprintf(char ** s, const char * template, va_list a) { |
428 |
int size = 100; |
int size = 100; |
435 |
va_copy(copy, a); |
va_copy(copy, a); |
436 |
int result = vsnprintf(*s, size, template, copy); |
int result = vsnprintf(*s, size, template, copy); |
437 |
if (result >= size) { |
if (result >= size) { |
|
/* TODO: check for overflow? */ |
|
438 |
int new_size = result; |
int new_size = result; |
439 |
if (new_size == INT_MAX) { |
if (new_size == INT_MAX) { |
440 |
free(*s); |
free(*s); |
441 |
return - 1; |
return -1; |
442 |
} |
} |
443 |
new_size++; |
new_size++; |
444 |
char * new_s = realloc(*s, new_size); |
char * new_s = realloc(*s, new_size); |
454 |
} |
} |
455 |
else if (result == -1) { |
else if (result == -1) { |
456 |
while (result == -1) { |
while (result == -1) { |
457 |
if (size > INT_MAX / 2) { |
if (size == INT_MAX) { |
458 |
free(*s); |
free(*s); |
459 |
return - 1; |
return -1; |
460 |
|
} |
461 |
|
int new_size; |
462 |
|
if (size > INT_MAX / 2) { |
463 |
|
new_size = INT_MAX; |
464 |
|
} |
465 |
|
else { |
466 |
|
new_size = 2 * size; |
467 |
} |
} |
|
int new_size = 2 * size; |
|
468 |
char * new_s = realloc(*s, new_size); |
char * new_s = realloc(*s, new_size); |
469 |
if (new_s == NULL) { |
if (new_s == NULL) { |
470 |
free(*s); |
free(*s); |
491 |
return result; |
return result; |
492 |
} |
} |
493 |
#endif |
#endif |
|
|
|