aboutsummaryrefslogtreecommitdiff
path: root/src/util/strings.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/strings.c')
-rw-r--r--src/util/strings.c404
1 files changed, 214 insertions, 190 deletions
diff --git a/src/util/strings.c b/src/util/strings.c
index d48d552a1..dc4037a1f 100644
--- a/src/util/strings.c
+++ b/src/util/strings.c
@@ -59,8 +59,7 @@
59 * (or number of bytes that would have been written) 59 * (or number of bytes that would have been written)
60 */ 60 */
61size_t 61size_t
62GNUNET_STRINGS_buffer_fill (char *buffer, size_t size, unsigned int count, 62GNUNET_STRINGS_buffer_fill (char *buffer, size_t size, unsigned int count, ...)
63 ...)
64{ 63{
65 size_t needed; 64 size_t needed;
66 size_t slen; 65 size_t slen;
@@ -70,18 +69,18 @@ GNUNET_STRINGS_buffer_fill (char *buffer, size_t size, unsigned int count,
70 needed = 0; 69 needed = 0;
71 va_start (ap, count); 70 va_start (ap, count);
72 while (count > 0) 71 while (count > 0)
73 { 72 {
74 s = va_arg (ap, const char *); 73 s = va_arg (ap, const char *);
75 74
76 slen = strlen (s) + 1; 75 slen = strlen (s) + 1;
77 if (buffer != NULL) 76 if (buffer != NULL)
78 { 77 {
79 GNUNET_assert (needed + slen <= size); 78 GNUNET_assert (needed + slen <= size);
80 memcpy (&buffer[needed], s, slen); 79 memcpy (&buffer[needed], s, slen);
81 }
82 needed += slen;
83 count--;
84 } 80 }
81 needed += slen;
82 count--;
83 }
85 va_end (ap); 84 va_end (ap);
86 return needed; 85 return needed;
87} 86}
@@ -102,7 +101,7 @@ GNUNET_STRINGS_buffer_fill (char *buffer, size_t size, unsigned int count,
102 */ 101 */
103unsigned int 102unsigned int
104GNUNET_STRINGS_buffer_tokenize (const char *buffer, size_t size, 103GNUNET_STRINGS_buffer_tokenize (const char *buffer, size_t size,
105 unsigned int count, ...) 104 unsigned int count, ...)
106{ 105{
107 unsigned int start; 106 unsigned int start;
108 unsigned int needed; 107 unsigned int needed;
@@ -112,21 +111,21 @@ GNUNET_STRINGS_buffer_tokenize (const char *buffer, size_t size,
112 needed = 0; 111 needed = 0;
113 va_start (ap, count); 112 va_start (ap, count);
114 while (count > 0) 113 while (count > 0)
114 {
115 r = va_arg (ap, const char **);
116
117 start = needed;
118 while ((needed < size) && (buffer[needed] != '\0'))
119 needed++;
120 if (needed == size)
115 { 121 {
116 r = va_arg (ap, const char **); 122 va_end (ap);
117 123 return 0; /* error */
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--;
129 } 124 }
125 *r = &buffer[start];
126 needed++; /* skip 0-termination */
127 count--;
128 }
130 va_end (ap); 129 va_end (ap);
131 return needed; 130 return needed;
132} 131}
@@ -145,25 +144,25 @@ GNUNET_STRINGS_byte_size_fancy (unsigned long long size)
145 char *ret; 144 char *ret;
146 145
147 if (size > 5 * 1024) 146 if (size > 5 * 1024)
147 {
148 size = size / 1024;
149 unit = "KiB";
150 if (size > 5 * 1024)
148 { 151 {
149 size = size / 1024; 152 size = size / 1024;
150 unit = "KiB"; 153 unit = "MiB";
151 if (size > 5 * 1024) 154 if (size > 5 * 1024)
152 { 155 {
153 size = size / 1024; 156 size = size / 1024;
154 unit = "MiB"; 157 unit = "GiB";
155 if (size > 5 * 1024) 158 if (size > 5 * 1024)
156 { 159 {
157 size = size / 1024; 160 size = size / 1024;
158 unit = "GiB"; 161 unit = "TiB";
159 if (size > 5 * 1024) 162 }
160 { 163 }
161 size = size / 1024;
162 unit = "TiB";
163 }
164 }
165 }
166 } 164 }
165 }
167 ret = GNUNET_malloc (32); 166 ret = GNUNET_malloc (32);
168 GNUNET_snprintf (ret, 32, "%llu %s", size, unit); 167 GNUNET_snprintf (ret, 32, "%llu %s", size, unit);
169 return ret; 168 return ret;
@@ -179,26 +178,42 @@ GNUNET_STRINGS_byte_size_fancy (unsigned long long size)
179 */ 178 */
180int 179int
181GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size, 180GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size,
182 unsigned long long *size) 181 unsigned long long *size)
183{ 182{
184 struct { 183 struct
185 const char *name; 184 {
185 const char *name;
186 unsigned long long value; 186 unsigned long long value;
187 } table[] = { 187 } table[] =
188 { "B", 1 }, 188 {
189 { "KiB", 1024 }, 189 {
190 { "kB", 1000 }, 190 "B", 1},
191 { "MiB", 1024 * 1024 }, 191 {
192 { "MB", 1000 * 1000 }, 192 "KiB", 1024},
193 { "GiB", 1024 * 1024 * 1024 }, 193 {
194 { "GB", 1000 * 1000 * 1000 }, 194 "kB", 1000},
195 { "TiB", 1024LL * 1024LL * 1024LL * 1024LL }, 195 {
196 { "TB", 1000LL * 1000LL * 1000LL * 1024LL }, 196 "MiB", 1024 * 1024},
197 { "PiB", 1024LL * 1024LL * 1024LL * 1024LL * 1024LL }, 197 {
198 { "PB", 1000LL * 1000LL * 1000LL * 1024LL * 1000LL}, 198 "MB", 1000 * 1000},
199 { "EiB", 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * 1024LL}, 199 {
200 { "EB", 1000LL * 1000LL * 1000LL * 1024LL * 1000LL * 1000LL }, 200 "GiB", 1024 * 1024 * 1024},
201 { NULL, 0 } 201 {
202 "GB", 1000 * 1000 * 1000},
203 {
204 "TiB", 1024LL * 1024LL * 1024LL * 1024LL},
205 {
206 "TB", 1000LL * 1000LL * 1000LL * 1024LL},
207 {
208 "PiB", 1024LL * 1024LL * 1024LL * 1024LL * 1024LL},
209 {
210 "PB", 1000LL * 1000LL * 1000LL * 1024LL * 1000LL},
211 {
212 "EiB", 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * 1024LL},
213 {
214 "EB", 1000LL * 1000LL * 1000LL * 1024LL * 1000LL * 1000LL},
215 {
216 NULL, 0}
202 }; 217 };
203 unsigned long long ret; 218 unsigned long long ret;
204 char *in; 219 char *in;
@@ -211,9 +226,8 @@ GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size,
211 in = GNUNET_strdup (fancy_size); 226 in = GNUNET_strdup (fancy_size);
212 for (tok = strtok (in, " "); tok != NULL; tok = strtok (NULL, " ")) 227 for (tok = strtok (in, " "); tok != NULL; tok = strtok (NULL, " "))
213 { 228 {
214 i=0; 229 i = 0;
215 while ( (table[i].name != NULL) && 230 while ((table[i].name != NULL) && (0 != strcasecmp (table[i].name, tok)))
216 (0 != strcasecmp (table[i].name, tok) ) )
217 i++; 231 i++;
218 if (table[i].name != NULL) 232 if (table[i].name != NULL)
219 last *= table[i].value; 233 last *= table[i].value;
@@ -222,8 +236,8 @@ GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size,
222 ret += last; 236 ret += last;
223 last = 0; 237 last = 0;
224 if (1 != sscanf (tok, "%llu", &last)) 238 if (1 != sscanf (tok, "%llu", &last))
225 return GNUNET_SYSERR; /* expected number */ 239 return GNUNET_SYSERR; /* expected number */
226 } 240 }
227 } 241 }
228 ret += last; 242 ret += last;
229 *size = ret; 243 *size = ret;
@@ -241,43 +255,54 @@ GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size,
241 */ 255 */
242int 256int
243GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_size, 257GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_size,
244 struct GNUNET_TIME_Relative *rtime) 258 struct GNUNET_TIME_Relative *rtime)
245{ 259{
246 struct { 260 struct
247 const char *name; 261 {
262 const char *name;
248 unsigned long long value; 263 unsigned long long value;
249 } table[] = { 264 } table[] =
250 { "ms", 1 }, 265 {
251 { "s", 1000 }, 266 {
252 { "\"", 1000 }, 267 "ms", 1},
253 { "min", 60 * 1000 }, 268 {
254 { "minutes", 60 * 1000 }, 269 "s", 1000},
255 { "'", 60 * 1000 }, 270 {
256 { "h", 60 * 60 * 1000 }, 271 "\"", 1000},
257 { "d", 24 * 60 * 60 * 1000 }, 272 {
258 { "a", 31557600 /* year */ }, 273 "min", 60 * 1000},
259 { NULL, 0 } 274 {
275 "minutes", 60 * 1000},
276 {
277 "'", 60 * 1000},
278 {
279 "h", 60 * 60 * 1000},
280 {
281 "d", 24 * 60 * 60 * 1000},
282 {
283 "a", 31557600 /* year */ },
284 {
285 NULL, 0}
260 }; 286 };
261 unsigned long long ret; 287 unsigned long long ret;
262 char *in; 288 char *in;
263 const char *tok; 289 const char *tok;
264 unsigned long long last; 290 unsigned long long last;
265 unsigned int i; 291 unsigned int i;
266 292
267 if ((0 == strcasecmp (fancy_size, "infinity")) || 293 if ((0 == strcasecmp (fancy_size, "infinity")) ||
268 (0 == strcasecmp (fancy_size, "forever"))) 294 (0 == strcasecmp (fancy_size, "forever")))
269 { 295 {
270 *rtime = GNUNET_TIME_UNIT_FOREVER_REL; 296 *rtime = GNUNET_TIME_UNIT_FOREVER_REL;
271 return GNUNET_OK; 297 return GNUNET_OK;
272 } 298 }
273 ret = 0; 299 ret = 0;
274 last = 0; 300 last = 0;
275 in = GNUNET_strdup (fancy_size); 301 in = GNUNET_strdup (fancy_size);
276 for (tok = strtok (in, " "); tok != NULL; tok = strtok (NULL, " ")) 302 for (tok = strtok (in, " "); tok != NULL; tok = strtok (NULL, " "))
277 { 303 {
278 i=0; 304 i = 0;
279 while ( (table[i].name != NULL) && 305 while ((table[i].name != NULL) && (0 != strcasecmp (table[i].name, tok)))
280 (0 != strcasecmp (table[i].name, tok) ) )
281 i++; 306 i++;
282 if (table[i].name != NULL) 307 if (table[i].name != NULL)
283 last *= table[i].value; 308 last *= table[i].value;
@@ -286,8 +311,8 @@ GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_size,
286 ret += last; 311 ret += last;
287 last = 0; 312 last = 0;
288 if (1 != sscanf (tok, "%llu", &last)) 313 if (1 != sscanf (tok, "%llu", &last))
289 return GNUNET_SYSERR; /* expected number */ 314 return GNUNET_SYSERR; /* expected number */
290 } 315 }
291 } 316 }
292 ret += last; 317 ret += last;
293 rtime->rel_value = (uint64_t) ret; 318 rtime->rel_value = (uint64_t) ret;
@@ -317,35 +342,35 @@ GNUNET_STRINGS_to_utf8 (const char *input, size_t len, const char *charset)
317 342
318 cd = iconv_open ("UTF-8", charset); 343 cd = iconv_open ("UTF-8", charset);
319 if (cd == (iconv_t) - 1) 344 if (cd == (iconv_t) - 1)
320 { 345 {
321 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "iconv_open"); 346 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "iconv_open");
322 LOG (GNUNET_ERROR_TYPE_WARNING, 347 LOG (GNUNET_ERROR_TYPE_WARNING, _("Character set requested was `%s'\n"),
323 _("Character set requested was `%s'\n"), charset); 348 charset);
324 ret = GNUNET_malloc (len + 1); 349 ret = GNUNET_malloc (len + 1);
325 memcpy (ret, input, len); 350 memcpy (ret, input, len);
326 ret[len] = '\0'; 351 ret[len] = '\0';
327 return ret; 352 return ret;
328 } 353 }
329 tmpSize = 3 * len + 4; 354 tmpSize = 3 * len + 4;
330 tmp = GNUNET_malloc (tmpSize); 355 tmp = GNUNET_malloc (tmpSize);
331 itmp = tmp; 356 itmp = tmp;
332 finSize = tmpSize; 357 finSize = tmpSize;
333 if (iconv (cd, 358 if (iconv (cd,
334#if FREEBSD || DARWIN || WINDOWS 359#if FREEBSD || DARWIN || WINDOWS
335 (const char **) &input, 360 (const char **) &input,
336#else 361#else
337 (char **) &input, 362 (char **) &input,
338#endif 363#endif
339 &len, &itmp, &finSize) == SIZE_MAX) 364 &len, &itmp, &finSize) == SIZE_MAX)
340 { 365 {
341 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "iconv"); 366 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "iconv");
342 iconv_close (cd); 367 iconv_close (cd);
343 GNUNET_free (tmp); 368 GNUNET_free (tmp);
344 ret = GNUNET_malloc (len + 1); 369 ret = GNUNET_malloc (len + 1);
345 memcpy (ret, input, len); 370 memcpy (ret, input, len);
346 ret[len] = '\0'; 371 ret[len] = '\0';
347 return ret; 372 return ret;
348 } 373 }
349 ret = GNUNET_malloc (tmpSize - finSize + 1); 374 ret = GNUNET_malloc (tmpSize - finSize + 1);
350 memcpy (ret, tmp, tmpSize - finSize); 375 memcpy (ret, tmp, tmpSize - finSize);
351 ret[tmpSize - finSize] = '\0'; 376 ret[tmpSize - finSize] = '\0';
@@ -392,89 +417,88 @@ GNUNET_STRINGS_filename_expand (const char *fil)
392 /* absolute path, just copy */ 417 /* absolute path, just copy */
393 return GNUNET_strdup (fil); 418 return GNUNET_strdup (fil);
394 if (fil[0] == '~') 419 if (fil[0] == '~')
420 {
421 fm = getenv ("HOME");
422 if (fm == NULL)
395 { 423 {
396 fm = getenv ("HOME"); 424 LOG (GNUNET_ERROR_TYPE_WARNING,
397 if (fm == NULL) 425 _("Failed to expand `$HOME': environment variable `HOME' not set"));
398 { 426 return NULL;
399 LOG (GNUNET_ERROR_TYPE_WARNING,
400 _
401 ("Failed to expand `$HOME': environment variable `HOME' not set"));
402 return NULL;
403 }
404 fm = GNUNET_strdup (fm);
405 /* do not copy '~' */
406 fil_ptr = fil + 1;
407
408 /* skip over dir seperator to be consistent */
409 if (fil_ptr[0] == DIR_SEPARATOR)
410 fil_ptr++;
411 } 427 }
428 fm = GNUNET_strdup (fm);
429 /* do not copy '~' */
430 fil_ptr = fil + 1;
431
432 /* skip over dir seperator to be consistent */
433 if (fil_ptr[0] == DIR_SEPARATOR)
434 fil_ptr++;
435 }
412 else 436 else
437 {
438 /* relative path */
439 fil_ptr = fil;
440 len = 512;
441 fm = NULL;
442 while (1)
413 { 443 {
414 /* relative path */ 444 buffer = GNUNET_malloc (len);
415 fil_ptr = fil; 445 if (getcwd (buffer, len) != NULL)
416 len = 512; 446 {
417 fm = NULL; 447 fm = buffer;
418 while (1) 448 break;
419 { 449 }
420 buffer = GNUNET_malloc (len); 450 if ((errno == ERANGE) && (len < 1024 * 1024 * 4))
421 if (getcwd (buffer, len) != NULL) 451 {
422 { 452 len *= 2;
423 fm = buffer; 453 GNUNET_free (buffer);
424 break; 454 continue;
425 } 455 }
426 if ((errno == ERANGE) && (len < 1024 * 1024 * 4)) 456 GNUNET_free (buffer);
427 { 457 break;
428 len *= 2; 458 }
429 GNUNET_free (buffer); 459 if (fm == NULL)
430 continue; 460 {
431 } 461 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "getcwd");
432 GNUNET_free (buffer); 462 buffer = getenv ("PWD"); /* alternative */
433 break; 463 if (buffer != NULL)
434 } 464 fm = GNUNET_strdup (buffer);
435 if (fm == NULL)
436 {
437 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "getcwd");
438 buffer = getenv ("PWD"); /* alternative */
439 if (buffer != NULL)
440 fm = GNUNET_strdup (buffer);
441 }
442 if (fm == NULL)
443 fm = GNUNET_strdup ("./"); /* give up */
444 } 465 }
466 if (fm == NULL)
467 fm = GNUNET_strdup ("./"); /* give up */
468 }
445 n = strlen (fm) + 1 + strlen (fil_ptr) + 1; 469 n = strlen (fm) + 1 + strlen (fil_ptr) + 1;
446 buffer = GNUNET_malloc (n); 470 buffer = GNUNET_malloc (n);
447 GNUNET_snprintf (buffer, n, "%s%s%s", fm, 471 GNUNET_snprintf (buffer, n, "%s%s%s", fm,
448 (fm[strlen (fm) - 1] == 472 (fm[strlen (fm) - 1] ==
449 DIR_SEPARATOR) ? "" : DIR_SEPARATOR_STR, fil_ptr); 473 DIR_SEPARATOR) ? "" : DIR_SEPARATOR_STR, fil_ptr);
450 GNUNET_free (fm); 474 GNUNET_free (fm);
451 return buffer; 475 return buffer;
452#else 476#else
453 fn = GNUNET_malloc (MAX_PATH + 1); 477 fn = GNUNET_malloc (MAX_PATH + 1);
454 478
455 if ((lRet = plibc_conv_to_win_path (fil, fn)) != ERROR_SUCCESS) 479 if ((lRet = plibc_conv_to_win_path (fil, fn)) != ERROR_SUCCESS)
456 { 480 {
457 SetErrnoFromWinError (lRet); 481 SetErrnoFromWinError (lRet);
458 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "plibc_conv_to_win_path"); 482 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "plibc_conv_to_win_path");
459 return NULL; 483 return NULL;
460 } 484 }
461 /* is the path relative? */ 485 /* is the path relative? */
462 if ((strncmp (fn + 1, ":\\", 2) != 0) && (strncmp (fn, "\\\\", 2) != 0)) 486 if ((strncmp (fn + 1, ":\\", 2) != 0) && (strncmp (fn, "\\\\", 2) != 0))
487 {
488 char szCurDir[MAX_PATH + 1];
489
490 lRet = GetCurrentDirectory (MAX_PATH + 1, szCurDir);
491 if (lRet + strlen (fn) + 1 > (MAX_PATH + 1))
463 { 492 {
464 char szCurDir[MAX_PATH + 1]; 493 SetErrnoFromWinError (ERROR_BUFFER_OVERFLOW);
465 494 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "GetCurrentDirectory");
466 lRet = GetCurrentDirectory (MAX_PATH + 1, szCurDir); 495 return NULL;
467 if (lRet + strlen (fn) + 1 > (MAX_PATH + 1))
468 {
469 SetErrnoFromWinError (ERROR_BUFFER_OVERFLOW);
470 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "GetCurrentDirectory");
471 return NULL;
472 }
473 buffer = GNUNET_malloc (MAX_PATH + 1);
474 GNUNET_snprintf (buffer, MAX_PATH + 1, "%s\\%s", szCurDir, fn);
475 GNUNET_free (fn);
476 fn = buffer;
477 } 496 }
497 buffer = GNUNET_malloc (MAX_PATH + 1);
498 GNUNET_snprintf (buffer, MAX_PATH + 1, "%s\\%s", szCurDir, fn);
499 GNUNET_free (fn);
500 fn = buffer;
501 }
478 502
479 return fn; 503 return fn;
480#endif 504#endif
@@ -497,25 +521,25 @@ GNUNET_STRINGS_relative_time_to_string (struct GNUNET_TIME_Relative delta)
497 if (delta.rel_value == GNUNET_TIME_UNIT_FOREVER_REL.rel_value) 521 if (delta.rel_value == GNUNET_TIME_UNIT_FOREVER_REL.rel_value)
498 return GNUNET_strdup (_("eternity")); 522 return GNUNET_strdup (_("eternity"));
499 if (dval > 5 * 1000) 523 if (dval > 5 * 1000)
524 {
525 dval = dval / 1000;
526 unit = _( /* time unit */ "s");
527 if (dval > 5 * 60)
500 { 528 {
501 dval = dval / 1000; 529 dval = dval / 60;
502 unit = _( /* time unit */ "s"); 530 unit = _( /* time unit */ "m");
503 if (dval > 5 * 60) 531 if (dval > 5 * 60)
504 { 532 {
505 dval = dval / 60; 533 dval = dval / 60;
506 unit = _( /* time unit */ "m"); 534 unit = _( /* time unit */ "h");
507 if (dval > 5 * 60) 535 if (dval > 5 * 24)
508 { 536 {
509 dval = dval / 60; 537 dval = dval / 24;
510 unit = _( /* time unit */ "h"); 538 unit = _( /* time unit */ " days");
511 if (dval > 5 * 24) 539 }
512 { 540 }
513 dval = dval / 24;
514 unit = _( /* time unit */ " days");
515 }
516 }
517 }
518 } 541 }
542 }
519 GNUNET_asprintf (&ret, "%llu %s", dval, unit); 543 GNUNET_asprintf (&ret, "%llu %s", dval, unit);
520 return ret; 544 return ret;
521} 545}