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.c291
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 */
57size_t 61size_t
58GNUNET_STRINGS_buffer_fill (char *buffer, size_t size, unsigned int count, ...) 62GNUNET_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 */
98unsigned int 103unsigned int
99GNUNET_STRINGS_buffer_tokenize (const char *buffer, size_t size, 104GNUNET_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}