nwrap: Fix resolving hostnames with a trailing dot.
[sfrench/samba-autobuild/.git] / lib / util / util_str_common.c
index 9999ee440ec7448a330a624aae8eba1c2847e371..0933e183c8063681127e3ce8a389b631b22ed3a7 100644 (file)
@@ -24,7 +24,7 @@
 #include "includes.h"
 
 /**
-Do a case-insensitive, whitespace-ignoring string compare.
+Do a case-insensitive, whitespace-ignoring ASCII string compare.
 **/
 _PUBLIC_ int strwicmp(const char *psz1, const char *psz2)
 {
@@ -43,7 +43,13 @@ _PUBLIC_ int strwicmp(const char *psz1, const char *psz2)
                        psz1++;
                while (isspace((int)*psz2))
                        psz2++;
-               if (toupper_ascii((unsigned char)*psz1) != toupper_ascii((unsigned char)*psz2)
+
+               /*
+                * This does not do a genuine multi-byte comparison,
+                * instead it just uses the fast-path for ASCII in
+                * these common routines
+                */
+               if (toupper_m((unsigned char)*psz1) != toupper_m((unsigned char)*psz2)
                    || *psz1 == '\0'
                    || *psz2 == '\0')
                        break;
@@ -59,3 +65,97 @@ _PUBLIC_ size_t ucs2_align(const void *base_ptr, const void *p, int flags)
                return 0;
        return PTR_DIFF(p, base_ptr) & 1;
 }
+
+/**
+ String replace.
+ NOTE: oldc and newc must be 7 bit characters
+**/
+void string_replace( char *s, char oldc, char newc )
+{
+       char *p;
+
+       /* this is quite a common operation, so we want it to be
+          fast. We optimise for the ascii case, knowing that all our
+          supported multi-byte character sets are ascii-compatible
+          (ie. they match for the first 128 chars) */
+
+       for (p = s; *p; p++) {
+               if (*p & 0x80) /* mb string - slow path. */
+                       break;
+               if (*p == oldc) {
+                       *p = newc;
+               }
+       }
+
+       if (!*p)
+               return;
+
+       /* Slow (mb) path. */
+#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
+       /* With compose characters we must restart from the beginning. JRA. */
+       p = s;
+#endif
+
+       while (*p) {
+               size_t c_size;
+               next_codepoint(p, &c_size);
+
+               if (c_size == 1) {
+                       if (*p == oldc) {
+                               *p = newc;
+                       }
+               }
+               p += c_size;
+       }
+}
+
+
+/**
+ Paranoid strcpy into a buffer of given length (includes terminating
+ zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
+ and replaces with '_'. Deliberately does *NOT* check for multibyte
+ characters. Treats src as an array of bytes, not as a multibyte
+ string. Any byte >0x7f is automatically converted to '_'.
+ other_safe_chars must also contain an ascii string (bytes<0x7f).
+**/
+
+char *alpha_strcpy(char *dest,
+                  const char *src,
+                  const char *other_safe_chars,
+                  size_t maxlength)
+{
+       size_t len, i;
+
+       if (!dest) {
+               smb_panic("ERROR: NULL dest in alpha_strcpy");
+       }
+
+       if (!src) {
+               *dest = 0;
+               return dest;
+       }
+
+       len = strlen(src);
+       if (len >= maxlength)
+               len = maxlength - 1;
+
+       if (!other_safe_chars)
+               other_safe_chars = "";
+
+       for(i = 0; i < len; i++) {
+               int val = (src[i] & 0xff);
+               if (val > 0x7f) {
+                       dest[i] = '_';
+                       continue;
+               }
+               if (isupper(val) || islower(val) ||
+                               isdigit(val) || strchr(other_safe_chars, val))
+                       dest[i] = src[i];
+               else
+                       dest[i] = '_';
+       }
+
+       dest[i] = '\0';
+
+       return dest;
+}