Cross Reference: line64.c
xref
: /
osnet-11
/
usr
/
src
/
lib
/
libldap4
/
util
/
line64.c
Home
History
Annotate
Line#
Navigate
Download
Search
only in
./
line64.c revision 1
1
N/A
/*
1
N/A
*
1
N/A
* Portions Copyright 07/23/97 Sun Microsystems, Inc. All Rights Reserved
1
N/A
*
1
N/A
*/
1
N/A
/*
line64.c
- routines for dealing with the slapd line format */
1
N/A
1
N/A
#
include
<
stdio.h
>
1
N/A
#
include
<
stdlib.h
>
1
N/A
#
include
<
unistd.h
>
1
N/A
#
include
<
string.h
>
1
N/A
#
include
<
ctype.h
>
1
N/A
#
include
<
sys
/
types.h
>
1
N/A
#
include
<
sys
/
socket.h
>
1
N/A
#
include
"
lber.h
"
1
N/A
#
include
"
ldap.h
"
1
N/A
#
include
"
ldif.h
"
1
N/A
1
N/A
#
define
RIGHT2
0x03
1
N/A
#
define
RIGHT4
0x0f
1
N/A
#
define
CONTINUED_LINE_MARKER
'\001'
1
N/A
1
N/A
static
char
nib2b64
[
0x40f
] =
1
N/A
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
;
1
N/A
1
N/A
static
unsigned
char
b642nib
[
0x80
] = {
1
N/A
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
1
N/A
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
1
N/A
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
1
N/A
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
1
N/A
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
1
N/A
0xff
,
0xff
,
0xff
,
0x3e
,
0xff
,
0xff
,
0xff
,
0x3f
,
1
N/A
0x34
,
0x35
,
0x36
,
0x37
,
0x38
,
0x39
,
0x3a
,
0x3b
,
1
N/A
0x3c
,
0x3d
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
1
N/A
0xff
,
0x00
,
0x01
,
0x02
,
0x03
,
0x04
,
0x05
,
0x06
,
1
N/A
0x07
,
0x08
,
0x09
,
0x0a
,
0x0b
,
0x0c
,
0x0d
,
0x0e
,
1
N/A
0x0f
,
0x10
,
0x11
,
0x12
,
0x13
,
0x14
,
0x15
,
0x16
,
1
N/A
0x17
,
0x18
,
0x19
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
1
N/A
0xff
,
0x1a
,
0x1b
,
0x1c
,
0x1d
,
0x1e
,
0x1f
,
0x20
,
1
N/A
0x21
,
0x22
,
0x23
,
0x24
,
0x25
,
0x26
,
0x27
,
0x28
,
1
N/A
0x29
,
0x2a
,
0x2b
,
0x2c
,
0x2d
,
0x2e
,
0x2f
,
0x30
,
1
N/A
0x31
,
0x32
,
0x33
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
1
N/A
};
1
N/A
1
N/A
/*
1
N/A
* str_parse_line - takes a line of the form "type:[:] value" and splits it
1
N/A
* into components "type" and "value". if a double colon separates type from
1
N/A
* value, then value is encoded in base 64, and parse_line un-decodes it
1
N/A
* (in place) before returning.
1
N/A
*/
1
N/A
1
N/A
int
1
N/A
str_parse_line
(
1
N/A
char
*
line
,
1
N/A
char
**
type
,
1
N/A
char
**
value
,
1
N/A
int
*
vlen
1
N/A
)
1
N/A
{
1
N/A
char
*p, *s, *d, *
byte
, *
stop
;
1
N/A
char
nib
;
1
N/A
int
i = 0,
b64
= 0;
1
N/A
1
N/A
int
url
= 0;
1
N/A
1
N/A
/* skip any leading space */
1
N/A
while
(
isspace
( *
line
) ) {
1
N/A
line
++;
1
N/A
}
1
N/A
*
type
=
line
;
1
N/A
1
N/A
for
( s =
line
; *s && *s !=
':'
; s++ )
1
N/A
;
/* NULL */
1
N/A
if
( *s ==
'\0'
) {
1
N/A
Debug
(
LDAP_DEBUG_PARSE
,
catgets
(
slapdcat
,
1
,
263
,
"parse_line missing ':'\n"
), 0, 0, 0 );
1
N/A
return
( -
1
);
1
N/A
}
1
N/A
1
N/A
/* trim any space between type and : */
1
N/A
for
( p = s -
1
; p >
line
&&
isspace
( *p ); p-- ) {
1
N/A
*p =
'\0'
;
1
N/A
}
1
N/A
*s++ =
'\0'
;
1
N/A
1
N/A
/* check for double : - indicates base 64 encoded value */
1
N/A
if
( *s ==
':'
) {
1
N/A
s++;
1
N/A
b64
=
1
;
1
N/A
1
N/A
}
else
if
( *s ==
'<'
) {
/* the value indicates an url */
1
N/A
s++;
1
N/A
url
=
1
;
1
N/A
1
N/A
}
else
{
/* single : - normally encoded value */
1
N/A
b64
= 0;
1
N/A
}
1
N/A
1
N/A
/* skip space between : and value */
1
N/A
while
(
isspace
( *s ) ) {
1
N/A
s++;
1
N/A
}
1
N/A
1
N/A
/* if no value is present, error out */
1
N/A
if
( *s ==
'\0'
) {
1
N/A
Debug
(
LDAP_DEBUG_PARSE
,
catgets
(
slapdcat
,
1
,
264
,
"parse_line missing value\n"
), 0,0,0 );
1
N/A
return
( -
1
);
1
N/A
}
1
N/A
1
N/A
/* check for continued line markers that should be deleted */
1
N/A
for
( p = s, d = s; *p; p++ ) {
1
N/A
if
( *p !=
CONTINUED_LINE_MARKER
)
1
N/A
*d++ = *p;
1
N/A
}
1
N/A
*d =
'\0'
;
1
N/A
1
N/A
if
(
b64
) {
1
N/A
*
value
= s;
1
N/A
stop
=
strchr
( s,
'\0'
);
1
N/A
byte
= s;
1
N/A
for
( p = s, *
vlen
= 0; p <
stop
; p +=
4
, *
vlen
+=
3
) {
1
N/A
for
( i = 0; i <
3
; i++ ) {
1
N/A
if
( p[i] !=
'='
&& (p[i] &
0x80
||
1
N/A
b642nib
[ p[i] &
0x7f
] >
0x3f
) ) {
1
N/A
Debug
(
LDAP_DEBUG_ANY
,
1
N/A
catgets
(
slapdcat
,
1
,
265
,
"invalid base 64 encoding char (%1$c) 0x%2$x\n"
),
1
N/A
p[i], p[i], 0 );
1
N/A
return
( -
1
);
1
N/A
}
1
N/A
}
1
N/A
1
N/A
/* first digit */
1
N/A
nib
=
b642nib
[ p[0] &
0x7f
];
1
N/A
byte
[0] =
nib
<<
2
;
1
N/A
/* second digit */
1
N/A
nib
=
b642nib
[ p[
1
] &
0x7f
];
1
N/A
byte
[0] |=
nib
>>
4
;
1
N/A
byte
[
1
] = (
nib
&
RIGHT4
) <<
4
;
1
N/A
/* third digit */
1
N/A
if
( p[
2
] ==
'='
) {
1
N/A
*
vlen
+=
1
;
1
N/A
break
;
1
N/A
}
1
N/A
nib
=
b642nib
[ p[
2
] &
0x7f
];
1
N/A
byte
[
1
] |=
nib
>>
2
;
1
N/A
byte
[
2
] = (
nib
&
RIGHT2
) <<
6
;
1
N/A
/* fourth digit */
1
N/A
if
( p[
3
] ==
'='
) {
1
N/A
*
vlen
+=
2
;
1
N/A
break
;
1
N/A
}
1
N/A
nib
=
b642nib
[ p[
3
] &
0x7f
];
1
N/A
byte
[
2
] |=
nib
;
1
N/A
1
N/A
byte
+=
3
;
1
N/A
}
1
N/A
s[ *
vlen
] =
'\0'
;
1
N/A
}
else
if
(
url
) {
/* checks that the url is properly formed */
1
N/A
/* file://[localhost]/<pathname> */
1
N/A
/* value contains the content of the file */
1
N/A
char
*
s2
;
1
N/A
char
*
filename
;
1
N/A
1
N/A
FILE
*
fp
;
1
N/A
int
rlen
;
1
N/A
int
eof
;
1
N/A
1
N/A
1
N/A
if
(
strncmp
(s,
"file://localhost"
,
16
) == 0 )
1
N/A
{
1
N/A
s = s+
16
;
1
N/A
}
1
N/A
else
if
(
strncmp
(s,
"file://"
,
7
) == 0 )
1
N/A
{
1
N/A
s = s+
7
;
1
N/A
}
1
N/A
else
1
N/A
{
1
N/A
/* url badly formed */
1
N/A
Debug
(
LDAP_DEBUG_ANY
,
catgets
(
slapdcat
,
1
,
1289
,
"invalid url %s\n"
), s, 0, 0);
1
N/A
return
-
1
;
1
N/A
}
1
N/A
1
N/A
filename
=
strdup
(s);
1
N/A
1
N/A
/* now we have the filename, read its content and return the value */
1
N/A
if
((
fp
=
fopen
(
filename
,
"r"
)) ==
NULL
)
1
N/A
{
1
N/A
perror
(
filename
);
1
N/A
return
( -
1
);
1
N/A
}
1
N/A
1
N/A
if
(
fseek
(
fp
, 0,
SEEK_END
) != 0 )
1
N/A
{
1
N/A
perror
(
filename
);
1
N/A
fclose
(
fp
);
1
N/A
return
( -
1
);
1
N/A
}
1
N/A
1
N/A
*
vlen
=
ftell
(
fp
);
1
N/A
if
( (*
value
= (
char
*)
malloc
(*
vlen
)) ==
NULL
)
1
N/A
{
1
N/A
perror
(
"malloc"
);
1
N/A
fclose
(
fp
);
1
N/A
return
(-
1
);
1
N/A
}
1
N/A
if
(
fseek
(
fp
, 0,
SEEK_SET
) != 0 )
1
N/A
{
1
N/A
perror
(
filename
);
1
N/A
fclose
(
fp
);
1
N/A
return
( -
1
);
1
N/A
}
1
N/A
1
N/A
rlen
=
fread
( *
value
,
1
, *
vlen
,
fp
);
1
N/A
eof
=
feof
(
fp
);
1
N/A
fclose
(
fp
);
1
N/A
1
N/A
if
(
rlen
!= *
vlen
)
1
N/A
{
1
N/A
perror
(
filename
);
1
N/A
return
( -
1
);
1
N/A
}
1
N/A
1
N/A
}
else
{
1
N/A
*
value
= s;
1
N/A
*
vlen
= (
int
) (d - s);
1
N/A
}
1
N/A
1
N/A
return
( 0 );
1
N/A
}
1
N/A
1
N/A
/*
1
N/A
* str_getline - return the next "line" (minus newline) of input from a
1
N/A
* string buffer of lines separated by newlines, terminated by \n\n
1
N/A
* or \0. this routine handles continued lines, bundling them into
1
N/A
* a single big line before returning. if a line begins with a white
1
N/A
* space character, it is a continuation of the previous line. the white
1
N/A
* space character (nb: only one char), and preceding newline are changed
1
N/A
* into CONTINUED_LINE_MARKER chars, to be deleted later by the
1
N/A
* str_parse_line() routine above.
1
N/A
*
1
N/A
* it takes a pointer to a pointer to the buffer on the first call,
1
N/A
* which it updates and must be supplied on subsequent calls.
1
N/A
*/
1
N/A
1
N/A
char
*
1
N/A
str_getline
(
char
**
next
)
1
N/A
{
1
N/A
char
*l;
1
N/A
char
c;
1
N/A
1
N/A
if
( *
next
==
NULL
|| **
next
==
'\n'
|| **
next
==
'\0'
) {
1
N/A
return
(
NULL
);
1
N/A
}
1
N/A
1
N/A
l = *
next
;
1
N/A
while
( (*
next
=
strchr
( *
next
,
'\n'
)) !=
NULL
) {
1
N/A
c = *(*
next
+
1
);
1
N/A
if
(
isspace
( c ) && c !=
'\n'
) {
1
N/A
**
next
=
CONTINUED_LINE_MARKER
;
1
N/A
*(*
next
+
1
) =
CONTINUED_LINE_MARKER
;
1
N/A
}
else
{
1
N/A
*(*
next
)++ =
'\0'
;
1
N/A
break
;
1
N/A
}
1
N/A
*(*
next
)++;
1
N/A
}
1
N/A
1
N/A
return
( l );
1
N/A
}
1
N/A
1
N/A
void
1
N/A
put_type_and_value
(
char
**
out
,
char
*t,
char
*
val
,
int
vlen
)
1
N/A
{
1
N/A
unsigned
char
*
byte
, *p, *
stop
;
1
N/A
unsigned
char
buf
[
3
];
1
N/A
unsigned
int
bits
;
1
N/A
char
*
save
;
1
N/A
int
i,
b64
,
pad
,
len
,
savelen
;
1
N/A
len
= 0;
1
N/A
1
N/A
/* put the type + ": " */
1
N/A
for
( p = (
unsigned
char
*) t; *p; p++,
len
++ ) {
1
N/A
*(*
out
)++ = *p;
1
N/A
}
1
N/A
*(*
out
)++ =
':'
;
1
N/A
len
++;
1
N/A
save
= *
out
;
1
N/A
savelen
=
len
;
1
N/A
*(*
out
)++ =
' '
;
1
N/A
b64
= 0;
1
N/A
1
N/A
stop
= (
unsigned
char
*) (
val
+
vlen
);
1
N/A
if
(
isascii
(
val
[0] ) &&
isspace
(
val
[0] ) ||
val
[0] ==
':'
) {
1
N/A
b64
=
1
;
1
N/A
}
else
{
1
N/A
for
(
byte
= (
unsigned
char
*)
val
;
byte
<
stop
;
1
N/A
byte
++,
len
++ ) {
1
N/A
if
( !
isascii
( *
byte
) || !
isprint
( *
byte
) ) {
1
N/A
b64
=
1
;
1
N/A
break
;
1
N/A
}
1
N/A
if
(
len
>
LINE_WIDTH
) {
1
N/A
*(*
out
)++ =
'\n'
;
1
N/A
*(*
out
)++ =
' '
;
1
N/A
len
=
1
;
1
N/A
}
1
N/A
*(*
out
)++ = *
byte
;
1
N/A
}
1
N/A
}
1
N/A
if
(
b64
) {
1
N/A
*
out
=
save
;
1
N/A
*(*
out
)++ =
':'
;
1
N/A
*(*
out
)++ =
' '
;
1
N/A
len
=
savelen
+
2
;
1
N/A
/* convert to base 64 (3 bytes => 4 base 64 digits) */
1
N/A
for
(
byte
= (
unsigned
char
*)
val
;
byte
<
stop
-
2
;
1
N/A
byte
+=
3
) {
1
N/A
bits
= (
byte
[0] &
0xff
) <<
16
;
1
N/A
bits
|= (
byte
[
1
] &
0xff
) <<
8
;
1
N/A
bits
|= (
byte
[
2
] &
0xff
);
1
N/A
1
N/A
for
( i = 0; i <
4
; i++,
len
++,
bits
<<=
6
) {
1
N/A
if
(
len
>
LINE_WIDTH
) {
1
N/A
*(*
out
)++ =
'\n'
;
1
N/A
*(*
out
)++ =
' '
;
1
N/A
len
=
1
;
1
N/A
}
1
N/A
1
N/A
/* get b64 digit from high order 6 bits */
1
N/A
*(*
out
)++ =
nib2b64
[ (
bits
&
0xfc0000
) >>
18
];
1
N/A
}
1
N/A
}
1
N/A
1
N/A
/* add padding if necessary */
1
N/A
if
(
byte
<
stop
) {
1
N/A
for
( i = 0;
byte
+ i <
stop
; i++ ) {
1
N/A
buf
[i] =
byte
[i];
1
N/A
}
1
N/A
for
(
pad
= 0; i <
3
; i++,
pad
++ ) {
1
N/A
buf
[i] =
'\0'
;
1
N/A
}
1
N/A
byte
=
buf
;
1
N/A
bits
= (
byte
[0] &
0xff
) <<
16
;
1
N/A
bits
|= (
byte
[
1
] &
0xff
) <<
8
;
1
N/A
bits
|= (
byte
[
2
] &
0xff
);
1
N/A
1
N/A
for
( i = 0; i <
4
; i++,
len
++,
bits
<<=
6
) {
1
N/A
if
(
len
>
LINE_WIDTH
) {
1
N/A
*(*
out
)++ =
'\n'
;
1
N/A
*(*
out
)++ =
' '
;
1
N/A
len
=
1
;
1
N/A
}
1
N/A
1
N/A
/* get b64 digit from low order 6 bits */
1
N/A
*(*
out
)++ =
nib2b64
[ (
bits
&
0xfc0000
) >>
18
];
1
N/A
}
1
N/A
1
N/A
for
( ;
pad
> 0;
pad
-- ) {
1
N/A
*(*
out
-
pad
) =
'='
;
1
N/A
}
1
N/A
}
1
N/A
}
1
N/A
*(*
out
)++ =
'\n'
;
1
N/A
}
1
N/A
1
N/A
1
N/A
char
*
1
N/A
ldif_type_and_value
(
char
*
type
,
char
*
val
,
int
vlen
)
1
N/A
/*
1
N/A
* return malloc'd, zero-terminated LDIF line
1
N/A
*/
1
N/A
{
1
N/A
char
*
buf
, *p;
1
N/A
int
tlen
;
1
N/A
1
N/A
buf
=
NULL
;
1
N/A
tlen
=
strlen
(
type
);
1
N/A
if
((
buf
= (
char
*)
malloc
(
LDIF_SIZE_NEEDED
(
tlen
,
vlen
) +
1
)) !=
1
N/A
NULL
) {
1
N/A
1
N/A
p =
buf
;
1
N/A
put_type_and_value
( &p,
type
,
val
,
vlen
);
1
N/A
*p =
'\0'
;
1
N/A
}
1
N/A
return
(
buf
);
1
N/A
}