17c478bd9Sstevel@tonic-gate /* 2*924965c7SSerge Dussud * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 3*924965c7SSerge Dussud * Use is subject to license terms. 47c478bd9Sstevel@tonic-gate */ 57c478bd9Sstevel@tonic-gate 67c478bd9Sstevel@tonic-gate /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * The contents of this file are subject to the Netscape Public License 97c478bd9Sstevel@tonic-gate * Version 1.0 (the "NPL"); you may not use this file except in 107c478bd9Sstevel@tonic-gate * compliance with the NPL. You may obtain a copy of the NPL at 117c478bd9Sstevel@tonic-gate * http://www.mozilla.org/NPL/ 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * Software distributed under the NPL is distributed on an "AS IS" basis, 147c478bd9Sstevel@tonic-gate * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL 157c478bd9Sstevel@tonic-gate * for the specific language governing rights and limitations under the 167c478bd9Sstevel@tonic-gate * NPL. 177c478bd9Sstevel@tonic-gate * 187c478bd9Sstevel@tonic-gate * The Initial Developer of this code under the NPL is Netscape 197c478bd9Sstevel@tonic-gate * Communications Corporation. Portions created by Netscape are 207c478bd9Sstevel@tonic-gate * Copyright (C) 1998 Netscape Communications Corporation. All Rights 217c478bd9Sstevel@tonic-gate * Reserved. 227c478bd9Sstevel@tonic-gate */ 237c478bd9Sstevel@tonic-gate 247c478bd9Sstevel@tonic-gate /* 257c478bd9Sstevel@tonic-gate * Copyright (c) 1990 Regents of the University of Michigan. 267c478bd9Sstevel@tonic-gate * All rights reserved. 277c478bd9Sstevel@tonic-gate * 287c478bd9Sstevel@tonic-gate * Redistribution and use in source and binary forms are permitted 297c478bd9Sstevel@tonic-gate * provided that this notice is preserved and that due credit is given 307c478bd9Sstevel@tonic-gate * to the University of Michigan at Ann Arbor. The name of the University 317c478bd9Sstevel@tonic-gate * may not be used to endorse or promote products derived from this 327c478bd9Sstevel@tonic-gate * software without specific prior written permission. This software 337c478bd9Sstevel@tonic-gate * is provided ``as is'' without express or implied warranty. 347c478bd9Sstevel@tonic-gate */ 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate /* encode.c - ber output encoding routines */ 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate #include "lber-int.h" 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate /* the following constants are used in ber_calc_lenlen */ 417c478bd9Sstevel@tonic-gate 427c478bd9Sstevel@tonic-gate #define LENMASK1 0xFF 437c478bd9Sstevel@tonic-gate #define LENMASK2 0xFFFF 447c478bd9Sstevel@tonic-gate #define LENMASK3 0xFFFFFF 457c478bd9Sstevel@tonic-gate #define LENMASK4 0xFFFFFFFF 467c478bd9Sstevel@tonic-gate #define _MASK 0x80 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate static int 497c478bd9Sstevel@tonic-gate ber_calc_taglen( ber_tag_t tag ) 507c478bd9Sstevel@tonic-gate { 517c478bd9Sstevel@tonic-gate int i; 527c478bd9Sstevel@tonic-gate ber_int_t mask; 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate /* find the first non-all-zero byte in the tag */ 557c478bd9Sstevel@tonic-gate for ( i = sizeof(ber_int_t) - 1; i > 0; i-- ) { 567c478bd9Sstevel@tonic-gate mask = (LENMASK3 << (i * 8)); 577c478bd9Sstevel@tonic-gate /* not all zero */ 587c478bd9Sstevel@tonic-gate if ( tag & mask ) 597c478bd9Sstevel@tonic-gate break; 607c478bd9Sstevel@tonic-gate } 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate return( i + 1 ); 637c478bd9Sstevel@tonic-gate } 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate static int 667c478bd9Sstevel@tonic-gate ber_put_tag( BerElement *ber, ber_tag_t tag, int nosos ) 677c478bd9Sstevel@tonic-gate { 687c478bd9Sstevel@tonic-gate int taglen; 697c478bd9Sstevel@tonic-gate ber_tag_t ntag; 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate taglen = ber_calc_taglen( tag ); 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate ntag = LBER_HTONL( tag ); 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate return( ber_write( ber, ((char *) &ntag) + sizeof(ber_int_t) - taglen, 767c478bd9Sstevel@tonic-gate taglen, nosos ) ); 777c478bd9Sstevel@tonic-gate } 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate static int 807c478bd9Sstevel@tonic-gate ber_calc_lenlen( ber_len_t len ) 817c478bd9Sstevel@tonic-gate { 827c478bd9Sstevel@tonic-gate /* 837c478bd9Sstevel@tonic-gate * short len if it's less than 128 - one byte giving the len, 847c478bd9Sstevel@tonic-gate * with bit 8 0. 857c478bd9Sstevel@tonic-gate */ 867c478bd9Sstevel@tonic-gate 877c478bd9Sstevel@tonic-gate if ( len <= 0x7F ) 887c478bd9Sstevel@tonic-gate return( 1 ); 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate /* 917c478bd9Sstevel@tonic-gate * long len otherwise - one byte with bit 8 set, giving the 927c478bd9Sstevel@tonic-gate * length of the length, followed by the length itself. 937c478bd9Sstevel@tonic-gate */ 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate if ( len <= LENMASK1 ) 967c478bd9Sstevel@tonic-gate return( 2 ); 977c478bd9Sstevel@tonic-gate if ( len <= LENMASK2 ) 987c478bd9Sstevel@tonic-gate return( 3 ); 997c478bd9Sstevel@tonic-gate if ( len <= LENMASK3 ) 1007c478bd9Sstevel@tonic-gate return( 4 ); 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate return( 5 ); 1037c478bd9Sstevel@tonic-gate } 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate static int 1067c478bd9Sstevel@tonic-gate ber_put_len( BerElement *ber, ber_len_t len, int nosos ) 1077c478bd9Sstevel@tonic-gate { 1087c478bd9Sstevel@tonic-gate int i; 1097c478bd9Sstevel@tonic-gate char lenlen; 1107c478bd9Sstevel@tonic-gate ber_int_t mask; 1117c478bd9Sstevel@tonic-gate ber_len_t netlen; 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate /* 1147c478bd9Sstevel@tonic-gate * short len if it's less than 128 - one byte giving the len, 1157c478bd9Sstevel@tonic-gate * with bit 8 0. 1167c478bd9Sstevel@tonic-gate */ 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate if ( len <= 127 ) { 1197c478bd9Sstevel@tonic-gate netlen = LBER_HTONL( len ); 1207c478bd9Sstevel@tonic-gate return( ber_write( ber, (char *) &netlen + sizeof(ber_int_t) - 1, 1217c478bd9Sstevel@tonic-gate 1, nosos ) ); 1227c478bd9Sstevel@tonic-gate } 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate /* 1257c478bd9Sstevel@tonic-gate * long len otherwise - one byte with bit 8 set, giving the 1267c478bd9Sstevel@tonic-gate * length of the length, followed by the length itself. 1277c478bd9Sstevel@tonic-gate */ 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate /* find the first non-all-zero byte */ 1307c478bd9Sstevel@tonic-gate for ( i = sizeof(ber_int_t) - 1; i > 0; i-- ) { 1317c478bd9Sstevel@tonic-gate mask = (LENMASK1 << (i * 8)); 1327c478bd9Sstevel@tonic-gate /* not all zero */ 1337c478bd9Sstevel@tonic-gate if ( len & mask ) 1347c478bd9Sstevel@tonic-gate break; 1357c478bd9Sstevel@tonic-gate } 1367c478bd9Sstevel@tonic-gate lenlen = ++i; 1377c478bd9Sstevel@tonic-gate if ( lenlen > 4 ) 1387c478bd9Sstevel@tonic-gate return( -1 ); 1397c478bd9Sstevel@tonic-gate lenlen |= 0x80; 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate /* write the length of the length */ 1427c478bd9Sstevel@tonic-gate if ( ber_write( ber, &lenlen, 1, nosos ) != 1 ) 1437c478bd9Sstevel@tonic-gate return( -1 ); 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate /* write the length itself */ 1467c478bd9Sstevel@tonic-gate netlen = LBER_HTONL( len ); 1477c478bd9Sstevel@tonic-gate if ( ber_write( ber, (char *) &netlen + (sizeof(ber_int_t) - i), i, nosos ) 1487c478bd9Sstevel@tonic-gate != i ) 1497c478bd9Sstevel@tonic-gate return( -1 ); 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate return( i + 1 ); 1527c478bd9Sstevel@tonic-gate } 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate static int 1557c478bd9Sstevel@tonic-gate ber_put_int_or_enum( BerElement *ber, ber_int_t num, ber_tag_t tag ) 1567c478bd9Sstevel@tonic-gate { 1577c478bd9Sstevel@tonic-gate int i, sign, taglen; 1587c478bd9Sstevel@tonic-gate int len, lenlen; 1597c478bd9Sstevel@tonic-gate ber_int_t netnum, mask; 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate sign = (num < 0); 1627c478bd9Sstevel@tonic-gate 1637c478bd9Sstevel@tonic-gate /* 1647c478bd9Sstevel@tonic-gate * high bit is set - look for first non-all-one byte 1657c478bd9Sstevel@tonic-gate * high bit is clear - look for first non-all-zero byte 1667c478bd9Sstevel@tonic-gate */ 1677c478bd9Sstevel@tonic-gate for ( i = sizeof(ber_int_t) - 1; i > 0; i-- ) { 1687c478bd9Sstevel@tonic-gate mask = (LENMASK1 << (i * 8)); 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate if ( sign ) { 1717c478bd9Sstevel@tonic-gate /* not all ones */ 1727c478bd9Sstevel@tonic-gate if ( (num & mask) != mask ) 1737c478bd9Sstevel@tonic-gate break; 1747c478bd9Sstevel@tonic-gate } else { 1757c478bd9Sstevel@tonic-gate /* not all zero */ 1767c478bd9Sstevel@tonic-gate if ( num & mask ) 1777c478bd9Sstevel@tonic-gate break; 1787c478bd9Sstevel@tonic-gate } 1797c478bd9Sstevel@tonic-gate } 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate /* 1827c478bd9Sstevel@tonic-gate * we now have the "leading byte". if the high bit on this 1837c478bd9Sstevel@tonic-gate * byte matches the sign bit, we need to "back up" a byte. 1847c478bd9Sstevel@tonic-gate */ 1857c478bd9Sstevel@tonic-gate mask = (num & (_MASK << (i * 8))); 1867c478bd9Sstevel@tonic-gate if ( (mask && !sign) || (sign && !mask) ) 1877c478bd9Sstevel@tonic-gate i++; 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate len = i + 1; 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 ) 1927c478bd9Sstevel@tonic-gate return( -1 ); 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate if ( (lenlen = ber_put_len( ber, len, 0 )) == -1 ) 1957c478bd9Sstevel@tonic-gate return( -1 ); 1967c478bd9Sstevel@tonic-gate i++; 1977c478bd9Sstevel@tonic-gate netnum = LBER_HTONL( num ); 1987c478bd9Sstevel@tonic-gate if ( ber_write( ber, (char *) &netnum + (sizeof(ber_int_t) - i), i, 0 ) 1997c478bd9Sstevel@tonic-gate == i) 2007c478bd9Sstevel@tonic-gate /* length of tag + length + contents */ 2017c478bd9Sstevel@tonic-gate return( taglen + lenlen + i ); 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate return( -1 ); 2047c478bd9Sstevel@tonic-gate } 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate int 2077c478bd9Sstevel@tonic-gate LDAP_CALL 2087c478bd9Sstevel@tonic-gate ber_put_enum( BerElement *ber, ber_int_t num, ber_tag_t tag ) 2097c478bd9Sstevel@tonic-gate { 2107c478bd9Sstevel@tonic-gate if ( tag == LBER_DEFAULT ) 2117c478bd9Sstevel@tonic-gate tag = LBER_ENUMERATED; 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate return( ber_put_int_or_enum( ber, num, tag ) ); 2147c478bd9Sstevel@tonic-gate } 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate int 2177c478bd9Sstevel@tonic-gate LDAP_CALL 2187c478bd9Sstevel@tonic-gate ber_put_int( BerElement *ber, ber_int_t num, ber_tag_t tag ) 2197c478bd9Sstevel@tonic-gate { 2207c478bd9Sstevel@tonic-gate if ( tag == LBER_DEFAULT ) 2217c478bd9Sstevel@tonic-gate tag = LBER_INTEGER; 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate return( ber_put_int_or_enum( ber, num, tag ) ); 2247c478bd9Sstevel@tonic-gate } 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate int 2277c478bd9Sstevel@tonic-gate LDAP_CALL 2287c478bd9Sstevel@tonic-gate ber_put_ostring( BerElement *ber, char *str, ber_len_t len, 2297c478bd9Sstevel@tonic-gate ber_tag_t tag ) 2307c478bd9Sstevel@tonic-gate { 2317c478bd9Sstevel@tonic-gate int taglen, lenlen, rc; 2327c478bd9Sstevel@tonic-gate #ifdef STR_TRANSLATION 2337c478bd9Sstevel@tonic-gate int free_str; 2347c478bd9Sstevel@tonic-gate #endif /* STR_TRANSLATION */ 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate if ( tag == LBER_DEFAULT ) 2377c478bd9Sstevel@tonic-gate tag = LBER_OCTETSTRING; 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 ) 2407c478bd9Sstevel@tonic-gate return( -1 ); 2417c478bd9Sstevel@tonic-gate 2427c478bd9Sstevel@tonic-gate #ifdef STR_TRANSLATION 2437c478bd9Sstevel@tonic-gate if ( len > 0 && ( ber->ber_options & LBER_OPT_TRANSLATE_STRINGS ) != 0 2447c478bd9Sstevel@tonic-gate && ber->ber_encode_translate_proc != NULL ) { 2457c478bd9Sstevel@tonic-gate if ( (*(ber->ber_encode_translate_proc))( &str, &len, 0 ) 2467c478bd9Sstevel@tonic-gate != 0 ) { 2477c478bd9Sstevel@tonic-gate return( -1 ); 2487c478bd9Sstevel@tonic-gate } 2497c478bd9Sstevel@tonic-gate free_str = 1; 2507c478bd9Sstevel@tonic-gate } else { 2517c478bd9Sstevel@tonic-gate free_str = 0; 2527c478bd9Sstevel@tonic-gate } 2537c478bd9Sstevel@tonic-gate #endif /* STR_TRANSLATION */ 2547c478bd9Sstevel@tonic-gate 2557c478bd9Sstevel@tonic-gate /* 2567c478bd9Sstevel@tonic-gate * Note: below is a spot where we limit ber_write 2577c478bd9Sstevel@tonic-gate * to signed long (instead of unsigned long) 2587c478bd9Sstevel@tonic-gate */ 2597c478bd9Sstevel@tonic-gate 2607c478bd9Sstevel@tonic-gate if ( (lenlen = ber_put_len( ber, len, 0 )) == -1 || 2617c478bd9Sstevel@tonic-gate ber_write( ber, str, len, 0 ) != (ber_int_t) len ) { 2627c478bd9Sstevel@tonic-gate rc = -1; 2637c478bd9Sstevel@tonic-gate } else { 2647c478bd9Sstevel@tonic-gate /* return length of tag + length + contents */ 2657c478bd9Sstevel@tonic-gate rc = taglen + lenlen + len; 2667c478bd9Sstevel@tonic-gate } 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate #ifdef STR_TRANSLATION 2697c478bd9Sstevel@tonic-gate if ( free_str ) { 2707c478bd9Sstevel@tonic-gate NSLBERI_FREE( str ); 2717c478bd9Sstevel@tonic-gate } 2727c478bd9Sstevel@tonic-gate #endif /* STR_TRANSLATION */ 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate return( rc ); 2757c478bd9Sstevel@tonic-gate } 2767c478bd9Sstevel@tonic-gate 2777c478bd9Sstevel@tonic-gate int 2787c478bd9Sstevel@tonic-gate LDAP_CALL 2797c478bd9Sstevel@tonic-gate ber_put_string( BerElement *ber, char *str, ber_tag_t tag ) 2807c478bd9Sstevel@tonic-gate { 2817c478bd9Sstevel@tonic-gate return( ber_put_ostring( ber, str, (ber_len_t) strlen( str ), tag )); 2827c478bd9Sstevel@tonic-gate } 2837c478bd9Sstevel@tonic-gate 2847c478bd9Sstevel@tonic-gate int 2857c478bd9Sstevel@tonic-gate LDAP_CALL 2867c478bd9Sstevel@tonic-gate ber_put_bitstring( BerElement *ber, char *str, 2877c478bd9Sstevel@tonic-gate ber_len_t blen /* in bits */, ber_tag_t tag ) 2887c478bd9Sstevel@tonic-gate { 2897c478bd9Sstevel@tonic-gate int taglen, lenlen, len; 2907c478bd9Sstevel@tonic-gate unsigned char unusedbits; 2917c478bd9Sstevel@tonic-gate 2927c478bd9Sstevel@tonic-gate if ( tag == LBER_DEFAULT ) 2937c478bd9Sstevel@tonic-gate tag = LBER_BITSTRING; 2947c478bd9Sstevel@tonic-gate 2957c478bd9Sstevel@tonic-gate if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 ) 2967c478bd9Sstevel@tonic-gate return( -1 ); 2977c478bd9Sstevel@tonic-gate 2987c478bd9Sstevel@tonic-gate len = ( blen + 7 ) / 8; 2997c478bd9Sstevel@tonic-gate unusedbits = (unsigned char) (len * 8 - blen); 3007c478bd9Sstevel@tonic-gate if ( (lenlen = ber_put_len( ber, len + 1, 0 )) == -1 ) 3017c478bd9Sstevel@tonic-gate return( -1 ); 3027c478bd9Sstevel@tonic-gate 3037c478bd9Sstevel@tonic-gate if ( ber_write( ber, (char *)&unusedbits, 1, 0 ) != 1 ) 3047c478bd9Sstevel@tonic-gate return( -1 ); 3057c478bd9Sstevel@tonic-gate 3067c478bd9Sstevel@tonic-gate if ( ber_write( ber, str, len, 0 ) != len ) 3077c478bd9Sstevel@tonic-gate return( -1 ); 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate /* return length of tag + length + unused bit count + contents */ 3107c478bd9Sstevel@tonic-gate return( taglen + 1 + lenlen + len ); 3117c478bd9Sstevel@tonic-gate } 3127c478bd9Sstevel@tonic-gate 3137c478bd9Sstevel@tonic-gate int 3147c478bd9Sstevel@tonic-gate LDAP_CALL 3157c478bd9Sstevel@tonic-gate ber_put_null( BerElement *ber, ber_tag_t tag ) 3167c478bd9Sstevel@tonic-gate { 3177c478bd9Sstevel@tonic-gate int taglen; 3187c478bd9Sstevel@tonic-gate 3197c478bd9Sstevel@tonic-gate if ( tag == LBER_DEFAULT ) 3207c478bd9Sstevel@tonic-gate tag = LBER_NULL; 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gate if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 ) 3237c478bd9Sstevel@tonic-gate return( -1 ); 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate if ( ber_put_len( ber, 0, 0 ) != 1 ) 3267c478bd9Sstevel@tonic-gate return( -1 ); 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate return( taglen + 1 ); 3297c478bd9Sstevel@tonic-gate } 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate int 3327c478bd9Sstevel@tonic-gate LDAP_CALL 3337c478bd9Sstevel@tonic-gate ber_put_boolean( BerElement *ber, int boolval, ber_tag_t tag ) 3347c478bd9Sstevel@tonic-gate { 3357c478bd9Sstevel@tonic-gate int taglen; 3367c478bd9Sstevel@tonic-gate unsigned char trueval = 0xff; 3377c478bd9Sstevel@tonic-gate unsigned char falseval = 0x00; 3387c478bd9Sstevel@tonic-gate 3397c478bd9Sstevel@tonic-gate if ( tag == LBER_DEFAULT ) 3407c478bd9Sstevel@tonic-gate tag = LBER_BOOLEAN; 3417c478bd9Sstevel@tonic-gate 3427c478bd9Sstevel@tonic-gate if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 ) 3437c478bd9Sstevel@tonic-gate return( -1 ); 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate if ( ber_put_len( ber, 1, 0 ) != 1 ) 3467c478bd9Sstevel@tonic-gate return( -1 ); 3477c478bd9Sstevel@tonic-gate 3487c478bd9Sstevel@tonic-gate if ( ber_write( ber, (char *)(boolval ? &trueval : &falseval), 1, 0 ) 3497c478bd9Sstevel@tonic-gate != 1 ) 3507c478bd9Sstevel@tonic-gate return( -1 ); 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate return( taglen + 2 ); 3537c478bd9Sstevel@tonic-gate } 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate #define FOUR_BYTE_LEN 5 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate 3587c478bd9Sstevel@tonic-gate /* the idea here is roughly this: we maintain a stack of these Seqorset 3597c478bd9Sstevel@tonic-gate * structures. This is pushed when we see the beginning of a new set or 3607c478bd9Sstevel@tonic-gate * sequence. It is popped when we see the end of a set or sequence. 3617c478bd9Sstevel@tonic-gate * Since we don't want to malloc and free these structures all the time, 3627c478bd9Sstevel@tonic-gate * we pre-allocate a small set of them within the ber element structure. 3637c478bd9Sstevel@tonic-gate * thus we need to spot when we've overflowed this stack and fall back to 3647c478bd9Sstevel@tonic-gate * malloc'ing instead. 3657c478bd9Sstevel@tonic-gate */ 3667c478bd9Sstevel@tonic-gate static int 3677c478bd9Sstevel@tonic-gate ber_start_seqorset( BerElement *ber, ber_tag_t tag ) 3687c478bd9Sstevel@tonic-gate { 3697c478bd9Sstevel@tonic-gate Seqorset *new_sos; 3707c478bd9Sstevel@tonic-gate 3717c478bd9Sstevel@tonic-gate /* can we fit into the local stack ? */ 3727c478bd9Sstevel@tonic-gate if (ber->ber_sos_stack_posn < SOS_STACK_SIZE) { 3737c478bd9Sstevel@tonic-gate /* yes */ 3747c478bd9Sstevel@tonic-gate new_sos = &ber->ber_sos_stack[ber->ber_sos_stack_posn]; 3757c478bd9Sstevel@tonic-gate } else { 3767c478bd9Sstevel@tonic-gate /* no */ 3777c478bd9Sstevel@tonic-gate if ( (new_sos = (Seqorset *)NSLBERI_MALLOC( sizeof(Seqorset))) 3787c478bd9Sstevel@tonic-gate == NULLSEQORSET ) { 3797c478bd9Sstevel@tonic-gate return( -1 ); 3807c478bd9Sstevel@tonic-gate } 3817c478bd9Sstevel@tonic-gate } 3827c478bd9Sstevel@tonic-gate ber->ber_sos_stack_posn++; 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate if ( ber->ber_sos == NULLSEQORSET ) 3857c478bd9Sstevel@tonic-gate new_sos->sos_first = ber->ber_ptr; 3867c478bd9Sstevel@tonic-gate else 3877c478bd9Sstevel@tonic-gate new_sos->sos_first = ber->ber_sos->sos_ptr; 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate /* Set aside room for a 4 byte length field */ 3907c478bd9Sstevel@tonic-gate new_sos->sos_ptr = new_sos->sos_first + ber_calc_taglen( tag ) + FOUR_BYTE_LEN; 3917c478bd9Sstevel@tonic-gate new_sos->sos_tag = tag; 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate new_sos->sos_next = ber->ber_sos; 3947c478bd9Sstevel@tonic-gate new_sos->sos_clen = 0; 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate ber->ber_sos = new_sos; 3977c478bd9Sstevel@tonic-gate if (ber->ber_sos->sos_ptr > ber->ber_end) { 3987c478bd9Sstevel@tonic-gate nslberi_ber_realloc(ber, ber->ber_sos->sos_ptr - ber->ber_end); 3997c478bd9Sstevel@tonic-gate } 4007c478bd9Sstevel@tonic-gate return( 0 ); 4017c478bd9Sstevel@tonic-gate } 4027c478bd9Sstevel@tonic-gate 4037c478bd9Sstevel@tonic-gate int 4047c478bd9Sstevel@tonic-gate LDAP_CALL 4057c478bd9Sstevel@tonic-gate ber_start_seq( BerElement *ber, ber_tag_t tag ) 4067c478bd9Sstevel@tonic-gate { 4077c478bd9Sstevel@tonic-gate if ( tag == LBER_DEFAULT ) 4087c478bd9Sstevel@tonic-gate tag = LBER_SEQUENCE; 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate return( ber_start_seqorset( ber, tag ) ); 4117c478bd9Sstevel@tonic-gate } 4127c478bd9Sstevel@tonic-gate 4137c478bd9Sstevel@tonic-gate int 4147c478bd9Sstevel@tonic-gate LDAP_CALL 4157c478bd9Sstevel@tonic-gate ber_start_set( BerElement *ber, ber_tag_t tag ) 4167c478bd9Sstevel@tonic-gate { 4177c478bd9Sstevel@tonic-gate if ( tag == LBER_DEFAULT ) 4187c478bd9Sstevel@tonic-gate tag = LBER_SET; 4197c478bd9Sstevel@tonic-gate 4207c478bd9Sstevel@tonic-gate return( ber_start_seqorset( ber, tag ) ); 4217c478bd9Sstevel@tonic-gate } 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate static int 4247c478bd9Sstevel@tonic-gate ber_put_seqorset( BerElement *ber ) 4257c478bd9Sstevel@tonic-gate { 4267c478bd9Sstevel@tonic-gate ber_len_t len, netlen; 4277c478bd9Sstevel@tonic-gate int taglen, lenlen; 4287c478bd9Sstevel@tonic-gate unsigned char ltag = 0x80 + FOUR_BYTE_LEN - 1; 4297c478bd9Sstevel@tonic-gate Seqorset *next; 4307c478bd9Sstevel@tonic-gate Seqorset **sos = &ber->ber_sos; 4317c478bd9Sstevel@tonic-gate 4327c478bd9Sstevel@tonic-gate /* 4337c478bd9Sstevel@tonic-gate * If this is the toplevel sequence or set, we need to actually 4347c478bd9Sstevel@tonic-gate * write the stuff out. Otherwise, it's already been put in 4357c478bd9Sstevel@tonic-gate * the appropriate buffer and will be written when the toplevel 4367c478bd9Sstevel@tonic-gate * one is written. In this case all we need to do is update the 4377c478bd9Sstevel@tonic-gate * length and tag. 4387c478bd9Sstevel@tonic-gate */ 4397c478bd9Sstevel@tonic-gate 4407c478bd9Sstevel@tonic-gate len = (*sos)->sos_clen; 4417c478bd9Sstevel@tonic-gate netlen = LBER_HTONL( len ); 4427c478bd9Sstevel@tonic-gate if ( sizeof(ber_int_t) > 4 && len > LENMASK4 ) 4437c478bd9Sstevel@tonic-gate return( -1 ); 4447c478bd9Sstevel@tonic-gate 4457c478bd9Sstevel@tonic-gate if ( ber->ber_options & LBER_OPT_USE_DER ) { 4467c478bd9Sstevel@tonic-gate lenlen = ber_calc_lenlen( len ); 4477c478bd9Sstevel@tonic-gate } else { 4487c478bd9Sstevel@tonic-gate lenlen = FOUR_BYTE_LEN; 4497c478bd9Sstevel@tonic-gate } 4507c478bd9Sstevel@tonic-gate 4517c478bd9Sstevel@tonic-gate if ( (next = (*sos)->sos_next) == NULLSEQORSET ) { 4527c478bd9Sstevel@tonic-gate /* write the tag */ 4537c478bd9Sstevel@tonic-gate if ( (taglen = ber_put_tag( ber, (*sos)->sos_tag, 1 )) == -1 ) 4547c478bd9Sstevel@tonic-gate return( -1 ); 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate if ( ber->ber_options & LBER_OPT_USE_DER ) { 4577c478bd9Sstevel@tonic-gate /* Write the length in the minimum # of octets */ 4587c478bd9Sstevel@tonic-gate if ( ber_put_len( ber, len, 1 ) == -1 ) 4597c478bd9Sstevel@tonic-gate return( -1 ); 4607c478bd9Sstevel@tonic-gate 4617c478bd9Sstevel@tonic-gate if (lenlen != FOUR_BYTE_LEN) { 4627c478bd9Sstevel@tonic-gate /* 4637c478bd9Sstevel@tonic-gate * We set aside FOUR_BYTE_LEN bytes for 4647c478bd9Sstevel@tonic-gate * the length field. Move the data if 4657c478bd9Sstevel@tonic-gate * we don't actually need that much 4667c478bd9Sstevel@tonic-gate */ 4677c478bd9Sstevel@tonic-gate SAFEMEMCPY( (*sos)->sos_first + taglen + 4687c478bd9Sstevel@tonic-gate lenlen, (*sos)->sos_first + taglen + 4697c478bd9Sstevel@tonic-gate FOUR_BYTE_LEN, len ); 4707c478bd9Sstevel@tonic-gate } 4717c478bd9Sstevel@tonic-gate } else { 4727c478bd9Sstevel@tonic-gate /* Fill FOUR_BYTE_LEN bytes for length field */ 4737c478bd9Sstevel@tonic-gate /* one byte of length length */ 4747c478bd9Sstevel@tonic-gate if ( ber_write( ber, (char *)<ag, 1, 1 ) != 1 ) 4757c478bd9Sstevel@tonic-gate return( -1 ); 4767c478bd9Sstevel@tonic-gate 4777c478bd9Sstevel@tonic-gate /* the length itself */ 4787c478bd9Sstevel@tonic-gate if ( ber_write( ber, (char *) &netlen + sizeof(ber_int_t) 4797c478bd9Sstevel@tonic-gate - (FOUR_BYTE_LEN - 1), FOUR_BYTE_LEN - 1, 1 ) 4807c478bd9Sstevel@tonic-gate != FOUR_BYTE_LEN - 1 ) 4817c478bd9Sstevel@tonic-gate return( -1 ); 4827c478bd9Sstevel@tonic-gate } 4837c478bd9Sstevel@tonic-gate /* The ber_ptr is at the set/seq start - move it to the end */ 4847c478bd9Sstevel@tonic-gate ber->ber_ptr += len; 4857c478bd9Sstevel@tonic-gate } else { 4867c478bd9Sstevel@tonic-gate ber_tag_t ntag; 4877c478bd9Sstevel@tonic-gate 4887c478bd9Sstevel@tonic-gate /* the tag */ 4897c478bd9Sstevel@tonic-gate taglen = ber_calc_taglen( (*sos)->sos_tag ); 4907c478bd9Sstevel@tonic-gate ntag = LBER_HTONL( (*sos)->sos_tag ); 4917c478bd9Sstevel@tonic-gate SAFEMEMCPY( (*sos)->sos_first, (char *) &ntag + 4927c478bd9Sstevel@tonic-gate sizeof(ber_int_t) - taglen, taglen ); 4937c478bd9Sstevel@tonic-gate 4947c478bd9Sstevel@tonic-gate if ( ber->ber_options & LBER_OPT_USE_DER ) { 4957c478bd9Sstevel@tonic-gate ltag = (lenlen == 1) ? (unsigned char)len : 4967c478bd9Sstevel@tonic-gate (unsigned char) (0x80 + (lenlen - 1)); 4977c478bd9Sstevel@tonic-gate } 4987c478bd9Sstevel@tonic-gate 4997c478bd9Sstevel@tonic-gate /* one byte of length length */ 5007c478bd9Sstevel@tonic-gate SAFEMEMCPY( (*sos)->sos_first + 1, <ag, 1 ); 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate if ( ber->ber_options & LBER_OPT_USE_DER ) { 5037c478bd9Sstevel@tonic-gate if (lenlen > 1) { 5047c478bd9Sstevel@tonic-gate /* Write the length itself */ 5057c478bd9Sstevel@tonic-gate SAFEMEMCPY( (*sos)->sos_first + 2, 5067c478bd9Sstevel@tonic-gate (char *)&netlen + sizeof(ber_uint_t) - 5077c478bd9Sstevel@tonic-gate (lenlen - 1), 5087c478bd9Sstevel@tonic-gate lenlen - 1 ); 5097c478bd9Sstevel@tonic-gate } 5107c478bd9Sstevel@tonic-gate if (lenlen != FOUR_BYTE_LEN) { 5117c478bd9Sstevel@tonic-gate /* 5127c478bd9Sstevel@tonic-gate * We set aside FOUR_BYTE_LEN bytes for 5137c478bd9Sstevel@tonic-gate * the length field. Move the data if 5147c478bd9Sstevel@tonic-gate * we don't actually need that much 5157c478bd9Sstevel@tonic-gate */ 5167c478bd9Sstevel@tonic-gate SAFEMEMCPY( (*sos)->sos_first + taglen + 5177c478bd9Sstevel@tonic-gate lenlen, (*sos)->sos_first + taglen + 5187c478bd9Sstevel@tonic-gate FOUR_BYTE_LEN, len ); 5197c478bd9Sstevel@tonic-gate } 5207c478bd9Sstevel@tonic-gate } else { 5217c478bd9Sstevel@tonic-gate /* the length itself */ 5227c478bd9Sstevel@tonic-gate SAFEMEMCPY( (*sos)->sos_first + taglen + 1, 5237c478bd9Sstevel@tonic-gate (char *) &netlen + sizeof(ber_int_t) - 5247c478bd9Sstevel@tonic-gate (FOUR_BYTE_LEN - 1), FOUR_BYTE_LEN - 1 ); 5257c478bd9Sstevel@tonic-gate } 5267c478bd9Sstevel@tonic-gate 5277c478bd9Sstevel@tonic-gate next->sos_clen += (taglen + lenlen + len); 5287c478bd9Sstevel@tonic-gate next->sos_ptr += (taglen + lenlen + len); 5297c478bd9Sstevel@tonic-gate } 5307c478bd9Sstevel@tonic-gate 5317c478bd9Sstevel@tonic-gate /* we're done with this seqorset, so free it up */ 5327c478bd9Sstevel@tonic-gate /* was this one from the local stack ? */ 5337c478bd9Sstevel@tonic-gate if (ber->ber_sos_stack_posn <= SOS_STACK_SIZE) { 5347c478bd9Sstevel@tonic-gate /* yes */ 5357c478bd9Sstevel@tonic-gate } else { 5367c478bd9Sstevel@tonic-gate /* no */ 5377c478bd9Sstevel@tonic-gate NSLBERI_FREE( (char *) (*sos) ); 5387c478bd9Sstevel@tonic-gate } 5397c478bd9Sstevel@tonic-gate ber->ber_sos_stack_posn--; 5407c478bd9Sstevel@tonic-gate *sos = next; 5417c478bd9Sstevel@tonic-gate 5427c478bd9Sstevel@tonic-gate return( taglen + lenlen + len ); 5437c478bd9Sstevel@tonic-gate } 5447c478bd9Sstevel@tonic-gate 5457c478bd9Sstevel@tonic-gate int 5467c478bd9Sstevel@tonic-gate LDAP_CALL 5477c478bd9Sstevel@tonic-gate ber_put_seq( BerElement *ber ) 5487c478bd9Sstevel@tonic-gate { 5497c478bd9Sstevel@tonic-gate return( ber_put_seqorset( ber ) ); 5507c478bd9Sstevel@tonic-gate } 5517c478bd9Sstevel@tonic-gate 5527c478bd9Sstevel@tonic-gate int 5537c478bd9Sstevel@tonic-gate LDAP_CALL 5547c478bd9Sstevel@tonic-gate ber_put_set( BerElement *ber ) 5557c478bd9Sstevel@tonic-gate { 5567c478bd9Sstevel@tonic-gate return( ber_put_seqorset( ber ) ); 5577c478bd9Sstevel@tonic-gate } 5587c478bd9Sstevel@tonic-gate 5597c478bd9Sstevel@tonic-gate /* VARARGS */ 5607c478bd9Sstevel@tonic-gate int 5617c478bd9Sstevel@tonic-gate LDAP_C 5627c478bd9Sstevel@tonic-gate ber_printf( BerElement *ber, const char *fmt, ... ) 5637c478bd9Sstevel@tonic-gate { 5647c478bd9Sstevel@tonic-gate va_list ap; 5657c478bd9Sstevel@tonic-gate char *s, **ss; 566*924965c7SSerge Dussud struct berval *bval, **bv; 5677c478bd9Sstevel@tonic-gate int rc, i; 5687c478bd9Sstevel@tonic-gate ber_len_t len; 5697c478bd9Sstevel@tonic-gate 5707c478bd9Sstevel@tonic-gate va_start( ap, fmt ); 5717c478bd9Sstevel@tonic-gate 5727c478bd9Sstevel@tonic-gate #ifdef LDAP_DEBUG 5737c478bd9Sstevel@tonic-gate if ( lber_debug & 64 ) { 5747c478bd9Sstevel@tonic-gate char msg[80]; 5757c478bd9Sstevel@tonic-gate sprintf( msg, "ber_printf fmt (%s)\n", fmt ); 5767c478bd9Sstevel@tonic-gate ber_err_print( msg ); 5777c478bd9Sstevel@tonic-gate } 5787c478bd9Sstevel@tonic-gate #endif 5797c478bd9Sstevel@tonic-gate 5807c478bd9Sstevel@tonic-gate for ( rc = 0; *fmt && rc != -1; fmt++ ) { 5817c478bd9Sstevel@tonic-gate switch ( *fmt ) { 5827c478bd9Sstevel@tonic-gate case 'b': /* boolean */ 5837c478bd9Sstevel@tonic-gate i = va_arg( ap, int ); 5847c478bd9Sstevel@tonic-gate rc = ber_put_boolean( ber, i, ber->ber_tag ); 5857c478bd9Sstevel@tonic-gate break; 5867c478bd9Sstevel@tonic-gate 5877c478bd9Sstevel@tonic-gate case 'i': /* int */ 5887c478bd9Sstevel@tonic-gate i = va_arg( ap, int ); 5897c478bd9Sstevel@tonic-gate rc = ber_put_int( ber, (ber_int_t)i, ber->ber_tag ); 5907c478bd9Sstevel@tonic-gate break; 5917c478bd9Sstevel@tonic-gate 5927c478bd9Sstevel@tonic-gate case 'e': /* enumeration */ 5937c478bd9Sstevel@tonic-gate i = va_arg( ap, int ); 5947c478bd9Sstevel@tonic-gate rc = ber_put_enum( ber, (ber_int_t)i, ber->ber_tag ); 5957c478bd9Sstevel@tonic-gate break; 5967c478bd9Sstevel@tonic-gate 5977c478bd9Sstevel@tonic-gate case 'n': /* null */ 5987c478bd9Sstevel@tonic-gate rc = ber_put_null( ber, ber->ber_tag ); 5997c478bd9Sstevel@tonic-gate break; 6007c478bd9Sstevel@tonic-gate 6017c478bd9Sstevel@tonic-gate case 'o': /* octet string (non-null terminated) */ 6027c478bd9Sstevel@tonic-gate s = va_arg( ap, char * ); 6037c478bd9Sstevel@tonic-gate len = va_arg( ap, int ); 6047c478bd9Sstevel@tonic-gate rc = ber_put_ostring( ber, s, len, ber->ber_tag ); 6057c478bd9Sstevel@tonic-gate break; 6067c478bd9Sstevel@tonic-gate 607*924965c7SSerge Dussud case 'O': /* berval octet string */ 608*924965c7SSerge Dussud if( ( bval = va_arg( ap, struct berval * ) ) == NULL ) 609*924965c7SSerge Dussud break; 610*924965c7SSerge Dussud if( bval->bv_len == 0 ) { 611*924965c7SSerge Dussud rc = ber_put_ostring( ber, "", 0, ber->ber_tag ); 612*924965c7SSerge Dussud } else { 613*924965c7SSerge Dussud rc = ber_put_ostring( ber, bval->bv_val, bval->bv_len, 614*924965c7SSerge Dussud ber->ber_tag ); 615*924965c7SSerge Dussud } 616*924965c7SSerge Dussud break; 617*924965c7SSerge Dussud 6187c478bd9Sstevel@tonic-gate case 's': /* string */ 6197c478bd9Sstevel@tonic-gate s = va_arg( ap, char * ); 6207c478bd9Sstevel@tonic-gate rc = ber_put_string( ber, s, ber->ber_tag ); 6217c478bd9Sstevel@tonic-gate break; 6227c478bd9Sstevel@tonic-gate 6237c478bd9Sstevel@tonic-gate case 'B': /* bit string */ 6247c478bd9Sstevel@tonic-gate s = va_arg( ap, char * ); 6257c478bd9Sstevel@tonic-gate len = va_arg( ap, int ); /* in bits */ 6267c478bd9Sstevel@tonic-gate rc = ber_put_bitstring( ber, s, len, ber->ber_tag ); 6277c478bd9Sstevel@tonic-gate break; 6287c478bd9Sstevel@tonic-gate 6297c478bd9Sstevel@tonic-gate case 't': /* tag for the next element */ 6307c478bd9Sstevel@tonic-gate ber->ber_tag = va_arg( ap, ber_tag_t ); 6317c478bd9Sstevel@tonic-gate ber->ber_usertag = 1; 6327c478bd9Sstevel@tonic-gate break; 6337c478bd9Sstevel@tonic-gate 6347c478bd9Sstevel@tonic-gate case 'v': /* vector of strings */ 6357c478bd9Sstevel@tonic-gate if ( (ss = va_arg( ap, char ** )) == NULL ) 6367c478bd9Sstevel@tonic-gate break; 6377c478bd9Sstevel@tonic-gate for ( i = 0; ss[i] != NULL; i++ ) { 6387c478bd9Sstevel@tonic-gate if ( (rc = ber_put_string( ber, ss[i], 6397c478bd9Sstevel@tonic-gate ber->ber_tag )) == -1 ) 6407c478bd9Sstevel@tonic-gate break; 6417c478bd9Sstevel@tonic-gate } 6427c478bd9Sstevel@tonic-gate break; 6437c478bd9Sstevel@tonic-gate 6447c478bd9Sstevel@tonic-gate case 'V': /* sequences of strings + lengths */ 6457c478bd9Sstevel@tonic-gate if ( (bv = va_arg( ap, struct berval ** )) == NULL ) 6467c478bd9Sstevel@tonic-gate break; 6477c478bd9Sstevel@tonic-gate for ( i = 0; bv[i] != NULL; i++ ) { 6487c478bd9Sstevel@tonic-gate if ( (rc = ber_put_ostring( ber, bv[i]->bv_val, 6497c478bd9Sstevel@tonic-gate bv[i]->bv_len, ber->ber_tag )) == -1 ) 6507c478bd9Sstevel@tonic-gate break; 6517c478bd9Sstevel@tonic-gate } 6527c478bd9Sstevel@tonic-gate break; 6537c478bd9Sstevel@tonic-gate 6547c478bd9Sstevel@tonic-gate case '{': /* begin sequence */ 6557c478bd9Sstevel@tonic-gate rc = ber_start_seq( ber, ber->ber_tag ); 6567c478bd9Sstevel@tonic-gate break; 6577c478bd9Sstevel@tonic-gate 6587c478bd9Sstevel@tonic-gate case '}': /* end sequence */ 6597c478bd9Sstevel@tonic-gate rc = ber_put_seqorset( ber ); 6607c478bd9Sstevel@tonic-gate break; 6617c478bd9Sstevel@tonic-gate 6627c478bd9Sstevel@tonic-gate case '[': /* begin set */ 6637c478bd9Sstevel@tonic-gate rc = ber_start_set( ber, ber->ber_tag ); 6647c478bd9Sstevel@tonic-gate break; 6657c478bd9Sstevel@tonic-gate 6667c478bd9Sstevel@tonic-gate case ']': /* end set */ 6677c478bd9Sstevel@tonic-gate rc = ber_put_seqorset( ber ); 6687c478bd9Sstevel@tonic-gate break; 6697c478bd9Sstevel@tonic-gate 6707c478bd9Sstevel@tonic-gate default: { 6717c478bd9Sstevel@tonic-gate char msg[80]; 6727c478bd9Sstevel@tonic-gate sprintf( msg, "unknown fmt %c\n", *fmt ); 6737c478bd9Sstevel@tonic-gate ber_err_print( msg ); 6747c478bd9Sstevel@tonic-gate rc = -1; 6757c478bd9Sstevel@tonic-gate break; 6767c478bd9Sstevel@tonic-gate } 6777c478bd9Sstevel@tonic-gate } 6787c478bd9Sstevel@tonic-gate 6797c478bd9Sstevel@tonic-gate if ( ber->ber_usertag == 0 ) 6807c478bd9Sstevel@tonic-gate ber->ber_tag = LBER_DEFAULT; 6817c478bd9Sstevel@tonic-gate else 6827c478bd9Sstevel@tonic-gate ber->ber_usertag = 0; 6837c478bd9Sstevel@tonic-gate } 6847c478bd9Sstevel@tonic-gate 6857c478bd9Sstevel@tonic-gate va_end( ap ); 6867c478bd9Sstevel@tonic-gate 6877c478bd9Sstevel@tonic-gate return( rc ); 6887c478bd9Sstevel@tonic-gate } 689