static int do_vals2text( LDAP *ld, char *buf, /* NULL for "use internal" */ char **vals, char *label, int labelwidth, /* 0 means use default */ unsigned long syntaxid, writeptype writeproc, void *writeparm, char *eol, int rdncount, char *urlprefix ) { int err, i, html, writeoutval, freebuf, notascii; char *p, *s, *outval; if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) || writeproc == NULL ) { return( LDAP_PARAM_ERROR ); } if ( vals == NULL ) { return( LDAP_SUCCESS ); } html = ( urlprefix != NULL ); switch( LDAP_GET_SYN_TYPE( syntaxid )) { case LDAP_SYN_TYPE_TEXT: case LDAP_SYN_TYPE_BOOLEAN: break; /* we only bother with these two types... */ default: return( LDAP_SUCCESS ); } if ( labelwidth == 0 || labelwidth < 0 ) { labelwidth = DEF_LABEL_WIDTH; } if ( buf == NULL ) { if (( buf = NSLDAPI_MALLOC( LDAP_DTMPL_BUFSIZ )) == NULL ) { err = LDAP_NO_MEMORY; LDAP_SET_LDERRNO( ld, err, NULL, NULL ); return( err ); } freebuf = 1; } else { freebuf = 0; } output_label( buf, label, labelwidth, writeproc, writeparm, eol, html ); for ( i = 0; vals[ i ] != NULL; ++i ) { for ( p = vals[ i ]; *p != '\0'; ++p ) { if ( !isascii( *p )) { break; } } notascii = ( *p != '\0' ); outval = notascii ? dgettext(TEXT_DOMAIN, "(unable to display non-ASCII text value)") : vals[ i ]; writeoutval = 0; /* if non-zero, write outval after switch */ switch( syntaxid ) { case LDAP_SYN_CASEIGNORESTR: ++writeoutval; break; case LDAP_SYN_RFC822ADDR: if ( html ) { strcpy( buf, "<DD><A HREF=\"mailto:" ); strcat_escaped( buf, outval ); sprintf( buf + strlen( buf ), "\">%s</A><BR>%s", outval, eol ); (*writeproc)( writeparm, buf, strlen( buf )); } else { ++writeoutval; } break; case LDAP_SYN_DN: /* for now */ output_dn( buf, outval, labelwidth, rdncount, writeproc, writeparm, eol, urlprefix ); break; case LDAP_SYN_MULTILINESTR: if ( i > 0 && !html ) { output_label( buf, label, labelwidth, writeproc, writeparm, eol, html ); } p = s = outval; while (( s = strchr( s, '$' )) != NULL ) { *s++ = '\0'; while ( ldap_utf8isspace( s )) { ++s; } if ( html ) { sprintf( buf, "<DD>%s<BR>%s", p, eol ); } else { sprintf( buf, "%-*s%s%s", labelwidth, " ", p, eol ); } (*writeproc)( writeparm, buf, strlen( buf )); p = s; } outval = p; ++writeoutval; break; case LDAP_SYN_BOOLEAN: outval = toupper( outval[ 0 ] ) == 'T' ? dgettext(TEXT_DOMAIN, "TRUE") : dgettext(TEXT_DOMAIN, "FALSE"); ++writeoutval; break; case LDAP_SYN_TIME: case LDAP_SYN_DATE: outval = time2text( outval, syntaxid == LDAP_SYN_DATE ); ++writeoutval; break; case LDAP_SYN_LABELEDURL: if ( !notascii && ( p = strchr( outval, '$' )) != NULL ) { *p++ = '\0'; while ( ldap_utf8isspace( p )) { ++p; } s = outval; } else if ( !notascii && ( s = strchr( outval, ' ' )) != NULL ) { *s++ = '\0'; while ( ldap_utf8isspace( s )) { ++s; } p = outval; } else { s = "URL"; p = outval; } /* * at this point `s' points to the label & `p' to the URL */ if ( html ) { sprintf( buf, "<DD><A HREF=\"%s\">%s</A><BR>%s", p, s, eol ); } else { sprintf( buf, "%-*s%s%s%-*s%s%s", labelwidth, " ", s, eol, labelwidth + 2, " ",p , eol ); } (*writeproc)( writeparm, buf, strlen( buf )); break; default: sprintf( buf, dgettext(TEXT_DOMAIN, " Can't display item type %ld%s"), syntaxid, eol ); (*writeproc)( writeparm, buf, strlen( buf )); } if ( writeoutval ) { if ( html ) { sprintf( buf, "<DD>%s<BR>%s", outval, eol ); } else { sprintf( buf, "%-*s%s%s", labelwidth, " ", outval, eol ); } (*writeproc)( writeparm, buf, strlen( buf )); } } if ( freebuf ) { NSLDAPI_FREE( buf ); } return( LDAP_SUCCESS ); }
LDAP_CALL ldap_dn2ufn( const char *dn ) { char *p, *ufn, *r; size_t plen; int state; LDAPDebug( LDAP_DEBUG_TRACE, "ldap_dn2ufn\n", 0, 0, 0 ); if ( dn == NULL ) { dn = ""; } if ( ldap_is_dns_dn( dn ) || ( p = strchr( dn, '=' )) == NULL ) return( nsldapi_strdup( (char *)dn )); ufn = nsldapi_strdup( ++p ); #define INQUOTE 1 #define OUTQUOTE 2 state = OUTQUOTE; for ( p = ufn, r = ufn; *p; p += plen ) { plen = 1; switch ( *p ) { case '\\': if ( *++p == '\0' ) plen=0; else { *r++ = '\\'; r += (plen = LDAP_UTF8COPY(r,p)); } break; case '"': if ( state == INQUOTE ) state = OUTQUOTE; else state = INQUOTE; *r++ = *p; break; case ';': case ',': if ( state == OUTQUOTE ) *r++ = ','; else *r++ = *p; break; case '=': if ( state == INQUOTE ) *r++ = *p; else { char *rsave = r; LDAP_UTF8DEC(r); *rsave = '\0'; while ( !ldap_utf8isspace( r ) && *r != ';' && *r != ',' && r > ufn ) LDAP_UTF8DEC(r); LDAP_UTF8INC(r); if ( strcasecmp( r, "c" ) && strcasecmp( r, "o" ) && strcasecmp( r, "ou" ) && strcasecmp( r, "st" ) && strcasecmp( r, "l" ) && strcasecmp( r, "dc" ) && strcasecmp( r, "uid" ) && strcasecmp( r, "cn" ) ) { r = rsave; *r++ = '='; } } break; default: r += (plen = LDAP_UTF8COPY(r,p)); break; } } *r = '\0'; return( ufn ); }
/* Caller must ensure that U == NULL and Ulen == 0 the first time called */ static UErrorCode SetUnicodeStringFromUTF_8 (UChar** U, int32_t* Ulen, int *isAlloced, const struct berval* bv) /* Copy the UTF-8 string bv into the UnicodeString U, but remove leading and trailing whitespace, and convert consecutive whitespaces into a single space. Ulen is set to the number of UChars in the array (not necessarily the number of bytes!) */ { size_t n; int32_t len = 0; /* length of non-space string */ UErrorCode err = U_ZERO_ERROR; const char* s = bv->bv_val; const char* begin = NULL; /* will point to beginning of non-space in val */ const char* end = NULL; /* will point to the first space after the last non-space char in val */ int32_t nUchars = 0; if (!bv->bv_len) { /* no value? */ return U_INVALID_FORMAT_ERROR; /* don't know what else to use here */ } /* first, set s to the first non-space char in bv->bv_val */ for (n = 0; (n < bv->bv_len) && ldap_utf8isspace((char *)s); ) { /* cast away const */ const char *next = LDAP_UTF8NEXT((char *)s); /* cast away const */ n += (next - s); /* count bytes, not chars */ s = next; } begin = s; /* begin points to first non-space char in val */ if (n >= bv->bv_len) { /* value is all spaces? */ return U_INVALID_FORMAT_ERROR; /* don't know what else to use here */ } s = bv->bv_val + (bv->bv_len-1); /* move s to last char of bv_val */ end = s; /* end points at last char of bv_val - may change below */ /* find the last non-null and non-space char of val */ for (n = bv->bv_len; (n > 0) && (!*s || ldap_utf8isspace((char *)s));) { const char *prev = LDAP_UTF8PREV((char *)s); end = prev; n -= (s - prev); /* count bytes, not chars */ s = prev; } /* end now points at last non-null/non-space of val */ if (n == 0) { /* bogus */ return U_INVALID_FORMAT_ERROR; /* don't know what else to use here */ } len = LDAP_UTF8NEXT((char *)end) - begin; u_strFromUTF8(*U, *Ulen, &nUchars, begin, len, &err); if (nUchars > *Ulen) { /* need more space */ if (*isAlloced) { /* realloc space */ *U = (UChar *)slapi_ch_realloc((char *)*U, sizeof(UChar) * nUchars); } else { /* must use malloc */ *U = (UChar *)slapi_ch_malloc(sizeof(UChar) * nUchars); *isAlloced = 1; /* no longer using fixed buffer */ } *Ulen = nUchars; err = U_ZERO_ERROR; /* reset */ u_strFromUTF8(*U, *Ulen, NULL, begin, len, &err); } else { *Ulen = nUchars; } return err; }