/** Case insensitive string compararison, handle specified for testing **/ _PUBLIC_ int strcasecmp_m_handle(struct smb_iconv_handle *iconv_handle, const char *s1, const char *s2) { codepoint_t c1=0, c2=0; size_t size1, size2; /* handle null ptr comparisons to simplify the use in qsort */ if (s1 == s2) return 0; if (s1 == NULL) return -1; if (s2 == NULL) return 1; while (*s1 && *s2) { c1 = next_codepoint_handle(iconv_handle, s1, &size1); c2 = next_codepoint_handle(iconv_handle, s2, &size2); if (c1 == INVALID_CODEPOINT || c2 == INVALID_CODEPOINT) { return strcasecmp(s1, s2); } s1 += size1; s2 += size2; if (c1 == c2) { continue; } if (toupper_m(c1) != toupper_m(c2)) { return c1 - c2; } } return *s1 - *s2; }
static bool test_toupper_m(struct torture_context *tctx) { torture_assert_int_equal(tctx, toupper_m('c'), 'C', "c"); torture_assert_int_equal(tctx, toupper_m('Z'), 'Z', "z"); torture_assert_int_equal(tctx, toupper_m(0xFFFF4565), 0xFFFF4565, "0xFFFF4565"); return true; }
/** Case insensitive string compararison, length limited, handle specified for testing **/ _PUBLIC_ int strncasecmp_m_handle(struct smb_iconv_handle *iconv_handle, const char *s1, const char *s2, size_t n) { codepoint_t c1=0, c2=0; size_t size1, size2; /* handle null ptr comparisons to simplify the use in qsort */ if (s1 == s2) return 0; if (s1 == NULL) return -1; if (s2 == NULL) return 1; while (*s1 && *s2 && n) { n--; c1 = next_codepoint_handle(iconv_handle, s1, &size1); c2 = next_codepoint_handle(iconv_handle, s2, &size2); if (c1 == INVALID_CODEPOINT || c2 == INVALID_CODEPOINT) { /* * n was specified in characters, * now we must convert it to bytes. * As bytes are the smallest * character unit, the following * increment and strncasecmp is always * safe. * * The source string was already known * to be n characters long, so we are * guaranteed to be able to look at the * (n remaining + size1) bytes from the * s1 position). */ n += size1; return strncasecmp(s1, s2, n); } s1 += size1; s2 += size2; if (c1 == c2) { continue; } if (toupper_m(c1) != toupper_m(c2)) { return c1 - c2; } } if (n == 0) { return 0; } return *s1 - *s2; }
smb_ucs2_t toupper_w(smb_ucs2_t v) { smb_ucs2_t ret; /* LE to native. */ codepoint_t cp = SVAL(&v,0); cp = toupper_m(cp); /* native to LE. */ SSVAL(&ret,0,cp); return ret; }
/** Case insensitive string compararison, length limited **/ _PUBLIC_ int strncasecmp_m(const char *s1, const char *s2, size_t n) { codepoint_t c1=0, c2=0; size_t size1, size2; struct smb_iconv_convenience *iconv_convenience = get_iconv_convenience(); /* handle null ptr comparisons to simplify the use in qsort */ if (s1 == s2) return 0; if (s1 == NULL) return -1; if (s2 == NULL) return 1; while (*s1 && *s2 && n) { n--; c1 = next_codepoint_convenience(iconv_convenience, s1, &size1); c2 = next_codepoint_convenience(iconv_convenience, s2, &size2); s1 += size1; s2 += size2; if (c1 == c2) { continue; } if (c1 == INVALID_CODEPOINT || c2 == INVALID_CODEPOINT) { /* what else can we do?? */ return strcasecmp(s1, s2); } if (toupper_m(c1) != toupper_m(c2)) { return c1 - c2; } } if (n == 0) { return 0; } return *s1 - *s2; }
static bool is_mangled(const char *s, const struct share_params *p) { char *magic; char magic_char; magic_char = lp_magicchar(p); if (chartest == NULL) { init_chartest(); } magic = strchr_m( s, magic_char ); while( magic && magic[1] && magic[2] ) { /* 3 chars, 1st is magic. */ if( ('.' == magic[3] || '/' == magic[3] || !(magic[3])) /* Ends with '.' or nul or '/' ? */ && isbasechar( toupper_m(magic[1]) ) /* is 2nd char basechar? */ && isbasechar( toupper_m(magic[2]) ) ) /* is 3rd char basechar? */ return( True ); /* If all above, then true, */ magic = strchr_m( magic+1, magic_char ); /* else seek next magic. */ } return( False ); }
bool strupper_w(smb_ucs2_t *s) { smb_ucs2_t cp; bool ret = false; while (*(COPY_UCS2_CHAR(&cp,s))) { smb_ucs2_t v = toupper_m(cp); if (v != cp) { COPY_UCS2_CHAR(s,&v); ret = true; } s++; } return ret; }
/* hash a string of the specified length. The string does not need to be null terminated hash alghorithm changed to FNV1 by [email protected] (Simo Sorce). see http://www.isthe.com/chongo/tech/comp/fnv/index.html for a discussion on Fowler / Noll / Vo (FNV) Hash by one of it's authors */ uint32_t pvfs_name_hash(const char *key, size_t length) { const uint32_t fnv1_prime = 0x01000193; const uint32_t fnv1_init = 0xa6b93095; uint32_t value = fnv1_init; while (*key && length--) { size_t c_size; codepoint_t c = next_codepoint(key, &c_size); c = toupper_m(c); value *= fnv1_prime; value ^= (uint32_t)c; key += c_size; } return value; }
static struct passwd *uname_string_combinations2(char *s, TALLOC_CTX *mem_ctx, int offset, struct passwd *(*fn)(TALLOC_CTX *mem_ctx, const char *), int N) { ssize_t len = (ssize_t)strlen(s); int i; struct passwd *ret; if (N <= 0 || offset >= len) return(fn(mem_ctx, s)); for (i=offset;i<(len-(N-1));i++) { char c = s[i]; if (!islower_m((int)c)) continue; s[i] = toupper_m(c); ret = uname_string_combinations2(s, mem_ctx, i+1, fn, N-1); if(ret) return(ret); s[i] = c; } return(NULL); }
bool torture_ldap_sort(struct torture_context *torture) { struct ldb_context *ldb; bool ret = false; const char *host = torture_setting_string(torture, "host", NULL); char *url; int i; codepoint_t j; struct ldb_message_element *elem; struct ldb_message *msg; struct ldb_server_sort_control **control; struct ldb_request *req; struct ldb_result *ctx; struct ldb_val *prev = NULL; const char *prev_txt = NULL; int prev_len = 0; struct ldb_val *cur = NULL; const char *cur_txt = NULL; int cur_len = 0; struct ldb_dn *dn; /* TALLOC_CTX* ctx;*/ url = talloc_asprintf(torture, "ldap://%s/", host); ldb = ldb_wrap_connect(torture, torture->ev, torture->lp_ctx, url, NULL, popt_get_cmdline_credentials(), 0); torture_assert(torture, ldb, "Failed to make LDB connection to target"); ctx = talloc_zero(ldb, struct ldb_result); control = talloc_array(ctx, struct ldb_server_sort_control *, 2); control[0] = talloc(control, struct ldb_server_sort_control); control[0]->attributeName = talloc_strdup(control, "cn"); control[0]->orderingRule = NULL; control[0]->reverse = 0; control[1] = NULL; dn = ldb_get_default_basedn(ldb); ldb_dn_add_child_fmt(dn, "cn=users"); ret = ldb_build_search_req(&req, ldb, ctx, dn, LDB_SCOPE_SUBTREE, "(objectClass=*)", NULL, NULL, ctx, ldb_search_default_callback, NULL); torture_assert(torture, ret == LDB_SUCCESS, "Failed to build search request"); ret = ldb_request_add_control(req, LDB_CONTROL_SERVER_SORT_OID, true, control); torture_assert(torture, ret == LDB_SUCCESS, "Failed to add control to search request"); ret = ldb_request(ldb, req); torture_assert(torture, ret == LDB_SUCCESS, ldb_errstring(ldb)); ret = ldb_wait(req->handle, LDB_WAIT_ALL); torture_assert(torture, ret == LDB_SUCCESS, ldb_errstring(ldb)); ret = true; if (ctx->count > 1) { for (i=0;i<ctx->count;i++) { msg = ctx->msgs[i]; elem = ldb_msg_find_element(msg,"cn"); torture_assert_not_null(torture, elem, "msg lacks CN"); cur = elem->values; torture_comment(torture, "cn: %s\n",cur->data); if (prev != NULL) { /* Do only the ascii case right now ... */ cur_txt = (const char *) cur->data; cur_len = cur->length; prev_txt = (const char *) prev->data; prev_len = prev->length; /* Remove leading whitespace as the sort function do so ... */ while ( cur_txt[0] == cur_txt[1] ) { cur_txt++; cur_len--;} while ( prev_txt[0] == prev_txt[1] ) { prev_txt++; prev_len--;} while( *(cur_txt) && *(prev_txt) && cur_len && prev_len ) { j = toupper_m(*(prev_txt))-toupper_m(*(cur_txt)); if ( j > 0 ) { /* Just check that is not due to trailling white space in prev_txt * That is to say *cur_txt = 0 and prev_txt = 20 */ /* Remove trailling whitespace */ while ( *prev_txt == ' ' ) { prev_txt++; prev_len--;} while ( *cur_txt == ' ' ) { cur_txt++; cur_len--;} /* Now that potential whitespace are removed if we are at the end * of the cur_txt then it means that in fact strings were identical */ torture_assert(torture, *cur_txt && *prev_txt, "Data wrongly sorted"); break; } else { if ( j == 0 ) { if ( *(cur_txt) == ' ') { while ( cur_txt[0] == cur_txt[1] ) { cur_txt++; cur_len--;} while ( prev_txt[0] == prev_txt[1] ) { prev_txt++; prev_len--;} } cur_txt++; prev_txt++; prev_len--; cur_len--; } else { break; } } } if ( ret != 1 ) { break; } } prev = cur; } } return ret; }
/* the main forward mapping function, which converts a long filename to a 8.3 name if cache83 is not set then we don't cache the result */ static bool hash2_name_to_8_3(const char *name, char new_name[13], bool cache83, int default_case, const struct share_params *p) { char *dot_p; char lead_chars[7]; char extension[4]; unsigned int extension_length, i; unsigned int prefix_len; unsigned int hash, v; /* reserved names are handled specially */ if (!is_reserved_name(name)) { /* if the name is already a valid 8.3 name then we don't need to * change anything */ if (is_legal_name(name) && is_8_3(name, False, False, p)) { safe_strcpy(new_name, name, 12); return True; } } /* find the '.' if any */ dot_p = strrchr(name, '.'); if (dot_p) { /* if the extension contains any illegal characters or is too long or zero length then we treat it as part of the prefix */ for (i=0; i<4 && dot_p[i+1]; i++) { if (! FLAG_CHECK(dot_p[i+1], FLAG_ASCII)) { dot_p = NULL; break; } } if (i == 0 || i == 4) { dot_p = NULL; } } /* the leading characters in the mangled name is taken from the first characters of the name, if they are ascii otherwise '_' is used */ for (i=0;i<mangle_prefix && name[i];i++) { lead_chars[i] = name[i]; if (! FLAG_CHECK(lead_chars[i], FLAG_ASCII)) { lead_chars[i] = '_'; } lead_chars[i] = toupper_m(lead_chars[i]); } for (;i<mangle_prefix;i++) { lead_chars[i] = '_'; } /* the prefix is anything up to the first dot */ if (dot_p) { prefix_len = PTR_DIFF(dot_p, name); } else { prefix_len = strlen(name); } /* the extension of the mangled name is taken from the first 3 ascii chars after the dot */ extension_length = 0; if (dot_p) { for (i=1; extension_length < 3 && dot_p[i]; i++) { char c = dot_p[i]; if (FLAG_CHECK(c, FLAG_ASCII)) { extension[extension_length++] = toupper_m(c); } } } /* find the hash for this prefix */ v = hash = mangle_hash(name, prefix_len); /* now form the mangled name. */ for (i=0;i<mangle_prefix;i++) { new_name[i] = lead_chars[i]; } new_name[7] = base_forward(v % 36); new_name[6] = '~'; for (i=5; i>=mangle_prefix; i--) { v = v / 36; new_name[i] = base_forward(v % 36); } /* add the extension */ if (extension_length) { new_name[8] = '.'; memcpy(&new_name[9], extension, extension_length); new_name[9+extension_length] = 0; } else { new_name[8] = 0; } if (cache83) { /* put it in the cache */ cache_insert(name, prefix_len, hash); } M_DEBUG(10,("hash2_name_to_8_3: %s -> %08X -> %s (cache=%d)\n", name, hash, new_name, cache83)); return True; }