Additional dictionary functions for working with dynamic attributes
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 12 Feb 2013 18:50:58 +0000 (13:50 -0500)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 12 Feb 2013 19:20:46 +0000 (14:20 -0500)
src/include/libradius.h
src/lib/dict.c

index 14516ff..eb350c0 100644 (file)
@@ -280,6 +280,8 @@ int         dict_addattr(const char *name, int attr, unsigned int vendor, int type, ATT
 int            dict_addvalue(const char *namestr, const char *attrstr, int value);
 int            dict_init(const char *dir, const char *fn);
 void           dict_free(void);
+void           dict_attr_free(const DICT_ATTR *da);
+const DICT_ATTR        *dict_attr_copy(const DICT_ATTR *da);
 DICT_ATTR      *dict_attrunknown(unsigned int attr, unsigned int vendor);
 DICT_ATTR      *dict_attrbyvalue(unsigned int attr, unsigned int vendor);
 DICT_ATTR      *dict_attrbyname(const char *attr);
index b507fa9..c8c4e7c 100644 (file)
@@ -44,6 +44,8 @@ RCSID("$Id$")
 #define DICT_VENDOR_MAX_NAME_LEN (128)
 #define DICT_ATTR_MAX_NAME_LEN (128)
 
+#define DICT_ATTR_SIZE sizeof(DICT_ATTR) + DICT_ATTR_MAX_NAME_LEN
+
 static fr_hash_table_t *vendors_byname = NULL;
 static fr_hash_table_t *vendors_byvalue = NULL;
 
@@ -2445,12 +2447,62 @@ static size_t print_attr_oid(char *buffer, size_t size, unsigned int attr,
        return outlen;
 }
 
-/** Allocs an dictionary struct for unknown attributes
+/** Free dynamically allocated (unknown attributes)
+ * 
+ * If the da was dynamically allocated it will be freed, else the function
+ * will return without doing anything.
+ *
+ * @param da to free.
+ */
+void dict_attr_free(const DICT_ATTR *da)
+{
+       DICT_ATTR *tmp;
+       
+       /* Don't free real DAs */
+       if (!da->flags.is_unknown) {
+               return;
+       }
+       
+       memcpy(&tmp, &da, sizeof(tmp));
+       free(tmp);      
+}
+
+/** Copies a dictionary attr
+ *
+ * If the attr is dynamically allocated (unknown attribute), then it will be
+ * copied to a new attr.
+ *
+ * If the attr is known, a pointer to the da will be returned.
+ *
+ * @param da to copy.
+ * @param return a copy of the da.
+ */
+const DICT_ATTR *dict_attr_copy(const DICT_ATTR *da)
+{
+       DICT_ATTR *copy;
+       
+       if (!da->flags.is_unknown) {
+               return da;
+       }
+       
+       copy = malloc(DICT_ATTR_SIZE);
+       if (!copy) {
+               fr_strerror_printf("Out of memory");
+               return NULL;
+       }
+       
+       memcpy(copy, da, DICT_ATTR_SIZE);
+       
+       return copy;
+}
+
+
+/** Allocs an dictionary attr for unknown attributes
  *
- * Allocates a dict entry for an unknown attribute/vendor type
+ * Allocates a dict attr for an unknown attribute/vendor/type
  * without adding it to dictionary pools/hashes.
  *
- * @note Dictionary attribute must be freed manually once it's no longer in use.
+ * @note Must be freed with dict_attr_free if not used as part of a valuepair.
  *
  * @param[in] attr number.
  * @param[in] vendor number.
@@ -2464,12 +2516,12 @@ DICT_ATTR *dict_attrunknown(unsigned int attr, unsigned int vendor)
        size_t len = 0;
        size_t bufsize = DICT_ATTR_MAX_NAME_LEN;
        
-       da = malloc(sizeof(*da) + DICT_ATTR_MAX_NAME_LEN);
+       da = malloc(DICT_ATTR_SIZE);
        if (!da) {
                fr_strerror_printf("Out of memory");
                return NULL;
        }
-       memset(da, 0, sizeof(*da) + DICT_ATTR_MAX_NAME_LEN);
+       memset(da, 0, DICT_ATTR_SIZE);
        
        da->attr = attr;
        da->vendor = vendor;