Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sudo-project
GitHub Repository: sudo-project/sudo
Path: blob/main/plugins/python/regress/iohelpers.c
1532 views
1
/*
2
* SPDX-License-Identifier: ISC
3
*
4
* Copyright (c) 2020 Robert Manner <[email protected]>
5
*
6
* Permission to use, copy, modify, and distribute this software for any
7
* purpose with or without fee is hereby granted, provided that the above
8
* copyright notice and this permission notice appear in all copies.
9
*
10
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
*/
18
19
#include "iohelpers.h"
20
#include <sudo_fatal.h>
21
22
int
23
rmdir_recursive(const char *path)
24
{
25
char *cmd = NULL;
26
int success = false;
27
28
if (asprintf(&cmd, "rm -rf \"%s\"", path) < 0)
29
return false;
30
31
if (system(cmd) == 0)
32
success = true;
33
34
free(cmd);
35
36
return success;
37
}
38
39
int
40
fwriteall(const char *file_path, const char *string)
41
{
42
int success = false;
43
44
FILE *file = fopen(file_path, "w+");
45
if (file == NULL)
46
goto cleanup;
47
48
size_t size = strlen(string);
49
if (fwrite(string, 1, size, file) != size) {
50
goto cleanup;
51
}
52
53
success = true;
54
55
cleanup:
56
if (file)
57
fclose(file);
58
59
return success;
60
}
61
62
int
63
freadall(const char *file_path, char *output, size_t max_len)
64
{
65
int rc = false;
66
FILE *file = fopen(file_path, "rb");
67
if (file == NULL) {
68
sudo_warn_nodebug("failed to open file '%s'", file_path);
69
goto cleanup;
70
}
71
72
size_t len = fread(output, 1, max_len - 1, file);
73
output[len] = '\0';
74
75
if (ferror(file) != 0) {
76
sudo_warn_nodebug("failed to read file '%s'", file_path);
77
goto cleanup;
78
}
79
80
if (!feof(file)) {
81
sudo_warn_nodebug("file '%s' was bigger than allocated buffer %zu",
82
file_path, max_len);
83
goto cleanup;
84
}
85
86
rc = true;
87
88
cleanup:
89
if (file)
90
fclose(file);
91
92
return rc;
93
}
94
95
int
96
vsnprintf_append(char * restrict output, size_t max_output_len, const char * restrict fmt, va_list args)
97
{
98
va_list args2;
99
va_copy(args2, args);
100
101
size_t output_len = strlen(output);
102
int rc = vsnprintf(output + output_len, max_output_len - output_len, fmt, args2);
103
104
va_end(args2);
105
return rc;
106
}
107
108
int
109
snprintf_append(char * restrict output, size_t max_output_len, const char * restrict fmt, ...)
110
{
111
va_list args;
112
va_start(args, fmt);
113
int rc = vsnprintf_append(output, max_output_len, fmt, args);
114
va_end(args);
115
return rc;
116
}
117
118
int
119
str_array_count(char **str_array)
120
{
121
int result = 0;
122
for (; str_array[result] != NULL; ++result) {}
123
return result;
124
}
125
126
void
127
str_array_snprint(char *out_str, size_t max_len, char **str_array, int array_len)
128
{
129
if (array_len < 0)
130
array_len = str_array_count(str_array);
131
132
for (int pos = 0; pos < array_len; ++pos) {
133
snprintf_append(out_str, max_len, "%s%s", pos > 0 ? ", " : "", str_array[pos]);
134
}
135
}
136
137
char *
138
str_replaced(const char *source, size_t dest_len, const char *old, const char *new)
139
{
140
char *result = malloc(dest_len);
141
char *dest = result;
142
char *pos = NULL;
143
size_t old_len = strlen(old);
144
145
if (result == NULL)
146
return NULL;
147
148
while ((pos = strstr(source, old)) != NULL) {
149
size_t len = (size_t)snprintf(dest, dest_len,
150
"%.*s%s", (int)(pos - source), source, new);
151
if (len >= dest_len)
152
goto fail;
153
154
dest_len -= len;
155
dest += len;
156
source = pos + old_len;
157
}
158
159
if (strlcpy(dest, source, dest_len) >= dest_len)
160
goto fail;
161
162
return result;
163
164
fail:
165
free(result);
166
return strdup("str_replace_all failed, string too long");
167
}
168
169
void
170
str_replace_in_place(char *string, size_t max_length, const char *old, const char *new)
171
{
172
char *replaced = str_replaced(string, max_length, old, new);
173
if (replaced != NULL) {
174
strlcpy(string, replaced, max_length);
175
free(replaced);
176
}
177
}
178
179