Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * lib/parser.c - simple parser for mount, etc. options.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/parser.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * match_one: - Determines if a string matches a simple pattern
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * @s: the string to examine for presence of the pattern
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * @p: the string containing the pattern
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * @args: array of %MAX_OPT_ARGS &substring_t elements. Used to return match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * locations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * Description: Determines if the pattern @p is present in string @s. Can only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * match extremely simple token=arg style patterns. If the pattern is found,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * the location(s) of the arguments will be returned in the @args array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) static int match_one(char *s, const char *p, substring_t args[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	char *meta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	int argc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	while(1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 		int len = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 		meta = strchr(p, '%');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 		if (!meta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 			return strcmp(p, s) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 		if (strncmp(p, s, meta-p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		s += meta - p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 		p = meta + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 		if (isdigit(*p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 			len = simple_strtoul(p, (char **) &p, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		else if (*p == '%') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 			if (*s++ != '%')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 			p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		if (argc >= MAX_OPT_ARGS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		args[argc].from = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		switch (*p++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		case 's': {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 			size_t str_len = strlen(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 			if (str_len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 			if (len == -1 || len > str_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 				len = str_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 			args[argc].to = s + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		case 'd':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 			simple_strtol(s, &args[argc].to, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 			goto num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		case 'u':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 			simple_strtoul(s, &args[argc].to, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 			goto num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		case 'o':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 			simple_strtoul(s, &args[argc].to, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 			goto num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		case 'x':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 			simple_strtoul(s, &args[argc].to, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		num:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 			if (args[argc].to == args[argc].from)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		s = args[argc].to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		argc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)  * match_token: - Find a token (and optional args) in a string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)  * @s: the string to examine for token/argument pairs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)  * @table: match_table_t describing the set of allowed option tokens and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)  * arguments that may be associated with them. Must be terminated with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)  * &struct match_token whose pattern is set to the NULL pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)  * @args: array of %MAX_OPT_ARGS &substring_t elements. Used to return match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)  * locations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)  * Description: Detects which if any of a set of token strings has been passed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)  * to it. Tokens can include up to MAX_OPT_ARGS instances of basic c-style
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  * format identifiers which will be taken into account when matching the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  * tokens, and whose locations will be returned in the @args array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int match_token(char *s, const match_table_t table, substring_t args[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	const struct match_token *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	for (p = table; !match_one(s, p->pattern, args) ; p++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	return p->token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) EXPORT_SYMBOL(match_token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)  * match_number: scan a number in the given base from a substring_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)  * @s: substring to be scanned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)  * @result: resulting integer on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)  * @base: base to use when converting string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  * Description: Given a &substring_t and a base, attempts to parse the substring
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  * as a number in that base. On success, sets @result to the integer represented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  * by the string and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static int match_number(substring_t *s, int *result, int base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	char *endp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	buf = match_strdup(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	val = simple_strtol(buf, &endp, base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	if (endp == buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	else if (val < (long)INT_MIN || val > (long)INT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		ret = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		*result = (int) val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)  * match_u64int: scan a number in the given base from a substring_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)  * @s: substring to be scanned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)  * @result: resulting u64 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)  * @base: base to use when converting string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)  * Description: Given a &substring_t and a base, attempts to parse the substring
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)  * as a number in that base. On success, sets @result to the integer represented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)  * by the string and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) static int match_u64int(substring_t *s, u64 *result, int base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	u64 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	buf = match_strdup(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	ret = kstrtoull(buf, base, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		*result = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)  * match_int: - scan a decimal representation of an integer from a substring_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)  * @s: substring_t to be scanned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)  * @result: resulting integer on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)  * Description: Attempts to parse the &substring_t @s as a decimal integer. On
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)  * success, sets @result to the integer represented by the string and returns 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)  * Returns -ENOMEM, -EINVAL, or -ERANGE on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) int match_int(substring_t *s, int *result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	return match_number(s, result, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) EXPORT_SYMBOL(match_int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)  * match_u64: - scan a decimal representation of a u64 from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)  *                  a substring_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)  * @s: substring_t to be scanned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)  * @result: resulting unsigned long long on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)  * Description: Attempts to parse the &substring_t @s as a long decimal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)  * integer. On success, sets @result to the integer represented by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)  * string and returns 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)  * Returns -ENOMEM, -EINVAL, or -ERANGE on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) int match_u64(substring_t *s, u64 *result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	return match_u64int(s, result, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) EXPORT_SYMBOL(match_u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)  * match_octal: - scan an octal representation of an integer from a substring_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)  * @s: substring_t to be scanned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)  * @result: resulting integer on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)  * Description: Attempts to parse the &substring_t @s as an octal integer. On
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)  * success, sets @result to the integer represented by the string and returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)  * 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) int match_octal(substring_t *s, int *result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	return match_number(s, result, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) EXPORT_SYMBOL(match_octal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)  * match_hex: - scan a hex representation of an integer from a substring_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)  * @s: substring_t to be scanned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)  * @result: resulting integer on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)  * Description: Attempts to parse the &substring_t @s as a hexadecimal integer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)  * On success, sets @result to the integer represented by the string and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)  * returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) int match_hex(substring_t *s, int *result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	return match_number(s, result, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) EXPORT_SYMBOL(match_hex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)  * match_wildcard: - parse if a string matches given wildcard pattern
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)  * @pattern: wildcard pattern
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)  * @str: the string to be parsed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)  * Description: Parse the string @str to check if matches wildcard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)  * pattern @pattern. The pattern may contain two type wildcardes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)  *   '*' - matches zero or more characters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)  *   '?' - matches one character
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)  * If it's matched, return true, else return false.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) bool match_wildcard(const char *pattern, const char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	const char *s = str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	const char *p = pattern;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	bool star = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	while (*s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		switch (*p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		case '?':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 			s++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 			p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		case '*':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 			star = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 			str = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 			if (!*++p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 				return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 			pattern = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 			if (*s == *p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 				s++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 				p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 				if (!star)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 					return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 				str++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 				s = str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 				p = pattern;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	if (*p == '*')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		++p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	return !*p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) EXPORT_SYMBOL(match_wildcard);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)  * match_strlcpy: - Copy the characters from a substring_t to a sized buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)  * @dest: where to copy to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)  * @src: &substring_t to copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)  * @size: size of destination buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)  * Description: Copy the characters in &substring_t @src to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)  * c-style string @dest.  Copy no more than @size - 1 characters, plus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)  * the terminating NUL.  Return length of @src.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) size_t match_strlcpy(char *dest, const substring_t *src, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	size_t ret = src->to - src->from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	if (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		size_t len = ret >= size ? size - 1 : ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		memcpy(dest, src->from, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		dest[len] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) EXPORT_SYMBOL(match_strlcpy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)  * match_strdup: - allocate a new string with the contents of a substring_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)  * @s: &substring_t to copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)  * Description: Allocates and returns a string filled with the contents of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)  * the &substring_t @s. The caller is responsible for freeing the returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)  * string with kfree().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) char *match_strdup(const substring_t *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	return kmemdup_nul(s->from, s->to - s->from, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) EXPORT_SYMBOL(match_strdup);