summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2005-08-21 02:12:25 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:34:15 -0500
commitf0b06b36f9d98e67de1b20dc840d317720ba4ab7 (patch)
tree0c80dcebdd8c9b0a76a73215767d2c51d8eb4b8c
parentdf3248f1087549d0fd11e003b3f1ac61b97aa7f7 (diff)
downloadsamba-f0b06b36f9d98e67de1b20dc840d317720ba4ab7.tar.gz
samba-f0b06b36f9d98e67de1b20dc840d317720ba4ab7.tar.bz2
samba-f0b06b36f9d98e67de1b20dc840d317720ba4ab7.zip
r9442: Support some more primitive types. Fix charset support.
(This used to be commit eeced29eb3dd2cbc4540555bdb642b2685eb9c5c)
-rw-r--r--source4/lib/tdr/tdr.c105
1 files changed, 90 insertions, 15 deletions
diff --git a/source4/lib/tdr/tdr.c b/source4/lib/tdr/tdr.c
index c9aa289f00..8cfbe3695b 100644
--- a/source4/lib/tdr/tdr.c
+++ b/source4/lib/tdr/tdr.c
@@ -125,7 +125,7 @@ NTSTATUS tdr_print_uint16(struct tdr_print *tdr, const char *name, uint16_t *v)
return NT_STATUS_OK;
}
-NTSTATUS tdr_pull_uint32(struct tdr_pull *tdr, uint16_t *v)
+NTSTATUS tdr_pull_uint32(struct tdr_pull *tdr, uint32_t *v)
{
TDR_PULL_NEED_BYTES(tdr, 4);
*v = TDR_IVAL(tdr, tdr->offset);
@@ -133,7 +133,7 @@ NTSTATUS tdr_pull_uint32(struct tdr_pull *tdr, uint16_t *v)
return NT_STATUS_OK;
}
-NTSTATUS tdr_push_uint32(struct tdr_push *tdr, const uint16_t *v)
+NTSTATUS tdr_push_uint32(struct tdr_push *tdr, const uint32_t *v)
{
TDR_PUSH_NEED_BYTES(tdr, 4);
TDR_SIVAL(tdr, tdr->offset, *v);
@@ -147,21 +147,24 @@ NTSTATUS tdr_print_uint32(struct tdr_print *tdr, const char *name, uint32_t *v)
return NT_STATUS_OK;
}
-NTSTATUS tdr_pull_charset(struct tdr_pull *tdr, char **v, uint32_t length, uint32_t el_size, int chset)
+NTSTATUS tdr_pull_charset(struct tdr_pull *tdr, const char **v, uint32_t length, uint32_t el_size, int chset)
{
int ret;
+
if (length == -1) {
switch (chset) {
- case CH_DOS:
- length = ascii_len_n((const char*)tdr->data+tdr->offset, tdr->length-tdr->offset);
- break;
- case CH_UTF16:
- length = utf16_len_n(tdr->data+tdr->offset, tdr->length-tdr->offset);
- default:
- return NT_STATUS_INVALID_PARAMETER;
+ case CH_DOS:
+ length = ascii_len_n((const char*)tdr->data+tdr->offset, tdr->length-tdr->offset);
+ break;
+ case CH_UTF16:
+ length = utf16_len_n(tdr->data+tdr->offset, tdr->length-tdr->offset);
+ break;
+
+ default:
+ return NT_STATUS_INVALID_PARAMETER;
}
}
-
+
TDR_PULL_NEED_BYTES(tdr, el_size*length);
ret = convert_string_talloc(tdr, chset, CH_UNIX, tdr->data+tdr->offset, el_size*length, (void **)v);
@@ -175,16 +178,23 @@ NTSTATUS tdr_pull_charset(struct tdr_pull *tdr, char **v, uint32_t length, uint3
NTSTATUS tdr_push_charset(struct tdr_push *tdr, const char **v, uint32_t length, uint32_t el_size, int chset)
{
- int ret;
- TDR_PUSH_NEED_BYTES(tdr, el_size*length);
+ ssize_t ret, required;
+
+ required = el_size * length;
+ TDR_PUSH_NEED_BYTES(tdr, required);
- ret = convert_string(CH_UNIX, chset, *v, length, tdr->data+tdr->offset, el_size*length);
+ ret = convert_string(CH_UNIX, chset, *v, strlen(*v), tdr->data+tdr->offset, required);
if (ret == -1) {
return NT_STATUS_INVALID_PARAMETER;
}
+
+ /* Make sure the remaining part of the string is filled with zeroes */
+ if (ret < required) {
+ memset(tdr->data+tdr->offset+ret, 0, required-ret);
+ }
- tdr->offset += ret;
+ tdr->offset += required;
return NT_STATUS_OK;
}
@@ -227,3 +237,68 @@ NTSTATUS tdr_print_ipv4address(struct tdr_print *tdr, const char *name,
tdr->print(tdr, "%-25s: %s", name, *address);
return NT_STATUS_OK;
}
+
+/*
+ parse a hyper
+*/
+NTSTATUS tdr_pull_hyper(struct tdr_pull *tdr, uint64_t *v)
+{
+ TDR_PULL_NEED_BYTES(tdr, 8);
+ *v = TDR_IVAL(tdr, tdr->offset);
+ *v |= (uint64_t)(TDR_IVAL(tdr, tdr->offset+4)) << 32;
+ tdr->offset += 8;
+ return NT_STATUS_OK;
+}
+
+/*
+ push a hyper
+*/
+NTSTATUS tdr_push_hyper(struct tdr_push *tdr, uint64_t *v)
+{
+ TDR_PUSH_NEED_BYTES(tdr, 8);
+ TDR_SIVAL(tdr, tdr->offset, ((*v) & 0xFFFFFFFF));
+ TDR_SIVAL(tdr, tdr->offset+4, ((*v)>>32));
+ tdr->offset += 8;
+ return NT_STATUS_OK;
+}
+
+
+
+/*
+ push a NTTIME
+*/
+NTSTATUS tdr_push_NTTIME(struct tdr_push *tdr, NTTIME *t)
+{
+ TDR_CHECK(tdr_push_hyper(tdr, t));
+ return NT_STATUS_OK;
+}
+
+/*
+ pull a NTTIME
+*/
+NTSTATUS tdr_pull_NTTIME(struct tdr_pull *tdr, NTTIME *t)
+{
+ TDR_CHECK(tdr_pull_hyper(tdr, t));
+ return NT_STATUS_OK;
+}
+
+/*
+ push a time_t
+*/
+NTSTATUS tdr_push_time_t(struct tdr_push *tdr, time_t *t)
+{
+ return tdr_push_uint32(tdr, (uint32_t *)t);
+}
+
+/*
+ pull a time_t
+*/
+NTSTATUS tdr_pull_time_t(struct tdr_pull *tdr, time_t *t)
+{
+ uint32_t tt;
+ TDR_CHECK(tdr_pull_uint32(tdr, &tt));
+ *t = tt;
+ return NT_STATUS_OK;
+}
+
+