Add support for ${Attribute-Name[2]}, which grabs value of the
authoraland <aland>
Fri, 11 Jun 2004 20:46:29 +0000 (20:46 +0000)
committeraland <aland>
Fri, 11 Jun 2004 20:46:29 +0000 (20:46 +0000)
N'th attribute of that name.

doc/variables.txt
src/main/xlat.c

index 0b4ecf9..33eba6b 100644 (file)
@@ -97,12 +97,23 @@ defined in 'sh'.  For example:
 
   The dynamic translations support a few additional operatons, too.
 
-     %{#string}        The number of characters in %{string}.  If %{string}
-               is not set, then the length is not set.
-               e.g. %{#Junk-junk:-foo} will yeild the string "foo".
-               This will NOT work for the one-character variables
-               defined below.
+     %{#string}
+       The number of characters in %{string}.  If %{string} is not
+       set, then the length is not set.  This will NOT work for the
+       one-character variables defined below.
 
+       e.g. %{#Junk-junk:-foo} will yeild the string "foo".
+
+
+     %{Attribute-Name[index]}
+       Reference the N'th occurance of the given attribute.  The
+       indexes start at zero.  This feature is NOT available for
+       non-attribute dynamic translations, like %{sql:...}.
+
+       e.g. %{User-Name[0]} is the same as %{User-Name}
+       e.g. %{Cisco-AVPair[2]} references the value of the *third*
+            Cisco-AVPair attribute (if it exists) in the request
+            packet,
 
   Attributes as environment variables in executed programs
   --------------------------------------------------------
index 59f1b8b..4684881 100644 (file)
@@ -137,7 +137,51 @@ static int xlat_packet(void *instance, REQUEST *request,
         *      The "format" string is the attribute name.
         */
        da = dict_attrbyname(fmt);
-       if (!da) return 0;
+       if (!da) {
+               int index;
+               const char *p = strchr(fmt, '[');
+               char buffer[256];
+
+               if (!p) return 0;
+               if (strlen(fmt) > sizeof(buffer)) return 0;
+
+               strNcpy(buffer, fmt, p - fmt + 1);
+
+               index = atoi(p + 1);
+
+               /*
+                *      Check the format of the index before looking
+                *      the attribute up in the dictionary, because
+                *      it's a cheap check.
+                */
+               p += 1 + strspn(p + 1, "0123456789");
+               if (*p != ']') {
+                       DEBUG2("xlat: Invalid array reference in string at %s %s",
+                              fmt, p);
+                       return 0;
+               }
+
+               da = dict_attrbyname(buffer);
+               if (!da) return 0;
+
+
+               /*
+                *      Find the N'th value.
+                */
+               for (vp = pairfind(vps, da->attr);
+                    vp != NULL;
+                    vp = pairfind(vp->next, da->attr)) {
+                       if (index == 0) break;
+                       index--;
+               }
+
+               /*
+                *      Non-existent array reference.
+                */
+               if (!vp) return 0;
+
+               return valuepair2str(out, outlen, vp, da->type, func);
+       }
 
        vp = pairfind(vps, da->attr);
        if (!vp) {