1/*
2 * Copyright (C) 2009-2010 Julien BLACHE <jb@jblache.org>
3 *
4 * Some code included below is in the public domain, check comments
5 * in the file.
6 *
7 * Pieces of code adapted from mt-daapd:
8 * Copyright (C) 2003-2007 Ron Pedde (ron@pedde.com)
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23 */
24
25#ifdef HAVE_CONFIG_H
26# include <config.h>
27#endif
28
29#include <stdlib.h>
30#include <string.h>
31#include <errno.h>
32#include <stdint.h>
33#include <limits.h>
34#include <sys/param.h>
35
36#include <unistr.h>
37#include <uniconv.h>
38
39#include "logger.h"
40#include "misc.h"
41
42
43int
44safe_atoi32(const char *str, int32_t *val)
45{
46  char *end;
47  long intval;
48
49  errno = 0;
50  intval = strtol(str, &end, 10);
51
52  if (((errno == ERANGE) && ((intval == LONG_MAX) || (intval == LONG_MIN)))
53      || ((errno != 0) && (intval == 0)))
54    {
55      DPRINTF(E_DBG, L_MISC, "Invalid integer in string (%s): %s\n", str, strerror(errno));
56
57      return -1;
58    }
59
60  if (end == str)
61    {
62      DPRINTF(E_DBG, L_MISC, "No integer found in string (%s)\n", str);
63
64      return -1;
65    }
66
67  if (intval > INT32_MAX)
68    {
69      DPRINTF(E_DBG, L_MISC, "Integer value too large (%s)\n", str);
70
71      return -1;
72    }
73
74  *val = (int32_t)intval;
75
76  return 0;
77}
78
79int
80safe_atou32(const char *str, uint32_t *val)
81{
82  char *end;
83  unsigned long intval;
84
85  errno = 0;
86  intval = strtoul(str, &end, 10);
87
88  if (((errno == ERANGE) && (intval == ULONG_MAX))
89      || ((errno != 0) && (intval == 0)))
90    {
91      DPRINTF(E_DBG, L_MISC, "Invalid integer in string (%s): %s\n", str, strerror(errno));
92
93      return -1;
94    }
95
96  if (end == str)
97    {
98      DPRINTF(E_DBG, L_MISC, "No integer found in string (%s)\n", str);
99
100      return -1;
101    }
102
103  if (intval > UINT32_MAX)
104    {
105      DPRINTF(E_DBG, L_MISC, "Integer value too large (%s)\n", str);
106
107      return -1;
108    }
109
110  *val = (uint32_t)intval;
111
112  return 0;
113}
114
115int
116safe_hextou32(const char *str, uint32_t *val)
117{
118  char *end;
119  unsigned long intval;
120
121  /* A hex shall begin with 0x */
122  if (strncmp(str, "0x", 2) != 0)
123    return safe_atou32(str, val);
124
125  errno = 0;
126  intval = strtoul(str, &end, 16);
127
128  if (((errno == ERANGE) && (intval == ULONG_MAX))
129      || ((errno != 0) && (intval == 0)))
130    {
131      DPRINTF(E_DBG, L_MISC, "Invalid integer in string (%s): %s\n", str, strerror(errno));
132
133      return -1;
134    }
135
136  if (end == str)
137    {
138      DPRINTF(E_DBG, L_MISC, "No integer found in string (%s)\n", str);
139
140      return -1;
141    }
142
143  if (intval > UINT32_MAX)
144    {
145      DPRINTF(E_DBG, L_MISC, "Integer value too large (%s)\n", str);
146
147      return -1;
148    }
149
150  *val = (uint32_t)intval;
151
152  return 0;
153}
154
155int
156safe_atoi64(const char *str, int64_t *val)
157{
158  char *end;
159  long long intval;
160
161  errno = 0;
162  intval = strtoll(str, &end, 10);
163
164  if (((errno == ERANGE) && ((intval == LLONG_MAX) || (intval == LLONG_MIN)))
165      || ((errno != 0) && (intval == 0)))
166    {
167      DPRINTF(E_DBG, L_MISC, "Invalid integer in string (%s): %s\n", str, strerror(errno));
168
169      return -1;
170    }
171
172  if (end == str)
173    {
174      DPRINTF(E_DBG, L_MISC, "No integer found in string (%s)\n", str);
175
176      return -1;
177    }
178
179  if (intval > INT64_MAX)
180    {
181      DPRINTF(E_DBG, L_MISC, "Integer value too large (%s)\n", str);
182
183      return -1;
184    }
185
186  *val = (int64_t)intval;
187
188  return 0;
189}
190
191int
192safe_atou64(const char *str, uint64_t *val)
193{
194  char *end;
195  unsigned long long intval;
196
197  errno = 0;
198  intval = strtoull(str, &end, 10);
199
200  if (((errno == ERANGE) && (intval == ULLONG_MAX))
201      || ((errno != 0) && (intval == 0)))
202    {
203      DPRINTF(E_DBG, L_MISC, "Invalid integer in string (%s): %s\n", str, strerror(errno));
204
205      return -1;
206    }
207
208  if (end == str)
209    {
210      DPRINTF(E_DBG, L_MISC, "No integer found in string (%s)\n", str);
211
212      return -1;
213    }
214
215  if (intval > UINT64_MAX)
216    {
217      DPRINTF(E_DBG, L_MISC, "Integer value too large (%s)\n", str);
218
219      return -1;
220    }
221
222  *val = (uint64_t)intval;
223
224  return 0;
225}
226
227int
228safe_hextou64(const char *str, uint64_t *val)
229{
230  char *end;
231  unsigned long long intval;
232
233  errno = 0;
234  intval = strtoull(str, &end, 16);
235
236  if (((errno == ERANGE) && (intval == ULLONG_MAX))
237      || ((errno != 0) && (intval == 0)))
238    {
239      DPRINTF(E_DBG, L_MISC, "Invalid integer in string (%s): %s\n", str, strerror(errno));
240
241      return -1;
242    }
243
244  if (end == str)
245    {
246      DPRINTF(E_DBG, L_MISC, "No integer found in string (%s)\n", str);
247
248      return -1;
249    }
250
251  if (intval > UINT64_MAX)
252    {
253      DPRINTF(E_DBG, L_MISC, "Integer value too large (%s)\n", str);
254
255      return -1;
256    }
257
258  *val = (uint64_t)intval;
259
260  return 0;
261}
262
263
264/* Key/value functions */
265int
266keyval_add_size(struct keyval *kv, const char *name, const char *value, size_t size)
267{
268  struct onekeyval *okv;
269  const char *val;
270
271  /* Check for duplicate key names */
272  val = keyval_get(kv, name);
273  if (val)
274    {
275      /* Same value, fine */
276      if (strcmp(val, value) == 0)
277        return 0;
278      else /* Different value, bad */
279        return -1;
280    }
281
282  okv = (struct onekeyval *)malloc(sizeof(struct onekeyval));
283  if (!okv)
284    {
285      DPRINTF(E_LOG, L_MISC, "Out of memory for new keyval\n");
286
287      return -1;
288    }
289
290  okv->name = strdup(name);
291  if (!okv->name)
292    {
293      DPRINTF(E_LOG, L_MISC, "Out of memory for new keyval name\n");
294
295      free(okv);
296      return -1;
297    }
298
299  okv->value = (char *)malloc(size + 1);
300  if (!okv->value)
301    {
302      DPRINTF(E_LOG, L_MISC, "Out of memory for new keyval value\n");
303
304      free(okv->name);
305      free(okv);
306      return -1;
307    }
308
309  memcpy(okv->value, value, size);
310  okv->value[size] = '\0';
311
312  okv->next = NULL;
313
314  if (!kv->head)
315    kv->head = okv;
316
317  if (kv->tail)
318    kv->tail->next = okv;
319
320  kv->tail = okv;
321
322  return 0;
323}
324
325int
326keyval_add(struct keyval *kv, const char *name, const char *value)
327{
328  return keyval_add_size(kv, name, value, strlen(value));
329}
330
331void
332keyval_remove(struct keyval *kv, const char *name)
333{
334  struct onekeyval *okv;
335  struct onekeyval *pokv;
336
337  for (pokv = NULL, okv = kv->head; okv; pokv = okv, okv = okv->next)
338    {
339      if (strcasecmp(okv->name, name) == 0)
340        break;
341    }
342
343  if (!okv)
344    return;
345
346  if (okv == kv->head)
347    kv->head = okv->next;
348
349  if (okv == kv->tail)
350    kv->tail = pokv;
351
352  if (pokv)
353    pokv->next = okv->next;
354
355  free(okv->name);
356  free(okv->value);
357  free(okv);
358}
359
360const char *
361keyval_get(struct keyval *kv, const char *name)
362{
363  struct onekeyval *okv;
364
365  for (okv = kv->head; okv; okv = okv->next)
366    {
367      if (strcasecmp(okv->name, name) == 0)
368        return okv->value;
369    }
370
371  return NULL;
372}
373
374void
375keyval_clear(struct keyval *kv)
376{
377  struct onekeyval *hokv;
378  struct onekeyval *okv;
379
380  hokv = kv->head;
381
382  for (okv = hokv; hokv; okv = hokv)
383    {
384      hokv = okv->next;
385
386      free(okv->name);
387      free(okv->value);
388      free(okv);
389    }
390
391  kv->head = NULL;
392  kv->tail = NULL;
393}
394
395
396char *
397m_realpath(const char *pathname)
398{
399  char buf[PATH_MAX];
400  char *ret;
401
402  ret = realpath(pathname, buf);
403  if (!ret)
404    return NULL;
405
406  ret = strdup(buf);
407  if (!ret)
408    {
409      DPRINTF(E_LOG, L_MISC, "Out of memory for realpath\n");
410
411      return NULL;
412    }
413
414  return ret;
415}
416
417char *
418unicode_fixup_string(char *str)
419{
420  uint8_t *ret;
421  size_t len;
422
423  if (!str)
424    return NULL;
425
426  len = strlen(str);
427
428  /* String is valid UTF-8 */
429  if (!u8_check((uint8_t *)str, len))
430    {
431      if (len >= 3)
432	{
433	  /* Check for and strip byte-order mark */
434	  if (memcmp("\xef\xbb\xbf", str, 3) == 0)
435	    memmove(str, str + 3, len - 3 + 1);
436	}
437
438      return str;
439    }
440
441  ret = u8_conv_from_encoding("ascii", iconveh_question_mark, str, len, NULL, NULL, &len);
442  if (!ret)
443    {
444      DPRINTF(E_LOG, L_MISC, "Could not convert string '%s' to UTF-8: %s\n", str, strerror(errno));
445
446      return NULL;
447    }
448
449  return (char *)ret;
450}
451
452uint32_t
453djb_hash(void *data, size_t len)
454{
455  unsigned char *bytes = data;
456  uint32_t hash = 5381;
457
458  while (len--)
459    {
460      hash = ((hash << 5) + hash) + *bytes;
461      bytes++;
462    }
463
464  return hash;
465}
466
467
468static unsigned char b64_decode_table[256];
469
470char *
471b64_decode(const char *b64)
472{
473  char *str;
474  const unsigned char *iptr;
475  unsigned char *optr;
476  unsigned char c;
477  int len;
478  int i;
479
480  if (b64_decode_table[0] == 0)
481    {
482      memset(b64_decode_table, 0xff, sizeof(b64_decode_table));
483
484      /* Base64 encoding: A-Za-z0-9+/ */
485      for (i = 0; i < 26; i++)
486	{
487	  b64_decode_table['A' + i] = i;
488	  b64_decode_table['a' + i] = i + 26;
489	}
490
491      for (i = 0; i < 10; i++)
492	b64_decode_table['0' + i] = i + 52;
493
494      b64_decode_table['+'] = 62;
495      b64_decode_table['/'] = 63;
496
497      /* Stop on '=' */
498      b64_decode_table['='] = 100; /* > 63 */
499    }
500
501  len = strlen(b64);
502
503  str = (char *)malloc(len);
504  if (!str)
505    return NULL;
506
507  memset(str, 0, len);
508
509  iptr = (const unsigned char *)b64;
510  optr = (unsigned char *)str;
511  i = 0;
512
513  while (len)
514    {
515      if (*iptr == '=')
516	break;
517
518      c = b64_decode_table[*iptr];
519      if (c > 63)
520	{
521	  iptr++;
522	  len--;
523	  continue;
524	}
525
526      switch (i)
527	{
528	  case 0:
529	    optr[0] = c << 2;
530	    break;
531	  case 1:
532	    optr[0] |= c >> 4;
533	    optr[1] = c << 4;
534	    break;
535	  case 2:
536	    optr[1] |= c >> 2;
537	    optr[2] = c << 6;
538	    break;
539	  case 3:
540	    optr[2] |= c;
541	    break;
542	}
543
544      i++;
545      if (i == 4)
546	{
547	  optr += 3;
548	  i = 0;
549	}
550
551      len--;
552      iptr++;
553    }
554
555  return str;
556}
557
558static const char b64_encode_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
559
560static void
561b64_encode_block(uint8_t *in, char *out, int len)
562{
563  out[0] = b64_encode_table[in[0] >> 2];
564
565  out[2] = out[3] = '=';
566
567  if (len == 1)
568    out[1] = b64_encode_table[((in[0] & 0x03) << 4)];
569  else
570    {
571      out[1] = b64_encode_table[((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4)];
572
573      if (len == 2)
574	out[2] = b64_encode_table[((in[1] & 0x0f) << 2)];
575      else
576	{
577	  out[2] = b64_encode_table[((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6)];
578	  out[3] = b64_encode_table[in[2] & 0x3f];
579	}
580    }
581}
582
583static void
584b64_encode_full_block(uint8_t *in, char *out)
585{
586  out[0] = b64_encode_table[in[0] >> 2];
587  out[1] = b64_encode_table[((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4)];
588  out[2] = b64_encode_table[((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6)];
589  out[3] = b64_encode_table[in[2] & 0x3f];
590}
591
592char *
593b64_encode(uint8_t *in, size_t len)
594{
595  char *encoded;
596  char *out;
597
598  /* 3 in chars -> 4 out chars */
599  encoded = (char *)malloc(len + (len / 3) + 4 + 1);
600  if (!encoded)
601    return NULL;
602
603  out = encoded;
604
605  while (len >= 3)
606    {
607      b64_encode_full_block(in, out);
608
609      len -= 3;
610      in += 3;
611      out += 4;
612    }
613
614  if (len > 0)
615    {
616      b64_encode_block(in, out, len);
617      out += 4;
618    }
619
620  out[0] = '\0';
621
622  return encoded;
623}
624
625/*
626 * MurmurHash2, 64-bit versions, by Austin Appleby
627 *
628 * Code released under the public domain, as per
629 *    <http://murmurhash.googlepages.com/>
630 * as of 2010-01-03.
631 */
632
633#if SIZEOF_VOID_P == 8 /* 64bit platforms */
634
635uint64_t
636murmur_hash64(const void *key, int len, uint32_t seed)
637{
638  const int r = 47;
639  const uint64_t m = 0xc6a4a7935bd1e995;
640
641  const uint64_t *data;
642  const uint64_t *end;
643  const unsigned char *data_tail;
644  uint64_t h;
645  uint64_t k;
646
647  h = seed ^ (len * m);
648  data = (const uint64_t *)key;
649  end = data + (len / 8);
650
651  while (data != end)
652    {
653      k = *data++;
654
655      k *= m;
656      k ^= k >> r;
657      k *= m;
658
659      h ^= k;
660      h *= m;
661    }
662
663  data_tail = (const unsigned char *)data;
664
665  switch (len & 7)
666    {
667      case 7:
668	h ^= (uint64_t)(data_tail[6]) << 48;
669      case 6:
670	h ^= (uint64_t)(data_tail[5]) << 40;
671      case 5:
672	h ^= (uint64_t)(data_tail[4]) << 32;
673      case 4:
674	h ^= (uint64_t)(data_tail[3]) << 24;
675      case 3:
676	h ^= (uint64_t)(data_tail[2]) << 16;
677      case 2:
678	h ^= (uint64_t)(data_tail[1]) << 8;
679      case 1:
680	h ^= (uint64_t)(data_tail[0]);
681	h *= m;
682    }
683
684  h ^= h >> r;
685  h *= m;
686  h ^= h >> r;
687
688  return h;
689}
690
691#elif SIZEOF_VOID_P == 4 /* 32bit platforms */
692
693uint64_t
694murmur_hash64(const void *key, int len, uint32_t seed)
695{
696  const int r = 24;
697  const uint32_t m = 0x5bd1e995;
698
699  const uint32_t *data;
700  const unsigned char *data_tail;
701  uint32_t k1;
702  uint32_t h1;
703  uint32_t k2;
704  uint32_t h2;
705
706  uint64_t h;
707
708  h1 = seed ^ len;
709  h2 = 0;
710
711  data = (const uint32_t *)key;
712
713  while (len >= 8)
714    {
715      k1 = *data++;
716      k1 *= m; k1 ^= k1 >> r; k1 *= m;
717      h1 *= m; h1 ^= k1;
718
719      k2 = *data++;
720      k2 *= m; k2 ^= k2 >> r; k2 *= m;
721      h2 *= m; h2 ^= k2;
722
723      len -= 8;
724    }
725
726  if (len >= 4)
727    {
728      k1 = *data++;
729      k1 *= m; k1 ^= k1 >> r; k1 *= m;
730      h1 *= m; h1 ^= k1;
731      len -= 4;
732    }
733
734  data_tail = (const unsigned char *)data;
735
736  switch(len)
737    {
738      case 3:
739	h2 ^= (uint32_t)(data_tail[2]) << 16;
740      case 2:
741	h2 ^= (uint32_t)(data_tail[1]) << 8;
742      case 1:
743	h2 ^= (uint32_t)(data_tail[0]);
744	h2 *= m;
745    };
746
747  h1 ^= h2 >> 18; h1 *= m;
748  h2 ^= h1 >> 22; h2 *= m;
749  h1 ^= h2 >> 17; h1 *= m;
750  h2 ^= h1 >> 19; h2 *= m;
751
752  h = h1;
753  h = (h << 32) | h2;
754
755  return h;
756}
757
758#else
759# error Platform not supported
760#endif
761