Remove pstrings from client/client.c by doing a large rewrite.
[kai/samba.git] / source / libsmb / clistr.c
index 887b5e84c1b395532fc2f81e4acd858e7569bed0..5d20d632aad002b4d15a7fdcd1d9788f27896787 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->outbuf, dest)) {
-               *(char *)dest = 0;
-               dest = (void *)((char *)dest + 1);
-               dest_len--;
-               len++;
-       }
-
-       if ((flags & STR_ASCII) || !(SVAL(cli->outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS)) {
-               /* 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);
 }
 
-/****************************************************************************
-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_fn(const char *function,
+                       unsigned int line,
+                       struct cli_state *cli,
+                       char *dest,
+                       const void *src,
+                       int dest_len,
+                       int src_len,
+                       int flags)
 {
-       int len;
-
-       if (dest_len == -1) {
-               dest_len = sizeof(pstring);
-       }
-
-       if (!(flags & STR_ASCII) && clistr_align(cli->inbuf, src)) {
-               src = (const void *)((const char *)src + 1);
-               if (src_len > 0) src_len--;
-       }
-
-       if ((flags & STR_ASCII) ||
-           (!(flags & STR_UNICODE) && !(SVAL(cli->inbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS))) {
-               /* 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) 
-                       safe_strcpy(dest,dos_to_unix(dest,False),dest_len);
-               return len;
-       }
+       return pull_string_fn(function, line, cli->inbuf,
+                             SVAL(cli->inbuf, smb_flg2), dest, src, dest_len,
+                             src_len, flags);
+}
 
-       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)
-               safe_strcpy(dest,dos_to_unix(dest,False),dest_len);
-       return len;
+size_t clistr_pull_talloc_fn(const char *function,
+                               unsigned int line,
+                               TALLOC_CTX *ctx,
+                               struct cli_state *cli,
+                               char **pp_dest,
+                               const void *src,
+                               int src_len,
+                               int flags)
+{
+       return pull_string_talloc_fn(function,
+                                       line,
+                                       ctx,
+                                       cli->inbuf,
+                                       SVAL(cli->inbuf, smb_flg2),
+                                       pp_dest,
+                                       src,
+                                       src_len,
+                                       flags);
 }
 
+size_t clistr_align_out(struct cli_state *cli, const void *p, int flags)
+{
+       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(const void *buf, const void *p)
+size_t clistr_align_in(struct cli_state *cli, const void *p, int flags)
 {
-       if (!(SVAL(buf, smb_flg2) & FLAGS2_UNICODE_STRINGS)) return 0;
-       return PTR_DIFF(p, buf) & 1;
+       return align_string(cli->inbuf, (const char *)p, flags);
 }