]>
Commit | Line | Data |
---|---|---|
221cc3ce MT |
1 | /*############################################################################# |
2 | # # | |
3 | # Pakfire - The IPFire package management system # | |
4 | # Copyright (C) 2013 Pakfire development team # | |
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 3 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 | #############################################################################*/ | |
20 | ||
3854acbd | 21 | #include <errno.h> |
221cc3ce MT |
22 | #include <libgen.h> |
23 | #include <math.h> | |
24 | #include <stddef.h> | |
25 | #include <stdio.h> | |
26 | #include <stdlib.h> | |
27 | #include <string.h> | |
3854acbd MT |
28 | #include <sys/stat.h> |
29 | #include <sys/types.h> | |
526e4cec | 30 | #include <time.h> |
3854acbd | 31 | #include <unistd.h> |
221cc3ce | 32 | |
658c740d MT |
33 | #include <gcrypt.h> |
34 | ||
221cc3ce | 35 | #include <pakfire/constants.h> |
3854acbd | 36 | #include <pakfire/logging.h> |
9f953e68 | 37 | #include <pakfire/private.h> |
96872372 | 38 | #include <pakfire/types.h> |
221cc3ce MT |
39 | |
40 | void pakfire_oom(size_t num, size_t len) { | |
41 | if (num) | |
42 | fprintf(stderr, "Out of memory allocating %zu*%zu bytes!\n", num, len); | |
43 | else | |
44 | fprintf(stderr, "Out of memory allocating %zu bytes!\n", len); | |
45 | ||
46 | abort(); | |
47 | exit(1); | |
48 | } | |
49 | ||
50 | void* pakfire_malloc(size_t len) { | |
51 | void* r = malloc(len ? len : 1); | |
52 | if (!r) | |
53 | pakfire_oom(0, len); | |
54 | ||
55 | return r; | |
56 | } | |
57 | ||
58 | void* pakfire_calloc(size_t num, size_t len) { | |
59 | void* r; | |
60 | ||
61 | if (num == 0 || len == 0) | |
62 | r = malloc(1); | |
63 | else | |
64 | r = calloc(num, len); | |
65 | ||
66 | if (!r) | |
67 | pakfire_oom(num, len); | |
68 | ||
69 | return r; | |
70 | } | |
71 | ||
72 | void* pakfire_realloc(void* ptr, size_t size) { | |
73 | ptr = realloc(ptr, size); | |
74 | if (!ptr) | |
75 | pakfire_oom(0, size); | |
76 | ||
77 | return ptr; | |
78 | } | |
79 | ||
9f953e68 | 80 | PAKFIRE_EXPORT void* pakfire_free(void* mem) { |
221cc3ce MT |
81 | if (mem) |
82 | free(mem); | |
83 | ||
84 | return 0; | |
85 | } | |
86 | ||
87 | char* pakfire_strdup(const char* s) { | |
88 | if (!s) | |
89 | return 0; | |
90 | ||
91 | char* r = strdup(s); | |
92 | if (!r) | |
93 | pakfire_oom(0, strlen(s)); | |
94 | ||
95 | return r; | |
96 | } | |
97 | ||
5c409596 MT |
98 | int pakfire_string_startswith(const char* s, const char* prefix) { |
99 | return strncmp(s, prefix, strlen(prefix)); | |
100 | } | |
101 | ||
221cc3ce MT |
102 | char* pakfire_format_size(double size) { |
103 | char string[STRING_SIZE]; | |
104 | const char* units[] = {" ", "k", "M", "G", "T", NULL}; | |
105 | const char** unit = units; | |
106 | ||
107 | while (*(unit + 1) && size >= 1024.0) { | |
108 | size /= 1024.0; | |
109 | unit++; | |
110 | } | |
111 | ||
112 | snprintf(string, STRING_SIZE, "%.0f%s", round(size), *unit); | |
113 | ||
114 | return pakfire_strdup(string); | |
115 | } | |
116 | ||
526e4cec MT |
117 | #pragma GCC diagnostic push |
118 | #pragma GCC diagnostic ignored "-Wformat-nonliteral" | |
119 | static char* pakfire_strftime(const char* format, time_t t) { | |
120 | char string[STRING_SIZE]; | |
121 | struct tm* tm = gmtime(&t); | |
122 | ||
123 | strftime(string, sizeof(string), format, tm); | |
124 | ||
125 | return pakfire_strdup(string); | |
126 | } | |
127 | #pragma GCC diagnostic pop | |
128 | ||
129 | char* pakfire_format_date(time_t t) { | |
130 | return pakfire_strftime("%Y-%m-%d", t); | |
131 | } | |
132 | ||
9f953e68 | 133 | PAKFIRE_EXPORT char* pakfire_path_join(const char* first, const char* second) { |
221cc3ce MT |
134 | char* buffer; |
135 | ||
136 | if (!second) | |
137 | return pakfire_strdup(first); | |
138 | ||
139 | if (*second == '/') | |
140 | return pakfire_strdup(second); | |
141 | ||
142 | asprintf(&buffer, "%s/%s", first, second); | |
143 | ||
144 | return buffer; | |
145 | } | |
146 | ||
147 | char* pakfire_basename(const char* path) { | |
148 | char* name = pakfire_strdup(path); | |
149 | ||
150 | return basename(name); | |
151 | } | |
152 | ||
153 | char* pakfire_dirname(const char* path) { | |
154 | char* parent = pakfire_strdup(path); | |
155 | ||
156 | return dirname(parent); | |
157 | } | |
158 | ||
12656820 | 159 | PAKFIRE_EXPORT int pakfire_access(Pakfire pakfire, const char* dir, const char* file, int mode) { |
3854acbd MT |
160 | char* path = pakfire_path_join(dir, file); |
161 | ||
162 | int r = access(path, mode); | |
163 | ||
164 | if (r) { | |
165 | if (mode & R_OK) | |
12656820 | 166 | DEBUG(pakfire, "%s is not readable\n", path); |
3854acbd MT |
167 | |
168 | if (mode & W_OK) | |
12656820 | 169 | DEBUG(pakfire, "%s is not writable\n", path); |
3854acbd MT |
170 | |
171 | if (mode & X_OK) | |
12656820 | 172 | DEBUG(pakfire, "%s is not executable\n", path); |
3854acbd MT |
173 | |
174 | if (mode & F_OK) | |
12656820 | 175 | DEBUG(pakfire, "%s does not exist\n", path); |
3854acbd MT |
176 | } |
177 | ||
4d54a3a9 MT |
178 | pakfire_free(path); |
179 | ||
3854acbd MT |
180 | return r; |
181 | } | |
182 | ||
12656820 | 183 | int pakfire_mkdir(Pakfire pakfire, const char* path, mode_t mode) { |
3854acbd MT |
184 | int r = 0; |
185 | ||
186 | if ((strcmp(path, "/") == 0) || (strcmp(path, ".") == 0)) | |
187 | return 0; | |
188 | ||
189 | // If parent does not exists, we try to create it. | |
190 | char* parent = pakfire_dirname(path); | |
12656820 | 191 | r = pakfire_access(pakfire, parent, NULL, F_OK); |
3854acbd | 192 | if (r) |
12656820 | 193 | r = pakfire_mkdir(pakfire, parent, 0); |
3854acbd MT |
194 | |
195 | pakfire_free(parent); | |
196 | ||
197 | if (r) | |
198 | return r; | |
199 | ||
200 | // Finally, create the directory we want. | |
201 | r = mkdir(path, mode); | |
202 | if (r) { | |
203 | switch (errno) { | |
204 | // If the directory already exists, this is fine. | |
205 | case EEXIST: | |
206 | r = 0; | |
207 | break; | |
208 | } | |
209 | } | |
210 | ||
211 | return r; | |
212 | } | |
213 | ||
221cc3ce MT |
214 | char* pakfire_sgets(char* str, int num, char** input) { |
215 | char* next = *input; | |
216 | int numread = 0; | |
217 | ||
218 | while (numread + 1 < num && *next) { | |
219 | int isnewline = (*next == '\n'); | |
220 | ||
221 | *str++ = *next++; | |
222 | numread++; | |
223 | ||
224 | if (isnewline) | |
225 | break; | |
226 | } | |
227 | ||
228 | // Terminate string | |
229 | *str = '\0'; | |
230 | ||
231 | *input = next; | |
232 | ||
233 | return str; | |
234 | } | |
235 | ||
236 | char* pakfire_remove_trailing_newline(char* str) { | |
237 | ssize_t pos = strlen(str) - 1; | |
238 | ||
239 | if (str[pos] == '\n') | |
240 | str[pos] = '\0'; | |
241 | ||
242 | return str; | |
243 | } | |
658c740d MT |
244 | |
245 | void init_libgcrypt() { | |
246 | // Only execute this once | |
247 | static int libgcrypt_initialized = 0; | |
248 | if (libgcrypt_initialized++) | |
249 | return; | |
250 | ||
251 | const char* version = gcry_check_version(NULL); | |
252 | if (!version) { | |
253 | fprintf(stderr, "Could not initialize libgcrypt\n"); | |
254 | exit(1); | |
255 | } | |
256 | ||
257 | // Disable secure memory | |
258 | gcry_control(GCRYCTL_DISABLE_SECMEM, 0); | |
259 | ||
260 | // Tell libgcrypt that initialization has completed | |
261 | gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); | |
262 | } | |
96872372 MT |
263 | |
264 | PAKFIRE_EXPORT const char* pakfire_action_type_string(pakfire_action_type_t type) { | |
265 | switch (type) { | |
266 | case PAKFIRE_ACTION_NOOP: | |
267 | return "NOOP"; | |
268 | ||
269 | case PAKFIRE_ACTION_VERIFY: | |
270 | return "VERIFY"; | |
271 | ||
272 | case PAKFIRE_ACTION_EXECUTE: | |
273 | return "EXECUTE"; | |
274 | ||
275 | case PAKFIRE_ACTION_PRETRANS: | |
276 | return "PRETRANS"; | |
277 | ||
278 | case PAKFIRE_ACTION_POSTTRANS: | |
279 | return "POSTTRANS"; | |
280 | } | |
281 | ||
282 | return NULL; | |
283 | } |