2 * $Id: dict.c,v 1.2 2002/03/05 15:14:06 dfs Exp $
4 * Copyright (C) 2002 Roaring Penguin Software Inc.
6 * Copyright (C) 1995,1996,1997 Lars Fenneberg
8 * Copyright 1992 Livingston Enterprises, Inc.
10 * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
11 * and Merit Network, Inc. All Rights Reserved
13 * See the file COPYRIGHT for the respective terms and conditions.
14 * If the file is missing contact me at lf@elemental.net
15 * and I'll send you a copy.
21 #include <radiusclient.h>
23 static DICT_ATTR *dictionary_attributes = NULL;
24 static DICT_VALUE *dictionary_values = NULL;
25 static VENDOR_DICT *vendor_dictionaries = NULL;
28 * Function: rc_read_dictionary
30 * Purpose: Initialize the dictionary. Read all ATTRIBUTES into
31 * the dictionary_attributes list. Read all VALUES into
32 * the dictionary_values list. Construct VENDOR dictionaries
37 int rc_read_dictionary (char *filename)
40 char dummystr[AUTH_ID_LEN];
41 char namestr[AUTH_ID_LEN];
42 char valstr[AUTH_ID_LEN];
43 char attrstr[AUTH_ID_LEN];
44 char typestr[AUTH_ID_LEN];
45 char vendorstr[AUTH_ID_LEN];
55 if ((dictfd = fopen (filename, "r")) == (FILE *) NULL)
57 rc_log(LOG_ERR, "rc_read_dictionary: couldn't open dictionary %s: %s",
58 filename, strerror(errno));
64 while (fgets (buffer, sizeof (buffer), dictfd) != (char *) NULL)
68 /* Skip empty space */
69 if (*buffer == '#' || *buffer == '\0' || *buffer == '\n')
74 if (strncmp (buffer, "VENDOR", 6) == 0) {
75 /* Read the VENDOR line */
76 if (sscanf(buffer, "%s%s%d", dummystr, namestr, &value) != 3) {
77 rc_log(LOG_ERR, "rc_read_dictionary: invalid vendor on line %d of dictionary %s",
83 if (strlen (namestr) > NAME_LENGTH) {
84 rc_log(LOG_ERR, "rc_read_dictionary: invalid name length on line %d of dictionary %s",
89 /* Create new vendor entry */
90 vdict = (VENDOR_DICT *) malloc (sizeof (VENDOR_DICT));
92 rc_log(LOG_CRIT, "rc_read_dictionary: out of memory");
96 strcpy(vdict->vendorname, namestr);
97 vdict->vendorcode = value;
98 vdict->attributes = NULL;
99 vdict->next = vendor_dictionaries;
100 vendor_dictionaries = vdict;
102 else if (strncmp (buffer, "ATTRIBUTE", 9) == 0)
105 /* Read the ATTRIBUTE line. It is one of:
106 * ATTRIBUTE attr_name attr_val type OR
107 * ATTRIBUTE attr_name attr_val type vendor */
109 n = sscanf(buffer, "%s%s%s%s%s", dummystr, namestr, valstr, typestr, vendorstr);
110 if (n != 4 && n != 5)
112 rc_log(LOG_ERR, "rc_read_dictionary: invalid attribute on line %d of dictionary %s",
119 * Validate all entries
121 if (strlen (namestr) > NAME_LENGTH)
123 rc_log(LOG_ERR, "rc_read_dictionary: invalid name length on line %d of dictionary %s",
129 if (strlen (vendorstr) > NAME_LENGTH)
131 rc_log(LOG_ERR, "rc_read_dictionary: invalid name length on line %d of dictionary %s",
137 if (!isdigit (*valstr))
140 "rc_read_dictionary: invalid value on line %d of dictionary %s",
145 value = atoi (valstr);
147 if (strcmp (typestr, "string") == 0)
149 type = PW_TYPE_STRING;
151 else if (strcmp (typestr, "integer") == 0)
153 type = PW_TYPE_INTEGER;
155 else if (strcmp (typestr, "ipaddr") == 0)
157 type = PW_TYPE_IPADDR;
159 else if (strcmp (typestr, "date") == 0)
166 "rc_read_dictionary: invalid type on line %d of dictionary %s",
172 /* Search for vendor if supplied */
174 vdict = rc_dict_findvendor(vendorstr);
177 "rc_read_dictionary: unknown vendor on line %d of dictionary %s",
185 /* Create a new attribute for the list */
187 (DICT_ATTR *) malloc (sizeof (DICT_ATTR)))
188 == (DICT_ATTR *) NULL)
190 rc_log(LOG_CRIT, "rc_read_dictionary: out of memory");
194 strcpy (attr->name, namestr);
196 attr->vendorcode = vdict->vendorcode;
198 attr->vendorcode = VENDOR_NONE;
203 /* Insert it into the list */
205 attr->next = vdict->attributes;
206 vdict->attributes = attr;
208 attr->next = dictionary_attributes;
209 dictionary_attributes = attr;
212 else if (strncmp (buffer, "VALUE", 5) == 0)
214 /* Read the VALUE line */
215 if (sscanf (buffer, "%s%s%s%s", dummystr, attrstr,
216 namestr, valstr) != 4)
219 "rc_read_dictionary: invalid value entry on line %d of dictionary %s",
226 * Validate all entries
228 if (strlen (attrstr) > NAME_LENGTH)
231 "rc_read_dictionary: invalid attribute length on line %d of dictionary %s",
237 if (strlen (namestr) > NAME_LENGTH)
240 "rc_read_dictionary: invalid name length on line %d of dictionary %s",
246 if (!isdigit (*valstr))
249 "rc_read_dictionary: invalid value on line %d of dictionary %s",
254 value = atoi (valstr);
256 /* Create a new VALUE entry for the list */
258 (DICT_VALUE *) malloc (sizeof (DICT_VALUE)))
259 == (DICT_VALUE *) NULL)
261 rc_log(LOG_CRIT, "rc_read_dictionary: out of memory");
265 strcpy (dval->attrname, attrstr);
266 strcpy (dval->name, namestr);
269 /* Insert it into the list */
270 dval->next = dictionary_values;
271 dictionary_values = dval;
273 else if (strncmp (buffer, "INCLUDE", 7) == 0)
275 /* Read the INCLUDE line */
276 if (sscanf (buffer, "%s%s", dummystr, namestr) != 2)
279 "rc_read_dictionary: invalid include entry on line %d of dictionary %s",
284 if (rc_read_dictionary(namestr) == -1)
296 * Function: rc_dict_getattr
298 * Purpose: Return the full attribute structure based on the
299 * attribute id number and vendor code. If vendor code is VENDOR_NONE,
300 * non-vendor-specific attributes are used
304 DICT_ATTR *rc_dict_getattr (int attribute, int vendor)
309 if (vendor == VENDOR_NONE) {
310 attr = dictionary_attributes;
311 while (attr != (DICT_ATTR *) NULL) {
312 if (attr->value == attribute) {
318 dict = rc_dict_getvendor(vendor);
322 attr = dict->attributes;
324 if (attr->value == attribute) {
334 * Function: rc_dict_findattr
336 * Purpose: Return the full attribute structure based on the
341 DICT_ATTR *rc_dict_findattr (char *attrname)
346 attr = dictionary_attributes;
347 while (attr != (DICT_ATTR *) NULL)
349 if (strcasecmp (attr->name, attrname) == 0)
356 /* Search vendor-specific dictionaries */
357 dict = vendor_dictionaries;
359 attr = dict->attributes;
361 if (strcasecmp (attr->name, attrname) == 0) {
368 return ((DICT_ATTR *) NULL);
373 * Function: rc_dict_findval
375 * Purpose: Return the full value structure based on the
380 DICT_VALUE *rc_dict_findval (char *valname)
384 val = dictionary_values;
385 while (val != (DICT_VALUE *) NULL)
387 if (strcasecmp (val->name, valname) == 0)
393 return ((DICT_VALUE *) NULL);
397 * Function: dict_getval
399 * Purpose: Return the full value structure based on the
400 * actual value and the associated attribute name.
404 DICT_VALUE * rc_dict_getval (UINT4 value, char *attrname)
408 val = dictionary_values;
409 while (val != (DICT_VALUE *) NULL)
411 if (strcmp (val->attrname, attrname) == 0 &&
418 return ((DICT_VALUE *) NULL);
422 * Function: rc_dict_findvendor
424 * Purpose: Return the vendor's dictionary given the vendor name.
427 VENDOR_DICT * rc_dict_findvendor (char *vendorname)
431 dict = vendor_dictionaries;
433 if (!strcmp(vendorname, dict->vendorname)) {
442 * Function: rc_dict_getvendor
444 * Purpose: Return the vendor's dictionary given the vendor ID
447 VENDOR_DICT * rc_dict_getvendor (int id)
451 dict = vendor_dictionaries;
453 if (id == dict->vendorcode) {