+/*
+ * Appends src to string dst of size siz (unlike strncat, siz is the
+ * full size of dst, not space left). At most siz-1 characters
+ * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
+ * Returns strlen(src) + MIN(siz, strlen(initial dst)).
+ * If retval >= siz, truncation occurred.
+ */
+size_t
+strlcat(char *dst, const char *src, size_t siz)
+{
+ char *d = dst;
+ const char *s = src;
+ size_t n = siz;
+ size_t dlen;
+
+ /* Find the end of dst and adjust bytes left but don't go past end */
+ while (n-- != 0 && *d != '\0')
+ d++;
+ dlen = d - dst;
+ n = siz - dlen;
+
+ if (n == 0)
+ return(dlen + strlen(s));
+ while (*s != '\0') {
+ if (n != 1) {
+ *d++ = *s;
+ n--;
+ }
+ s++;
+ }
+ *d = '\0';
+
+ return(dlen + (s - src)); /* count does not include NUL */
+}
+
+/*
+ * Copy src to string dst of size siz. At most siz-1 characters
+ * will be copied. Always NUL terminates (unless siz == 0).
+ * Returns strlen(src); if retval >= siz, truncation occurred.
+ */
+
+// ARM and ARM64 implementation in ../arm/strlcpy.c
+size_t
+strlcpy(char *dst, const char *src, size_t siz)
+{
+ char *d = dst;
+ const char *s = src;
+ size_t n = siz;
+
+ /* Copy as many bytes as will fit */
+ if (n != 0 && --n != 0) {
+ do {
+ if ((*d++ = *s++) == 0)
+ break;
+ } while (--n != 0);
+ }
+
+ /* Not enough room in dst, add NUL and traverse rest of src */
+ if (n == 0) {
+ if (siz != 0)
+ *d = '\0'; /* NUL-terminate dst */
+ while (*s++)
+ ;
+ }
+
+ return(s - src - 1); /* count does not include NUL */
+}
+
+/*
+ * STRDUP
+ *
+ * Description: The STRDUP function allocates sufficient memory for a copy
+ * of the string "string", does the copy, and returns a pointer
+ * it. The pointer may subsequently be used as an argument to
+ * the macro FREE().
+ *
+ * Parameters: string String to be duplicated
+ * type type of memory to be allocated (normally
+ * M_TEMP)
+ *
+ * Returns: char * A pointer to the newly allocated string with
+ * duplicated contents in it.
+ *
+ * NULL If MALLOC() fails.
+ *
+ * Note: This function can *not* be called from interrupt context as
+ * it calls MALLOC with M_WAITOK. In fact, you really
+ * shouldn't be doing string manipulation in interrupt context
+ * ever.
+ *
+ * This function name violates the kernel style(9) guide
+ * by being all caps. This was done on purpose to emphasize
+ * one should use FREE() with the allocated buffer.
+ *
+ */
+char *
+STRDUP(const char *string, int type)
+{
+ size_t len;
+ char *copy;
+
+ len = strlen(string) + 1;
+ MALLOC(copy, char *, len, type, M_WAITOK);
+ if (copy == NULL)
+ return (NULL);
+ bcopy(string, copy, len);
+ return (copy);
+}
+
+/*
+ * Return TRUE(1) if string 2 is a prefix of string 1.
+ */
+int
+strprefix(const char *s1, const char *s2)
+{
+ int c;
+
+ while ((c = *s2++) != '\0') {
+ if (c != *s1++)
+ return (0);
+ }
+ return (1);
+}
+
+char *
+strnstr(char *s, const char *find, size_t slen)
+{
+ char c, sc;
+ size_t len;
+
+ if ((c = *find++) != '\0') {
+ len = strlen(find);
+ do {
+ do {
+ if ((sc = *s++) == '\0' || slen-- < 1)
+ return (NULL);
+ } while (sc != c);
+ if (len > slen)
+ return (NULL);
+ } while (strncmp(s, find, len) != 0);
+ s--;
+ }
+ return (s);
+}
+