Add pairmark_xlat
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sat, 16 Feb 2013 20:25:20 +0000 (15:25 -0500)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sat, 16 Feb 2013 22:25:47 +0000 (17:25 -0500)
src/include/libradius.h
src/lib/valuepair.c

index 10b0fc3..1cde6ba 100644 (file)
@@ -180,6 +180,18 @@ typedef union value_pair_data {
        uint8_t                 *tlv;
 } VALUE_PAIR_DATA;
 
+typedef enum value_type {
+       VT_NONE = 0,                            //!< VALUE_PAIR has no value.
+       VT_SET,                                 //!< VALUE_PAIR has children.
+       VT_LIST,                                //!< VALUE_PAIR has multiple 
+                                               //!< values.
+       VT_DATA,                                //!< VALUE_PAIR has a single
+                                               //!< value.
+       VT_XLAT                                 //!< valuepair value must be 
+                                               //!< xlat expanded when it's 
+                                               //!< added to VALUE_PAIR tree.
+} value_type_t;
+
 typedef struct value_pair {
        const DICT_ATTR         *da;            //!< Dictionary attribute
                                                //!< defines the attribute
@@ -194,7 +206,6 @@ typedef struct value_pair {
         */
        unsigned int            attribute;
        unsigned int            vendor;
-       PW_TYPE                 type;
 
        FR_TOKEN                op;             //!< Operator to use when 
                                                //!< moving or inserting 
@@ -205,7 +216,21 @@ typedef struct value_pair {
 
         ATTR_FLAGS              flags;
 
-       size_t                  length; /* of data field */
+       union {
+       //      VALUE_SET       *set;           //!< Set of child attributes.
+       //      VLAUE_LIST      *list;          //!< List of values for 
+                                               //!< multivalued attribute.
+       //      VALUE_DATA      *data;          //!< Value data for this 
+                                               //!< attribute.
+       
+               const char      *xlat;          //!< Source string for xlat
+                                               //!< expansion.
+       } value;
+       
+       value_type_t            type;           //!< Type of pointer in value
+                                               //!< union.
+                                               
+       size_t                  length;         //!< of Data field.
        VALUE_PAIR_DATA         data;
 } VALUE_PAIR;
 #define vp_strvalue   data.strvalue
@@ -418,6 +443,7 @@ VALUE_PAIR  *pairmake(const char *attribute, const char *value, FR_TOKEN op);
 VALUE_PAIR     *pairmake_xlat(const char *attribute, const char *value, FR_TOKEN op);
 VALUE_PAIR     *pairread(const char **ptr, FR_TOKEN *eol);
 FR_TOKEN       userparse(const char *buffer, VALUE_PAIR **first_pair);
+int            pairmark_xlat(VALUE_PAIR *vp, const char *value);
 VALUE_PAIR     *readvp2(FILE *fp, int *pfiledone, const char *errprefix);
 
 /*
index 46d29bb..dccfb69 100644 (file)
@@ -191,7 +191,9 @@ VALUE_PAIR *paircreate(unsigned int attr, unsigned int vendor)
  */
 void pairbasicfree(VALUE_PAIR *pair)
 {
-       if (pair->type == PW_TYPE_TLV) free(pair->vp_tlv);
+       if (pair->da->type == PW_TYPE_TLV) {
+               free(pair->vp_tlv);
+       }
        /* clear the memory here */
        memset(pair, 0, sizeof(*pair));
        free(pair);
@@ -404,7 +406,7 @@ VALUE_PAIR *paircopyvp(const VALUE_PAIR *vp)
 
        n->next = NULL;
 
-       if ((n->type == PW_TYPE_TLV) &&
+       if ((n->da->type == PW_TYPE_TLV) &&
            (n->vp_tlv != NULL)) {
                n->vp_tlv = malloc(n->length);
                memcpy(n->vp_tlv, vp->vp_tlv, n->length);
@@ -430,7 +432,7 @@ VALUE_PAIR *paircopyvpdata(const DICT_ATTR *da, const VALUE_PAIR *vp)
 
        if (!vp) return NULL;
 
-       if (da->type != vp->type) return NULL;
+       if (da->type != vp->da->type) return NULL;
        
        n = pairalloc(da);
        if (!n) {
@@ -441,7 +443,7 @@ VALUE_PAIR *paircopyvpdata(const DICT_ATTR *da, const VALUE_PAIR *vp)
        
        n->length = vp->length;
        
-       if ((n->type == PW_TYPE_TLV) &&
+       if ((n->da->type == PW_TYPE_TLV) &&
            (n->vp_tlv != NULL)) {
                n->vp_tlv = malloc(n->length);
                memcpy(n->vp_tlv, vp->vp_tlv, n->length);
@@ -1911,6 +1913,36 @@ static const int valid_attr_name[256] = {
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
 
+/** Mark a valuepair for xlat expansion
+ *
+ * Copies xlat source (unprocessed) string to valuepair value,
+ * and sets value type.
+ *
+ * @param vp to mark for expansion.
+ * @param value to expand.
+ * @return 0 if marking succeeded or -1 if vp already had a value, or OOM.
+ */
+int pairmark_xlat(VALUE_PAIR *vp, const char *value)
+{
+       char *raw;
+       
+       /*
+        *      valuepair should not already have a value.
+        */
+       if (vp->type != VT_NONE) {
+               return -1;
+       }
+       
+       raw = strdup(value);
+       if (!raw) {
+               return -1;
+       }
+       
+       vp->type = VT_XLAT;
+       vp->value.xlat = raw;
+
+       return 0;        
+}
 /*
  *     Read a valuepair from a buffer, and advance pointer.
  *     Sets *eol to T_EOL if end of line was encountered.