return NULL;
 }
 
-/* Glob expression pattern matching */
+/* Character class matching */
+static bool __match_charclass(const char *pat, char c, const char **npat)
+{
+       bool complement = false, ret = true;
+
+       if (*pat == '!') {
+               complement = true;
+               pat++;
+       }
+       if (*pat++ == c)        /* First character is special */
+               goto end;
+
+       while (*pat && *pat != ']') {   /* Matching */
+               if (*pat == '-' && *(pat + 1) != ']') { /* Range */
+                       if (*(pat - 1) <= c && c <= *(pat + 1))
+                               goto end;
+                       if (*(pat - 1) > *(pat + 1))
+                               goto error;
+                       pat += 2;
+               } else if (*pat++ == c)
+                       goto end;
+       }
+       if (!*pat)
+               goto error;
+       ret = false;
+
+end:
+       while (*pat && *pat != ']')     /* Searching closing */
+               pat++;
+       if (!*pat)
+               goto error;
+       *npat = pat + 1;
+       return complement ? !ret : ret;
+
+error:
+       return false;
+}
+
+/**
+ * strglobmatch - glob expression pattern matching
+ * @str: the target string to match
+ * @pat: the pattern string to match
+ *
+ * This returns true if the @str matches @pat. @pat can includes wildcards
+ * ('*','?') and character classes ([CHARS], complementation and ranges are
+ * also supported). Also, this supports escape character ('\') to use special
+ * characters as normal character.
+ *
+ * Note: if @pat syntax is broken, this always returns false.
+ */
 bool strglobmatch(const char *str, const char *pat)
 {
        while (*str && *pat && *pat != '*') {
-               if (*pat == '?') {
+               if (*pat == '?') {      /* Matches any single character */
                        str++;
                        pat++;
-               } else
-                       if (*str++ != *pat++)
+                       continue;
+               } else if (*pat == '[') /* Character classes/Ranges */
+                       if (__match_charclass(pat + 1, *str, &pat)) {
+                               str++;
+                               continue;
+                       } else
                                return false;
+               else if (*pat == '\\') /* Escaped char match as normal char */
+                       pat++;
+               if (*str++ != *pat++)
+                       return false;
        }
        /* Check wild card */
        if (*pat == '*') {