From c9b7cbbfa572512cd0348817965b99fd1df01285 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 9 Mar 2004 00:17:14 +0000 Subject: Added strstr_m() function. Use in all places where we might run into mb (should fix the mb service name problem, can't remember the bugid). Jeremy. (This used to be commit 94a272b9a881ec0004c5da2a7242b0a818da5630) --- source3/lib/util.c | 4 +-- source3/lib/util_str.c | 78 +++++++++++++++++++++++++++++++++++++++++--- source3/printing/lpq_parse.c | 6 ++-- source3/smbd/chgpasswd.c | 2 +- source3/smbd/service.c | 2 +- source3/utils/testparm.c | 2 +- 6 files changed, 82 insertions(+), 12 deletions(-) (limited to 'source3') diff --git a/source3/lib/util.c b/source3/lib/util.c index f169a3103e5..3a8d627ee9e 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -551,7 +551,7 @@ void dos_clean_name(char *s) /* remove any double slashes */ all_string_sub(s, "\\\\", "\\", 0); - while ((p = strstr(s,"\\..\\")) != NULL) { + while ((p = strstr_m(s,"\\..\\")) != NULL) { pstring s1; *p = 0; @@ -589,7 +589,7 @@ void unix_clean_name(char *s) pstrcpy(s,"./"); } - while ((p = strstr(s,"/../")) != NULL) { + while ((p = strstr_m(s,"/../")) != NULL) { pstring s1; *p = 0; diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 71c8d56e403..cad0df48a49 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -919,7 +919,7 @@ void string_sub(char *s,const char *pattern, const char *insert, size_t len) if (len == 0) len = ls + 1; /* len is number of *bytes* */ - while (lp <= ls && (p = strstr(s,pattern))) { + while (lp <= ls && (p = strstr_m(s,pattern))) { if (ls + (li-lp) >= len) { DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", (int)(ls + (li-lp) - len), @@ -1004,7 +1004,7 @@ char *realloc_string_sub(char *string, const char *pattern, const char *insert) } } - while ((p = strstr(s,pattern))) { + while ((p = strstr_m(s,pattern))) { if (ld > 0) { int offset = PTR_DIFF(s,string); char *t = Realloc(string, ls + ld + 1); @@ -1052,7 +1052,7 @@ void all_string_sub(char *s,const char *pattern,const char *insert, size_t len) if (len == 0) len = ls + 1; /* len is number of *bytes* */ - while (lp <= ls && (p = strstr(s,pattern))) { + while (lp <= ls && (p = strstr_m(s,pattern))) { if (ls + (li-lp) >= len) { DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", (int)(ls + (li-lp) - len), @@ -1294,6 +1294,76 @@ char *strnrchr_m(const char *s, char c, unsigned int n) return (char *)(s+strlen(s2)); } +/*********************************************************************** + strstr_m - We convert via ucs2 for now. +***********************************************************************/ + +char *strstr_m(const char *src, const char *findstr) +{ + smb_ucs2_t *p; + smb_ucs2_t *src_w, *find_w; + const char *s; + char *s2; + char *retp; + + /* Samba does single character findstr calls a *lot*. */ + if (findstr[1] == '\0') + return strchr_m(src, *findstr); + + /* 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 (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) { + if (*s == *findstr) { + if (strcmp(s, findstr) == 0) { + return (char *)s; + } + } + } + + if (!*s) + return NULL; + +#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS + /* With compose characters we must restart from the beginning. JRA. */ + s = src; +#endif + + if (push_ucs2_allocate(&src_w, src) == (size_t)-1) { + DEBUG(0,("strstr_m: src malloc fail\n")); + return NULL; + } + + if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) { + SAFE_FREE(src_w); + DEBUG(0,("strstr_m: find malloc fail\n")); + return NULL; + } + + for (p = src_w; (p = strchr_w(p, *find_w)) != NULL; p++) { + if (strcmp_w(p, find_w) == 0) + break; + } + if (!p) { + SAFE_FREE(src_w); + SAFE_FREE(find_w); + return NULL; + } + *p = 0; + if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) { + SAFE_FREE(src_w); + SAFE_FREE(find_w); + DEBUG(0,("strstr_m: dest malloc fail\n")); + return NULL; + } + retp = (char *)(s+strlen(s2)); + SAFE_FREE(src_w); + SAFE_FREE(find_w); + SAFE_FREE(s2); + return retp; +} + /** Convert a string to lower case. **/ @@ -1624,7 +1694,7 @@ BOOL str_list_substitute(char **list, const char *pattern, const char *insert) s = *list; ls = (ssize_t)strlen(s); - while ((p = strstr(s, pattern))) { + while ((p = strstr_m(s, pattern))) { t = *list; d = p -t; if (ld) { diff --git a/source3/printing/lpq_parse.c b/source3/printing/lpq_parse.c index 111617e3aed..b7e41964f1b 100644 --- a/source3/printing/lpq_parse.c +++ b/source3/printing/lpq_parse.c @@ -989,21 +989,21 @@ BOOL parse_lpq_entry(int snum,char *line, switch (status->status) { case LPSTAT_OK: for (i=0; stat0_strings[i]; i++) - if (strstr(line,stat0_strings[i])) { + if (strstr_m(line,stat0_strings[i])) { fstrcpy(status->message,line); status->status=LPSTAT_OK; return ret; } case LPSTAT_STOPPED: for (i=0; stat1_strings[i]; i++) - if (strstr(line,stat1_strings[i])) { + if (strstr_m(line,stat1_strings[i])) { fstrcpy(status->message,line); status->status=LPSTAT_STOPPED; return ret; } case LPSTAT_ERROR: for (i=0; stat2_strings[i]; i++) - if (strstr(line,stat2_strings[i])) { + if (strstr_m(line,stat2_strings[i])) { fstrcpy(status->message,line); status->status=LPSTAT_ERROR; return ret; diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c index e3df8a11d02..d928445d94e 100644 --- a/source3/smbd/chgpasswd.c +++ b/source3/smbd/chgpasswd.c @@ -542,7 +542,7 @@ BOOL chgpasswd(const char *name, const struct passwd *pass, if (as_root) { /* The password program *must* contain the user name to work. Fail if not. */ - if (strstr(passwordprogram, "%u") == NULL) { + if (strstr_m(passwordprogram, "%u") == NULL) { DEBUG(0,("chgpasswd: Running as root the 'passwd program' parameter *MUST* contain \ the string %%u, and the given string %s does not.\n", passwordprogram )); return False; diff --git a/source3/smbd/service.c b/source3/smbd/service.c index a53b9267b75..08b66482496 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -174,7 +174,7 @@ int find_service(fstring service) /* just possibly it's a default service? */ if (iService < 0) { char *pdefservice = lp_defaultservice(); - if (pdefservice && *pdefservice && !strequal(pdefservice,service) && !strstr(service,"..")) { + if (pdefservice && *pdefservice && !strequal(pdefservice,service) && !strstr_m(service,"..")) { /* * We need to do a local copy here as lp_defaultservice() * returns one of the rotating lp_string buffers that diff --git a/source3/utils/testparm.c b/source3/utils/testparm.c index a74c2eaa973..9db6d538d24 100644 --- a/source3/utils/testparm.c +++ b/source3/utils/testparm.c @@ -150,7 +150,7 @@ parameter.\n"); */ if(lp_encrypted_passwords()) { - if(strstr( lp_passwd_chat(), "%o")!=NULL) { + if(strstr_m( lp_passwd_chat(), "%o")!=NULL) { fprintf(stderr, "ERROR: the 'passwd chat' script [%s] expects to use the old plaintext password \ via the %%o substitution. With encrypted passwords this is not possible.\n", lp_passwd_chat() ); ret = 1; -- cgit