[SCM] Samba Shared Repository - branch v3-2-test updated -
initial-v3-2-unstable-403-g0ae61e2
Jeremy Allison
jra at samba.org
Fri Nov 30 21:09:39 GMT 2007
The branch, v3-2-test has been updated
via 0ae61e26547e594e94037d4474a008221e5df8cf (commit)
from d5658914c2d6ec878d9a11f8a1fa57f1697362e3 (commit)
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-2-test
- Log -----------------------------------------------------------------
commit 0ae61e26547e594e94037d4474a008221e5df8cf
Author: Jeremy Allison <jra at samba.org>
Date: Fri Nov 30 13:09:04 2007 -0800
Add talloc versions of all the next_token() functions.
Now I can really start removing fixed length strings...
Jeremy.
-----------------------------------------------------------------------
Summary of changes:
source/lib/util_str.c | 105 ++++-
source/libsmb/libsmbclient.c | 1333 +++++++++++++++++++++++-------------------
2 files changed, 830 insertions(+), 608 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source/lib/util_str.c b/source/lib/util_str.c
index f5a50b3..886ae2a 100644
--- a/source/lib/util_str.c
+++ b/source/lib/util_str.c
@@ -85,6 +85,73 @@ static bool next_token_internal(const char **ptr,
return(true);
}
+static bool next_token_internal_talloc(TALLOC_CTX *ctx,
+ const char **ptr,
+ char **pp_buff,
+ const char *sep,
+ bool ltrim)
+{
+ char *s;
+ char *pbuf;
+ bool quoted;
+ size_t len=1;
+
+ *pp_buff = NULL;
+ if (!ptr) {
+ return(false);
+ }
+
+ s = (char *)*ptr;
+
+ /* default to simple separators */
+ if (!sep) {
+ sep = " \t\n\r";
+ }
+
+ /* find the first non sep char, if left-trimming is requested */
+ if (ltrim) {
+ while (*s && strchr_m(sep,*s))
+ s++;
+ }
+
+ /* nothing left? */
+ if (!*s) {
+ return(false);
+ }
+
+ /* Work out the length needed. */
+ for (quoted = false; *s &&
+ (quoted || !strchr_m(sep,*s)); s++) {
+ if (*s == '\"') {
+ quoted = !quoted;
+ } else {
+ len++;
+ }
+ }
+
+ /* We started with len = 1 so we have space for the nul. */
+ *pp_buff = TALLOC_ARRAY(ctx, char, len);
+ if (!*pp_buff) {
+ return false;
+ }
+
+ /* copy over the token */
+ pbuf = *pp_buff;
+ for (quoted = false; *s &&
+ (quoted || !strchr_m(sep,*s)); s++) {
+ if ( *s == '\"' ) {
+ quoted = !quoted;
+ } else {
+ *pbuf++ = *s;
+ }
+ }
+
+ *ptr = (*s) ? s+1 : s;
+ *pbuf = 0;
+
+ return true;
+}
+
/*
* Get the next token from a string, return false if none found. Handles
* double-quotes. This version trims leading separator characters before
@@ -92,7 +159,15 @@ static bool next_token_internal(const char **ptr,
*/
bool next_token(const char **ptr, char *buff, const char *sep, size_t bufsize)
{
- return next_token_internal(ptr, buff, sep, bufsize, true);
+ return next_token_internal(ptr, buff, sep, bufsize, true);
+}
+
+bool next_token_talloc(TALLOC_CTX *ctx,
+ const char **ptr,
+ char **pp_buff,
+ const char *sep)
+{
+ return next_token_internal_talloc(ctx, ptr, pp_buff, sep, true);
}
/*
@@ -105,7 +180,15 @@ bool next_token_no_ltrim(const char **ptr,
const char *sep,
size_t bufsize)
{
- return next_token_internal(ptr, buff, sep, bufsize, false);
+ return next_token_internal(ptr, buff, sep, bufsize, false);
+}
+
+bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx,
+ const char **ptr,
+ char **pp_buff,
+ const char *sep)
+{
+ return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false);
}
/**
@@ -119,14 +202,30 @@ static const char *last_ptr=NULL;
bool next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
{
bool ret;
- if (!ptr)
+ if (!ptr) {
ptr = &last_ptr;
+ }
ret = next_token(ptr, buff, sep, bufsize);
last_ptr = *ptr;
return ret;
}
+bool next_token_nr_talloc(TALLOC_CTX *ctx,
+ const char **ptr,
+ char **pp_buff,
+ const char *sep)
+{
+ bool ret;
+ if (!ptr) {
+ ptr = &last_ptr;
+ }
+
+ ret = next_token_talloc(ctx, ptr, pp_buff, sep);
+ last_ptr = *ptr;
+ return ret;
+}
+
void set_first_token(char *ptr)
{
last_ptr = ptr;
diff --git a/source/libsmb/libsmbclient.c b/source/libsmb/libsmbclient.c
index b20b1ca..c81002b 100644
--- a/source/libsmb/libsmbclient.c
+++ b/source/libsmb/libsmbclient.c
@@ -132,6 +132,7 @@ hex2int( unsigned int _char )
/*
* smbc_urldecode()
+ * and smbc_urldecode_talloc() (internal fn.)
*
* Convert strings of %xx to their single character equivalent. Each 'x' must
* be a valid hexadecimal digit, or that % sequence is left undecoded.
@@ -141,53 +142,87 @@ hex2int( unsigned int _char )
* Returns the number of % sequences which could not be converted due to lack
* of two following hexadecimal digits.
*/
-int
-smbc_urldecode(char *dest, char * src, size_t max_dest_len)
+static int
+smbc_urldecode_talloc(TALLOC_CTX *ctx, char **pp_dest, const char *src)
{
- int old_length = strlen(src);
- int i = 0;
- int err_count = 0;
- pstring temp;
- char * p;
+ int old_length = strlen(src);
+ int i = 0;
+ int err_count = 0;
+ size_t newlen = 1;
+ char *p, *dest;
+
+ *pp_dest = NULL;
+ if (old_length == 0) {
+ return 0;
+ }
- if ( old_length == 0 ) {
- return 0;
- }
+ for (i = 0; i < old_length; ) {
+ unsigned char character = src[i++];
+
+ if (character == '%') {
+ int a = i+1 < old_length ? hex2int(src[i]) : -1;
+ int b = i+1 < old_length ? hex2int(src[i+1]) : -1;
- p = temp;
- while ( i < old_length ) {
- unsigned char character = src[ i++ ];
+ /* Replace valid sequence */
+ if (a != -1 && b != -1) {
+ /* Replace valid %xx sequence with %dd */
+ character = (a * 16) + b;
+ if (character == '\0') {
+ break; /* Stop at %00 */
+ }
+ i += 2;
+ } else {
+ err_count++;
+ }
+ }
+ newlen++;
+ }
+
+ dest = TALLOC_ARRAY(ctx, char, newlen);
+ if (!dest) {
+ return err_count;
+ }
+
+ err_count = 0;
+ for (p = dest, i = 0; i < old_length; ) {
+ unsigned char character = src[i++];
if (character == '%') {
- int a = i+1 < old_length ? hex2int( src[i] ) : -1;
- int b = i+1 < old_length ? hex2int( src[i+1] ) : -1;
+ int a = i+1 < old_length ? hex2int(src[i]) : -1;
+ int b = i+1 < old_length ? hex2int(src[i+1]) : -1;
/* Replace valid sequence */
if (a != -1 && b != -1) {
-
/* Replace valid %xx sequence with %dd */
character = (a * 16) + b;
-
if (character == '\0') {
break; /* Stop at %00 */
}
-
i += 2;
} else {
-
err_count++;
}
}
-
*p++ = character;
}
*p = '\0';
+ *pp_dest = dest;
+ return err_count;
+}
- strncpy(dest, temp, max_dest_len - 1);
- dest[max_dest_len - 1] = '\0';
+int
+smbc_urldecode(char *dest, char *src, size_t max_dest_len)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ char *pdest;
+ int ret = smbc_urldecode_talloc(frame, &pdest, src);
- return err_count;
+ if (pdest) {
+ strlcpy(dest, pdest, max_dest_len);
+ }
+ TALLOC_FREE(frame);
+ return ret;
}
/*
@@ -199,7 +234,7 @@ smbc_urldecode(char *dest, char * src, size_t max_dest_len)
* Returns the remaining buffer length.
*/
int
-smbc_urlencode(char * dest, char * src, int max_dest_len)
+smbc_urlencode(char *dest, char *src, int max_dest_len)
{
char hex[] = "0123456789ABCDEF";
@@ -226,7 +261,7 @@ smbc_urlencode(char * dest, char * src, int max_dest_len)
*dest++ = '\0';
max_dest_len--;
-
+
return max_dest_len;
}
@@ -270,37 +305,46 @@ smbc_urlencode(char * dest, char * src, int max_dest_len)
static const char *smbc_prefix = "smb:";
static int
-smbc_parse_path(SMBCCTX *context,
+smbc_parse_path(TALLOC_CTX *ctx,
+ SMBCCTX *context,
const char *fname,
- char *workgroup, int workgroup_len,
- char *server, int server_len,
- char *share, int share_len,
- char *path, int path_len,
- char *user, int user_len,
- char *password, int password_len,
- char *options, int options_len)
+ char **pp_workgroup,
+ char **pp_server,
+ char **pp_share,
+ char **pp_path,
+ char **pp_user,
+ char **pp_password,
+ char **pp_options)
{
- static pstring s;
- pstring userinfo;
+ char *s;
const char *p;
char *q, *r;
int len;
- server[0] = share[0] = path[0] = user[0] = password[0] = (char)0;
+ /* Ensure these returns are at least valid pointers. */
+ *pp_server = talloc_strdup(ctx, "");
+ *pp_share = talloc_strdup(ctx, "");
+ *pp_path = talloc_strdup(ctx, "");
+ *pp_user = talloc_strdup(ctx, "");
+ *pp_password = talloc_strdup(ctx, "");
+
+ if (!*pp_server || !*pp_share || !*pp_path ||
+ !*pp_user || !*pp_password) {
+ return -1;
+ }
/*
* Assume we wont find an authentication domain to parse, so default
* to the workgroup in the provided context.
*/
- if (workgroup != NULL) {
- strncpy(workgroup, context->workgroup, workgroup_len - 1);
- workgroup[workgroup_len - 1] = '\0';
- }
+ if (pp_workgroup != NULL) {
+ *pp_workgroup = talloc_strdup(ctx, context->workgroup);
+ }
- if (options != NULL && options_len > 0) {
- options[0] = (char)0;
- }
- pstrcpy(s, fname);
+ if (pp_options) {
+ *pp_options = talloc_strdup(ctx, "");
+ }
+ s = talloc_strdup(ctx, fname);
/* see if it has the right prefix */
len = strlen(smbc_prefix);
@@ -313,10 +357,8 @@ smbc_parse_path(SMBCCTX *context,
/* Watch the test below, we are testing to see if we should exit */
if (strncmp(p, "//", 2) && strncmp(p, "\\\\", 2)) {
-
DEBUG(1, ("Invalid path (does not begin with smb://"));
return -1;
-
}
p += 2; /* Skip the double slash */
@@ -325,17 +367,19 @@ smbc_parse_path(SMBCCTX *context,
if ((q = strrchr(p, '?')) != NULL ) {
/* There are options. Null terminate here and point to them */
*q++ = '\0';
-
+
DEBUG(4, ("Found options '%s'", q));
- /* Copy the options */
- if (options != NULL && options_len > 0) {
- safe_strcpy(options, q, options_len - 1);
- }
- }
+ /* Copy the options */
+ if (*pp_options != NULL) {
+ TALLOC_FREE(*pp_options);
+ *pp_options = talloc_strdup(ctx, q);
+ }
+ }
- if (*p == (char)0)
- goto decoding;
+ if (*p == '\0') {
+ goto decoding;
+ }
if (*p == '/') {
int wl = strlen(context->workgroup);
@@ -344,13 +388,16 @@ smbc_parse_path(SMBCCTX *context,
wl = 16;
}
- strncpy(server, context->workgroup, wl);
- server[wl] = '\0';
+ *pp_server = talloc_strdup(ctx, context->workgroup);
+ if (!*pp_server) {
+ return -1;
+ }
+ *pp_server[wl] = '\0';
return 0;
}
/*
- * ok, its for us. Now parse out the server, share etc.
+ * ok, its for us. Now parse out the server, share etc.
*
* However, we want to parse out [[domain;]user[:password]@] if it
* exists ...
@@ -360,81 +407,78 @@ smbc_parse_path(SMBCCTX *context,
q = strchr_m(p, '@');
r = strchr_m(p, '/');
if (q && (!r || q < r)) {
- pstring username, passwd, domain;
- const char *u = userinfo;
-
- next_token_no_ltrim(&p, userinfo, "@", sizeof(fstring));
+ char *userinfo = NULL;
+ const char *u;
- username[0] = passwd[0] = domain[0] = 0;
+ next_token_no_ltrim_talloc(ctx, &p, &userinfo, "@");
+ if (!userinfo) {
+ return -1;
+ }
+ u = userinfo;
if (strchr_m(u, ';')) {
-
- next_token_no_ltrim(&u, domain, ";", sizeof(fstring));
-
+ char *workgroup;
+ next_token_no_ltrim_talloc(ctx, &u, &workgroup, ";");
+ if (!workgroup) {
+ return -1;
+ }
+ if (pp_workgroup) {
+ *pp_workgroup = workgroup;
+ }
}
if (strchr_m(u, ':')) {
-
- next_token_no_ltrim(&u, username, ":", sizeof(fstring));
-
- pstrcpy(passwd, u);
-
- }
- else {
-
- pstrcpy(username, u);
-
+ next_token_no_ltrim_talloc(ctx, &u, pp_user, ":");
+ if (!*pp_user) {
+ return -1;
+ }
+ *pp_password = talloc_strdup(ctx, u);
+ if (!*pp_password) {
+ return -1;
+ }
+ } else {
+ *pp_user = talloc_strdup(ctx, u);
+ if (!*pp_user) {
+ return -1;
+ }
}
-
- if (domain[0] && workgroup) {
- strncpy(workgroup, domain, workgroup_len - 1);
- workgroup[workgroup_len - 1] = '\0';
- }
-
- if (username[0]) {
- strncpy(user, username, user_len - 1);
- user[user_len - 1] = '\0';
- }
-
- if (passwd[0]) {
- strncpy(password, passwd, password_len - 1);
- password[password_len - 1] = '\0';
- }
-
}
- if (!next_token(&p, server, "/", sizeof(fstring))) {
-
+ if (!next_token_talloc(ctx, &p, pp_server, "/")) {
return -1;
-
}
- if (*p == (char)0) goto decoding; /* That's it ... */
-
- if (!next_token(&p, share, "/", sizeof(fstring))) {
+ if (*p == (char)0) {
+ goto decoding; /* That's it ... */
+ }
+ if (!next_token_talloc(ctx, &p, pp_share, "/")) {
--
Samba Shared Repository
More information about the samba-cvs
mailing list