string.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*
  2. * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
  3. * All rights reserved
  4. *
  5. * "THE BEER-WARE LICENSE" (Revision 42):
  6. * Sergey Lyubka wrote this file. As long as you retain this notice you
  7. * can do whatever you want with this stuff. If we meet some day, and you think
  8. * this stuff is worth it, you can buy me a beer in return.
  9. */
  10. #include "defs.h"
  11. void
  12. _shttpd_strlcpy(register char *dst, register const char *src, size_t n)
  13. {
  14. for (; *src != '\0' && n > 1; n--)
  15. *dst++ = *src++;
  16. *dst = '\0';
  17. }
  18. int
  19. _shttpd_strncasecmp(const char *str1, const char *str2, size_t len)
  20. {
  21. register const unsigned char *s1 = (unsigned char *) str1,
  22. *s2 = (unsigned char *) str2, *e;
  23. int ret;
  24. for (e = s1 + len - 1; s1 < e && *s1 != '\0' && *s2 != '\0' &&
  25. tolower(*s1) == tolower(*s2); s1++, s2++) ;
  26. ret = tolower(*s1) - tolower(*s2);
  27. return (ret);
  28. }
  29. char *
  30. _shttpd_strndup(const char *ptr, size_t len)
  31. {
  32. char *p;
  33. if ((p = malloc(len + 1)) != NULL)
  34. _shttpd_strlcpy(p, ptr, len + 1);
  35. return (p);
  36. }
  37. char *
  38. _shttpd_strdup(const char *str)
  39. {
  40. return (_shttpd_strndup(str, strlen(str)));
  41. }
  42. /*
  43. * Sane snprintf(). Acts like snprintf(), but never return -1 or the
  44. * value bigger than supplied buffer.
  45. * Thanks Adam Zeldis to pointing snprintf()-caused vulnerability
  46. * in his audit report.
  47. */
  48. int
  49. _shttpd_snprintf(char *buf, size_t buflen, const char *fmt, ...)
  50. {
  51. va_list ap;
  52. int n;
  53. if (buflen == 0)
  54. return (0);
  55. va_start(ap, fmt);
  56. n = vsnprintf(buf, buflen, fmt, ap);
  57. va_end(ap);
  58. if (n < 0 || (size_t) n >= buflen)
  59. n = buflen - 1;
  60. buf[n] = '\0';
  61. return (n);
  62. }
  63. /*
  64. * Verify that given file has certain extension
  65. */
  66. int
  67. _shttpd_match_extension(const char *path, const char *ext_list)
  68. {
  69. size_t len, path_len;
  70. path_len = strlen(path);
  71. FOR_EACH_WORD_IN_LIST(ext_list, len)
  72. if (len < path_len && path[path_len - len - 1] == '.' &&
  73. !_shttpd_strncasecmp(path + path_len - len, ext_list, len))
  74. return (TRUE);
  75. return (FALSE);
  76. }