diff options
Diffstat (limited to 'src/util/strings.c')
-rw-r--r-- | src/util/strings.c | 291 |
1 files changed, 148 insertions, 143 deletions
diff --git a/src/util/strings.c b/src/util/strings.c index e2ca69e10..9e9aac3b1 100644 --- a/src/util/strings.c +++ b/src/util/strings.c | |||
@@ -32,6 +32,10 @@ | |||
32 | #include "gnunet_common.h" | 32 | #include "gnunet_common.h" |
33 | #include "gnunet_strings_lib.h" | 33 | #include "gnunet_strings_lib.h" |
34 | 34 | ||
35 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | ||
36 | |||
37 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall) | ||
38 | |||
35 | 39 | ||
36 | /** | 40 | /** |
37 | * Fill a buffer of the given size with | 41 | * Fill a buffer of the given size with |
@@ -55,7 +59,8 @@ | |||
55 | * (or number of bytes that would have been written) | 59 | * (or number of bytes that would have been written) |
56 | */ | 60 | */ |
57 | size_t | 61 | size_t |
58 | GNUNET_STRINGS_buffer_fill (char *buffer, size_t size, unsigned int count, ...) | 62 | GNUNET_STRINGS_buffer_fill (char *buffer, size_t size, unsigned int count, |
63 | ...) | ||
59 | { | 64 | { |
60 | size_t needed; | 65 | size_t needed; |
61 | size_t slen; | 66 | size_t slen; |
@@ -65,18 +70,18 @@ GNUNET_STRINGS_buffer_fill (char *buffer, size_t size, unsigned int count, ...) | |||
65 | needed = 0; | 70 | needed = 0; |
66 | va_start (ap, count); | 71 | va_start (ap, count); |
67 | while (count > 0) | 72 | while (count > 0) |
68 | { | ||
69 | s = va_arg (ap, const char *); | ||
70 | |||
71 | slen = strlen (s) + 1; | ||
72 | if (buffer != NULL) | ||
73 | { | 73 | { |
74 | GNUNET_assert (needed + slen <= size); | 74 | s = va_arg (ap, const char *); |
75 | memcpy (&buffer[needed], s, slen); | 75 | |
76 | slen = strlen (s) + 1; | ||
77 | if (buffer != NULL) | ||
78 | { | ||
79 | GNUNET_assert (needed + slen <= size); | ||
80 | memcpy (&buffer[needed], s, slen); | ||
81 | } | ||
82 | needed += slen; | ||
83 | count--; | ||
76 | } | 84 | } |
77 | needed += slen; | ||
78 | count--; | ||
79 | } | ||
80 | va_end (ap); | 85 | va_end (ap); |
81 | return needed; | 86 | return needed; |
82 | } | 87 | } |
@@ -97,7 +102,7 @@ GNUNET_STRINGS_buffer_fill (char *buffer, size_t size, unsigned int count, ...) | |||
97 | */ | 102 | */ |
98 | unsigned int | 103 | unsigned int |
99 | GNUNET_STRINGS_buffer_tokenize (const char *buffer, size_t size, | 104 | GNUNET_STRINGS_buffer_tokenize (const char *buffer, size_t size, |
100 | unsigned int count, ...) | 105 | unsigned int count, ...) |
101 | { | 106 | { |
102 | unsigned int start; | 107 | unsigned int start; |
103 | unsigned int needed; | 108 | unsigned int needed; |
@@ -107,21 +112,21 @@ GNUNET_STRINGS_buffer_tokenize (const char *buffer, size_t size, | |||
107 | needed = 0; | 112 | needed = 0; |
108 | va_start (ap, count); | 113 | va_start (ap, count); |
109 | while (count > 0) | 114 | while (count > 0) |
110 | { | ||
111 | r = va_arg (ap, const char **); | ||
112 | |||
113 | start = needed; | ||
114 | while ((needed < size) && (buffer[needed] != '\0')) | ||
115 | needed++; | ||
116 | if (needed == size) | ||
117 | { | 115 | { |
118 | va_end (ap); | 116 | r = va_arg (ap, const char **); |
119 | return 0; /* error */ | 117 | |
118 | start = needed; | ||
119 | while ((needed < size) && (buffer[needed] != '\0')) | ||
120 | needed++; | ||
121 | if (needed == size) | ||
122 | { | ||
123 | va_end (ap); | ||
124 | return 0; /* error */ | ||
125 | } | ||
126 | *r = &buffer[start]; | ||
127 | needed++; /* skip 0-termination */ | ||
128 | count--; | ||
120 | } | 129 | } |
121 | *r = &buffer[start]; | ||
122 | needed++; /* skip 0-termination */ | ||
123 | count--; | ||
124 | } | ||
125 | va_end (ap); | 130 | va_end (ap); |
126 | return needed; | 131 | return needed; |
127 | } | 132 | } |
@@ -140,25 +145,25 @@ GNUNET_STRINGS_byte_size_fancy (unsigned long long size) | |||
140 | char *ret; | 145 | char *ret; |
141 | 146 | ||
142 | if (size > 5 * 1024) | 147 | if (size > 5 * 1024) |
143 | { | ||
144 | size = size / 1024; | ||
145 | unit = _( /* size unit */ "KiB"); | ||
146 | if (size > 5 * 1024) | ||
147 | { | 148 | { |
148 | size = size / 1024; | 149 | size = size / 1024; |
149 | unit = _( /* size unit */ "MiB"); | 150 | unit = _( /* size unit */ "KiB"); |
150 | if (size > 5 * 1024) | 151 | if (size > 5 * 1024) |
151 | { | 152 | { |
152 | size = size / 1024; | 153 | size = size / 1024; |
153 | unit = _( /* size unit */ "GiB"); | 154 | unit = _( /* size unit */ "MiB"); |
154 | if (size > 5 * 1024) | 155 | if (size > 5 * 1024) |
155 | { | 156 | { |
156 | size = size / 1024; | 157 | size = size / 1024; |
157 | unit = _( /* size unit */ "TiB"); | 158 | unit = _( /* size unit */ "GiB"); |
158 | } | 159 | if (size > 5 * 1024) |
159 | } | 160 | { |
161 | size = size / 1024; | ||
162 | unit = _( /* size unit */ "TiB"); | ||
163 | } | ||
164 | } | ||
165 | } | ||
160 | } | 166 | } |
161 | } | ||
162 | ret = GNUNET_malloc (32); | 167 | ret = GNUNET_malloc (32); |
163 | GNUNET_snprintf (ret, 32, "%llu %s", size, unit); | 168 | GNUNET_snprintf (ret, 32, "%llu %s", size, unit); |
164 | return ret; | 169 | return ret; |
@@ -187,41 +192,41 @@ GNUNET_STRINGS_to_utf8 (const char *input, size_t len, const char *charset) | |||
187 | 192 | ||
188 | cd = iconv_open ("UTF-8", charset); | 193 | cd = iconv_open ("UTF-8", charset); |
189 | if (cd == (iconv_t) - 1) | 194 | if (cd == (iconv_t) - 1) |
190 | { | 195 | { |
191 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "iconv_open"); | 196 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "iconv_open"); |
192 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 197 | LOG (GNUNET_ERROR_TYPE_WARNING, |
193 | _("Character set requested was `%s'\n"), charset); | 198 | _("Character set requested was `%s'\n"), charset); |
194 | ret = GNUNET_malloc (len + 1); | 199 | ret = GNUNET_malloc (len + 1); |
195 | memcpy (ret, input, len); | 200 | memcpy (ret, input, len); |
196 | ret[len] = '\0'; | 201 | ret[len] = '\0'; |
197 | return ret; | 202 | return ret; |
198 | } | 203 | } |
199 | tmpSize = 3 * len + 4; | 204 | tmpSize = 3 * len + 4; |
200 | tmp = GNUNET_malloc (tmpSize); | 205 | tmp = GNUNET_malloc (tmpSize); |
201 | itmp = tmp; | 206 | itmp = tmp; |
202 | finSize = tmpSize; | 207 | finSize = tmpSize; |
203 | if (iconv (cd, | 208 | if (iconv (cd, |
204 | #if FREEBSD || DARWIN || WINDOWS | 209 | #if FREEBSD || DARWIN || WINDOWS |
205 | (const char **) &input, | 210 | (const char **) &input, |
206 | #else | 211 | #else |
207 | (char **) &input, | 212 | (char **) &input, |
208 | #endif | 213 | #endif |
209 | &len, &itmp, &finSize) == SIZE_MAX) | 214 | &len, &itmp, &finSize) == SIZE_MAX) |
210 | { | 215 | { |
211 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "iconv"); | 216 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "iconv"); |
212 | iconv_close (cd); | 217 | iconv_close (cd); |
213 | GNUNET_free (tmp); | 218 | GNUNET_free (tmp); |
214 | ret = GNUNET_malloc (len + 1); | 219 | ret = GNUNET_malloc (len + 1); |
215 | memcpy (ret, input, len); | 220 | memcpy (ret, input, len); |
216 | ret[len] = '\0'; | 221 | ret[len] = '\0'; |
217 | return ret; | 222 | return ret; |
218 | } | 223 | } |
219 | ret = GNUNET_malloc (tmpSize - finSize + 1); | 224 | ret = GNUNET_malloc (tmpSize - finSize + 1); |
220 | memcpy (ret, tmp, tmpSize - finSize); | 225 | memcpy (ret, tmp, tmpSize - finSize); |
221 | ret[tmpSize - finSize] = '\0'; | 226 | ret[tmpSize - finSize] = '\0'; |
222 | GNUNET_free (tmp); | 227 | GNUNET_free (tmp); |
223 | if (0 != iconv_close (cd)) | 228 | if (0 != iconv_close (cd)) |
224 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "iconv_close"); | 229 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "iconv_close"); |
225 | return ret; | 230 | return ret; |
226 | #else | 231 | #else |
227 | ret = GNUNET_malloc (len + 1); | 232 | ret = GNUNET_malloc (len + 1); |
@@ -262,89 +267,89 @@ GNUNET_STRINGS_filename_expand (const char *fil) | |||
262 | /* absolute path, just copy */ | 267 | /* absolute path, just copy */ |
263 | return GNUNET_strdup (fil); | 268 | return GNUNET_strdup (fil); |
264 | if (fil[0] == '~') | 269 | if (fil[0] == '~') |
265 | { | ||
266 | fm = getenv ("HOME"); | ||
267 | if (fm == NULL) | ||
268 | { | 270 | { |
269 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 271 | fm = getenv ("HOME"); |
270 | _ | 272 | if (fm == NULL) |
271 | ("Failed to expand `$HOME': environment variable `HOME' not set")); | 273 | { |
272 | return NULL; | 274 | LOG (GNUNET_ERROR_TYPE_WARNING, |
275 | _ | ||
276 | ("Failed to expand `$HOME': environment variable `HOME' not set")); | ||
277 | return NULL; | ||
278 | } | ||
279 | fm = GNUNET_strdup (fm); | ||
280 | /* do not copy '~' */ | ||
281 | fil_ptr = fil + 1; | ||
282 | |||
283 | /* skip over dir seperator to be consistent */ | ||
284 | if (fil_ptr[0] == DIR_SEPARATOR) | ||
285 | fil_ptr++; | ||
273 | } | 286 | } |
274 | fm = GNUNET_strdup (fm); | ||
275 | /* do not copy '~' */ | ||
276 | fil_ptr = fil + 1; | ||
277 | |||
278 | /* skip over dir seperator to be consistent */ | ||
279 | if (fil_ptr[0] == DIR_SEPARATOR) | ||
280 | fil_ptr++; | ||
281 | } | ||
282 | else | 287 | else |
283 | { | ||
284 | /* relative path */ | ||
285 | fil_ptr = fil; | ||
286 | len = 512; | ||
287 | fm = NULL; | ||
288 | while (1) | ||
289 | { | 288 | { |
290 | buffer = GNUNET_malloc (len); | 289 | /* relative path */ |
291 | if (getcwd (buffer, len) != NULL) | 290 | fil_ptr = fil; |
292 | { | 291 | len = 512; |
293 | fm = buffer; | 292 | fm = NULL; |
294 | break; | 293 | while (1) |
295 | } | 294 | { |
296 | if ((errno == ERANGE) && (len < 1024 * 1024 * 4)) | 295 | buffer = GNUNET_malloc (len); |
297 | { | 296 | if (getcwd (buffer, len) != NULL) |
298 | len *= 2; | 297 | { |
299 | GNUNET_free (buffer); | 298 | fm = buffer; |
300 | continue; | 299 | break; |
301 | } | 300 | } |
302 | GNUNET_free (buffer); | 301 | if ((errno == ERANGE) && (len < 1024 * 1024 * 4)) |
303 | break; | 302 | { |
303 | len *= 2; | ||
304 | GNUNET_free (buffer); | ||
305 | continue; | ||
306 | } | ||
307 | GNUNET_free (buffer); | ||
308 | break; | ||
309 | } | ||
310 | if (fm == NULL) | ||
311 | { | ||
312 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "getcwd"); | ||
313 | buffer = getenv ("PWD"); /* alternative */ | ||
314 | if (buffer != NULL) | ||
315 | fm = GNUNET_strdup (buffer); | ||
316 | } | ||
317 | if (fm == NULL) | ||
318 | fm = GNUNET_strdup ("./"); /* give up */ | ||
304 | } | 319 | } |
305 | if (fm == NULL) | ||
306 | { | ||
307 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "getcwd"); | ||
308 | buffer = getenv ("PWD"); /* alternative */ | ||
309 | if (buffer != NULL) | ||
310 | fm = GNUNET_strdup (buffer); | ||
311 | } | ||
312 | if (fm == NULL) | ||
313 | fm = GNUNET_strdup ("./"); /* give up */ | ||
314 | } | ||
315 | n = strlen (fm) + 1 + strlen (fil_ptr) + 1; | 320 | n = strlen (fm) + 1 + strlen (fil_ptr) + 1; |
316 | buffer = GNUNET_malloc (n); | 321 | buffer = GNUNET_malloc (n); |
317 | GNUNET_snprintf (buffer, n, "%s%s%s", fm, | 322 | GNUNET_snprintf (buffer, n, "%s%s%s", fm, |
318 | (fm[strlen (fm) - 1] == | 323 | (fm[strlen (fm) - 1] == |
319 | DIR_SEPARATOR) ? "" : DIR_SEPARATOR_STR, fil_ptr); | 324 | DIR_SEPARATOR) ? "" : DIR_SEPARATOR_STR, fil_ptr); |
320 | GNUNET_free (fm); | 325 | GNUNET_free (fm); |
321 | return buffer; | 326 | return buffer; |
322 | #else | 327 | #else |
323 | fn = GNUNET_malloc (MAX_PATH + 1); | 328 | fn = GNUNET_malloc (MAX_PATH + 1); |
324 | 329 | ||
325 | if ((lRet = plibc_conv_to_win_path (fil, fn)) != ERROR_SUCCESS) | 330 | if ((lRet = plibc_conv_to_win_path (fil, fn)) != ERROR_SUCCESS) |
326 | { | 331 | { |
327 | SetErrnoFromWinError (lRet); | 332 | SetErrnoFromWinError (lRet); |
328 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "plibc_conv_to_win_path"); | 333 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "plibc_conv_to_win_path"); |
329 | return NULL; | 334 | return NULL; |
330 | } | 335 | } |
331 | /* is the path relative? */ | 336 | /* is the path relative? */ |
332 | if ((strncmp (fn + 1, ":\\", 2) != 0) && (strncmp (fn, "\\\\", 2) != 0)) | 337 | if ((strncmp (fn + 1, ":\\", 2) != 0) && (strncmp (fn, "\\\\", 2) != 0)) |
333 | { | ||
334 | char szCurDir[MAX_PATH + 1]; | ||
335 | |||
336 | lRet = GetCurrentDirectory (MAX_PATH + 1, szCurDir); | ||
337 | if (lRet + strlen (fn) + 1 > (MAX_PATH + 1)) | ||
338 | { | 338 | { |
339 | SetErrnoFromWinError (ERROR_BUFFER_OVERFLOW); | 339 | char szCurDir[MAX_PATH + 1]; |
340 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "GetCurrentDirectory"); | 340 | |
341 | return NULL; | 341 | lRet = GetCurrentDirectory (MAX_PATH + 1, szCurDir); |
342 | if (lRet + strlen (fn) + 1 > (MAX_PATH + 1)) | ||
343 | { | ||
344 | SetErrnoFromWinError (ERROR_BUFFER_OVERFLOW); | ||
345 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "GetCurrentDirectory"); | ||
346 | return NULL; | ||
347 | } | ||
348 | buffer = GNUNET_malloc (MAX_PATH + 1); | ||
349 | GNUNET_snprintf (buffer, MAX_PATH + 1, "%s\\%s", szCurDir, fn); | ||
350 | GNUNET_free (fn); | ||
351 | fn = buffer; | ||
342 | } | 352 | } |
343 | buffer = GNUNET_malloc (MAX_PATH + 1); | ||
344 | GNUNET_snprintf (buffer, MAX_PATH + 1, "%s\\%s", szCurDir, fn); | ||
345 | GNUNET_free (fn); | ||
346 | fn = buffer; | ||
347 | } | ||
348 | 353 | ||
349 | return fn; | 354 | return fn; |
350 | #endif | 355 | #endif |
@@ -367,25 +372,25 @@ GNUNET_STRINGS_relative_time_to_string (struct GNUNET_TIME_Relative delta) | |||
367 | if (delta.rel_value == GNUNET_TIME_UNIT_FOREVER_REL.rel_value) | 372 | if (delta.rel_value == GNUNET_TIME_UNIT_FOREVER_REL.rel_value) |
368 | return GNUNET_strdup (_("eternity")); | 373 | return GNUNET_strdup (_("eternity")); |
369 | if (dval > 5 * 1000) | 374 | if (dval > 5 * 1000) |
370 | { | ||
371 | dval = dval / 1000; | ||
372 | unit = _( /* time unit */ "s"); | ||
373 | if (dval > 5 * 60) | ||
374 | { | 375 | { |
375 | dval = dval / 60; | 376 | dval = dval / 1000; |
376 | unit = _( /* time unit */ "m"); | 377 | unit = _( /* time unit */ "s"); |
377 | if (dval > 5 * 60) | 378 | if (dval > 5 * 60) |
378 | { | 379 | { |
379 | dval = dval / 60; | 380 | dval = dval / 60; |
380 | unit = _( /* time unit */ "h"); | 381 | unit = _( /* time unit */ "m"); |
381 | if (dval > 5 * 24) | 382 | if (dval > 5 * 60) |
382 | { | 383 | { |
383 | dval = dval / 24; | 384 | dval = dval / 60; |
384 | unit = _( /* time unit */ " days"); | 385 | unit = _( /* time unit */ "h"); |
385 | } | 386 | if (dval > 5 * 24) |
386 | } | 387 | { |
388 | dval = dval / 24; | ||
389 | unit = _( /* time unit */ " days"); | ||
390 | } | ||
391 | } | ||
392 | } | ||
387 | } | 393 | } |
388 | } | ||
389 | GNUNET_asprintf (&ret, "%llu %s", dval, unit); | 394 | GNUNET_asprintf (&ret, "%llu %s", dval, unit); |
390 | return ret; | 395 | return ret; |
391 | } | 396 | } |