attr->attr = value;
attr->type = type;
attr->flags = flags;
+ attr->vendor = vendor;
if (vendor) attr->attr |= (vendor << 16);
((const DICT_VALUE *)b)->attr);
if (rcode != 0) return rcode;
-return strcasecmp(((const DICT_VALUE *)a)->name,
+ return strcasecmp(((const DICT_VALUE *)a)->name,
((const DICT_VALUE *)b)->name);
}
/*
* Get an attribute by its name.
+ *
+ * We can refer to an attribute by it's name, or by
+ * canonical reference:
+ *
+ * Attribute-Name
+ * Attr-%d
+ * VendorName-Attr-%d
+ * Vendor-%d-Attr-%d
+ * VendorName-Attribute-Name
*/
DICT_ATTR *dict_attrbyname(const char *name)
{
- DICT_ATTR myattr;
+ DICT_ATTR myattr, *da;
strNcpy(myattr.name, name, sizeof(myattr.name));
+ da = rbtree_finddata(attributes_byname, &myattr);
+ if (da) return da;
+
+ {
+ int value, attr;
+ const char *p = name;
+ char *q;
+
+ /*
+ * Look for:
+ *
+ * Vendor-%d-Attr-%d
+ * VendorName-Attr-%d
+ * Attr-%d %d = 1-65535
+ */
+
+ attr = 0;
+
+ if (strncasecmp(p, "Vendor-", 7) == 0) {
+ p += 7;
+ value = (int) strtol(p, &q, 10);
+ /*
+ * Validate the parsed data.
+ */
+ if ((value <= 0) || (value > 65535)) {
+ return NULL;
+ }
+ p = q + 1; /* skip the '-' */
+ attr = value << 16; /* FIXME: horrid hack */
+
+ } else if (((q = strchr(name, '-')) != NULL) &&
+ (strncasecmp(q, "-Attr-", 6) == 0)) {
+ /*
+ * myattr.name is a temporary buffer
+ */
+ if ((q - name) >= sizeof(myattr.name)) return NULL;
+
+ memcpy(myattr.name, name, q - name);
+ myattr.name[q - name] = '\0';
+
+ value = dict_vendorbyname(myattr.name);
+ if (!value) return NULL;
+
+ p = q + 1; /* skip the '-' */
+ attr = value << 16;
+ }
+
+ /*
+ * Accept only certain names.
+ */
+ if (strncasecmp(p, "Attr-", 5) == 0) {
+ value = (int) strtol(p + 5, &q, 10);
+ if (*q) return NULL; /* characters after the digits */
+ if ((value <= 0) || (value > 65535)) return NULL; /* bad value */
+ attr |= value;
+ return dict_attrbyvalue(attr);
+ }
+
+ /*
+ * If there's no leading Vendor-%d, or Vendorname,
+ * and the attribute is not Attr-%d, then don't
+ * bother looking it up again.
+ */
+ if (attr == 0) return NULL;
+
+ /*
+ * Else maybe it's Vendor-%d-Attribute-Name
+ */
+ strNcpy(myattr.name, p, sizeof(myattr.name));
+ }
+
return rbtree_finddata(attributes_byname, &myattr);
}