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
|
#include "mem.h"
#include "outf.h"
#include "sys.h"
#include <errno.h>
#include <stdarg.h>
#include <sys/stat.h>
/* Define extract_APPLE_IOS if we are on iOS. */
#undef extract_APPLE_IOS
#ifdef __APPLE__
#include "TargetConditionals.h"
#ifdef TARGET_OS_IPHONE
#define extract_APPLE_IOS
#elif TARGET_IPHONE_SIMULATOR
#define extract_APPLE_IOS
#endif
#endif
int extract_systemf(extract_alloc_t* alloc, const char* format, ...)
{
#ifdef extract_APPLE_IOS
/* system() not available on iOS. */
(void) alloc;
(void) format;
errno = ENOTSUP;
return -1;
#else
int e;
char* command;
va_list va;
va_start(va, format);
e = extract_vasprintf(alloc, &command, format, va);
va_end(va);
if (e < 0) return e;
outf("running: %s", command);
e = system(command);
extract_free(alloc, &command);
if (e > 0) {
errno = EIO;
}
return e;
#endif
}
int extract_read_all(extract_alloc_t* alloc, FILE* in, char** o_out)
{
size_t len = 0;
size_t delta = 128;
for(;;) {
size_t n;
if (extract_realloc2(alloc, o_out, len, len + delta + 1)) {
extract_free(alloc, o_out);
return -1;
}
n = fread(*o_out + len, 1 /*size*/, delta /*nmemb*/, in);
len += n;
if (feof(in)) {
(*o_out)[len] = 0;
return 0;
}
if (ferror(in)) {
/* It's weird that fread() and ferror() don't set errno. */
errno = EIO;
extract_free(alloc, o_out);
return -1;
}
}
}
int extract_read_all_path(extract_alloc_t* alloc, const char* path, char** o_text)
{
int e = -1;
FILE* f = NULL;
f = fopen(path, "rb");
if (!f) goto end;
if (extract_read_all(alloc, f, o_text)) goto end;
e = 0;
end:
if (f) fclose(f);
if (e) extract_free(alloc, o_text);
return e;
}
int extract_write_all(const void* data, size_t data_size, const char* path)
{
int e = -1;
FILE* f = fopen(path, "w");
if (!f) goto end;
if (fwrite(data, data_size, 1 /*nmemb*/, f) != 1) goto end;
e = 0;
end:
if (f) fclose(f);
return e;
}
int extract_check_path_shell_safe(const char* path)
/* Returns -1 with errno=EINVAL if <path> contains sequences that could make it
unsafe in shell commands. */
{
if (0
|| strstr(path, "..")
|| strchr(path, '\'')
|| strchr(path, '"')
|| strchr(path, ' ')
) {
errno = EINVAL;
return -1;
}
return 0;
}
int extract_remove_directory(extract_alloc_t* alloc, const char* path)
{
if (extract_check_path_shell_safe(path)) {
outf("path_out is unsafe: %s", path);
return -1;
}
return extract_systemf(alloc, "rm -r '%s'", path);
}
#ifdef _WIN32
#include <direct.h>
int extract_mkdir(const char* path, int mode)
{
(void) mode;
return _mkdir(path);
}
#else
int extract_mkdir(const char* path, int mode)
{
return mkdir(path, mode);
}
#endif
|