You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
796 lines
16 KiB
796 lines
16 KiB
/*
|
|
* $Id: avpair.c,v 1.1 2004/11/14 07:26:26 paulus Exp $
|
|
*
|
|
* Copyright (C) 1995 Lars Fenneberg
|
|
*
|
|
* Copyright 1992 Livingston Enterprises, Inc.
|
|
*
|
|
* Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
|
|
* and Merit Network, Inc. All Rights Reserved
|
|
*
|
|
* See the file COPYRIGHT for the respective terms and conditions.
|
|
* If the file is missing contact me at lf@elemental.net
|
|
* and I'll send you a copy.
|
|
*
|
|
*/
|
|
|
|
#include <includes.h>
|
|
#include <radiusclient.h>
|
|
|
|
static void rc_extract_vendor_specific_attributes(int attrlen,
|
|
unsigned char *ptr,
|
|
VALUE_PAIR **vp);
|
|
/*
|
|
* Function: rc_avpair_add
|
|
*
|
|
* Purpose: add an attribute-value pair to the given list.
|
|
*
|
|
* Returns: pointer to added a/v pair upon success, NULL pointer upon failure.
|
|
*
|
|
* Remarks: Always appends the new pair to the end of the list.
|
|
*
|
|
*/
|
|
|
|
VALUE_PAIR *rc_avpair_add (VALUE_PAIR **list, int attrid, void *pval, int len,
|
|
int vendorcode)
|
|
{
|
|
VALUE_PAIR *vp;
|
|
|
|
vp = rc_avpair_new (attrid, pval, len, vendorcode);
|
|
|
|
if (vp != (VALUE_PAIR *) NULL)
|
|
{
|
|
rc_avpair_insert (list, (VALUE_PAIR *) NULL, vp);
|
|
}
|
|
|
|
return vp;
|
|
|
|
}
|
|
|
|
/*
|
|
* Function: rc_avpair_assign
|
|
*
|
|
* Purpose: assign the given value to an attribute-value pair.
|
|
*
|
|
* Returns: 0 on success,
|
|
* -1 on failure.
|
|
*
|
|
*/
|
|
|
|
int rc_avpair_assign (VALUE_PAIR *vp, void *pval, int len)
|
|
{
|
|
int result = -1;
|
|
|
|
switch (vp->type)
|
|
{
|
|
case PW_TYPE_STRING:
|
|
|
|
if (((len == 0) && (strlen ((char *) pval)) > AUTH_STRING_LEN)
|
|
|| (len > AUTH_STRING_LEN)) {
|
|
error("rc_avpair_assign: bad attribute length");
|
|
return result;
|
|
}
|
|
|
|
if (len > 0) {
|
|
memcpy(vp->strvalue, (char *)pval, len);
|
|
vp->strvalue[len] = '\0';
|
|
vp->lvalue = len;
|
|
} else {
|
|
strncpy (vp->strvalue, (char *) pval, AUTH_STRING_LEN);
|
|
vp->lvalue = strlen((char *) pval);
|
|
}
|
|
|
|
result = 0;
|
|
break;
|
|
|
|
case PW_TYPE_DATE:
|
|
case PW_TYPE_INTEGER:
|
|
case PW_TYPE_IPADDR:
|
|
|
|
vp->lvalue = * (UINT4 *) pval;
|
|
|
|
result = 0;
|
|
break;
|
|
|
|
default:
|
|
error("rc_avpair_assign: unknown attribute %d", vp->type);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
* Function: rc_avpair_new
|
|
*
|
|
* Purpose: make a new attribute-value pair with given parameters.
|
|
*
|
|
* Returns: pointer to generated a/v pair when successful, NULL when failure.
|
|
*
|
|
*/
|
|
|
|
VALUE_PAIR *rc_avpair_new (int attrid, void *pval, int len, int vendorcode)
|
|
{
|
|
VALUE_PAIR *vp = (VALUE_PAIR *) NULL;
|
|
DICT_ATTR *pda;
|
|
|
|
if ((pda = rc_dict_getattr (attrid, vendorcode)) == (DICT_ATTR *) NULL)
|
|
{
|
|
error("rc_avpair_new: unknown attribute %d", attrid);
|
|
}
|
|
else
|
|
{
|
|
if ((vp = (VALUE_PAIR *) malloc (sizeof (VALUE_PAIR)))
|
|
!= (VALUE_PAIR *) NULL)
|
|
{
|
|
strncpy (vp->name, pda->name, sizeof (vp->name));
|
|
vp->attribute = attrid;
|
|
vp->vendorcode = vendorcode;
|
|
vp->next = (VALUE_PAIR *) NULL;
|
|
vp->type = pda->type;
|
|
if (rc_avpair_assign (vp, pval, len) == 0)
|
|
{
|
|
return vp;
|
|
}
|
|
free (vp);
|
|
vp = (VALUE_PAIR *) NULL;
|
|
}
|
|
else
|
|
novm("rc_avpair_new");
|
|
}
|
|
return vp;
|
|
}
|
|
|
|
/*
|
|
*
|
|
* Function: rc_avpair_gen
|
|
*
|
|
* Purpose: takes attribute/value pairs from buffer and builds a
|
|
* value_pair list using allocated memory.
|
|
*
|
|
* Returns: value_pair list or NULL on failure
|
|
*/
|
|
|
|
VALUE_PAIR *rc_avpair_gen (AUTH_HDR *auth)
|
|
{
|
|
int length;
|
|
int x_len;
|
|
int attribute;
|
|
int attrlen;
|
|
UINT4 lvalue;
|
|
unsigned char *x_ptr;
|
|
unsigned char *ptr;
|
|
DICT_ATTR *attr;
|
|
VALUE_PAIR *vp;
|
|
VALUE_PAIR *pair;
|
|
unsigned char hex[3]; /* For hex string conversion. */
|
|
char buffer[512];
|
|
|
|
/*
|
|
* Extract attribute-value pairs
|
|
*/
|
|
ptr = auth->data;
|
|
length = ntohs ((unsigned short) auth->length) - AUTH_HDR_LEN;
|
|
vp = (VALUE_PAIR *) NULL;
|
|
|
|
while (length > 0)
|
|
{
|
|
attribute = *ptr++;
|
|
attrlen = *ptr++;
|
|
attrlen -= 2;
|
|
if (attrlen < 0)
|
|
{
|
|
error("rc_avpair_gen: received attribute with invalid length");
|
|
break;
|
|
}
|
|
|
|
/* Handle vendor-specific specially */
|
|
if (attribute == PW_VENDOR_SPECIFIC) {
|
|
rc_extract_vendor_specific_attributes(attrlen, ptr, &vp);
|
|
ptr += attrlen;
|
|
length -= (attrlen + 2);
|
|
continue;
|
|
}
|
|
if ((attr = rc_dict_getattr (attribute, VENDOR_NONE)) == (DICT_ATTR *) NULL)
|
|
{
|
|
*buffer= '\0'; /* Initial length. */
|
|
for (x_ptr = ptr, x_len = attrlen ;
|
|
x_len > 0 ;
|
|
x_len--, x_ptr++)
|
|
{
|
|
sprintf (hex, "%2.2X", *x_ptr);
|
|
strcat (buffer, hex);
|
|
}
|
|
warn("rc_avpair_gen: received unknown attribute %d of length %d: 0x%s",
|
|
attribute, attrlen, buffer);
|
|
}
|
|
else
|
|
{
|
|
if ((pair =
|
|
(VALUE_PAIR *) malloc (sizeof (VALUE_PAIR))) ==
|
|
(VALUE_PAIR *) NULL)
|
|
{
|
|
novm("rc_avpair_gen");
|
|
rc_avpair_free(vp);
|
|
return NULL;
|
|
}
|
|
strcpy (pair->name, attr->name);
|
|
pair->attribute = attr->value;
|
|
pair->vendorcode = VENDOR_NONE;
|
|
pair->type = attr->type;
|
|
pair->next = (VALUE_PAIR *) NULL;
|
|
|
|
switch (attr->type)
|
|
{
|
|
|
|
case PW_TYPE_STRING:
|
|
memcpy (pair->strvalue, (char *) ptr, (size_t) attrlen);
|
|
pair->strvalue[attrlen] = '\0';
|
|
pair->lvalue = attrlen;
|
|
rc_avpair_insert (&vp, (VALUE_PAIR *) NULL, pair);
|
|
break;
|
|
|
|
case PW_TYPE_INTEGER:
|
|
case PW_TYPE_IPADDR:
|
|
memcpy ((char *) &lvalue, (char *) ptr,
|
|
sizeof (UINT4));
|
|
pair->lvalue = ntohl (lvalue);
|
|
rc_avpair_insert (&vp, (VALUE_PAIR *) NULL, pair);
|
|
break;
|
|
|
|
default:
|
|
warn("rc_avpair_gen: %s has unknown type", attr->name);
|
|
free (pair);
|
|
break;
|
|
}
|
|
|
|
}
|
|
ptr += attrlen;
|
|
length -= attrlen + 2;
|
|
}
|
|
return (vp);
|
|
}
|
|
|
|
/*
|
|
* Function: rc_extract_vendor_specific_attributes
|
|
*
|
|
* Purpose: Extracts vendor-specific attributes, assuming they are in
|
|
* the "SHOULD" format recommended by RCF 2138.
|
|
*
|
|
* Returns: found value_pair
|
|
*
|
|
*/
|
|
static void rc_extract_vendor_specific_attributes(int attrlen,
|
|
unsigned char *ptr,
|
|
VALUE_PAIR **vp)
|
|
{
|
|
int vendor_id;
|
|
int vtype;
|
|
int vlen;
|
|
UINT4 lvalue;
|
|
DICT_ATTR *attr;
|
|
VALUE_PAIR *pair;
|
|
|
|
/* ptr is sitting at vendor-ID */
|
|
if (attrlen < 8) {
|
|
/* Nothing to see here... */
|
|
return;
|
|
}
|
|
|
|
/* High-order octet of Vendor-Id must be zero (RFC2138) */
|
|
if (*ptr) {
|
|
return;
|
|
}
|
|
|
|
/* Extract vendor_id */
|
|
vendor_id = (int) (
|
|
((unsigned int) ptr[1]) * 256 * 256 +
|
|
((unsigned int) ptr[2]) * 256 +
|
|
((unsigned int) ptr[3]));
|
|
/* Bump ptr up to contents */
|
|
ptr += 4;
|
|
|
|
/* Set attrlen to length of data */
|
|
attrlen -= 4;
|
|
for (; attrlen; attrlen -= vlen+2, ptr += vlen) {
|
|
vtype = *ptr++;
|
|
vlen = *ptr++;
|
|
vlen -= 2;
|
|
if (vlen < 0 || vlen > attrlen - 2) {
|
|
/* Do not log an error. We are supposed to be able to cope with
|
|
arbitrary vendor-specific gunk */
|
|
return;
|
|
}
|
|
/* Looks plausible... */
|
|
if ((attr = rc_dict_getattr(vtype, vendor_id)) == NULL) {
|
|
continue;
|
|
}
|
|
|
|
/* TODO: Check that length matches data size!!!!! */
|
|
pair = (VALUE_PAIR *) malloc(sizeof(VALUE_PAIR));
|
|
if (!pair) {
|
|
novm("rc_avpair_gen");
|
|
return;
|
|
}
|
|
strcpy(pair->name, attr->name);
|
|
pair->attribute = attr->value;
|
|
pair->vendorcode = vendor_id;
|
|
pair->type = attr->type;
|
|
pair->next = NULL;
|
|
switch (attr->type) {
|
|
case PW_TYPE_STRING:
|
|
memcpy (pair->strvalue, (char *) ptr, (size_t) vlen);
|
|
pair->strvalue[vlen] = '\0';
|
|
pair->lvalue = vlen;
|
|
rc_avpair_insert (vp, (VALUE_PAIR *) NULL, pair);
|
|
break;
|
|
|
|
case PW_TYPE_INTEGER:
|
|
case PW_TYPE_IPADDR:
|
|
memcpy ((char *) &lvalue, (char *) ptr,
|
|
sizeof (UINT4));
|
|
pair->lvalue = ntohl (lvalue);
|
|
rc_avpair_insert (vp, (VALUE_PAIR *) NULL, pair);
|
|
break;
|
|
|
|
default:
|
|
warn("rc_avpair_gen: %s has unknown type", attr->name);
|
|
free (pair);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Function: rc_avpair_get
|
|
*
|
|
* Purpose: Find the first attribute value-pair (which matches the given
|
|
* attribute) from the specified value-pair list.
|
|
*
|
|
* Returns: found value_pair
|
|
*
|
|
*/
|
|
|
|
VALUE_PAIR *rc_avpair_get (VALUE_PAIR *vp, UINT4 attr)
|
|
{
|
|
for (; vp != (VALUE_PAIR *) NULL && vp->attribute != attr; vp = vp->next)
|
|
{
|
|
continue;
|
|
}
|
|
return (vp);
|
|
}
|
|
|
|
/*
|
|
* Function: rc_avpair_copy
|
|
*
|
|
* Purpose: Return a copy of the existing list "p" ala strdup().
|
|
*
|
|
*/
|
|
VALUE_PAIR *rc_avpair_copy(VALUE_PAIR *p)
|
|
{
|
|
VALUE_PAIR *vp, *fp = NULL, *lp = NULL;
|
|
|
|
while (p) {
|
|
vp = malloc(sizeof(VALUE_PAIR));
|
|
if (!vp) {
|
|
novm("rc_avpair_copy");
|
|
return NULL; /* leaks a little but so what */
|
|
}
|
|
*vp = *p;
|
|
if (!fp)
|
|
fp = vp;
|
|
if (lp)
|
|
lp->next = vp;
|
|
lp = vp;
|
|
p = p->next;
|
|
}
|
|
|
|
return fp;
|
|
}
|
|
|
|
/*
|
|
* Function: rc_avpair_insert
|
|
*
|
|
* Purpose: Given the address of an existing list "a" and a pointer
|
|
* to an entry "p" in that list, add the list "b" to
|
|
* the "a" list after the "p" entry. If "p" is NULL, add
|
|
* the list "b" to the end of "a".
|
|
*
|
|
*/
|
|
|
|
void rc_avpair_insert (VALUE_PAIR **a, VALUE_PAIR *p, VALUE_PAIR *b)
|
|
{
|
|
VALUE_PAIR *this_node = NULL;
|
|
VALUE_PAIR *vp;
|
|
|
|
if (*a == (VALUE_PAIR *) NULL)
|
|
{
|
|
*a = b;
|
|
return;
|
|
}
|
|
|
|
if (!b)
|
|
return;
|
|
|
|
vp = *a;
|
|
|
|
if ( p == (VALUE_PAIR *) NULL) /* run to end of "a" list */
|
|
{
|
|
while (vp != (VALUE_PAIR *) NULL)
|
|
{
|
|
this_node = vp;
|
|
vp = vp->next;
|
|
}
|
|
}
|
|
else /* look for the "p" entry in the "a" list (or run to end) */
|
|
{
|
|
this_node = *a;
|
|
while (this_node != (VALUE_PAIR *) NULL)
|
|
{
|
|
if (this_node == p)
|
|
{
|
|
break;
|
|
}
|
|
this_node = this_node->next;
|
|
}
|
|
}
|
|
|
|
/* add "b" at this_node */
|
|
vp = this_node->next;
|
|
this_node->next = b;
|
|
|
|
/* run to end of "b" and connect the rest of "a" */
|
|
while (b->next)
|
|
b = b->next;
|
|
b->next = vp;
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* Function: rc_avpair_free
|
|
*
|
|
* Purpose: frees all value_pairs in the list
|
|
*
|
|
*/
|
|
|
|
void rc_avpair_free (VALUE_PAIR *pair)
|
|
{
|
|
VALUE_PAIR *next;
|
|
|
|
while (pair != (VALUE_PAIR *) NULL)
|
|
{
|
|
next = pair->next;
|
|
free (pair);
|
|
pair = next;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Function: rc_fieldcpy
|
|
*
|
|
* Purpose: Copy a data field from the buffer. Advance the buffer
|
|
* past the data field.
|
|
*
|
|
*/
|
|
|
|
static void rc_fieldcpy (char *string, char **uptr)
|
|
{
|
|
char *ptr;
|
|
|
|
ptr = *uptr;
|
|
if (*ptr == '"')
|
|
{
|
|
ptr++;
|
|
while (*ptr != '"' && *ptr != '\0' && *ptr != '\n')
|
|
{
|
|
*string++ = *ptr++;
|
|
}
|
|
*string = '\0';
|
|
if (*ptr == '"')
|
|
{
|
|
ptr++;
|
|
}
|
|
*uptr = ptr;
|
|
return;
|
|
}
|
|
|
|
while (*ptr != ' ' && *ptr != '\t' && *ptr != '\0' && *ptr != '\n' &&
|
|
*ptr != '=' && *ptr != ',')
|
|
{
|
|
*string++ = *ptr++;
|
|
}
|
|
*string = '\0';
|
|
*uptr = ptr;
|
|
return;
|
|
}
|
|
|
|
|
|
/*
|
|
* Function: rc_avpair_parse
|
|
*
|
|
* Purpose: parses the buffer to extract the attribute-value pairs.
|
|
*
|
|
* Returns: 0 = successful parse of attribute-value pair,
|
|
* -1 = syntax (or other) error detected.
|
|
*
|
|
*/
|
|
|
|
#define PARSE_MODE_NAME 0
|
|
#define PARSE_MODE_EQUAL 1
|
|
#define PARSE_MODE_VALUE 2
|
|
#define PARSE_MODE_INVALID 3
|
|
|
|
int rc_avpair_parse (char *buffer, VALUE_PAIR **first_pair)
|
|
{
|
|
int mode;
|
|
char attrstr[AUTH_ID_LEN];
|
|
char valstr[AUTH_ID_LEN];
|
|
DICT_ATTR *attr = NULL;
|
|
DICT_VALUE *dval;
|
|
VALUE_PAIR *pair;
|
|
VALUE_PAIR *link;
|
|
struct tm *tm;
|
|
time_t timeval;
|
|
|
|
mode = PARSE_MODE_NAME;
|
|
while (*buffer != '\n' && *buffer != '\0')
|
|
{
|
|
if (*buffer == ' ' || *buffer == '\t')
|
|
{
|
|
buffer++;
|
|
continue;
|
|
}
|
|
|
|
switch (mode)
|
|
{
|
|
case PARSE_MODE_NAME: /* Attribute Name */
|
|
rc_fieldcpy (attrstr, &buffer);
|
|
if ((attr =
|
|
rc_dict_findattr (attrstr)) == (DICT_ATTR *) NULL)
|
|
{
|
|
error("rc_avpair_parse: unknown attribute");
|
|
if (*first_pair) {
|
|
rc_avpair_free(*first_pair);
|
|
*first_pair = (VALUE_PAIR *) NULL;
|
|
}
|
|
return (-1);
|
|
}
|
|
mode = PARSE_MODE_EQUAL;
|
|
break;
|
|
|
|
case PARSE_MODE_EQUAL: /* Equal sign */
|
|
if (*buffer == '=')
|
|
{
|
|
mode = PARSE_MODE_VALUE;
|
|
buffer++;
|
|
}
|
|
else
|
|
{
|
|
error("rc_avpair_parse: missing or misplaced equal sign");
|
|
if (*first_pair) {
|
|
rc_avpair_free(*first_pair);
|
|
*first_pair = (VALUE_PAIR *) NULL;
|
|
}
|
|
return (-1);
|
|
}
|
|
break;
|
|
|
|
case PARSE_MODE_VALUE: /* Value */
|
|
rc_fieldcpy (valstr, &buffer);
|
|
|
|
if ((pair =
|
|
(VALUE_PAIR *) malloc (sizeof (VALUE_PAIR)))
|
|
== (VALUE_PAIR *) NULL)
|
|
{
|
|
novm("rc_avpair_parse");
|
|
if (*first_pair) {
|
|
rc_avpair_free(*first_pair);
|
|
*first_pair = (VALUE_PAIR *) NULL;
|
|
}
|
|
return (-1);
|
|
}
|
|
strcpy (pair->name, attr->name);
|
|
pair->attribute = attr->value;
|
|
pair->type = attr->type;
|
|
pair->vendorcode = attr->vendorcode;
|
|
|
|
switch (pair->type)
|
|
{
|
|
|
|
case PW_TYPE_STRING:
|
|
strcpy (pair->strvalue, valstr);
|
|
pair->lvalue = strlen(valstr);
|
|
break;
|
|
|
|
case PW_TYPE_INTEGER:
|
|
if (isdigit (*valstr))
|
|
{
|
|
pair->lvalue = atoi (valstr);
|
|
}
|
|
else
|
|
{
|
|
if ((dval = rc_dict_findval (valstr))
|
|
== (DICT_VALUE *) NULL)
|
|
{
|
|
error("rc_avpair_parse: unknown attribute value: %s", valstr);
|
|
if (*first_pair) {
|
|
rc_avpair_free(*first_pair);
|
|
*first_pair = (VALUE_PAIR *) NULL;
|
|
}
|
|
free (pair);
|
|
return (-1);
|
|
}
|
|
else
|
|
{
|
|
pair->lvalue = dval->value;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case PW_TYPE_IPADDR:
|
|
pair->lvalue = rc_get_ipaddr(valstr);
|
|
break;
|
|
|
|
case PW_TYPE_DATE:
|
|
timeval = time (0);
|
|
tm = localtime (&timeval);
|
|
tm->tm_hour = 0;
|
|
tm->tm_min = 0;
|
|
tm->tm_sec = 0;
|
|
rc_str2tm (valstr, tm);
|
|
#ifdef TIMELOCAL
|
|
pair->lvalue = (UINT4) timelocal (tm);
|
|
#else /* TIMELOCAL */
|
|
pair->lvalue = (UINT4) mktime (tm);
|
|
#endif /* TIMELOCAL */
|
|
break;
|
|
|
|
default:
|
|
error("rc_avpair_parse: unknown attribute type %d", pair->type);
|
|
if (*first_pair) {
|
|
rc_avpair_free(*first_pair);
|
|
*first_pair = (VALUE_PAIR *) NULL;
|
|
}
|
|
free (pair);
|
|
return (-1);
|
|
}
|
|
pair->next = (VALUE_PAIR *) NULL;
|
|
|
|
if (*first_pair == (VALUE_PAIR *) NULL)
|
|
{
|
|
*first_pair = pair;
|
|
}
|
|
else
|
|
{
|
|
link = *first_pair;
|
|
while (link->next != (VALUE_PAIR *) NULL)
|
|
{
|
|
link = link->next;
|
|
}
|
|
link->next = pair;
|
|
}
|
|
|
|
mode = PARSE_MODE_NAME;
|
|
break;
|
|
|
|
default:
|
|
mode = PARSE_MODE_NAME;
|
|
break;
|
|
}
|
|
}
|
|
return (0);
|
|
}
|
|
|
|
/*
|
|
* Function: rc_avpair_tostr
|
|
*
|
|
* Purpose: Translate an av_pair into two strings
|
|
*
|
|
* Returns: 0 on success, -1 on failure
|
|
*
|
|
*/
|
|
|
|
int rc_avpair_tostr (VALUE_PAIR *pair, char *name, int ln, char *value, int lv)
|
|
{
|
|
DICT_VALUE *dval;
|
|
char buffer[32];
|
|
struct in_addr inad;
|
|
unsigned char *ptr;
|
|
|
|
*name = *value = '\0';
|
|
|
|
if (!pair || pair->name[0] == '\0') {
|
|
error("rc_avpair_tostr: pair is NULL or empty");
|
|
return (-1);
|
|
}
|
|
|
|
strncpy(name, pair->name, (size_t) ln);
|
|
|
|
switch (pair->type)
|
|
{
|
|
case PW_TYPE_STRING:
|
|
lv--;
|
|
ptr = (unsigned char *) pair->strvalue;
|
|
while (*ptr != '\0')
|
|
{
|
|
if (!(isprint (*ptr)))
|
|
{
|
|
sprintf (buffer, "\\%03o", *ptr);
|
|
strncat(value, buffer, (size_t) lv);
|
|
lv -= 4;
|
|
if (lv < 0) break;
|
|
}
|
|
else
|
|
{
|
|
strncat(value, ptr, 1);
|
|
lv--;
|
|
if (lv < 0) break;
|
|
}
|
|
ptr++;
|
|
}
|
|
break;
|
|
|
|
case PW_TYPE_INTEGER:
|
|
dval = rc_dict_getval (pair->lvalue, pair->name);
|
|
if (dval != (DICT_VALUE *) NULL)
|
|
{
|
|
strncpy(value, dval->name, (size_t) lv-1);
|
|
}
|
|
else
|
|
{
|
|
sprintf (buffer, "%ld", pair->lvalue);
|
|
strncpy(value, buffer, (size_t) lv);
|
|
}
|
|
break;
|
|
|
|
case PW_TYPE_IPADDR:
|
|
inad.s_addr = htonl(pair->lvalue);
|
|
strncpy (value, inet_ntoa (inad), (size_t) lv-1);
|
|
break;
|
|
|
|
case PW_TYPE_DATE:
|
|
strftime (buffer, sizeof (buffer), "%m/%d/%y %H:%M:%S",
|
|
gmtime ((time_t *) & pair->lvalue));
|
|
strncpy(value, buffer, lv-1);
|
|
break;
|
|
|
|
default:
|
|
error("rc_avpair_tostr: unknown attribute type %d", pair->type);
|
|
return (-1);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Function: rc_avpair_readin
|
|
*
|
|
* Purpose: get a sequence of attribute value pairs from the file input
|
|
* and make them into a list of value_pairs
|
|
*
|
|
*/
|
|
|
|
VALUE_PAIR *rc_avpair_readin(FILE *input)
|
|
{
|
|
VALUE_PAIR *vp = NULL;
|
|
char buffer[1024], *q;
|
|
|
|
while (fgets(buffer, sizeof(buffer), input) != NULL)
|
|
{
|
|
q = buffer;
|
|
|
|
while(*q && isspace(*q)) q++;
|
|
|
|
if ((*q == '\n') || (*q == '#') || (*q == '\0'))
|
|
continue;
|
|
|
|
if (rc_avpair_parse(q, &vp) < 0) {
|
|
error("rc_avpair_readin: malformed attribute: %s", buffer);
|
|
rc_avpair_free(vp);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
return vp;
|
|
}
|