/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/* encode.c - ber output encoding routines */
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of Michigan at Ann Arbor. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*/
#include <stdio.h>
#ifdef MACOS
#include <stdlib.h>
#include <stdarg.h>
#include "macos.h"
#else /* MACOS */
#include <stdlib.h>
#else /* next || vms */
#include <malloc.h>
#endif /* next || vms */
#include <stdarg.h>
#else /* BC31 || _WIN32 */
#include <varargs.h>
#endif /* BC31 || _WIN32 */
#ifdef PCNFS
#include <tklib.h>
#endif /* PCNFS */
#endif /* MACOS */
#ifndef VMS
#include <memory.h>
#endif
#include <string.h>
#include "lber.h"
#include "ldap.h"
#include "ldap-private.h"
#include "ldap-int.h"
#include "msdos.h"
#endif /* DOS */
#ifdef NEEDPROTOS
#endif /* NEEDPROTOS */
static int
{
int i;
int mask;
/* find the first non-all-zero byte in the tag */
for ( i = sizeof(int) - 1; i > 0; i-- ) {
/* not all zero */
break;
}
return( i + 1 );
}
static int
{
int taglen;
unsigned int ntag;
}
static int
{
/*
* short len if it's less than 128 - one byte giving the len,
* with bit 8 0.
*/
if ( len <= 0x7F )
return( 1 );
/*
* int len otherwise - one byte with bit 8 set, giving the
* length of the length, followed by the length itself.
*/
if ( len <= 0xFF )
return( 2 );
if ( len <= 0xFFFF )
return( 3 );
if ( len <= 0xFFFFFF )
return( 4 );
return( 5 );
}
static int
{
int i;
char lenlen;
int mask;
unsigned int netlen;
/*
* short len if it's less than 128 - one byte giving the len,
* with bit 8 0.
*/
if ( len <= 127 ) {
1, nosos ) );
}
/*
* int len otherwise - one byte with bit 8 set, giving the
* length of the length, followed by the length itself.
*/
/* find the first non-all-zero byte */
for ( i = sizeof(int) - 1; i > 0; i-- ) {
/* not all zero */
break;
}
lenlen = ++i;
if ( lenlen > 4 )
return( -1 );
lenlen |= 0x80;
/* write the length of the length */
return( -1 );
/* write the length itself */
!= i )
return( -1 );
return( i + 1 );
}
static int
{
/*
* high bit is set - look for first non-all-one byte
* high bit is clear - look for first non-all-zero byte
*/
for ( i = sizeof(int) - 1; i > 0; i-- ) {
if ( sign ) {
/* not all ones */
break;
} else {
/* not all zero */
break;
}
}
/*
* we now have the "leading byte". if the high bit on this
* byte matches the sign bit, we need to "back up" a byte.
*/
i++;
len = i + 1;
return( -1 );
return( -1 );
i++;
!= i )
return( -1 );
/* length of tag + length + contents */
}
int
{
if ( tag == LBER_DEFAULT )
}
int
{
if ( tag == LBER_DEFAULT )
tag = LBER_INTEGER;
}
int
unsigned int tag )
{
#ifdef STR_TRANSLATION
int free_str;
#endif /* STR_TRANSLATION */
if ( tag == LBER_DEFAULT )
return( -1 );
#ifdef STR_TRANSLATION
!= 0 ) {
return( -1 );
}
free_str = 1;
} else {
free_str = 0;
}
#endif /* STR_TRANSLATION */
rc = -1;
} else {
/* return length of tag + length + contents */
}
#ifdef STR_TRANSLATION
if ( free_str ) {
}
#endif /* STR_TRANSLATION */
return( rc );
}
int
{
}
int
{
unsigned char unusedbits;
if ( tag == LBER_DEFAULT )
return( -1 );
return( -1 );
return( -1 );
return( -1 );
/* return length of tag + length + unused bit count + contents */
}
int
{
int taglen;
if ( tag == LBER_DEFAULT )
return( -1 );
return( -1 );
return( taglen + 1 );
}
int
{
int taglen;
if ( tag == LBER_DEFAULT )
tag = LBER_BOOLEAN;
return( -1 );
return( -1 );
!= 1 )
return( -1 );
return( taglen + 2 );
}
static int
{
== NULLSEQORSET )
return( -1 );
else
/* Set aside room for a 4 byte length field */
return( 0 );
}
int
{
if ( tag == LBER_DEFAULT )
tag = LBER_SEQUENCE;
}
int
{
if ( tag == LBER_DEFAULT )
}
static int
{
/*
* If this is the toplevel sequence or set, we need to actually
* write the stuff out. Otherwise, it's already been put in
* the appropriate buffer and will be written when the toplevel
* one is written. In this case all we need to do is update the
* length and tag.
*/
/* CONSTCOND */
return( -1 );
} else {
}
/* write the tag */
return( -1 );
/* Write the length in the minimum # of octets */
return( -1 );
if (lenlen != FOUR_BYTE_LEN) {
/*
* We set aside FOUR_BYTE_LEN bytes for
* the length field. Move the data if
* we don't actually need that much
*/
FOUR_BYTE_LEN, len );
}
} else {
/* Fill FOUR_BYTE_LEN bytes for length field */
/* one byte of length length */
return( -1 );
/* the length itself */
!= FOUR_BYTE_LEN - 1 )
return( -1 );
}
} else {
unsigned int ntag;
/* the tag */
}
/* one byte of length length */
if (lenlen > 1) {
/* Write the length itself */
(char *)&netlen + sizeof(unsigned int) -
(lenlen - 1),
lenlen - 1 );
}
if (lenlen != FOUR_BYTE_LEN) {
/*
* We set aside FOUR_BYTE_LEN bytes for
* the length field. Move the data if
* we don't actually need that much
*/
FOUR_BYTE_LEN, len );
}
} else {
/* the length itself */
(char *) &netlen + sizeof(int) -
}
}
/* we're done with this seqorset, so free it up */
}
int
{
return( ber_put_seqorset( ber ) );
}
int
{
return( ber_put_seqorset( ber ) );
}
/* VARARGS */
int
#else /* MACOS || _WIN32 || BC31 */
va_alist )
#endif /* MACOS || _WIN32 || BC31 */
{
char *fmt;
#endif /* !MACOS && !_WIN32 && !BC31 */
char *s, **ss;
int rc, i;
unsigned int len;
#else /* MACOS || _WIN32 || BC31 */
#endif /* MACOS || _WIN32 || BC31 */
switch ( *fmt ) {
case 'b': /* boolean */
break;
case 'i': /* int */
break;
case 'e': /* enumeration */
break;
case 'n': /* null */
break;
case 'o': /* octet string (non-null terminated) */
break;
case 's': /* string */
break;
case 'B': /* bit string */
break;
case 't': /* tag for the next element */
break;
case 'v': /* vector of strings */
break;
break;
}
break;
case 'V': /* sequences of strings + lengths */
break;
break;
}
break;
case '{': /* begin sequence */
break;
case '}': /* end sequence */
break;
case '[': /* begin set */
break;
case ']': /* end set */
break;
default:
#ifndef NO_USERINTERFACE
#endif /* NO_USERINTERFACE */
rc = -1;
break;
}
if ( ber->ber_usertag == 0 )
else
ber->ber_usertag = 0;
}
return( rc );
}