Decouple clistr_pull from struct cli_state->inbuf
[metze/samba/wip.git] / source3 / libsmb / clistr.c
index c0e7231d7a79ef25698e8f97884d660e5a4f77fa..86857814043338df630c326d6a3b2007bf067338 100644 (file)
@@ -1,12 +1,12 @@
 /* 
-   Unix SMB/Netbios implementation.
-   Version 3.0
+   Unix SMB/CIFS implementation.
    client string routines
    Copyright (C) Andrew Tridgell 2001
-   
+   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#define NO_SYSLOG
-
 #include "includes.h"
 
-/****************************************************************************
-copy a string from a char* src to a unicode or ascii
-dos code page destination choosing unicode or ascii based on the 
-cli->capabilities flag
-return the number of bytes occupied by the string in the destination
-flags can have:
-  STR_TERMINATE means include the null termination
-  STR_CONVERT   means convert from unix to dos codepage
-  STR_UPPER     means uppercase in the destination
-  STR_ASCII     use ascii even with unicode servers
-dest_len is the maximum length allowed in the destination. If dest_len
-is -1 then no maxiumum is used
-****************************************************************************/
-int clistr_push(struct cli_state *cli, void *dest, const char *src, int dest_len, int flags)
+size_t clistr_push_fn(const char *function,
+                       unsigned int line,
+                       struct cli_state *cli,
+                       void *dest,
+                       const char *src,
+                       int dest_len,
+                       int flags)
 {
-       int len=0;
-
-       /* treat a pstring as "unlimited" length */
+       size_t buf_used = PTR_DIFF(dest, cli->outbuf);
        if (dest_len == -1) {
-               dest_len = sizeof(pstring);
-       }
-
-       if (!(flags & STR_ASCII) && clistr_align(cli, PTR_DIFF(dest, cli->outbuf))) {
-               *(char *)dest = 0;
-               dest++;
-               dest_len--;
-               len++;
-       }
-
-       if ((flags & STR_ASCII) || !(cli->capabilities & CAP_UNICODE)) {
-               /* the server doesn't want unicode */
-               safe_strcpy(dest, src, dest_len);
-               len = strlen(dest);
-               if (flags & STR_TERMINATE) len++;
-               if (flags & STR_CONVERT) unix_to_dos(dest,True);
-               if (flags & STR_UPPER) strupper(dest);
-               return len;
+               if (((ptrdiff_t)dest < (ptrdiff_t)cli->outbuf) || (buf_used > cli->bufsize)) {
+                       DEBUG(0, ("Pushing string of 'unlimited' length into non-SMB buffer!\n"));
+                       return push_string_fn(function, line,
+                                             cli->outbuf,
+                                             SVAL(cli->outbuf, smb_flg2),
+                                             dest, src, -1, flags);
+               }
+               return push_string_fn(function, line, cli->outbuf,
+                                     SVAL(cli->outbuf, smb_flg2),
+                                     dest, src, cli->bufsize - buf_used,
+                                     flags);
        }
 
-       /* the server likes unicode. give it the works */
-       if (flags & STR_CONVERT) {
-               dos_PutUniCode(dest, src, dest_len, flags & STR_TERMINATE);
-       } else {
-               ascii_to_unistr(dest, src, dest_len);
-       }
-       if (flags & STR_UPPER) {
-               strupper_w(dest);
-       }
-       len += strlen(src)*2;
-       if (flags & STR_TERMINATE) len += 2;
-       return len;
+       /* 'normal' push into size-specified buffer */
+       return push_string_fn(function, line, cli->outbuf,
+                             SVAL(cli->outbuf, smb_flg2),
+                             dest, src, dest_len, flags);
 }
 
-
-/****************************************************************************
-return the length that a string would occupy when copied with clistr_push()
-  STR_TERMINATE means include the null termination
-  STR_CONVERT   means convert from unix to dos codepage
-  STR_UPPER     means uppercase in the destination
-note that dest is only used for alignment purposes. No data is written.
-****************************************************************************/
-int clistr_push_size(struct cli_state *cli, const void *dest, const char *src, int dest_len, int flags)
+size_t clistr_pull_fn(const char *function,
+                       unsigned int line,
+                       const char *inbuf,
+                       char *dest,
+                       const void *src,
+                       int dest_len,
+                       int src_len,
+                       int flags)
 {
-       int len = strlen(src);
-       if (flags & STR_TERMINATE) len++;
-       if (!(flags & STR_ASCII) && (cli->capabilities & CAP_UNICODE)) len *= 2;
-
-       if (!(flags & STR_ASCII) && dest && clistr_align(cli, PTR_DIFF(cli->outbuf, dest))) {
-               len++;
-       }
-
-       return len;
+       return pull_string_fn(function, line, inbuf,
+                             SVAL(inbuf, smb_flg2), dest, src, dest_len,
+                             src_len, flags);
 }
 
-/****************************************************************************
-copy a string from a unicode or ascii source (depending on
-cli->capabilities) to a char* destination
-flags can have:
-  STR_CONVERT   means convert from dos to unix codepage
-  STR_TERMINATE means the string in src is null terminated
-  STR_UNICODE   means to force as unicode
-if STR_TERMINATE is set then src_len is ignored
-src_len is the length of the source area in bytes
-return the number of bytes occupied by the string in src
-****************************************************************************/
-int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len, int src_len, int flags)
+size_t clistr_pull_talloc_fn(const char *function,
+                               unsigned int line,
+                               TALLOC_CTX *ctx,
+                               const char *inbuf,
+                               char **pp_dest,
+                               const void *src,
+                               int src_len,
+                               int flags)
 {
-       int len;
-
-       if (dest_len == -1) {
-               dest_len = sizeof(pstring);
-       }
-
-       if (clistr_align(cli, PTR_DIFF(src, cli->inbuf))) {
-               src++;
-               if (src_len > 0) src_len--;
-       }
-
-       if (!(flags & STR_UNICODE) && !(cli->capabilities & CAP_UNICODE)) {
-               /* the server doesn't want unicode */
-               if (flags & STR_TERMINATE) {
-                       safe_strcpy(dest, src, dest_len);
-                       len = strlen(src)+1;
-               } else {
-                       if (src_len > dest_len) src_len = dest_len;
-                       len = src_len;
-                       memcpy(dest, src, len);
-                       dest[len] = 0;
-               }
-               if (flags & STR_CONVERT) dos_to_unix(dest,True);
-               return len;
-       }
-
-       if (flags & STR_TERMINATE) {
-               unistr_to_ascii(dest, src, dest_len);
-               len = strlen(dest)*2 + 2;
-       } else {
-               int i, c;
-               if (dest_len*2 < src_len) src_len = 2*dest_len;
-               for (i=0; i < src_len; i += 2) {
-                       c = SVAL(src, i);
-                       *dest++ = c;
-               }
-               *dest++ = 0;
-               len = src_len;
-       }
-       if (flags & STR_CONVERT) dos_to_unix(dest,True);
-       return len;
+       return pull_string_talloc_fn(function,
+                                       line,
+                                       ctx,
+                                       inbuf,
+                                       SVAL(inbuf, smb_flg2),
+                                       pp_dest,
+                                       src,
+                                       src_len,
+                                       flags);
 }
 
-/****************************************************************************
-return the length that a string would occupy (not including the null)
-when copied with clistr_pull()
-if src_len is -1 then assume the source is null terminated
-****************************************************************************/
-int clistr_pull_size(struct cli_state *cli, const void *src, int src_len)
+size_t clistr_align_out(struct cli_state *cli, const void *p, int flags)
 {
-       if (clistr_align(cli, PTR_DIFF(src, cli->inbuf))) {
-               src++;
-               if (src_len > 0) src_len--;
-       }
-
-       if (!(cli->capabilities & CAP_UNICODE)) {
-               return strlen(src);
-       }       
-       return strlen_w(src);
+       return align_string(cli->outbuf, (const char *)p, flags);
 }
 
-/****************************************************************************
-return an alignment of either 0 or 1
-if unicode is not negotiated then return 0
-otherwise return 1 if offset is off
-****************************************************************************/
-int clistr_align(struct cli_state *cli, int offset)
+size_t clistr_align_in(struct cli_state *cli, const void *p, int flags)
 {
-       if (!(cli->capabilities & CAP_UNICODE)) return 0;
-       return offset & 1;
+       return align_string(cli->inbuf, (const char *)p, flags);
 }