18d59ecb2SHans Petter Selasky /*-
28d59ecb2SHans Petter Selasky  * Copyright (c) 2010 Isilon Systems, Inc.
38d59ecb2SHans Petter Selasky  * Copyright (c) 2010 iX Systems, Inc.
48d59ecb2SHans Petter Selasky  * Copyright (c) 2010 Panasas, Inc.
50f32531aSHans Petter Selasky  * Copyright (c) 2013-2017 Mellanox Technologies, Ltd.
68d59ecb2SHans Petter Selasky  * All rights reserved.
78d59ecb2SHans Petter Selasky  *
88d59ecb2SHans Petter Selasky  * Redistribution and use in source and binary forms, with or without
98d59ecb2SHans Petter Selasky  * modification, are permitted provided that the following conditions
108d59ecb2SHans Petter Selasky  * are met:
118d59ecb2SHans Petter Selasky  * 1. Redistributions of source code must retain the above copyright
128d59ecb2SHans Petter Selasky  *    notice unmodified, this list of conditions, and the following
138d59ecb2SHans Petter Selasky  *    disclaimer.
148d59ecb2SHans Petter Selasky  * 2. Redistributions in binary form must reproduce the above copyright
158d59ecb2SHans Petter Selasky  *    notice, this list of conditions and the following disclaimer in the
168d59ecb2SHans Petter Selasky  *    documentation and/or other materials provided with the distribution.
178d59ecb2SHans Petter Selasky  *
188d59ecb2SHans Petter Selasky  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
198d59ecb2SHans Petter Selasky  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
208d59ecb2SHans Petter Selasky  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
218d59ecb2SHans Petter Selasky  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
228d59ecb2SHans Petter Selasky  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
238d59ecb2SHans Petter Selasky  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
248d59ecb2SHans Petter Selasky  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
258d59ecb2SHans Petter Selasky  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
268d59ecb2SHans Petter Selasky  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
278d59ecb2SHans Petter Selasky  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
288d59ecb2SHans Petter Selasky  *
298d59ecb2SHans Petter Selasky  * $FreeBSD$
308d59ecb2SHans Petter Selasky  */
318d59ecb2SHans Petter Selasky #ifndef	_LINUX_STRING_H_
328d59ecb2SHans Petter Selasky #define	_LINUX_STRING_H_
338d59ecb2SHans Petter Selasky 
340f32531aSHans Petter Selasky #include <sys/ctype.h>
350f32531aSHans Petter Selasky 
368d59ecb2SHans Petter Selasky #include <linux/types.h>
378d59ecb2SHans Petter Selasky #include <linux/gfp.h>
388d59ecb2SHans Petter Selasky #include <linux/slab.h>
390f32531aSHans Petter Selasky #include <linux/uaccess.h>
400f32531aSHans Petter Selasky #include <linux/err.h>
418d59ecb2SHans Petter Selasky 
428d59ecb2SHans Petter Selasky #include <sys/libkern.h>
438d59ecb2SHans Petter Selasky 
44510ebed7SHans Petter Selasky #define	strnicmp(...) strncasecmp(__VA_ARGS__)
458d59ecb2SHans Petter Selasky 
460f32531aSHans Petter Selasky static inline int
match_string(const char * const * table,int n,const char * key)470f32531aSHans Petter Selasky match_string(const char *const *table, int n, const char *key)
480f32531aSHans Petter Selasky {
490f32531aSHans Petter Selasky 	int i;
500f32531aSHans Petter Selasky 
510f32531aSHans Petter Selasky 	for (i = 0; i != n && table[i] != NULL; i++) {
520f32531aSHans Petter Selasky 		if (strcmp(table[i], key) == 0)
530f32531aSHans Petter Selasky 			return (i);
540f32531aSHans Petter Selasky 	}
550f32531aSHans Petter Selasky 	return (-EINVAL);
560f32531aSHans Petter Selasky }
570f32531aSHans Petter Selasky 
580f32531aSHans Petter Selasky static inline void *
memdup_user(const void * ptr,size_t len)590f32531aSHans Petter Selasky memdup_user(const void *ptr, size_t len)
600f32531aSHans Petter Selasky {
610f32531aSHans Petter Selasky 	void *retval;
620f32531aSHans Petter Selasky 	int error;
630f32531aSHans Petter Selasky 
640f32531aSHans Petter Selasky 	retval = malloc(len, M_KMALLOC, M_WAITOK);
650f32531aSHans Petter Selasky 	error = linux_copyin(ptr, retval, len);
660f32531aSHans Petter Selasky 	if (error != 0) {
670f32531aSHans Petter Selasky 		free(retval, M_KMALLOC);
680f32531aSHans Petter Selasky 		return (ERR_PTR(error));
690f32531aSHans Petter Selasky 	}
700f32531aSHans Petter Selasky 	return (retval);
710f32531aSHans Petter Selasky }
720f32531aSHans Petter Selasky 
738d59ecb2SHans Petter Selasky static inline void *
memdup_user_nul(const void * ptr,size_t len)74*10ee3d30SHans Petter Selasky memdup_user_nul(const void *ptr, size_t len)
75*10ee3d30SHans Petter Selasky {
76*10ee3d30SHans Petter Selasky 	char *retval;
77*10ee3d30SHans Petter Selasky 	int error;
78*10ee3d30SHans Petter Selasky 
79*10ee3d30SHans Petter Selasky 	retval = malloc(len + 1, M_KMALLOC, M_WAITOK);
80*10ee3d30SHans Petter Selasky 	error = linux_copyin(ptr, retval, len);
81*10ee3d30SHans Petter Selasky 	if (error != 0) {
82*10ee3d30SHans Petter Selasky 		free(retval, M_KMALLOC);
83*10ee3d30SHans Petter Selasky 		return (ERR_PTR(error));
84*10ee3d30SHans Petter Selasky 	}
85*10ee3d30SHans Petter Selasky 	retval[len] = '\0';
86*10ee3d30SHans Petter Selasky 	return (retval);
87*10ee3d30SHans Petter Selasky }
88*10ee3d30SHans Petter Selasky 
89*10ee3d30SHans Petter Selasky static inline void *
kmemdup(const void * src,size_t len,gfp_t gfp)908d59ecb2SHans Petter Selasky kmemdup(const void *src, size_t len, gfp_t gfp)
918d59ecb2SHans Petter Selasky {
928d59ecb2SHans Petter Selasky 	void *dst;
938d59ecb2SHans Petter Selasky 
948d59ecb2SHans Petter Selasky 	dst = kmalloc(len, gfp);
950f32531aSHans Petter Selasky 	if (dst != NULL)
968d59ecb2SHans Petter Selasky 		memcpy(dst, src, len);
978d59ecb2SHans Petter Selasky 	return (dst);
988d59ecb2SHans Petter Selasky }
998d59ecb2SHans Petter Selasky 
1000f32531aSHans Petter Selasky static inline char *
kstrdup(const char * string,gfp_t gfp)1010f32531aSHans Petter Selasky kstrdup(const char *string, gfp_t gfp)
1020f32531aSHans Petter Selasky {
1030f32531aSHans Petter Selasky 	char *retval;
1040f32531aSHans Petter Selasky 	size_t len;
1050f32531aSHans Petter Selasky 
1060f32531aSHans Petter Selasky 	len = strlen(string) + 1;
1070f32531aSHans Petter Selasky 	retval = kmalloc(len, gfp);
1080f32531aSHans Petter Selasky 	if (retval != NULL)
1090f32531aSHans Petter Selasky 		memcpy(retval, string, len);
1100f32531aSHans Petter Selasky 	return (retval);
1110f32531aSHans Petter Selasky }
1120f32531aSHans Petter Selasky 
1130f32531aSHans Petter Selasky static inline char *
kstrndup(const char * string,size_t len,gfp_t gfp)1140f32531aSHans Petter Selasky kstrndup(const char *string, size_t len, gfp_t gfp)
1150f32531aSHans Petter Selasky {
1160f32531aSHans Petter Selasky 	char *retval;
1170f32531aSHans Petter Selasky 
1180f32531aSHans Petter Selasky 	retval = kmalloc(len + 1, gfp);
1190f32531aSHans Petter Selasky 	if (retval != NULL)
1200f32531aSHans Petter Selasky 		strncpy(retval, string, len);
1210f32531aSHans Petter Selasky 	return (retval);
1220f32531aSHans Petter Selasky }
1230f32531aSHans Petter Selasky 
124510ebed7SHans Petter Selasky static inline const char *
kstrdup_const(const char * src,gfp_t gfp)125510ebed7SHans Petter Selasky kstrdup_const(const char *src, gfp_t gfp)
126510ebed7SHans Petter Selasky {
127510ebed7SHans Petter Selasky 	return (kmemdup(src, strlen(src) + 1, gfp));
128510ebed7SHans Petter Selasky }
129510ebed7SHans Petter Selasky 
1300f32531aSHans Petter Selasky static inline char *
skip_spaces(const char * str)1310f32531aSHans Petter Selasky skip_spaces(const char *str)
1320f32531aSHans Petter Selasky {
1330f32531aSHans Petter Selasky 	while (isspace(*str))
1340f32531aSHans Petter Selasky 		++str;
1350f32531aSHans Petter Selasky 	return (__DECONST(char *, str));
1360f32531aSHans Petter Selasky }
1370f32531aSHans Petter Selasky 
1380f32531aSHans Petter Selasky static inline void *
memchr_inv(const void * start,int c,size_t length)1390f32531aSHans Petter Selasky memchr_inv(const void *start, int c, size_t length)
1400f32531aSHans Petter Selasky {
1410f32531aSHans Petter Selasky 	const u8 *ptr;
1420f32531aSHans Petter Selasky 	const u8 *end;
1430f32531aSHans Petter Selasky 	u8 ch;
1440f32531aSHans Petter Selasky 
1450f32531aSHans Petter Selasky 	ch = c;
1460f32531aSHans Petter Selasky 	ptr = start;
1470f32531aSHans Petter Selasky 	end = ptr + length;
1480f32531aSHans Petter Selasky 
1490f32531aSHans Petter Selasky 	while (ptr != end) {
1500f32531aSHans Petter Selasky 		if (*ptr != ch)
1510f32531aSHans Petter Selasky 			return (__DECONST(void *, ptr));
1520f32531aSHans Petter Selasky 		ptr++;
1530f32531aSHans Petter Selasky 	}
1540f32531aSHans Petter Selasky 	return (NULL);
1550f32531aSHans Petter Selasky }
1560f32531aSHans Petter Selasky 
1578d59ecb2SHans Petter Selasky #endif					/* _LINUX_STRING_H_ */
158