version 0.2.15
[fms.git] / libs / shttpd / string.c
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
11 #include "defs.h"
12
13 void
14 my_strlcpy(register char *dst, register const char *src, size_t n)
15 {
16         for (; *src != '\0' && n > 1; n--)
17                 *dst++ = *src++;
18         *dst = '\0';
19 }
20
21 int
22 my_strncasecmp(const char *str1, const char *str2, size_t len)
23 {
24         register const unsigned char    *s1 = (unsigned char *) str1,
25                                         *s2 = (unsigned char *) str2, *e;
26         int                             ret;
27
28         for (e = s1 + len - 1; s1 < e && *s1 != '\0' && *s2 != '\0' &&
29             tolower(*s1) == tolower(*s2); s1++, s2++) ;
30         ret = tolower(*s1) - tolower(*s2);
31
32         return (ret);
33 }
34
35 char *
36 my_strndup(const char *ptr, size_t len)
37 {
38         char    *p;
39
40         if ((p = malloc(len + 1)) != NULL)
41                 my_strlcpy(p, ptr, len + 1);
42
43         return (p);
44
45 }
46
47 char *
48 my_strdup(const char *str)
49 {
50         return (my_strndup(str, strlen(str)));
51 }
52
53 /*
54  * Sane snprintf(). Acts like snprintf(), but never return -1 or the
55  * value bigger than supplied buffer.
56  * Thanks Adam Zeldis to pointing snprintf()-caused vulnerability
57  * in his audit report.
58  */
59 int
60 my_snprintf(char *buf, size_t buflen, const char *fmt, ...)
61 {
62         va_list         ap;
63         int             n;
64
65         if (buflen == 0)
66                 return (0);
67
68         va_start(ap, fmt);
69         n = vsnprintf(buf, buflen, fmt, ap);
70         va_end(ap);
71
72         if (n < 0 || (size_t) n >= buflen)
73                 n = buflen - 1;
74         buf[n] = '\0';
75
76         return (n);
77 }
78
79 /*
80  * Verify that given file has certain extension
81  */
82 int
83 match_extension(const char *path, const char *ext_list)
84 {
85         size_t          len, path_len;
86         
87         path_len = strlen(path);
88
89         FOR_EACH_WORD_IN_LIST(ext_list, len)
90                 if (len < path_len && path[path_len - len - 1] == '.' &&
91                     !my_strncasecmp(path + path_len - len, ext_list, len))
92                         return (TRUE);
93
94         return (FALSE);
95 }