]> git.ipfire.org Git - pakfire.git/blame - src/libpakfire/util.c
Pass architecture to the Pakfire module as a string instead of Arch object
[pakfire.git] / src / libpakfire / util.c
CommitLineData
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
40void 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
50void* 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
58void* 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
72void* 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 80PAKFIRE_EXPORT void* pakfire_free(void* mem) {
221cc3ce
MT
81 if (mem)
82 free(mem);
83
84 return 0;
85}
86
87char* 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
98int pakfire_string_startswith(const char* s, const char* prefix) {
99 return strncmp(s, prefix, strlen(prefix));
100}
101
221cc3ce
MT
102char* 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"
119static 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
129char* pakfire_format_date(time_t t) {
130 return pakfire_strftime("%Y-%m-%d", t);
131}
132
9f953e68 133PAKFIRE_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
147char* pakfire_basename(const char* path) {
148 char* name = pakfire_strdup(path);
149
150 return basename(name);
151}
152
153char* pakfire_dirname(const char* path) {
154 char* parent = pakfire_strdup(path);
155
156 return dirname(parent);
157}
158
12656820 159PAKFIRE_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 183int 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
214char* 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
236char* 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
245void 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
264PAKFIRE_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}