Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/ldap/libldap/ldif.c
4394 views
1
/* ldif.c - routines for dealing with LDIF files */
2
/* $OpenLDAP$ */
3
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4
*
5
* Copyright 1998-2024 The OpenLDAP Foundation.
6
* All rights reserved.
7
*
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted only as authorized by the OpenLDAP
10
* Public License.
11
*
12
* A copy of this license is available in the file LICENSE in the
13
* top-level directory of the distribution or, alternatively, at
14
* <http://www.OpenLDAP.org/license.html>.
15
*/
16
/* Portions Copyright (c) 1992-1996 Regents of the University of Michigan.
17
* All rights reserved.
18
*
19
* Redistribution and use in source and binary forms are permitted
20
* provided that this notice is preserved and that due credit is given
21
* to the University of Michigan at Ann Arbor. The name of the
22
* University may not be used to endorse or promote products derived
23
* from this software without specific prior written permission. This
24
* software is provided ``as is'' without express or implied warranty.
25
*/
26
/* This work was originally developed by the University of Michigan
27
* and distributed as part of U-MICH LDAP.
28
*/
29
30
#include "portable.h"
31
32
#include <stdio.h>
33
34
#include <ac/stdlib.h>
35
#include <ac/ctype.h>
36
37
#include <ac/string.h>
38
#include <ac/socket.h>
39
#include <ac/time.h>
40
41
int ldif_debug = 0;
42
43
#include "ldap-int.h"
44
#include "ldif.h"
45
46
#define CONTINUED_LINE_MARKER '\r'
47
48
#ifdef CSRIMALLOC
49
#define ber_memalloc malloc
50
#define ber_memcalloc calloc
51
#define ber_memrealloc realloc
52
#define ber_strdup strdup
53
#endif
54
55
static const char nib2b64[0x40] =
56
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
57
58
/*
59
* ldif_parse_line - takes a line of the form "type:[:] value" and splits it
60
* into components "type" and "value". if a double colon separates type from
61
* value, then value is encoded in base 64, and parse_line un-decodes it
62
* (in place) before returning. The type and value are stored in malloc'd
63
* memory which must be freed by the caller.
64
*
65
* ldif_parse_line2 - operates in-place on input buffer, returning type
66
* in-place. Will return value in-place if possible, (must malloc for
67
* fetched URLs). If freeval is NULL, all return data will be malloc'd
68
* and the input line will be unmodified. Otherwise freeval is set to
69
* True if the value was malloc'd.
70
*/
71
72
int
73
ldif_parse_line(
74
LDAP_CONST char *line,
75
char **typep,
76
char **valuep,
77
ber_len_t *vlenp
78
)
79
{
80
struct berval type, value;
81
int rc = ldif_parse_line2( (char *)line, &type, &value, NULL );
82
83
*typep = type.bv_val;
84
*valuep = value.bv_val;
85
*vlenp = value.bv_len;
86
return rc;
87
}
88
89
int
90
ldif_parse_line2(
91
char *line,
92
struct berval *type,
93
struct berval *value,
94
int *freeval
95
)
96
{
97
char *s, *p, *d;
98
int b64, url;
99
100
BER_BVZERO( type );
101
BER_BVZERO( value );
102
103
/* skip any leading space */
104
while ( isspace( (unsigned char) *line ) ) {
105
line++;
106
}
107
108
if ( freeval ) {
109
*freeval = 0;
110
} else {
111
line = ber_strdup( line );
112
113
if( line == NULL ) {
114
ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug,
115
_("ldif_parse_line: line malloc failed\n"));
116
return( -1 );
117
}
118
}
119
120
type->bv_val = line;
121
122
s = strchr( type->bv_val, ':' );
123
124
if ( s == NULL ) {
125
ber_pvt_log_printf( LDAP_DEBUG_PARSE, ldif_debug,
126
_("ldif_parse_line: missing ':' after %s\n"),
127
type->bv_val );
128
if ( !freeval ) ber_memfree( line );
129
return( -1 );
130
}
131
132
/* trim any space between type and : */
133
for ( p = &s[-1]; p > type->bv_val && isspace( * (unsigned char *) p ); p-- ) {
134
*p = '\0';
135
}
136
*s++ = '\0';
137
type->bv_len = s - type->bv_val - 1;
138
139
url = 0;
140
b64 = 0;
141
142
if ( *s == '<' ) {
143
s++;
144
url = 1;
145
146
} else if ( *s == ':' ) {
147
/* base 64 encoded value */
148
s++;
149
b64 = 1;
150
}
151
152
/* skip space between : and value */
153
while ( isspace( (unsigned char) *s ) ) {
154
s++;
155
}
156
157
/* check for continued line markers that should be deleted */
158
for ( p = s, d = s; *p; p++ ) {
159
if ( *p != CONTINUED_LINE_MARKER )
160
*d++ = *p;
161
}
162
*d = '\0';
163
164
if ( b64 ) {
165
char *byte = s;
166
167
if ( *s == '\0' ) {
168
/* no value is present, error out */
169
ber_pvt_log_printf( LDAP_DEBUG_PARSE, ldif_debug,
170
_("ldif_parse_line: %s missing base64 value\n"),
171
type->bv_val );
172
if ( !freeval ) ber_memfree( line );
173
return( -1 );
174
}
175
176
value->bv_val = s;
177
value->bv_len = d - s;
178
if ( ldap_int_decode_b64_inplace( value ) != LDAP_SUCCESS ) {
179
ber_pvt_log_printf( LDAP_DEBUG_PARSE, ldif_debug,
180
_("ldif_parse_line: %s base64 decode failed\n"),
181
type->bv_val );
182
if ( !freeval ) ber_memfree( line );
183
return( -1 );
184
}
185
} else if ( url ) {
186
if ( *s == '\0' ) {
187
/* no value is present, error out */
188
ber_pvt_log_printf( LDAP_DEBUG_PARSE, ldif_debug,
189
_("ldif_parse_line: %s missing URL value\n"),
190
type->bv_val );
191
if ( !freeval ) ber_memfree( line );
192
return( -1 );
193
}
194
195
if( ldif_fetch_url( s, &value->bv_val, &value->bv_len ) ) {
196
ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug,
197
_("ldif_parse_line: %s: URL \"%s\" fetch failed\n"),
198
type->bv_val, s );
199
if ( !freeval ) ber_memfree( line );
200
return( -1 );
201
}
202
if ( freeval ) *freeval = 1;
203
204
} else {
205
value->bv_val = s;
206
value->bv_len = (int) (d - s);
207
}
208
209
if ( !freeval ) {
210
struct berval bv = *type;
211
212
ber_dupbv( type, &bv );
213
214
if( BER_BVISNULL( type )) {
215
ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug,
216
_("ldif_parse_line: type malloc failed\n"));
217
if( url ) ber_memfree( value->bv_val );
218
ber_memfree( line );
219
return( -1 );
220
}
221
222
if( !url ) {
223
bv = *value;
224
ber_dupbv( value, &bv );
225
if( BER_BVISNULL( value )) {
226
ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug,
227
_("ldif_parse_line: value malloc failed\n"));
228
ber_memfree( type->bv_val );
229
ber_memfree( line );
230
return( -1 );
231
}
232
}
233
234
ber_memfree( line );
235
}
236
237
return( 0 );
238
}
239
240
/*
241
* ldif_getline - return the next "line" (minus newline) of input from a
242
* string buffer of lines separated by newlines, terminated by \n\n
243
* or \0. this routine handles continued lines, bundling them into
244
* a single big line before returning. if a line begins with a white
245
* space character, it is a continuation of the previous line. the white
246
* space character (nb: only one char), and preceding newline are changed
247
* into CONTINUED_LINE_MARKER chars, to be deleted later by the
248
* ldif_parse_line() routine above.
249
*
250
* ldif_getline will skip over any line which starts '#'.
251
*
252
* ldif_getline takes a pointer to a pointer to the buffer on the first call,
253
* which it updates and must be supplied on subsequent calls.
254
*/
255
256
int
257
ldif_countlines( LDAP_CONST char *buf )
258
{
259
char *nl;
260
int ret = 0;
261
262
if ( !buf ) return ret;
263
264
for ( nl = strchr(buf, '\n'); nl; nl = strchr(nl, '\n') ) {
265
nl++;
266
if ( *nl != ' ' ) ret++;
267
}
268
return ret;
269
}
270
271
char *
272
ldif_getline( char **next )
273
{
274
char *line;
275
276
do {
277
if ( *next == NULL || **next == '\n' || **next == '\0' ) {
278
return( NULL );
279
}
280
281
line = *next;
282
283
while ( (*next = strchr( *next, '\n' )) != NULL ) {
284
#if CONTINUED_LINE_MARKER != '\r'
285
if ( (*next)[-1] == '\r' ) {
286
(*next)[-1] = CONTINUED_LINE_MARKER;
287
}
288
#endif
289
290
if ( (*next)[1] != ' ' ) {
291
if ( (*next)[1] == '\r' && (*next)[2] == '\n' ) {
292
*(*next)++ = '\0';
293
}
294
*(*next)++ = '\0';
295
break;
296
}
297
298
**next = CONTINUED_LINE_MARKER;
299
(*next)[1] = CONTINUED_LINE_MARKER;
300
(*next)++;
301
}
302
} while( *line == '#' );
303
304
return( line );
305
}
306
307
/*
308
* name and OID of attributeTypes that must be base64 encoded in any case
309
*/
310
typedef struct must_b64_encode_s {
311
struct berval name;
312
struct berval oid;
313
} must_b64_encode_s;
314
315
static must_b64_encode_s default_must_b64_encode[] = {
316
{ BER_BVC( "userPassword" ), BER_BVC( "2.5.4.35" ) },
317
{ BER_BVNULL, BER_BVNULL }
318
};
319
320
static must_b64_encode_s *must_b64_encode = default_must_b64_encode;
321
322
/*
323
* register name and OID of attributeTypes that must always be base64
324
* encoded
325
*
326
* NOTE: this routine mallocs memory in a static struct which must
327
* be explicitly freed when no longer required
328
*/
329
int
330
ldif_must_b64_encode_register( LDAP_CONST char *name, LDAP_CONST char *oid )
331
{
332
int i;
333
ber_len_t len;
334
335
assert( must_b64_encode != NULL );
336
assert( name != NULL );
337
assert( oid != NULL );
338
339
len = strlen( name );
340
341
for ( i = 0; !BER_BVISNULL( &must_b64_encode[i].name ); i++ ) {
342
if ( len != must_b64_encode[i].name.bv_len ) {
343
continue;
344
}
345
346
if ( strcasecmp( name, must_b64_encode[i].name.bv_val ) == 0 ) {
347
break;
348
}
349
}
350
351
if ( !BER_BVISNULL( &must_b64_encode[i].name ) ) {
352
return 1;
353
}
354
355
for ( i = 0; !BER_BVISNULL( &must_b64_encode[i].name ); i++ )
356
/* just count */ ;
357
358
if ( must_b64_encode == default_must_b64_encode ) {
359
must_b64_encode = ber_memalloc( sizeof( must_b64_encode_s ) * ( i + 2 ) );
360
if ( must_b64_encode == NULL ) {
361
return 1;
362
}
363
364
for ( i = 0; !BER_BVISNULL( &default_must_b64_encode[i].name ); i++ ) {
365
ber_dupbv( &must_b64_encode[i].name, &default_must_b64_encode[i].name );
366
ber_dupbv( &must_b64_encode[i].oid, &default_must_b64_encode[i].oid );
367
}
368
369
} else {
370
must_b64_encode_s *tmp;
371
372
tmp = ber_memrealloc( must_b64_encode,
373
sizeof( must_b64_encode_s ) * ( i + 2 ) );
374
if ( tmp == NULL ) {
375
return 1;
376
}
377
must_b64_encode = tmp;
378
}
379
380
ber_str2bv( name, len, 1, &must_b64_encode[i].name );
381
ber_str2bv( oid, 0, 1, &must_b64_encode[i].oid );
382
383
BER_BVZERO( &must_b64_encode[i + 1].name );
384
385
return 0;
386
}
387
388
void
389
ldif_must_b64_encode_release( void )
390
{
391
int i;
392
393
assert( must_b64_encode != NULL );
394
395
if ( must_b64_encode == default_must_b64_encode ) {
396
return;
397
}
398
399
for ( i = 0; !BER_BVISNULL( &must_b64_encode[i].name ); i++ ) {
400
ber_memfree( must_b64_encode[i].name.bv_val );
401
ber_memfree( must_b64_encode[i].oid.bv_val );
402
}
403
404
ber_memfree( must_b64_encode );
405
406
must_b64_encode = default_must_b64_encode;
407
}
408
409
/*
410
* returns 1 iff the string corresponds to the name or the OID of any
411
* of the attributeTypes listed in must_b64_encode
412
*/
413
static int
414
ldif_must_b64_encode( LDAP_CONST char *s )
415
{
416
int i;
417
struct berval bv;
418
419
assert( must_b64_encode != NULL );
420
assert( s != NULL );
421
422
ber_str2bv( s, 0, 0, &bv );
423
424
for ( i = 0; !BER_BVISNULL( &must_b64_encode[i].name ); i++ ) {
425
if ( ber_bvstrcasecmp( &must_b64_encode[i].name, &bv ) == 0
426
|| ber_bvcmp( &must_b64_encode[i].oid, &bv ) == 0 )
427
{
428
return 1;
429
}
430
}
431
432
return 0;
433
}
434
435
/* NOTE: only preserved for binary compatibility */
436
void
437
ldif_sput(
438
char **out,
439
int type,
440
LDAP_CONST char *name,
441
LDAP_CONST char *val,
442
ber_len_t vlen )
443
{
444
ldif_sput_wrap( out, type, name, val, vlen, 0 );
445
}
446
447
void
448
ldif_sput_wrap(
449
char **out,
450
int type,
451
LDAP_CONST char *name,
452
LDAP_CONST char *val,
453
ber_len_t vlen,
454
ber_len_t wrap )
455
{
456
const unsigned char *byte, *stop;
457
unsigned char buf[3];
458
unsigned long bits;
459
char *save;
460
int pad;
461
int namelen = 0;
462
463
ber_len_t savelen;
464
ber_len_t len=0;
465
ber_len_t i;
466
467
if ( !wrap )
468
wrap = LDIF_LINE_WIDTH;
469
470
/* prefix */
471
switch( type ) {
472
case LDIF_PUT_COMMENT:
473
*(*out)++ = '#';
474
len++;
475
476
if( vlen ) {
477
*(*out)++ = ' ';
478
len++;
479
}
480
481
break;
482
483
case LDIF_PUT_SEP:
484
*(*out)++ = '\n';
485
return;
486
}
487
488
/* name (attribute type) */
489
if( name != NULL ) {
490
/* put the name + ":" */
491
namelen = strlen(name);
492
strcpy(*out, name);
493
*out += namelen;
494
len += namelen;
495
496
if( type != LDIF_PUT_COMMENT ) {
497
*(*out)++ = ':';
498
len++;
499
}
500
501
}
502
#ifdef LDAP_DEBUG
503
else {
504
assert( type == LDIF_PUT_COMMENT );
505
}
506
#endif
507
508
if( vlen == 0 ) {
509
*(*out)++ = '\n';
510
return;
511
}
512
513
switch( type ) {
514
case LDIF_PUT_NOVALUE:
515
*(*out)++ = '\n';
516
return;
517
518
case LDIF_PUT_URL: /* url value */
519
*(*out)++ = '<';
520
len++;
521
break;
522
523
case LDIF_PUT_B64: /* base64 value */
524
*(*out)++ = ':';
525
len++;
526
break;
527
}
528
529
switch( type ) {
530
case LDIF_PUT_TEXT:
531
case LDIF_PUT_URL:
532
case LDIF_PUT_B64:
533
*(*out)++ = ' ';
534
len++;
535
/* fall-thru */
536
537
case LDIF_PUT_COMMENT:
538
/* pre-encoded names */
539
for ( i=0; i < vlen; i++ ) {
540
if ( len > wrap ) {
541
*(*out)++ = '\n';
542
*(*out)++ = ' ';
543
len = 1;
544
}
545
546
*(*out)++ = val[i];
547
len++;
548
}
549
*(*out)++ = '\n';
550
return;
551
}
552
553
save = *out;
554
savelen = len;
555
556
*(*out)++ = ' ';
557
len++;
558
559
stop = (const unsigned char *) (val + vlen);
560
561
if ( type == LDIF_PUT_VALUE
562
&& isgraph( (unsigned char) val[0] ) && val[0] != ':' && val[0] != '<'
563
&& isgraph( (unsigned char) val[vlen-1] )
564
#ifndef LDAP_BINARY_DEBUG
565
&& strstr( name, ";binary" ) == NULL
566
#endif
567
#ifndef LDAP_PASSWD_DEBUG
568
&& !ldif_must_b64_encode( name )
569
#endif
570
) {
571
int b64 = 0;
572
573
for ( byte = (const unsigned char *) val; byte < stop;
574
byte++, len++ )
575
{
576
if ( !isascii( *byte ) || !isprint( *byte ) ) {
577
b64 = 1;
578
break;
579
}
580
if ( len >= wrap ) {
581
*(*out)++ = '\n';
582
*(*out)++ = ' ';
583
len = 1;
584
}
585
*(*out)++ = *byte;
586
}
587
588
if( !b64 ) {
589
*(*out)++ = '\n';
590
return;
591
}
592
}
593
594
*out = save;
595
*(*out)++ = ':';
596
*(*out)++ = ' ';
597
len = savelen + 2;
598
599
/* convert to base 64 (3 bytes => 4 base 64 digits) */
600
for ( byte = (const unsigned char *) val;
601
byte < stop - 2;
602
byte += 3 )
603
{
604
bits = (byte[0] & 0xff) << 16;
605
bits |= (byte[1] & 0xff) << 8;
606
bits |= (byte[2] & 0xff);
607
608
for ( i = 0; i < 4; i++, len++, bits <<= 6 ) {
609
if ( len >= wrap ) {
610
*(*out)++ = '\n';
611
*(*out)++ = ' ';
612
len = 1;
613
}
614
615
/* get b64 digit from high order 6 bits */
616
*(*out)++ = nib2b64[ (bits & 0xfc0000L) >> 18 ];
617
}
618
}
619
620
/* add padding if necessary */
621
if ( byte < stop ) {
622
for ( i = 0; byte + i < stop; i++ ) {
623
buf[i] = byte[i];
624
}
625
for ( pad = 0; i < 3; i++, pad++ ) {
626
buf[i] = '\0';
627
}
628
byte = buf;
629
bits = (byte[0] & 0xff) << 16;
630
bits |= (byte[1] & 0xff) << 8;
631
bits |= (byte[2] & 0xff);
632
633
for ( i = 0; i < 4; i++, len++, bits <<= 6 ) {
634
if ( len >= wrap ) {
635
*(*out)++ = '\n';
636
*(*out)++ = ' ';
637
len = 1;
638
}
639
640
if( i + pad < 4 ) {
641
/* get b64 digit from low order 6 bits */
642
*(*out)++ = nib2b64[ (bits & 0xfc0000L) >> 18 ];
643
} else {
644
*(*out)++ = '=';
645
}
646
}
647
}
648
*(*out)++ = '\n';
649
}
650
651
652
/*
653
* ldif_type_and_value return BER malloc'd, zero-terminated LDIF line
654
*/
655
656
/* NOTE: only preserved for binary compatibility */
657
char *
658
ldif_put(
659
int type,
660
LDAP_CONST char *name,
661
LDAP_CONST char *val,
662
ber_len_t vlen )
663
{
664
return ldif_put_wrap( type, name, val, vlen, 0 );
665
}
666
667
char *
668
ldif_put_wrap(
669
int type,
670
LDAP_CONST char *name,
671
LDAP_CONST char *val,
672
ber_len_t vlen,
673
ber_len_t wrap )
674
{
675
char *buf, *p;
676
ber_len_t nlen;
677
678
nlen = ( name != NULL ) ? strlen( name ) : 0;
679
680
buf = (char *) ber_memalloc( LDIF_SIZE_NEEDED_WRAP( nlen, vlen, wrap ) + 1 );
681
682
if ( buf == NULL ) {
683
ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug,
684
_("ldif_type_and_value: malloc failed!"));
685
return NULL;
686
}
687
688
p = buf;
689
ldif_sput_wrap( &p, type, name, val, vlen, wrap );
690
*p = '\0';
691
692
return( buf );
693
}
694
695
int ldif_is_not_printable(
696
LDAP_CONST char *val,
697
ber_len_t vlen )
698
{
699
if( vlen == 0 || val == NULL ) {
700
return -1;
701
}
702
703
if( isgraph( (unsigned char) val[0] ) && val[0] != ':' && val[0] != '<' &&
704
isgraph( (unsigned char) val[vlen-1] ) )
705
{
706
ber_len_t i;
707
708
for ( i = 0; val[i]; i++ ) {
709
if ( !isascii( val[i] ) || !isprint( (unsigned char) val[i] ) ) {
710
return 1;
711
}
712
}
713
714
return 0;
715
}
716
717
return 1;
718
}
719
720
LDIFFP *
721
ldif_open(
722
LDAP_CONST char *file,
723
LDAP_CONST char *mode
724
)
725
{
726
FILE *fp = fopen( file, mode );
727
LDIFFP *lfp = NULL;
728
729
if ( fp ) {
730
lfp = ber_memalloc( sizeof( LDIFFP ));
731
if ( lfp == NULL ) {
732
fclose( fp );
733
return NULL;
734
}
735
lfp->fp = fp;
736
lfp->prev = NULL;
737
}
738
return lfp;
739
}
740
741
LDIFFP *
742
ldif_open_mem(
743
char *ldif,
744
size_t size,
745
LDAP_CONST char *mode
746
)
747
{
748
#ifdef HAVE_FMEMOPEN
749
FILE *fp = fmemopen( ldif, size, mode );
750
LDIFFP *lfp = NULL;
751
752
if ( fp ) {
753
lfp = ber_memalloc( sizeof( LDIFFP ));
754
lfp->fp = fp;
755
lfp->prev = NULL;
756
}
757
return lfp;
758
#else /* !HAVE_FMEMOPEN */
759
return NULL;
760
#endif /* !HAVE_FMEMOPEN */
761
}
762
763
void
764
ldif_close(
765
LDIFFP *lfp
766
)
767
{
768
LDIFFP *prev;
769
770
while ( lfp ) {
771
fclose( lfp->fp );
772
prev = lfp->prev;
773
ber_memfree( lfp );
774
lfp = prev;
775
}
776
}
777
778
#define LDIF_MAXLINE 4096
779
780
/*
781
* ldif_read_record - read an ldif record. Return 1 for success, 0 for EOF,
782
* -1 for error.
783
*/
784
int
785
ldif_read_record(
786
LDIFFP *lfp,
787
unsigned long *lno, /* ptr to line number counter */
788
char **bufp, /* ptr to malloced output buffer */
789
int *buflenp ) /* ptr to length of *bufp */
790
{
791
char line[LDIF_MAXLINE], *nbufp;
792
ber_len_t lcur = 0, len;
793
int last_ch = '\n', found_entry = 0, stop, top_comment = 0;
794
795
for ( stop = 0; !stop; last_ch = line[len-1] ) {
796
/* If we're at the end of this file, see if we should pop
797
* back to a previous file. (return from an include)
798
*/
799
while ( feof( lfp->fp )) {
800
pop:
801
if ( lfp->prev ) {
802
LDIFFP *tmp = lfp->prev;
803
fclose( lfp->fp );
804
*lfp = *tmp;
805
ber_memfree( tmp );
806
} else {
807
stop = 1;
808
break;
809
}
810
}
811
if ( !stop ) {
812
if ( fgets( line, sizeof( line ), lfp->fp ) == NULL ) {
813
if ( !found_entry && !ferror( lfp->fp ) ) {
814
/* ITS#9811 Reached the end looking for an entry, try again */
815
goto pop;
816
}
817
stop = 1;
818
len = 0;
819
} else {
820
len = strlen( line );
821
}
822
}
823
824
if ( stop ) {
825
/* Add \n in case the file does not end with newline */
826
if (last_ch != '\n') {
827
len = 1;
828
line[0] = '\n';
829
line[1] = '\0';
830
goto last;
831
}
832
break;
833
}
834
835
/* Squash \r\n to \n */
836
if ( len > 1 && line[len-2] == '\r' ) {
837
len--;
838
line[len] = '\0';
839
line[len-1] = '\n';
840
}
841
842
if ( last_ch == '\n' ) {
843
(*lno)++;
844
845
if ( line[0] == '\n' ) {
846
if ( !found_entry ) {
847
lcur = 0;
848
top_comment = 0;
849
continue;
850
}
851
break;
852
}
853
854
if ( !found_entry ) {
855
if ( line[0] == '#' ) {
856
top_comment = 1;
857
} else if ( ! ( top_comment && line[0] == ' ' ) ) {
858
/* Found a new entry */
859
found_entry = 1;
860
861
if ( isdigit( (unsigned char) line[0] ) ) {
862
/* skip index */
863
continue;
864
}
865
if ( !strncasecmp( line, "include:",
866
STRLENOF("include:"))) {
867
FILE *fp2;
868
char *ptr;
869
found_entry = 0;
870
871
if ( line[len-1] == '\n' ) {
872
len--;
873
line[len] = '\0';
874
}
875
876
ptr = line + STRLENOF("include:");
877
while (isspace((unsigned char) *ptr)) ptr++;
878
fp2 = ldif_open_url( ptr );
879
if ( fp2 ) {
880
LDIFFP *lnew = ber_memalloc( sizeof( LDIFFP ));
881
if ( lnew == NULL ) {
882
fclose( fp2 );
883
return 0;
884
}
885
lnew->prev = lfp->prev;
886
lnew->fp = lfp->fp;
887
lfp->prev = lnew;
888
lfp->fp = fp2;
889
line[len] = '\n';
890
len++;
891
continue;
892
} else {
893
/* We failed to open the file, this should
894
* be reported as an error somehow.
895
*/
896
ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug,
897
_("ldif_read_record: include %s failed\n"), ptr );
898
return -1;
899
}
900
}
901
}
902
}
903
}
904
905
last:
906
if ( *buflenp - lcur <= len ) {
907
*buflenp += len + LDIF_MAXLINE;
908
nbufp = ber_memrealloc( *bufp, *buflenp );
909
if( nbufp == NULL ) {
910
return 0;
911
}
912
*bufp = nbufp;
913
}
914
strcpy( *bufp + lcur, line );
915
lcur += len;
916
}
917
918
return( found_entry );
919
}
920
921