summaryrefslogtreecommitdiff
path: root/source3/lib/util_str.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/lib/util_str.c')
-rw-r--r--source3/lib/util_str.c281
1 files changed, 152 insertions, 129 deletions
diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c
index a25043df78..58718f395a 100644
--- a/source3/lib/util_str.c
+++ b/source3/lib/util_str.c
@@ -462,7 +462,7 @@ char *skip_string(char *buf,size_t n)
{
while (n--)
buf += strlen(buf) + 1;
- return buf;
+ return(buf);
}
/*******************************************************************
@@ -733,21 +733,69 @@ size_t count_chars(const char *s,char c)
return(count);
}
+/*******************************************************************
+Return True if a string consists only of one particular character.
+********************************************************************/
+BOOL str_is_all(const char *s,char c)
+{
+ if(s == NULL)
+ return False;
+ if(!*s)
+ return False;
+
+#if !defined(KANJI_WIN95_COMPATIBILITY)
+ /*
+ * For completeness we should put in equivalent code for code pages
+ * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+ * doubt anyone wants Samba to behave differently from Win95 and WinNT
+ * here. They both treat full width ascii characters as case senstive
+ * filenames (ie. they don't do the work we do here).
+ * JRA.
+ */
+
+ if(lp_client_code_page() == KANJI_CODEPAGE)
+ {
+ /* Win95 treats full width ascii characters as case sensitive. */
+ while (*s)
+ {
+ if (is_shift_jis (*s))
+ s += 2;
+ else
+ {
+ if (*s != c)
+ return False;
+ s++;
+ }
+ }
+ }
+ else
+#endif /* KANJI_WIN95_COMPATIBILITY */
+ {
+ while (*s)
+ {
+ size_t skip = skip_multibyte_char( *s );
+ if( skip != 0 )
+ s += skip;
+ else {
+ if (*s != c)
+ return False;
+ s++;
+ }
+ }
+ }
+ return True;
+}
/*******************************************************************
safe string copy into a known length string. maxlength does not
include the terminating zero.
********************************************************************/
+
char *safe_strcpy(char *dest,const char *src, size_t maxlength)
{
size_t len;
- if (maxlength == 0)
- {
- return dest;
- }
-
if (!dest) {
DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
return NULL;
@@ -762,7 +810,7 @@ char *safe_strcpy(char *dest,const char *src, size_t maxlength)
if (len > maxlength) {
DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
- len-maxlength, src));
+ (int)(len-maxlength), src));
len = maxlength;
}
@@ -775,6 +823,7 @@ char *safe_strcpy(char *dest,const char *src, size_t maxlength)
safe string cat into a string. maxlength does not
include the terminating zero.
********************************************************************/
+
char *safe_strcat(char *dest, const char *src, size_t maxlength)
{
size_t src_len, dest_len;
@@ -793,7 +842,7 @@ char *safe_strcat(char *dest, const char *src, size_t maxlength)
if (src_len + dest_len > maxlength) {
DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
- src_len + dest_len - maxlength, src));
+ (int)(src_len + dest_len - maxlength), src));
src_len = maxlength - dest_len;
}
@@ -802,28 +851,48 @@ char *safe_strcat(char *dest, const char *src, size_t maxlength)
return dest;
}
-/****************************************************************************
-this is a safer strcpy(), meant to prevent core dumps when nasty things happen
-****************************************************************************/
-char *StrCpy(char *dest,const char *src)
+/*******************************************************************
+ Paranoid strcpy into a buffer of given length (includes terminating
+ zero. Strips out all but 'a-Z0-9' and replaces with '_'. Deliberately
+ does *NOT* check for multibyte characters. Don't change it !
+********************************************************************/
+
+char *alpha_strcpy(char *dest, const char *src, size_t maxlength)
{
- char *d = dest;
+ size_t len, i;
- /* I don't want to get lazy with these ... */
- SMB_ASSERT(dest && src);
+ if (!dest) {
+ DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
+ return NULL;
+ }
- if (!dest) return(NULL);
- if (!src) {
- *dest = 0;
- return(dest);
- }
- while ((*d++ = *src++)) ;
- return(dest);
+ if (!src) {
+ *dest = 0;
+ return dest;
+ }
+
+ len = strlen(src);
+ if (len >= maxlength)
+ len = maxlength - 1;
+
+ for(i = 0; i < len; i++) {
+ int val = (src[i] & 0xff);
+ if(isupper(val) ||islower(val) || isdigit(val))
+ dest[i] = src[i];
+ else
+ dest[i] = '_';
+ }
+
+ dest[i] = '\0';
+
+ return dest;
}
/****************************************************************************
-like strncpy but always null terminates. Make sure there is room!
+ Like strncpy but always null terminates. Make sure there is room!
+ The variable n should always be one less than the available size.
****************************************************************************/
+
char *StrnCpy(char *dest,const char *src,size_t n)
{
char *d = dest;
@@ -837,12 +906,11 @@ char *StrnCpy(char *dest,const char *src,size_t n)
return(dest);
}
-
/****************************************************************************
like strncpy but copies up to the character marker. always null terminates.
returns a pointer to the character marker in the source string (src).
****************************************************************************/
-char *strncpyn(char *dest, char *src,size_t n, char c)
+char *strncpyn(char *dest, const char *src,size_t n, char c)
{
char *p;
size_t str_len;
@@ -1003,29 +1071,42 @@ enough room!
This routine looks for pattern in s and replaces it with
insert. It may do multiple replacements.
-any of " ; ' or ` in the insert string are replaced with _
+any of " ; ' $ or ` in the insert string are replaced with _
+if len==0 then no length check is performed
****************************************************************************/
-void string_sub(char *s,const char *pattern,const char *insert)
+void string_sub(char *s,const char *pattern,const char *insert, size_t len)
{
char *p;
- size_t ls,lp,li, i;
+ ssize_t ls,lp,li, i;
if (!insert || !pattern || !s) return;
- ls = strlen(s);
- lp = strlen(pattern);
- li = strlen(insert);
+ ls = (ssize_t)strlen(s);
+ lp = (ssize_t)strlen(pattern);
+ li = (ssize_t)strlen(insert);
if (!*pattern) return;
while (lp <= ls && (p = strstr(s,pattern))) {
- memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
+ if (len && (ls + (li-lp) >= len)) {
+ DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
+ (int)(ls + (li-lp) - len),
+ pattern, (int)len));
+ break;
+ }
+ if (li != lp) {
+ memmove(p+li,p+lp,strlen(p+lp)+1);
+ }
for (i=0;i<li;i++) {
switch (insert[i]) {
case '`':
case '"':
case '\'':
case ';':
+ case '$':
+ case '%':
+ case '\r':
+ case '\n':
p[i] = '_';
break;
default:
@@ -1037,26 +1118,44 @@ void string_sub(char *s,const char *pattern,const char *insert)
}
}
+void fstring_sub(char *s,const char *pattern,const char *insert)
+{
+ string_sub(s, pattern, insert, sizeof(fstring));
+}
+
+void pstring_sub(char *s,const char *pattern,const char *insert)
+{
+ string_sub(s, pattern, insert, sizeof(pstring));
+}
/****************************************************************************
similar to string_sub() but allows for any character to be substituted.
Use with caution!
+if len==0 then no length check is performed
****************************************************************************/
-void all_string_sub(char *s,const char *pattern,const char *insert)
+void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
{
char *p;
- size_t ls,lp,li;
+ ssize_t ls,lp,li;
if (!insert || !pattern || !s) return;
- ls = strlen(s);
- lp = strlen(pattern);
- li = strlen(insert);
+ ls = (ssize_t)strlen(s);
+ lp = (ssize_t)strlen(pattern);
+ li = (ssize_t)strlen(insert);
if (!*pattern) return;
while (lp <= ls && (p = strstr(s,pattern))) {
- memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
+ if (len && (ls + (li-lp) >= len)) {
+ DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
+ (int)(ls + (li-lp) - len),
+ pattern, (int)len));
+ break;
+ }
+ if (li != lp) {
+ memmove(p+li,p+lp,strlen(p+lp)+1);
+ }
memcpy(p, insert, li);
s = p + li;
ls += (li-lp);
@@ -1066,38 +1165,6 @@ void all_string_sub(char *s,const char *pattern,const char *insert)
/****************************************************************************
splits out the front and back at a separator.
****************************************************************************/
-void split_at_first_component(char *path, char *front, char sep, char *back)
-{
- char *p = strchr(path, sep);
-
- if (p != NULL)
- {
- *p = 0;
- }
- if (front != NULL)
- {
- pstrcpy(front, path);
- }
- if (p != NULL)
- {
- if (back != NULL)
- {
- pstrcpy(back, p+1);
- }
- *p = sep;
- }
- else
- {
- if (back != NULL)
- {
- back[0] = 0;
- }
- }
-}
-
-/****************************************************************************
- splits out the front and back at a separator.
-****************************************************************************/
void split_at_last_component(char *path, char *front, char sep, char *back)
{
char *p = strrchr(path, sep);
@@ -1116,7 +1183,7 @@ void split_at_last_component(char *path, char *front, char sep, char *back)
{
pstrcpy(back, p+1);
}
- *p = sep;
+ *p = '\\';
}
else
{
@@ -1127,72 +1194,28 @@ void split_at_last_component(char *path, char *front, char sep, char *back)
}
}
-/****************************************************************************
-convert a bit field to a string. if you want multiple bits to be detected
-set them first, e.g SV_TYPE_ALL to be "All" or "Full Control" for ACB_INFOs.
-
-strings are expected to contain their own separators, although the code
-below only assumes that separators are spaces.
+/****************************************************************************
+write an octal as a string
****************************************************************************/
-char *bit_field_to_str(uint32 type, struct field_info *bs)
+char *octal_string(int i)
{
- static fstring typestr;
- int i = 0;
-
- typestr[0] = 0;
-
- if (type == 0 || bs == NULL)
- {
- return NULL;
- }
-
- while (bs[i].str != NULL && type != 0)
- {
- if (IS_BITS_SET_ALL(bs[i].bits, type))
- {
- fstrcat(typestr, bs[i].str);
- type &= ~bs[i].bits;
- }
- i++;
- }
-
- i = strlen(typestr)-1;
- if (i > 0 && typestr[i] == ' ')
- {
- typestr[i] = 0;
+ static char ret[64];
+ if (i == -1) {
+ return "-1";
}
-
- return typestr;
+ slprintf(ret, sizeof(ret), "0%o", i);
+ return ret;
}
+
/****************************************************************************
-convert an enumeration to a string. first item is the default.
+truncate a string at a specified length
****************************************************************************/
-char *enum_field_to_str(uint32 type, struct field_info *bs, BOOL first_default)
+char *string_truncate(char *s, int length)
{
- int i = 0;
-
- if (bs == NULL)
- {
- return NULL;
+ if (s && strlen(s) > length) {
+ s[length] = 0;
}
-
- while (bs[i].str != NULL && type != 0)
- {
- if (bs[i].bits == type)
- {
- return bs[i].str;
- }
- i++;
- }
-
- /* oops - none found */
-
- if (first_default)
- {
- return bs[0].str;
- }
-
- return NULL;
+ return s;
}