Add %{Attribute-Name#}
authorAlan T. DeKok <aland@freeradius.org>
Mon, 7 Dec 2009 12:53:14 +0000 (13:53 +0100)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 7 Dec 2009 12:53:14 +0000 (13:53 +0100)
This prints the numerical value, rather than the decoded time/VALUE

man/man5/unlang.5
src/main/xlat.c

index c7beea5..6d36bb7 100644 (file)
@@ -502,6 +502,15 @@ 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".
+.IP %{Attribute-Name#}
+Will print the integer value of the attribute, rather than a decoded
+VALUE or date.  This feature applies only to attributes of type
+"date", "integer", "byte", and "short".  It has no effect on any other
+attributes.  It is used when the numerical value is needed (e.g. Unix
+seconds), rather than a humanly-readable string.
+
+e.g. If a request contains "Service-Type = Login-User", the expansion
+of %{Service-Type#} will yeild "1".
 .IP %{Attribute-Name[index]}
 Reference the N'th occurance of the given attribute.  The syntax
 %{<list>:Attribute-Name[index]} may also be used.  The indexes start
index 8edc2e8..4d1572a 100644 (file)
@@ -159,18 +159,46 @@ static size_t xlat_packet(void *instance, REQUEST *request,
         */
        da = dict_attrbyname(fmt);
        if (!da) {
+               int do_number = FALSE;
                size_t count;
-               const char *p = strchr(fmt, '[');
+               const char *p;
                char buffer[256];
 
-               if (!p) return 0;
                if (strlen(fmt) > sizeof(buffer)) return 0;
 
+               DEBUG("GOT SHIT %s", fmt);
+
+               p = strchr(fmt, '[');
+               if (!p) {
+                       p = strchr(fmt, '#');
+                       if (!p) return 0;
+                       do_number = TRUE;
+               }
+
                strlcpy(buffer, fmt, p - fmt + 1);
 
                da = dict_attrbyname(buffer);
                if (!da) return 0;
 
+               if (do_number) {
+                       vp = pairfind(vps, da->attr);
+                       if (!vp) return 0;
+
+                       switch (da->type) {
+                       default:
+                               break;
+
+                       case PW_TYPE_INTEGER:
+                       case PW_TYPE_DATE:
+                       case PW_TYPE_SHORT:
+                       case PW_TYPE_BYTE:
+                               snprintf(out, outlen, "%u", vp->lvalue);
+                               return strlen(out);
+                       }
+
+                       goto just_print;
+               }
+
                /*
                 *      %{Attribute-Name[#]} returns the count of
                 *      attributes of that name in the list.
@@ -237,7 +265,7 @@ static size_t xlat_packet(void *instance, REQUEST *request,
                 *      Non-existent array reference.
                 */
                if (!vp) return 0;
-
+       just_print:
                return valuepair2str(out, outlen, vp, da->type, func);
        }
 
@@ -499,7 +527,8 @@ static xlat_t *xlat_find(const char *module)
         *      Look for dictionary attributes first.
         */
        if ((dict_attrbyname(module) != NULL) ||
-           (strchr(module, '[') != NULL)) {
+           (strchr(module, '[') != NULL) ||
+           (strchr(module, '#') != NULL)) {
                module = "request";
        }