#include "k5-int.h"
#include <stdio.h>
#define REALM_SEP '@'
#define COMPONENT_SEP '/'
krb5_error_code KRB5_CALLCONV
krb5_unparse_name_ext(krb5_context context, krb5_const_principal principal, register char **name, unsigned int *size)
{
register char *cp, *q;
register int i,j;
int length;
krb5_int32 nelem;
register unsigned int totalsize = 0;
if (!principal || !name)
return KRB5_PARSE_MALFORMED;
cp = krb5_princ_realm(context, principal)->data;
length = krb5_princ_realm(context, principal)->length;
totalsize += length;
for (j = 0; j < length; j++,cp++)
if (*cp == REALM_SEP || *cp == COMPONENT_SEP ||
*cp == '\0' || *cp == '\\' || *cp == '\t' ||
*cp == '\n' || *cp == '\b')
totalsize++;
totalsize++;
nelem = krb5_princ_size(context, principal);
for (i = 0; i < (int) nelem; i++) {
cp = krb5_princ_component(context, principal, i)->data;
length = krb5_princ_component(context, principal, i)->length;
totalsize += length;
for (j=0; j < length; j++,cp++)
if (*cp == REALM_SEP || *cp == COMPONENT_SEP ||
*cp == '\0' || *cp == '\\' || *cp == '\t' ||
*cp == '\n' || *cp == '\b')
totalsize++;
totalsize++;
}
if (nelem == 0)
totalsize++;
if (size) {
if (*name && (*size < totalsize)) {
*name = realloc(*name, totalsize);
} else {
*name = malloc(totalsize);
}
*size = totalsize;
} else {
*name = malloc(totalsize);
}
if (!*name)
return ENOMEM;
q = *name;
for (i = 0; i < (int) nelem; i++) {
cp = krb5_princ_component(context, principal, i)->data;
length = krb5_princ_component(context, principal, i)->length;
for (j=0; j < length; j++,cp++) {
switch (*cp) {
case COMPONENT_SEP:
case REALM_SEP:
case '\\':
*q++ = '\\';
*q++ = *cp;
break;
case '\t':
*q++ = '\\';
*q++ = 't';
break;
case '\n':
*q++ = '\\';
*q++ = 'n';
break;
case '\b':
*q++ = '\\';
*q++ = 'b';
break;
case '\0':
*q++ = '\\';
*q++ = '0';
break;
default:
*q++ = *cp;
}
}
*q++ = COMPONENT_SEP;
}
if (i > 0)
q--;
*q++ = REALM_SEP;
cp = krb5_princ_realm(context, principal)->data;
length = krb5_princ_realm(context, principal)->length;
for (j=0; j < length; j++,cp++) {
switch (*cp) {
case COMPONENT_SEP:
case REALM_SEP:
case '\\':
*q++ = '\\';
*q++ = *cp;
break;
case '\t':
*q++ = '\\';
*q++ = 't';
break;
case '\n':
*q++ = '\\';
*q++ = 'n';
break;
case '\b':
*q++ = '\\';
*q++ = 'b';
break;
case '\0':
*q++ = '\\';
*q++ = '0';
break;
default:
*q++ = *cp;
}
}
*q++ = '\0';
return 0;
}
krb5_error_code KRB5_CALLCONV
krb5_unparse_name(krb5_context context, krb5_const_principal principal, register char **name)
{
if (name)
*name = NULL;
return(krb5_unparse_name_ext(context, principal, name, NULL));
}